• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

messagelist

  • sources
  • kde-4.12
  • kdepim
  • messagelist
  • utils
themeeditor.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright 2008 Szymon Tomasz Stefanek <pragma@kvirc.net>
4  *
5  * This program is free softhisare; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Softhisare Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Softhisare
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  *******************************************************************************/
20 
21 #include "utils/themeeditor.h"
22 #include "core/theme.h"
23 #include "core/groupheaderitem.h"
24 #include "core/messageitem.h"
25 #include "core/modelinvariantrowmapper.h"
26 #include "core/manager.h"
27 #include "utils/comboboxutils.h"
28 
29 #include <akonadi/kmime/messagestatus.h>
30 
31 #include <QActionGroup>
32 #include <QCheckBox>
33 #include <QCursor>
34 #include <QDrag>
35 #include <QGridLayout>
36 #include <QGroupBox>
37 #include <QHeaderView>
38 #include <QLabel>
39 #include <QMouseEvent>
40 #include <QTreeWidget>
41 #include <QPainter>
42 #include <QPaintEvent>
43 #include <QPixmap>
44 #include <QPushButton>
45 #include <QSpinBox>
46 #include <QStringList>
47 
48 #include <KColorDialog>
49 #include <KComboBox>
50 #include <KLineEdit>
51 #include <KLocale>
52 #include <KFontDialog>
53 #include <KMenu>
54 #include <KIconLoader>
55 #include <KNumInput>
56 #include <KTextEdit>
57 
58 #include <time.h> // for time_t
59 
60 using namespace MessageList::Utils;
61 using namespace MessageList::Core;
62 
63 static const char * gThemeContentItemTypeDndMimeDataFormat = "application/x-kmail-messagelistview-theme-contentitem-type";
64 
65 
66 
67 
68 
69 ThemeColumnPropertiesDialog::ThemeColumnPropertiesDialog( QWidget * parent, Theme::Column * column, const QString &title )
70  : KDialog( parent ), mColumn( column )
71 {
72  //setAttribute( Qt::WA_DeleteOnClose );
73  setWindowModality( Qt::ApplicationModal ); // FIXME: Sure ?
74  setButtons( Ok | Cancel );
75  setWindowTitle( title );
76 
77  QWidget * base = new QWidget( this );
78  setMainWidget( base );
79 
80  QGridLayout * g = new QGridLayout( base );
81 
82  QLabel * l;
83 
84  l = new QLabel( i18nc( "@label:textbox Property name", "Name:" ), base );
85  g->addWidget( l, 0, 0 );
86 
87  mNameEdit = new KLineEdit( base );
88  mNameEdit->setToolTip( i18n( "The label that will be displayed in the column header." ) );
89  g->addWidget( mNameEdit, 0, 1 );
90 
91  l = new QLabel( i18n( "Header click sorts messages:" ), base );
92  g->addWidget( l, 1, 0 );
93 
94  mMessageSortingCombo = new KComboBox( base );
95  mMessageSortingCombo->setToolTip( i18n( "The sorting order that clicking on this column header will switch to." ) );
96  g->addWidget( mMessageSortingCombo, 1, 1 );
97 
98  mVisibleByDefaultCheck = new QCheckBox( i18n( "Visible by default" ), base );
99  mVisibleByDefaultCheck->setToolTip( i18n( "Check this if this column should be visible when the theme is selected." ) );
100  g->addWidget( mVisibleByDefaultCheck, 2, 1 );
101 
102  mIsSenderOrReceiverCheck = new QCheckBox( i18n( "Contains \"Sender or Receiver\" field" ), base );
103  mIsSenderOrReceiverCheck->setToolTip( i18n( "Check this if this column label should be updated depending on the folder \"inbound\"/\"outbound\" type." ) );
104  g->addWidget( mIsSenderOrReceiverCheck, 3, 1 );
105 
106  g->setColumnStretch( 1, 1 );
107  g->setRowStretch( 10, 1 );
108 
109  connect( this, SIGNAL(okClicked()),
110  SLOT(slotOkButtonClicked()) );
111 
112  // Display the current settings
113  mNameEdit->setText( mColumn->label() );
114  mVisibleByDefaultCheck->setChecked( mColumn->visibleByDefault() );
115  mIsSenderOrReceiverCheck->setChecked( mColumn->isSenderOrReceiver() );
116  ComboBoxUtils::fillIntegerOptionCombo( mMessageSortingCombo, SortOrder::enumerateMessageSortingOptions( Aggregation::PerfectReferencesAndSubject ) );
117  ComboBoxUtils::setIntegerOptionComboValue( mMessageSortingCombo, mColumn->messageSorting() );
118 
119 }
120 
121 void ThemeColumnPropertiesDialog::slotOkButtonClicked()
122 {
123  QString text = mNameEdit->text();
124  if ( text.isEmpty() )
125  text = i18n( "Unnamed Column" );
126  mColumn->setLabel( text );
127  mColumn->setVisibleByDefault( mVisibleByDefaultCheck->isChecked() );
128  mColumn->setIsSenderOrReceiver( mIsSenderOrReceiverCheck->isChecked() );
129  mColumn->setMessageSorting(
130  static_cast< SortOrder::MessageSorting >(
131  ComboBoxUtils::getIntegerOptionComboValue( mMessageSortingCombo, SortOrder::NoMessageSorting )
132  )
133  );
134 
135  accept();
136 }
137 
138 ThemeContentItemSourceLabel::ThemeContentItemSourceLabel( QWidget * parent, Theme::ContentItem::Type type )
139  : QLabel( parent ), mType( type )
140 {
141  setFrameStyle( QFrame::StyledPanel | QFrame::Raised );
142 }
143 
144 ThemeContentItemSourceLabel::~ThemeContentItemSourceLabel()
145 {
146 }
147 
148 MessageList::Core::Theme::ContentItem::Type ThemeContentItemSourceLabel::type() const
149 {
150  return mType;
151 }
152 
153 
154 void ThemeContentItemSourceLabel::mousePressEvent( QMouseEvent * e )
155 {
156  if ( e->button() == Qt::LeftButton )
157  mMousePressPoint = e->pos();
158 }
159 
160 void ThemeContentItemSourceLabel::mouseMoveEvent( QMouseEvent * e )
161 {
162  if ( e->buttons() & Qt::LeftButton )
163  {
164  const QPoint diff = mMousePressPoint - e->pos();
165  if ( diff.manhattanLength() > 4 )
166  startDrag();
167  }
168 }
169 
170 void ThemeContentItemSourceLabel::startDrag()
171 {
172  //QPixmap pix = QPixmap::grabWidget( this );
173  //QPixmap alpha( pix.width(), pix.height() );
174  //alpha.fill(0x0f0f0f0f);
175  //pix.setAlphaChannel( alpha ); // <-- this crashes... no alpha for dragged pixmap :(
176  QMimeData * data = new QMimeData();
177  QByteArray arry;
178  arry.resize( sizeof( Theme::ContentItem::Type ) );
179  *( ( Theme::ContentItem::Type * ) arry.data() ) = mType;
180  data->setData( QLatin1String( gThemeContentItemTypeDndMimeDataFormat ), arry );
181  QDrag * drag = new QDrag( this );
182  drag->setMimeData( data );
183  //drag->setPixmap( pix );
184  //drag->setHotSpot( mapFromGlobal( QCursor::pos() ) );
185  drag->exec( Qt::CopyAction, Qt::CopyAction );
186 }
187 
188 ThemePreviewDelegate::ThemePreviewDelegate( QAbstractItemView * parent )
189  : ThemeDelegate( parent )
190 {
191  mRowMapper = new ModelInvariantRowMapper();
192 
193  mSampleGroupHeaderItem = new GroupHeaderItem( i18n( "Message Group" ) );
194 
195  mSampleGroupHeaderItem->setDate( time( 0 ) );
196  mSampleGroupHeaderItem->setMaxDate( time( 0 ) + 31337 );
197  mSampleGroupHeaderItem->setSubject( i18n( "Very long subject very long subject very long subject very long subject very long subject very long" ) );
198 
199  mSampleMessageItem = new FakeItem();
200 
201  mSampleMessageItem->setDate( time( 0 ) );
202  mSampleMessageItem->setSize( 0x31337 );
203  mSampleMessageItem->setMaxDate( time( 0 ) + 31337 );
204  mSampleMessageItem->setSender( i18n( "Sender" ) );
205  mSampleMessageItem->setReceiver( i18n( "Receiver" ) );
206  mSampleMessageItem->setSubject( i18n( "Very long subject very long subject very long subject very long subject very long subject very long" ) );
207  mSampleMessageItem->setSignatureState( MessageItem::FullySigned );
208  mSampleMessageItem->setEncryptionState( MessageItem::FullyEncrypted );
209 
210  QList< MessageItem::Tag * > list;
211  list.append( new MessageItem::Tag( SmallIcon( QLatin1String( "feed-subscribe" ) ), i18n( "Sample Tag 1" ), QString() ) );
212  list.append( new MessageItem::Tag( SmallIcon( QLatin1String( "feed-subscribe" ) ), i18n( "Sample Tag 2" ), QString() ) );
213  list.append( new MessageItem::Tag( SmallIcon( QLatin1String( "feed-subscribe" ) ), i18n( "Sample Tag 3" ), QString() ) );
214  mSampleMessageItem->setFakeTags( list );
215 
216  mRowMapper->createModelInvariantIndex( 0, mSampleMessageItem );
217 
218  mSampleGroupHeaderItem->rawAppendChildItem( mSampleMessageItem );
219  mSampleMessageItem->setParent( mSampleGroupHeaderItem );
220 
221  Akonadi::MessageStatus stat;
222 
223  stat.fromQInt32( 0x7fffffff );
224  stat.setQueued( false );
225  stat.setSent( false );
226  stat.setSpam( true );
227  stat.setWatched( true );
228  stat.setHasInvitation();
229  //stat.setHasAttachment( false );
230 
231  mSampleMessageItem->setStatus( stat );
232 }
233 
234 ThemePreviewDelegate::~ThemePreviewDelegate()
235 {
236  delete mSampleGroupHeaderItem;
237  //delete mSampleMessageItem; (deleted by the parent)
238  delete mRowMapper;
239 }
240 
241 Item * ThemePreviewDelegate::itemFromIndex( const QModelIndex &index ) const
242 {
243  if ( index.parent().isValid() )
244  return mSampleMessageItem;
245 
246  return mSampleGroupHeaderItem;
247 }
248 
249 
250 
251 
252 
253 ThemePreviewWidget::ThemePreviewWidget( QWidget * parent )
254  : QTreeWidget( parent ),
255  mTheme( 0 )
256 {
257  mSelectedThemeContentItem = 0;
258  mSelectedThemeColumn = 0;
259  mFirstShow = true;
260  mReadOnly = false;
261 
262  mDelegate = new ThemePreviewDelegate( this );
263  setItemDelegate( mDelegate );
264  setRootIsDecorated( false );
265  viewport()->setAcceptDrops( true );
266 
267  header()->setContextMenuPolicy( Qt::CustomContextMenu ); // make sure it's true
268  connect( header(), SIGNAL(customContextMenuRequested(QPoint)),
269  SLOT(slotHeaderContextMenuRequested(QPoint)) );
270 
271  mGroupHeaderSampleItem = new QTreeWidgetItem( this );
272  mGroupHeaderSampleItem->setText( 0, QString() );
273  mGroupHeaderSampleItem->setFlags( Qt::ItemIsEnabled );
274 
275  QTreeWidgetItem * m = new QTreeWidgetItem( mGroupHeaderSampleItem );
276  m->setText( 0, QString() );
277 
278  mGroupHeaderSampleItem->setExpanded( true );
279  header()->setMovable(false);
280 }
281 
282 ThemePreviewWidget::~ThemePreviewWidget()
283 {
284 }
285 
286 QSize ThemePreviewWidget::sizeHint() const
287 {
288  return QSize( 350, 180 );
289 }
290 
291 void ThemePreviewWidget::setReadOnly( bool readOnly )
292 {
293  mReadOnly = readOnly;
294 }
295 
296 void ThemePreviewWidget::applyThemeColumnWidths()
297 {
298  if ( !mTheme )
299  return;
300 
301  const QList< Theme::Column * > & columns = mTheme->columns();
302 
303  if ( columns.isEmpty() )
304  {
305  viewport()->update(); // trigger a repaint
306  return;
307  }
308 
309  // Now we want to distribute the available width on all the columns.
310  // The algorithm used here is very similar to the one used in View::applyThemeColumns().
311  // It just takes care of ALL the columns instead of the visible ones.
312 
313  QList< Theme::Column * >::ConstIterator it;
314 
315  // Gather size hints for all sections.
316  int idx = 0;
317  int totalVisibleWidthHint = 0;
318  QList< Theme::Column * >::ConstIterator end( columns.constEnd() );
319 
320  for ( it = columns.constBegin(); it != end; ++it )
321  {
322  totalVisibleWidthHint += mDelegate->sizeHintForItemTypeAndColumn( Item::Message, idx ).width();
323  idx++;
324  }
325 
326  if ( totalVisibleWidthHint < 16 )
327  totalVisibleWidthHint = 16; // be reasonable
328 
329  // Now we can compute proportional widths.
330 
331  idx = 0;
332 
333  QList< int > realWidths;
334  int totalVisibleWidth = 0;
335 
336  end = columns.constEnd();
337  for ( it = columns.constBegin(); it != end; ++it )
338  {
339  int hintWidth = mDelegate->sizeHintForItemTypeAndColumn( Item::Message, idx ).width();
340  int realWidth;
341  if ( ( *it )->containsTextItems() )
342  {
343  // the column contains text items, it should get more space
344  realWidth = ( ( hintWidth * viewport()->width() ) / totalVisibleWidthHint ) - 2; // -2 is heuristic
345  if ( realWidth < ( hintWidth + 2 ) )
346  realWidth = hintWidth + 2; // can't be less
347  } else {
348  // the column contains no text items, it should get just a little bit more than its sizeHint().
349  realWidth = hintWidth + 2;
350  }
351 
352  realWidths.append( realWidth );
353  totalVisibleWidth += realWidth;
354 
355  idx++;
356  }
357 
358  idx = 0;
359 
360  totalVisibleWidth += 4; // account for some view's border
361 
362  if ( totalVisibleWidth < viewport()->width() )
363  {
364  // give the additional space to the text columns
365  // also give more space to the first ones and less space to the last ones
366  int available = viewport()->width() - totalVisibleWidth;
367 
368  for ( it = columns.begin(); it != columns.end(); ++it )
369  {
370  if ( ( ( *it )->visibleByDefault() || ( idx == 0 ) ) && ( *it )->containsTextItems() )
371  {
372  // give more space to this column
373  available >>= 1; // eat half of the available space
374  realWidths[ idx ] += available; // and give it to this column
375  }
376 
377  idx++;
378  }
379 
380  // if any space is still available, give it to the first column
381  if ( available )
382  realWidths[ 0 ] += available;
383  }
384 
385 
386  idx = 0;
387 
388  // We're ready.
389  // Assign widths. Hide the sections that are not visible by default, show the other ones.
390  for ( it = columns.begin(); it != columns.end(); ++it )
391  {
392  header()->resizeSection( idx, realWidths[ idx ] );
393  idx++;
394  }
395 
396 #if 0
397  if( mTheme->viewHeaderPolicy() == Theme::NeverShowHeader )
398  header()->hide();
399  else
400  header()->show();
401 #endif
402 }
403 
404 
405 void ThemePreviewWidget::setTheme( Theme * theme )
406 {
407  bool themeChanged = theme != mTheme;
408 
409  mSelectedThemeContentItem = 0;
410  mThemeSelectedContentItemRect = QRect();
411  mDropIndicatorPoint1 = QPoint();
412  mDropIndicatorPoint2 = QPoint();
413  mTheme = theme;
414  mDelegate->setTheme( theme );
415  if (!mTheme)
416  return;
417  mGroupHeaderSampleItem->setExpanded( true );
418 
419  const QList< Theme::Column * > & columns = mTheme->columns();
420 
421  setColumnCount( columns.count() );
422 
423  QStringList headerLabels;
424  QList< Theme::Column * >::ConstIterator end( columns.constEnd() );
425  for( QList< Theme::Column * >::ConstIterator it = columns.constBegin(); it != end; ++it )
426  {
427  QString label = ( *it )->label();
428  if ( ( *it )->visibleByDefault() )
429  label += QString::fromLatin1( " (%1)" ).arg( i18nc( "Indicates whether or not a header label is visible", "Visible") );
430 
431  headerLabels.append( label );
432  }
433 
434  setHeaderLabels( headerLabels );
435 
436  if ( themeChanged )
437  applyThemeColumnWidths();
438 
439  viewport()->update(); // trigger a repaint
440 }
441 
442 void ThemePreviewWidget::internalHandleDragEnterEvent( QDragEnterEvent * e )
443 {
444  e->ignore();
445 
446  if ( !e->mimeData() )
447  return;
448  if ( !e->mimeData()->hasFormat( QLatin1String( gThemeContentItemTypeDndMimeDataFormat ) ) )
449  return;
450 
451  e->accept();
452 }
453 
454 void ThemePreviewWidget::showEvent( QShowEvent * e )
455 {
456  QTreeWidget::showEvent( e );
457 
458  if ( mFirstShow )
459  {
460  // Make sure we re-apply column widths the first time we're shown.
461  // The first "apply" call was made while the widget was still hidden and
462  // almost surely had wrong sizes.
463  applyThemeColumnWidths();
464  mFirstShow = false;
465  }
466 }
467 
468 void ThemePreviewWidget::dragEnterEvent( QDragEnterEvent * e )
469 {
470  internalHandleDragEnterEvent( e );
471 
472  mThemeSelectedContentItemRect = QRect();
473 
474  viewport()->update(); // trigger a repaint
475 }
476 
477 void ThemePreviewWidget::internalHandleDragMoveEvent( QDragMoveEvent * e )
478 {
479  e->ignore();
480 
481  if ( mReadOnly )
482  return;
483 
484  if ( !e->mimeData() )
485  return;
486  if ( !e->mimeData()->hasFormat( QLatin1String( gThemeContentItemTypeDndMimeDataFormat ) ) )
487  return;
488 
489  QByteArray arry = e->mimeData()->data(QLatin1String( gThemeContentItemTypeDndMimeDataFormat ) );
490 
491  if ( arry.size() != sizeof( Theme::ContentItem::Type ) )
492  return; // ugh
493 
494  Theme::ContentItem::Type type = *( ( Theme::ContentItem::Type * ) arry.data() );
495 
496  if ( !computeContentItemInsertPosition( e->pos(), type ) )
497  return;
498 
499  e->accept();
500 }
501 
502 void ThemePreviewWidget::dragMoveEvent( QDragMoveEvent * e )
503 {
504  if ( mReadOnly )
505  return;
506 
507  internalHandleDragMoveEvent( e );
508 
509  mThemeSelectedContentItemRect = QRect();
510 
511  viewport()->update(); // trigger a repaint
512 }
513 
514 
515 void ThemePreviewWidget::dropEvent( QDropEvent * e )
516 {
517  mDropIndicatorPoint1 = mDropIndicatorPoint2;
518 
519  e->ignore();
520 
521  if ( mReadOnly )
522  return;
523 
524  if ( !e->mimeData() )
525  return;
526 
527  if ( !e->mimeData()->hasFormat( QLatin1String( gThemeContentItemTypeDndMimeDataFormat ) ) )
528  return;
529 
530  QByteArray arry = e->mimeData()->data( QLatin1String( gThemeContentItemTypeDndMimeDataFormat ) );
531 
532  if ( arry.size() != sizeof( Theme::ContentItem::Type ) )
533  return; // ugh
534 
535  Theme::ContentItem::Type type = *( ( Theme::ContentItem::Type * ) arry.data() );
536 
537  if ( !computeContentItemInsertPosition( e->pos(), type ) )
538  {
539  viewport()->update();
540  return;
541  }
542 
543  Theme::Row * row = 0;
544 
545  switch ( mRowInsertPosition )
546  {
547  case AboveRow:
548  row = new Theme::Row();
549  if ( mDelegate->hitItem()->type() == Item::Message )
550  const_cast< Theme::Column * >( mDelegate->hitColumn() )->insertMessageRow( mDelegate->hitRowIndex(), row );
551  else
552  const_cast< Theme::Column * >( mDelegate->hitColumn() )->insertGroupHeaderRow( mDelegate->hitRowIndex(), row );
553  break;
554  case InsideRow:
555  row = const_cast< Theme::Row * >( mDelegate->hitRow() );
556  break;
557  case BelowRow:
558  row = new Theme::Row();
559  if ( mDelegate->hitItem()->type() == Item::Message )
560  const_cast< Theme::Column * >( mDelegate->hitColumn() )->insertMessageRow( mDelegate->hitRowIndex()+1, row );
561  else
562  const_cast< Theme::Column * >( mDelegate->hitColumn() )->insertGroupHeaderRow( mDelegate->hitRowIndex()+1, row );
563  break;
564  }
565 
566  if ( !row )
567  return;
568 
569  Theme::ContentItem * ci = new Theme::ContentItem( type );
570  if ( ci->canBeDisabled() )
571  {
572  if ( ci->isClickable() )
573  ci->setSoftenByBlendingWhenDisabled( true ); // default to softened
574  else
575  ci->setHideWhenDisabled( true ); // default to hidden
576  }
577 
578  int idx;
579 
580  switch( mItemInsertPosition )
581  {
582  case OnLeftOfItem:
583  if ( !mDelegate->hitContentItem() )
584  {
585  // bleah
586  delete ci;
587  return;
588  }
589  idx = mDelegate->hitContentItemRight() ? \
590  row->rightItems().indexOf( const_cast< Theme::ContentItem * >( mDelegate->hitContentItem() ) ) : \
591  row->leftItems().indexOf( const_cast< Theme::ContentItem * >( mDelegate->hitContentItem() ) );
592  if ( idx < 0 )
593  {
594  // bleah
595  delete ci;
596  return;
597  }
598  if ( mDelegate->hitContentItemRight() )
599  row->insertRightItem( idx+1, ci );
600  else
601  row->insertLeftItem( idx, ci );
602  break;
603  case OnRightOfItem:
604  if ( !mDelegate->hitContentItem() )
605  {
606  // bleah
607  delete ci;
608  return;
609  }
610  idx = mDelegate->hitContentItemRight() ? \
611  row->rightItems().indexOf( const_cast< Theme::ContentItem * >( mDelegate->hitContentItem() ) ) : \
612  row->leftItems().indexOf( const_cast< Theme::ContentItem * >( mDelegate->hitContentItem() ) );
613  if ( idx < 0 )
614  {
615  // bleah
616  delete ci;
617  return;
618  }
619  if ( mDelegate->hitContentItemRight() )
620  row->insertRightItem( idx, ci );
621  else
622  row->insertLeftItem( idx+1, ci );
623  break;
624  case AsLastLeftItem:
625  row->addLeftItem( ci );
626  break;
627  case AsLastRightItem:
628  row->addRightItem( ci );
629  break;
630  case AsFirstLeftItem:
631  row->insertLeftItem( 0, ci );
632  break;
633  case AsFirstRightItem:
634  row->insertRightItem( 0, ci );
635  break;
636  default: // should never happen
637  row->addRightItem( ci );
638  break;
639  }
640 
641  e->acceptProposedAction();
642 
643  mThemeSelectedContentItemRect = QRect();
644  mDropIndicatorPoint1 = mDropIndicatorPoint2;
645  mSelectedThemeContentItem = 0;
646 
647  setTheme( mTheme ); // this will reset theme cache and trigger a global update
648 }
649 
650 bool ThemePreviewWidget::computeContentItemInsertPosition( const QPoint &pos, Theme::ContentItem::Type type )
651 {
652  mDropIndicatorPoint1 = mDropIndicatorPoint2; // this marks the position as invalid
653 
654  if ( !mDelegate->hitTest( pos, false ) )
655  return false;
656 
657  if ( !mDelegate->hitRow() )
658  return false;
659 
660  if ( mDelegate->hitRowIsMessageRow() )
661  {
662  if ( !Theme::ContentItem::applicableToMessageItems( type ) )
663  return false;
664  } else {
665  if ( !Theme::ContentItem::applicableToGroupHeaderItems( type ) )
666  return false;
667  }
668 
669  QRect rowRect = mDelegate->hitRowRect();
670 
671  if ( pos.y() < rowRect.top() + 3 )
672  {
673  // above a row
674  mRowInsertPosition = AboveRow;
675  if ( pos.x() < ( rowRect.left() + ( rowRect.width() / 2 ) ) )
676  {
677  mDropIndicatorPoint1 = rowRect.topLeft();
678  mItemInsertPosition = AsLastLeftItem;
679  } else {
680  mDropIndicatorPoint1 = rowRect.topRight();
681  mItemInsertPosition = AsLastRightItem;
682  }
683  mDropIndicatorPoint2 = QPoint( rowRect.left() + ( rowRect.width() / 2 ), rowRect.top() );
684  return true;
685  }
686 
687  if ( pos.y() > rowRect.bottom() - 3 )
688  {
689  // below a row
690  mRowInsertPosition = BelowRow;
691  if ( pos.x() < ( rowRect.left() + ( rowRect.width() / 2 ) ) )
692  {
693  mDropIndicatorPoint1 = rowRect.bottomLeft();
694  mItemInsertPosition = AsLastLeftItem;
695  } else {
696  mDropIndicatorPoint1 = rowRect.bottomRight();
697  mItemInsertPosition = AsLastRightItem;
698  }
699  mDropIndicatorPoint2 = QPoint( rowRect.left() + ( rowRect.width() / 2 ), rowRect.bottom() );
700  return true;
701  }
702 
703  mRowInsertPosition = InsideRow;
704 
705  if ( !mDelegate->hitContentItem() )
706  {
707  // didn't hit anything... probably no items in the row
708  if ( pos.x() < ( rowRect.left() + ( rowRect.width() / 2 ) ) )
709  {
710  mItemInsertPosition = AsLastLeftItem;
711  mDropIndicatorPoint1 = QPoint( rowRect.left(), rowRect.top() );
712  mDropIndicatorPoint2 = QPoint( rowRect.left(), rowRect.bottom() );
713  } else {
714  mItemInsertPosition = AsLastRightItem;
715  mDropIndicatorPoint1 = QPoint( rowRect.right(), rowRect.top() );
716  mDropIndicatorPoint2 = QPoint( rowRect.right(), rowRect.bottom() );
717  }
718  return true;
719  }
720 
721  // hit something, maybe inexactly
722  QRect itemRect = mDelegate->hitContentItemRect();
723 
724  if ( !itemRect.contains( pos ) )
725  {
726  // inexact hit: outside an item
727  if ( pos.x() > itemRect.right() )
728  {
729  // right side of an item
730  if ( mDelegate->hitRow()->rightItems().count() < 1 )
731  {
732  // between the last left item and the right side
733  if ( pos.x() > ( itemRect.right() + ( ( rowRect.right() - itemRect.right() ) / 2 ) ) )
734  {
735  // first/last right item
736  mItemInsertPosition = AsFirstRightItem;
737  mDropIndicatorPoint1 = rowRect.topRight();
738  mDropIndicatorPoint2 = rowRect.bottomRight();
739  }
740  return true;
741  }
742  // either there were some right items (so the theme delegate knows that the reported item is the closest)
743  // or there were no right items but the position is closest to the left item than the right row end
744  mItemInsertPosition = OnRightOfItem;
745  mDropIndicatorPoint1 = itemRect.topRight();
746  mDropIndicatorPoint2 = itemRect.bottomRight();
747  return true;
748  }
749 
750  // left side of an item
751  if ( mDelegate->hitRow()->leftItems().count() < 1 )
752  {
753  // between the left side and the leftmost right item
754  if ( pos.x() < ( itemRect.left() - ( ( itemRect.left() - rowRect.left() ) / 2 ) ) )
755  {
756  mItemInsertPosition = AsFirstLeftItem;
757  mDropIndicatorPoint1 = rowRect.topLeft();
758  mDropIndicatorPoint2 = rowRect.bottomLeft();
759  return true;
760  }
761  }
762  mItemInsertPosition = OnLeftOfItem;
763  mDropIndicatorPoint1 = itemRect.topLeft();
764  mDropIndicatorPoint2 = itemRect.bottomLeft();
765  return true;
766  }
767 
768  // exact hit
769  if ( pos.x() < ( itemRect.left() + ( itemRect.width() / 2 ) ) )
770  {
771  // left side
772  mItemInsertPosition = OnLeftOfItem;
773  mDropIndicatorPoint1 = itemRect.topLeft();
774  mDropIndicatorPoint2 = itemRect.bottomLeft();
775  return true;
776  }
777 
778  // right side
779  mItemInsertPosition = OnRightOfItem;
780  mDropIndicatorPoint1 = itemRect.topRight();
781  mDropIndicatorPoint2 = itemRect.bottomRight();
782  return true;
783 }
784 
785 void ThemePreviewWidget::mouseMoveEvent( QMouseEvent * e )
786 {
787  if ( ! ( mSelectedThemeContentItem && ( e->buttons() & Qt::LeftButton ) ) || mReadOnly )
788  {
789  QTreeWidget::mouseMoveEvent( e );
790  return;
791  }
792 
793  if ( mSelectedThemeContentItem != mDelegate->hitContentItem() )
794  {
795  QTreeWidget::mouseMoveEvent( e );
796  return; // ugh.. something weird happened
797  }
798 
799  // starting a drag ?
800  const QPoint diff = e->pos() - mMouseDownPoint;
801  if ( diff.manhattanLength() <= 4 )
802  {
803  QTreeWidget::mouseMoveEvent( e );
804  return; // ugh.. something weird happened
805  }
806 
807  // starting a drag
808  QMimeData * data = new QMimeData();
809  QByteArray arry;
810  arry.resize( sizeof( Theme::ContentItem::Type ) );
811  *( ( Theme::ContentItem::Type * ) arry.data() ) = mSelectedThemeContentItem->type();
812  data->setData( QLatin1String( gThemeContentItemTypeDndMimeDataFormat ), arry );
813  QDrag * drag = new QDrag( this );
814  drag->setMimeData( data );
815 
816  // remove the Theme::ContentItem from the Theme
817  if ( mDelegate->hitContentItemRight() )
818  const_cast< Theme::Row * >( mDelegate->hitRow() )->removeRightItem( mSelectedThemeContentItem );
819  else
820  const_cast< Theme::Row * >( mDelegate->hitRow() )->removeLeftItem( mSelectedThemeContentItem );
821 
822  delete mSelectedThemeContentItem;
823 
824  if ( mDelegate->hitRow()->rightItems().isEmpty() && mDelegate->hitRow()->leftItems().isEmpty() )
825  {
826  if ( mDelegate->hitItem()->type() == Item::Message )
827  {
828  if ( mDelegate->hitColumn()->messageRows().count() > 1 )
829  {
830  const_cast< Theme::Column * >( mDelegate->hitColumn() )->removeMessageRow( const_cast< Theme::Row * >( mDelegate->hitRow() ) );
831  delete mDelegate->hitRow();
832  }
833  } else {
834  if ( mDelegate->hitColumn()->groupHeaderRows().count() > 1 )
835  {
836  const_cast< Theme::Column * >( mDelegate->hitColumn() )->removeGroupHeaderRow( const_cast< Theme::Row * >( mDelegate->hitRow() ) );
837  delete mDelegate->hitRow();
838  }
839  }
840  }
841 
842  mSelectedThemeContentItem = 0;
843  mThemeSelectedContentItemRect = QRect();
844  mDropIndicatorPoint1 = mDropIndicatorPoint2;
845 
846  setTheme( mTheme ); // this will reset theme cache and trigger a global update
847 
848  // and do drag
849  drag->exec( Qt::CopyAction, Qt::CopyAction );
850 }
851 
852 void ThemePreviewWidget::mousePressEvent( QMouseEvent * e )
853 {
854  if ( mReadOnly ) {
855  QTreeWidget::mousePressEvent( e );
856  return;
857  }
858 
859  mMouseDownPoint = e->pos();
860 
861  if ( mDelegate->hitTest( mMouseDownPoint ) )
862  {
863  mSelectedThemeContentItem = const_cast< Theme::ContentItem * >( mDelegate->hitContentItem() );
864  mThemeSelectedContentItemRect = mSelectedThemeContentItem ? mDelegate->hitContentItemRect() : QRect();
865  } else {
866  mSelectedThemeContentItem = 0;
867  mThemeSelectedContentItemRect = QRect();
868  }
869 
870  QTreeWidget::mousePressEvent( e );
871  viewport()->update();
872 
873  if ( e->button() == Qt::RightButton )
874  {
875  KMenu menu;
876 
877  if ( mSelectedThemeContentItem )
878  {
879 
880  menu.addTitle( Theme::ContentItem::description( mSelectedThemeContentItem->type() ) );
881 
882  if ( mSelectedThemeContentItem->displaysText() )
883  {
884  QAction * act;
885  act = menu.addAction( i18nc( "@action:inmenu soften the text color", "Soften" ) );
886  act->setCheckable( true );
887  act->setChecked( mSelectedThemeContentItem->softenByBlending() );
888  connect( act, SIGNAL(triggered(bool)),
889  SLOT(slotSoftenActionTriggered(bool)) );
890 
891  KMenu * childmenu = new KMenu( &menu );
892 
893  QActionGroup * grp = new QActionGroup( childmenu );
894 
895  act = childmenu->addAction( i18nc("@action:inmenu Font setting", "Default") );
896  act->setData( QVariant( static_cast< int >( 0 ) ) );
897  act->setCheckable( true );
898  act->setChecked( !mSelectedThemeContentItem->useCustomFont() );
899  grp->addAction( act );
900  act = childmenu->addAction( i18nc("@action:inmenu Font setting", "Custom...") );
901  act->setData( QVariant( static_cast< int >( Theme::ContentItem::UseCustomFont ) ) );
902  act->setCheckable( true );
903  act->setChecked( mSelectedThemeContentItem->useCustomFont() );
904  grp->addAction( act );
905 
906 
907  connect( childmenu, SIGNAL(triggered(QAction*)),
908  SLOT(slotFontMenuTriggered(QAction*)) );
909 
910  menu.addMenu( childmenu )->setText( i18n( "Font" ) );
911  }
912 
913  if ( mSelectedThemeContentItem->canUseCustomColor() )
914  {
915  KMenu * childmenu = new KMenu( &menu );
916 
917  QActionGroup * grp = new QActionGroup( childmenu );
918 
919  QAction * act;
920  act = childmenu->addAction( i18nc("@action:inmenu Foreground color setting", "Default") );
921  act->setData( QVariant( static_cast< int >( 0 ) ) );
922  act->setCheckable( true );
923  act->setChecked( !mSelectedThemeContentItem->useCustomColor() );
924  grp->addAction( act );
925  act = childmenu->addAction( i18nc("@action:inmenu Foreground color setting", "Custom...") );
926  act->setData( QVariant( static_cast< int >( Theme::ContentItem::UseCustomColor ) ) );
927  act->setCheckable( true );
928  act->setChecked( mSelectedThemeContentItem->useCustomColor() );
929  grp->addAction( act );
930 
931  connect( childmenu, SIGNAL(triggered(QAction*)),
932  SLOT(slotForegroundColorMenuTriggered(QAction*)) );
933 
934  menu.addMenu( childmenu )->setText( i18n( "Foreground Color" ) );
935  }
936 
937 
938  if ( mSelectedThemeContentItem->canBeDisabled() )
939  {
940  KMenu * childmenu = new KMenu( &menu );
941 
942  QActionGroup * grp = new QActionGroup( childmenu );
943 
944  QAction * act;
945  act = childmenu->addAction( i18nc("Hide a mark if the mail does not have the attribute, e.g. Important mark on a non important mail", "Hide") );
946  act->setData( QVariant( static_cast< int >( Theme::ContentItem::HideWhenDisabled ) ) );
947  act->setCheckable( true );
948  act->setChecked( mSelectedThemeContentItem->hideWhenDisabled() );
949  grp->addAction( act );
950  act = childmenu->addAction( i18nc("Keep a empty space in the list if the mail does not have the attribute, e.g. Important mark on a non important mail", "Keep Empty Space") );
951  act->setData( QVariant( static_cast< int >( 0 ) ) );
952  act->setCheckable( true );
953  act->setChecked( ! ( mSelectedThemeContentItem->softenByBlendingWhenDisabled() || mSelectedThemeContentItem->hideWhenDisabled() ) );
954  grp->addAction( act );
955  act = childmenu->addAction( i18nc("Show the icon softened in the list if the mail does not have the attribute, e.g. Important mark on a non important mail", "Keep Softened Icon") );
956  act->setData( QVariant( static_cast< int >( Theme::ContentItem::SoftenByBlendingWhenDisabled ) ) );
957  act->setCheckable( true );
958  act->setChecked( mSelectedThemeContentItem->softenByBlendingWhenDisabled() );
959  grp->addAction( act );
960 
961  connect( childmenu, SIGNAL(triggered(QAction*)),
962  SLOT(slotDisabledFlagsMenuTriggered(QAction*)) );
963 
964  menu.addMenu( childmenu )->setText( i18n( "When Disabled" ) );
965  }
966 
967  }
968 
969  if ( mDelegate->hitItem() )
970  {
971  if ( mDelegate->hitItem()->type() == Item::GroupHeader )
972  {
973  menu.addTitle( i18n( "Group Header" ) );
974 
975  // Background color (mode) submenu
976  KMenu * childmenu = new KMenu( &menu );
977 
978  QActionGroup * grp = new QActionGroup( childmenu );
979 
980  QAction * act;
981  act = childmenu->addAction( i18nc("@action:inmenu Group header background color setting", "None") );
982  act->setData( QVariant( static_cast< int >( Theme::Transparent ) ) );
983  act->setCheckable( true );
984  act->setChecked( mTheme->groupHeaderBackgroundMode() == Theme::Transparent );
985  grp->addAction( act );
986  act = childmenu->addAction( i18nc("@action:inmenu Group header background color setting", "Automatic") );
987  act->setData( QVariant( static_cast< int >( Theme::AutoColor ) ) );
988  act->setCheckable( true );
989  act->setChecked( mTheme->groupHeaderBackgroundMode() == Theme::AutoColor );
990  grp->addAction( act );
991  act = childmenu->addAction( i18nc("@action:inmenu Group header background color setting", "Custom...") );
992  act->setData( QVariant( static_cast< int >( Theme::CustomColor ) ) );
993  act->setCheckable( true );
994  act->setChecked( mTheme->groupHeaderBackgroundMode() == Theme::CustomColor );
995  grp->addAction( act );
996 
997 
998  connect( childmenu, SIGNAL(triggered(QAction*)),
999  SLOT(slotGroupHeaderBackgroundModeMenuTriggered(QAction*)) );
1000 
1001  menu.addMenu( childmenu )->setText( i18n( "Background Color" ) );
1002 
1003  // Background style submenu
1004  childmenu = new KMenu( &menu );
1005 
1006  grp = new QActionGroup( childmenu );
1007  QList< QPair< QString, int > > styles = Theme::enumerateGroupHeaderBackgroundStyles();
1008  QList< QPair< QString, int > >::ConstIterator end( styles.constEnd() );
1009 
1010  for ( QList< QPair< QString, int > >::ConstIterator it = styles.constBegin(); it != end; ++it )
1011  {
1012  act = childmenu->addAction( ( *it ).first );
1013  act->setData( QVariant( ( *it ).second ) );
1014  act->setCheckable( true );
1015  act->setChecked( mTheme->groupHeaderBackgroundStyle() == static_cast< Theme::GroupHeaderBackgroundStyle >( ( *it ).second ) );
1016  grp->addAction( act );
1017  }
1018 
1019  connect( childmenu, SIGNAL(triggered(QAction*)),
1020  SLOT(slotGroupHeaderBackgroundStyleMenuTriggered(QAction*)) );
1021 
1022  act = menu.addMenu( childmenu );
1023  act->setText( i18n( "Background Style" ) );
1024  if ( mTheme->groupHeaderBackgroundMode() == Theme::Transparent )
1025  act->setEnabled( false );
1026 
1027  }
1028  }
1029 
1030 
1031  if ( menu.isEmpty() )
1032  return;
1033 
1034  menu.exec( viewport()->mapToGlobal( e->pos() ) );
1035 
1036  }
1037 }
1038 
1039 void ThemePreviewWidget::slotDisabledFlagsMenuTriggered( QAction * act )
1040 {
1041  if ( !mSelectedThemeContentItem )
1042  return;
1043 
1044  bool ok;
1045  const int flags = act->data().toInt( &ok );
1046  if ( !ok )
1047  return;
1048 
1049  mSelectedThemeContentItem->setHideWhenDisabled( flags == Theme::ContentItem::HideWhenDisabled );
1050  mSelectedThemeContentItem->setSoftenByBlendingWhenDisabled( flags == Theme::ContentItem::SoftenByBlendingWhenDisabled );
1051 
1052  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1053 }
1054 
1055 void ThemePreviewWidget::slotForegroundColorMenuTriggered( QAction * act )
1056 {
1057  if ( !mSelectedThemeContentItem )
1058  return;
1059 
1060  bool ok;
1061  const int flag = act->data().toInt( &ok );
1062  if ( !ok )
1063  return;
1064 
1065  if ( flag == 0 )
1066  {
1067  mSelectedThemeContentItem->setUseCustomColor( false );
1068  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1069  return;
1070  }
1071 
1072  QColor clr;
1073  const int result = KColorDialog::getColor( clr, mSelectedThemeContentItem->customColor(), this );
1074  if ( result != KColorDialog::Accepted )
1075  return;
1076 
1077  mSelectedThemeContentItem->setCustomColor( clr );
1078  mSelectedThemeContentItem->setUseCustomColor( true );
1079 
1080  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1081 }
1082 
1083 void ThemePreviewWidget::slotSoftenActionTriggered( bool )
1084 {
1085  if ( !mSelectedThemeContentItem )
1086  return;
1087 
1088  mSelectedThemeContentItem->setSoftenByBlending( !mSelectedThemeContentItem->softenByBlending() );
1089  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1090 }
1091 
1092 void ThemePreviewWidget::slotFontMenuTriggered( QAction * act )
1093 {
1094  if ( !mSelectedThemeContentItem )
1095  return;
1096 
1097  bool ok;
1098  const int flag = act->data().toInt( &ok );
1099  if ( !ok )
1100  return;
1101 
1102  if ( flag == 0 )
1103  {
1104  mSelectedThemeContentItem->setUseCustomFont( false );
1105  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1106  return;
1107  }
1108 
1109  QFont f = mSelectedThemeContentItem->font();
1110  if ( KFontDialog::getFont( f ) != KFontDialog::Accepted )
1111  return;
1112 
1113  mSelectedThemeContentItem->setFont( f );
1114  mSelectedThemeContentItem->setUseCustomFont( true );
1115 
1116  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1117 }
1118 
1119 void ThemePreviewWidget::slotGroupHeaderBackgroundModeMenuTriggered( QAction * act )
1120 {
1121  bool ok;
1122  Theme::GroupHeaderBackgroundMode mode = static_cast< Theme::GroupHeaderBackgroundMode >( act->data().toInt( &ok ) );
1123  if ( !ok )
1124  return;
1125 
1126  switch( mode )
1127  {
1128  case Theme::Transparent:
1129  mTheme->setGroupHeaderBackgroundMode( Theme::Transparent );
1130  break;
1131  case Theme::AutoColor:
1132  mTheme->setGroupHeaderBackgroundMode( Theme::AutoColor );
1133  break;
1134  case Theme::CustomColor:
1135  {
1136  QColor clr;
1137  int result = KColorDialog::getColor( clr, mTheme->groupHeaderBackgroundColor(), this );
1138  if ( result != KColorDialog::Accepted )
1139  return;
1140 
1141  mTheme->setGroupHeaderBackgroundMode( Theme::CustomColor );
1142  mTheme->setGroupHeaderBackgroundColor( clr );
1143  }
1144  break;
1145  }
1146 
1147  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1148 }
1149 
1150 void ThemePreviewWidget::slotGroupHeaderBackgroundStyleMenuTriggered( QAction * act )
1151 {
1152  bool ok;
1153  Theme::GroupHeaderBackgroundStyle mode = static_cast< Theme::GroupHeaderBackgroundStyle >( act->data().toInt( &ok ) );
1154  if ( !ok )
1155  return;
1156 
1157  mTheme->setGroupHeaderBackgroundStyle( mode );
1158 
1159  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1160 }
1161 
1162 
1163 void ThemePreviewWidget::paintEvent( QPaintEvent * e )
1164 {
1165  QTreeWidget::paintEvent( e );
1166 
1167  if (
1168  mThemeSelectedContentItemRect.isValid() ||
1169  ( mDropIndicatorPoint1 != mDropIndicatorPoint2 )
1170  )
1171  {
1172  QPainter painter( viewport() );
1173 
1174  if ( mThemeSelectedContentItemRect.isValid() )
1175  {
1176  painter.setPen( QPen( Qt::black ) );
1177  painter.drawRect( mThemeSelectedContentItemRect );
1178  }
1179  if ( mDropIndicatorPoint1 != mDropIndicatorPoint2 )
1180  {
1181  painter.setPen( QPen( Qt::black, 3 ) );
1182  painter.drawLine( mDropIndicatorPoint1, mDropIndicatorPoint2 );
1183  }
1184  }
1185 }
1186 
1187 
1188 
1189 void ThemePreviewWidget::slotHeaderContextMenuRequested( const QPoint &pos )
1190 {
1191  if ( mReadOnly )
1192  return;
1193 
1194  QTreeWidgetItem * hitem = headerItem();
1195  if ( !hitem )
1196  return; // ooops
1197 
1198  int col = header()->logicalIndexAt( pos );
1199 
1200  if ( col < 0 )
1201  return;
1202 
1203  if ( col >= mTheme->columns().count() )
1204  return;
1205 
1206  mSelectedThemeColumn = mTheme->column( col );
1207  if ( !mSelectedThemeColumn )
1208  return;
1209 
1210  KMenu menu;
1211 
1212  menu.addTitle( mSelectedThemeColumn->label() );
1213 
1214  QAction * act;
1215 
1216  act = menu.addAction( i18n( "Column Properties..." ) );
1217  connect( act, SIGNAL(triggered(bool)),
1218  SLOT(slotColumnProperties()) );
1219 
1220  act = menu.addAction( i18n( "Add Column..." ) );
1221  connect( act, SIGNAL(triggered(bool)),
1222  SLOT(slotAddColumn()) );
1223 
1224  act = menu.addAction( i18n( "Delete Column" ) );
1225  connect( act, SIGNAL(triggered(bool)),
1226  SLOT(slotDeleteColumn()) );
1227  act->setEnabled( col > 0 );
1228 
1229  menu.addSeparator();
1230 
1231  act = menu.addAction( i18n( "Move Column to Left"));
1232  connect( act, SIGNAL(triggered(bool)),
1233  SLOT(slotMoveColumnToLeft()) );
1234  act->setEnabled( col > 0 );
1235 
1236 
1237  act = menu.addAction( i18n( "Move Column to Right"));
1238  connect( act, SIGNAL(triggered(bool)),
1239  SLOT(slotMoveColumnToRight()) );
1240  act->setEnabled( col < mTheme->columns().count()-1 );
1241 
1242 
1243  menu.exec( header()->mapToGlobal( pos ) );
1244 }
1245 
1246 void ThemePreviewWidget::slotMoveColumnToLeft()
1247 {
1248  if ( !mSelectedThemeColumn )
1249  return;
1250 
1251  const int columnIndex = mTheme->columns().indexOf( mSelectedThemeColumn );
1252  mTheme->moveColumn(columnIndex, columnIndex -1);
1253  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1254 }
1255 
1256 void ThemePreviewWidget::slotMoveColumnToRight()
1257 {
1258  if ( !mSelectedThemeColumn )
1259  return;
1260 
1261  const int columnIndex = mTheme->columns().indexOf( mSelectedThemeColumn );
1262  mTheme->moveColumn(columnIndex, columnIndex +1);
1263  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1264 }
1265 
1266 
1267 void ThemePreviewWidget::slotAddColumn()
1268 {
1269  int newColumnIndex = mTheme->columns().count();
1270 
1271  if ( mSelectedThemeColumn )
1272  {
1273  newColumnIndex = mTheme->columns().indexOf( mSelectedThemeColumn );
1274  if ( newColumnIndex < 0 )
1275  newColumnIndex = mTheme->columns().count();
1276  else
1277  newColumnIndex++;
1278  }
1279 
1280  mSelectedThemeColumn = new Theme::Column();
1281  mSelectedThemeColumn->setLabel( i18n( "New Column" ) );
1282  mSelectedThemeColumn->setVisibleByDefault( true );
1283 
1284  mSelectedThemeColumn->addMessageRow( new Theme::Row() );
1285  mSelectedThemeColumn->addGroupHeaderRow( new Theme::Row() );
1286 
1287  ThemeColumnPropertiesDialog* dlg =
1288  new ThemeColumnPropertiesDialog( this, mSelectedThemeColumn, i18n( "Add New Column" ) );
1289 
1290  if ( dlg->exec() == QDialog::Accepted )
1291  {
1292  mTheme->insertColumn( newColumnIndex, mSelectedThemeColumn );
1293 
1294  mSelectedThemeContentItem = 0;
1295  mThemeSelectedContentItemRect = QRect();
1296  mDropIndicatorPoint1 = mDropIndicatorPoint2;
1297 
1298  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1299 
1300  } else {
1301 
1302  delete mSelectedThemeColumn;
1303  mSelectedThemeColumn = 0;
1304  }
1305 
1306  delete dlg;
1307 }
1308 
1309 void ThemePreviewWidget::slotColumnProperties()
1310 {
1311  if ( !mSelectedThemeColumn )
1312  return;
1313 
1314  ThemeColumnPropertiesDialog *dlg =
1315  new ThemeColumnPropertiesDialog( this, mSelectedThemeColumn, i18n( "Column Properties" ) );
1316 
1317  if ( dlg->exec() == QDialog::Accepted )
1318  {
1319  mSelectedThemeContentItem = 0;
1320  mThemeSelectedContentItemRect = QRect();
1321  mDropIndicatorPoint1 = mDropIndicatorPoint2;
1322 
1323  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1324  }
1325 
1326  delete dlg;
1327 }
1328 
1329 void ThemePreviewWidget::slotDeleteColumn()
1330 {
1331  if ( !mSelectedThemeColumn )
1332  return;
1333 
1334  const int idx = mTheme->columns().indexOf( mSelectedThemeColumn );
1335  if ( idx < 1 ) // first column can't be deleted
1336  return;
1337 
1338  mTheme->removeColumn( mSelectedThemeColumn );
1339  delete mSelectedThemeColumn;
1340  mSelectedThemeColumn = 0;
1341 
1342  mSelectedThemeContentItem = 0;
1343  mThemeSelectedContentItemRect = QRect();
1344  mDropIndicatorPoint1 = mDropIndicatorPoint2;
1345 
1346  setTheme( mTheme ); // this will reset theme cache and trigger a global update
1347 }
1348 
1349 
1350 
1351 
1352 
1353 ThemeEditor::ThemeEditor( QWidget *parent )
1354  : OptionSetEditor( parent )
1355 {
1356  mCurrentTheme = 0;
1357 
1358  // Appearance tab
1359  QWidget * tab = new QWidget( this );
1360  addTab( tab, i18n( "Appearance" ) );
1361 
1362  QGridLayout * tabg = new QGridLayout( tab );
1363 
1364  QGroupBox * gb = new QGroupBox( i18n( "Content Items" ), tab );
1365  tabg->addWidget( gb, 0, 0 );
1366 
1367  QGridLayout * gblayout = new QGridLayout( gb );
1368 
1369  ThemeContentItemSourceLabel * cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::Subject );
1370  cil->setText( Theme::ContentItem::description( cil->type() ) );
1371  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1372  gblayout->addWidget( cil, 0, 0 );
1373 
1374  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::Date );
1375  cil->setText( Theme::ContentItem::description( cil->type() ) );
1376  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1377  gblayout->addWidget( cil, 1, 0 );
1378 
1379  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::Size );
1380  cil->setText( Theme::ContentItem::description( cil->type() ) );
1381  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1382  gblayout->addWidget( cil, 2, 0 );
1383 
1384 
1385  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::Sender );
1386  cil->setText( Theme::ContentItem::description( cil->type() ) );
1387  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1388  gblayout->addWidget( cil, 0, 1 );
1389 
1390  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::Receiver );
1391  cil->setText( Theme::ContentItem::description( cil->type() ) );
1392  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1393  gblayout->addWidget( cil, 1, 1 );
1394 
1395  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::SenderOrReceiver );
1396  cil->setText( Theme::ContentItem::description( cil->type() ) );
1397  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1398  gblayout->addWidget( cil, 2, 1 );
1399 
1400 
1401 
1402  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::MostRecentDate );
1403  cil->setText( Theme::ContentItem::description( cil->type() ) );
1404  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1405  gblayout->addWidget( cil, 0, 2 );
1406 
1407  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::TagList );
1408  cil->setText( Theme::ContentItem::description( cil->type() ) );
1409  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1410  gblayout->addWidget( cil, 1, 2 );
1411 
1412 
1413 
1414  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::CombinedReadRepliedStateIcon );
1415  cil->setPixmap( *( Manager::instance()->pixmapMessageRepliedAndForwarded() ) );
1416  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1417  gblayout->addWidget( cil, 0, 3 );
1418 
1419  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::ReadStateIcon );
1420  cil->setPixmap( *( Manager::instance()->pixmapMessageNew() ) );
1421  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1422  gblayout->addWidget( cil, 1, 3 );
1423 
1424  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::RepliedStateIcon );
1425  cil->setPixmap( *( Manager::instance()->pixmapMessageReplied() ) );
1426  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1427  gblayout->addWidget( cil, 2, 3 );
1428 
1429 
1430 
1431  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::AttachmentStateIcon );
1432  cil->setPixmap( *( Manager::instance()->pixmapMessageAttachment() ) );
1433  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1434  gblayout->addWidget( cil, 0, 4 );
1435 
1436  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::EncryptionStateIcon );
1437  cil->setPixmap( *( Manager::instance()->pixmapMessageFullyEncrypted() ) );
1438  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1439  gblayout->addWidget( cil, 1, 4 );
1440 
1441  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::SignatureStateIcon );
1442  cil->setPixmap( *( Manager::instance()->pixmapMessageFullySigned() ) );
1443  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1444  gblayout->addWidget( cil, 2, 4 );
1445 
1446 
1447 
1448  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::ActionItemStateIcon );
1449  cil->setPixmap( *( Manager::instance()->pixmapMessageActionItem() ) );
1450  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1451  gblayout->addWidget( cil, 0, 5 );
1452 
1453  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::AnnotationIcon );
1454  cil->setPixmap( *( Manager::instance()->pixmapMessageAnnotation() ) );
1455  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1456  gblayout->addWidget( cil, 1, 5 );
1457 
1458  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::InvitationIcon );
1459  cil->setPixmap( *( Manager::instance()->pixmapMessageInvitation() ) );
1460  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1461  gblayout->addWidget( cil, 2, 5 );
1462 
1463 
1464 
1465  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::ImportantStateIcon );
1466  cil->setPixmap( *( Manager::instance()->pixmapMessageImportant() ) );
1467  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1468  gblayout->addWidget( cil, 0, 6 );
1469 
1470  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::SpamHamStateIcon );
1471  cil->setPixmap( *( Manager::instance()->pixmapMessageSpam() ) );
1472  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1473  gblayout->addWidget( cil, 1, 6 );
1474 
1475  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::WatchedIgnoredStateIcon );
1476  cil->setPixmap( *( Manager::instance()->pixmapMessageWatched() ) );
1477  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1478  gblayout->addWidget( cil, 2, 6 );
1479 
1480 
1481 
1482 
1483 
1484  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::ExpandedStateIcon );
1485  cil->setPixmap( *( Manager::instance()->pixmapShowMore() ) );
1486  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1487  gblayout->addWidget( cil, 0, 7 );
1488 
1489  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::VerticalLine );
1490  cil->setPixmap( *( Manager::instance()->pixmapVerticalLine() ) );
1491  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1492  gblayout->addWidget( cil, 1, 7 );
1493 
1494  cil = new ThemeContentItemSourceLabel( gb, Theme::ContentItem::HorizontalSpacer );
1495  cil->setPixmap( *( Manager::instance()->pixmapHorizontalSpacer() ) );
1496  cil->setToolTip( Theme::ContentItem::description( cil->type() ) );
1497  gblayout->addWidget( cil, 2, 7 );
1498 
1499 
1500 
1501  mPreviewWidget = new ThemePreviewWidget( tab );
1502  tabg->addWidget( mPreviewWidget, 1, 0 );
1503 
1504  QLabel * l = new QLabel( tab );
1505  l->setText( i18n( "Right click on the header to add or modify columns. Drag the content items and drop them on the columns in order to compose your theme. Right click on the items inside the view for more options." ) );
1506  l->setWordWrap( true );
1507  l->setAlignment( Qt::AlignCenter );
1508  tabg->addWidget( l, 2, 0 );
1509 
1510  tabg->setRowStretch( 1, 1 );
1511 
1512  // Advanced tab
1513  tab = new QWidget( this );
1514  addTab( tab, i18nc( "@title:tab Advanced theme settings", "Advanced" ) );
1515 
1516  tabg = new QGridLayout( tab );
1517 
1518  l = new QLabel( i18n( "Header:" ), tab );
1519  tabg->addWidget( l, 0, 0 );
1520 
1521  mViewHeaderPolicyCombo = new KComboBox( tab );
1522  tabg->addWidget( mViewHeaderPolicyCombo, 0, 1 );
1523 
1524  l = new QLabel( i18n( "Icon size:" ), tab );
1525  tabg->addWidget( l, 1, 0 );
1526 
1527  mIconSizeSpinBox = new KIntSpinBox( tab );
1528  mIconSizeSpinBox->setMinimum( 8 );
1529  mIconSizeSpinBox->setMaximum( 64 );
1530  mIconSizeSpinBox->setSuffix( ki18ncp( "suffix in a spinbox", " pixel", " pixels" ) );
1531 
1532  QObject::connect(
1533  mIconSizeSpinBox, SIGNAL(valueChanged(int)),
1534  this, SLOT(slotIconSizeSpinBoxValueChanged(int))
1535  );
1536 
1537  tabg->addWidget( mIconSizeSpinBox, 1, 1 );
1538 
1539 
1540  tabg->setColumnStretch( 1, 1 );
1541  tabg->setRowStretch( 2, 1 );
1542  fillViewHeaderPolicyCombo();
1543 
1544 }
1545 
1546 ThemeEditor::~ThemeEditor()
1547 {
1548 }
1549 
1550 void ThemeEditor::editTheme( Theme *set )
1551 {
1552  mCurrentTheme = set;
1553  mPreviewWidget->setTheme(mCurrentTheme);
1554 
1555  if ( !mCurrentTheme )
1556  {
1557  setEnabled( false );
1558  return;
1559  }
1560  setEnabled( true );
1561 
1562  nameEdit()->setText( set->name() );
1563  descriptionEdit()->setPlainText( set->description() );
1564 
1565  ComboBoxUtils::setIntegerOptionComboValue( mViewHeaderPolicyCombo, (int)mCurrentTheme->viewHeaderPolicy() );
1566 
1567  mIconSizeSpinBox->setValue( set->iconSize() );
1568  setReadOnly( mCurrentTheme->readOnly() );
1569 }
1570 
1571 void ThemeEditor::setReadOnly( bool readOnly )
1572 {
1573  mPreviewWidget->setReadOnly( readOnly );
1574  mViewHeaderPolicyCombo->setEnabled( !readOnly );
1575  mIconSizeSpinBox->setEnabled( !readOnly );
1576  OptionSetEditor::setReadOnly( readOnly );
1577 }
1578 
1579 void ThemeEditor::commit()
1580 {
1581  if ( !mCurrentTheme || mCurrentTheme->readOnly() )
1582  return;
1583 
1584  mCurrentTheme->setName( nameEdit()->text() );
1585  mCurrentTheme->setDescription( descriptionEdit()->toPlainText() );
1586 
1587  mCurrentTheme->setViewHeaderPolicy(
1588  (Theme::ViewHeaderPolicy)ComboBoxUtils::getIntegerOptionComboValue( mViewHeaderPolicyCombo, 0 )
1589  );
1590  mCurrentTheme->setIconSize( mIconSizeSpinBox->value() );
1591  // other settings are already committed to this theme
1592 }
1593 
1594 void ThemeEditor::fillViewHeaderPolicyCombo()
1595 {
1596  ComboBoxUtils::fillIntegerOptionCombo(
1597  mViewHeaderPolicyCombo,
1598  Theme::enumerateViewHeaderPolicyOptions()
1599  );
1600 }
1601 
1602 void ThemeEditor::slotNameEditTextEdited( const QString &newName )
1603 {
1604  if( !mCurrentTheme )
1605  return;
1606  mCurrentTheme->setName( newName );
1607  emit themeNameChanged();
1608 }
1609 
1610 void ThemeEditor::slotIconSizeSpinBoxValueChanged( int val )
1611 {
1612  if( !mCurrentTheme )
1613  return;
1614  mCurrentTheme->setIconSize( val );
1615 
1616  mPreviewWidget->setTheme( mCurrentTheme ); // will trigger a cache reset and a view update
1617 }
1618 
1619 MessageList::Core::Theme *ThemeEditor::editedTheme() const
1620 {
1621  return mCurrentTheme;
1622 }
1623 
1624 
1625 #include "themeeditor.moc"
MessageList::Core::Theme::ContentItem
The ContentItem class defines a content item inside a Row.
Definition: theme.h:73
MessageList::Core::FakeItem::setFakeTags
void setFakeTags(const QList< Tag * > &tagList)
Sets a list of fake tags for this item.
Definition: messageitem.cpp:710
MessageList::Utils::ThemeColumnPropertiesDialog::mVisibleByDefaultCheck
QCheckBox * mVisibleByDefaultCheck
Definition: themeeditor.h:67
MessageList::Utils::ThemePreviewWidget
Definition: themeeditor.h:90
MessageList::Utils::ThemeEditor::slotNameEditTextEdited
void slotNameEditTextEdited(const QString &newName)
Definition: themeeditor.cpp:1602
MessageList::Core::GroupHeaderItem
Definition: groupheaderitem.h:34
MessageList::Utils::ThemeEditor::ThemeEditor
ThemeEditor(QWidget *parent)
Definition: themeeditor.cpp:1353
MessageList::Core::OptionSet::setDescription
void setDescription(const QString &description)
Sets the description for this option set.
Definition: optionset.h:94
MessageList::Core::Item::rawAppendChildItem
void rawAppendChildItem(Item *child)
Appends a child item without inserting it via the model.
Definition: item.cpp:514
MessageList::Utils::OptionSetEditor::setReadOnly
void setReadOnly(bool readOnly)
Definition: optionseteditor.cpp:70
MessageList::Utils::ThemeEditor::editedTheme
Core::Theme * editedTheme() const
Definition: themeeditor.cpp:1619
MessageList::Utils::ComboBoxUtils::setIntegerOptionComboValue
void setIntegerOptionComboValue(KComboBox *combo, int value)
Sets the currently selected option in the specified combo.
Definition: comboboxutils.cpp:59
QTreeWidget
MessageList::Core::Theme::Row::rightItems
const QList< ContentItem * > & rightItems() const
Returns the list of right aligned items for this row.
Definition: theme.h:512
MessageList::Utils::ThemePreviewWidget::slotFontMenuTriggered
void slotFontMenuTriggered(QAction *act)
Definition: themeeditor.cpp:1092
MessageList::Utils::ThemePreviewWidget::slotGroupHeaderBackgroundStyleMenuTriggered
void slotGroupHeaderBackgroundStyleMenuTriggered(QAction *act)
Definition: themeeditor.cpp:1150
MessageList::Core::Theme::Column::messageSorting
SortOrder::MessageSorting messageSorting() const
Returns the sort order for messages that we should switch to when clicking on this column's header (i...
Definition: theme.h:731
MessageList::Core::Theme::ContentItem::useCustomFont
bool useCustomFont() const
Returns true if this item uses a custom font.
Definition: theme.h:348
MessageList::Utils::ThemePreviewDelegate::ThemePreviewDelegate
ThemePreviewDelegate(QAbstractItemView *parent)
Definition: themeeditor.cpp:188
MessageList::Core::Theme::Column::addMessageRow
void addMessageRow(Row *row)
Appends a message row to this theme column.
Definition: theme.h:785
MessageList::Core::Theme::ContentItem::font
const QFont & font() const
Returns the font used by this item.
Definition: theme.h:419
MessageList::Core::Item::setDate
void setDate(time_t date)
Sets the date of this item.
Definition: item.cpp:427
MessageList::Utils::ThemePreviewWidget::slotHeaderContextMenuRequested
void slotHeaderContextMenuRequested(const QPoint &pos)
Definition: themeeditor.cpp:1189
MessageList::Utils::ThemeContentItemSourceLabel::mousePressEvent
void mousePressEvent(QMouseEvent *e)
Definition: themeeditor.cpp:154
MessageList::Utils::OptionSetEditor::nameEdit
KLineEdit * nameEdit() const
Returns the editor for the name of the OptionSet.
Definition: optionseteditor.cpp:81
MessageList::Core::ThemeDelegate::hitRowRect
QRect hitRowRect() const
Returns the rectangle of the row that was reported as hit by the previous call to hitTest()...
Definition: themedelegate.h:160
MessageList::Utils::ThemeEditor::editTheme
void editTheme(Core::Theme *set)
Sets the option set to be edited.
Definition: themeeditor.cpp:1550
QWidget
MessageList::Core::Theme::insertColumn
void insertColumn(int idx, Column *column)
Inserts a column to this theme at the specified position.
Definition: theme.cpp:749
MessageList::Core::Theme::Row
The Row class defines a row of items inside a Column.
Definition: theme.h:466
MessageList::Core::Item::setSize
void setSize(size_t size)
Sets the size of this item (size of the Message, mainly)
Definition: item.cpp:417
MessageList::Core::OptionSet::description
const QString & description() const
Returns a description of this option set.
Definition: optionset.h:88
MessageList::Core::Theme::removeColumn
void removeColumn(Column *col)
Removes the specified message row.
Definition: theme.h:970
MessageList::Core::Theme::moveColumn
void moveColumn(int idx, int newPosition)
Definition: theme.cpp:759
MessageList::Core::Theme::Row::addRightItem
void addRightItem(ContentItem *item)
Adds a right aligned item to this row.
Definition: theme.h:525
MessageList::Core::Theme::ContentItem::setSoftenByBlendingWhenDisabled
void setSoftenByBlendingWhenDisabled(bool softenByBlendingWhenDisabled)
Sets the flag that causes this item to be painted "softly" when disabled.
Definition: theme.h:389
theme.h
MessageList::Core::ModelInvariantRowMapper
This class is an optimizing helper for dealing with large flat QAbstractItemModel objects...
Definition: modelinvariantrowmapper.h:93
KDialog
MessageList::Core::Item::setSubject
void setSubject(const QString &subject)
Sets the subject associated to this Item.
Definition: item.cpp:477
MessageList::Core::Theme::setGroupHeaderBackgroundMode
void setGroupHeaderBackgroundMode(GroupHeaderBackgroundMode bm)
Sets the group header background mode for this theme.
Definition: theme.cpp:766
MessageList::Utils::ThemeEditor::commit
void commit()
Definition: themeeditor.cpp:1579
MessageList::Core::Theme::groupHeaderBackgroundStyle
GroupHeaderBackgroundStyle groupHeaderBackgroundStyle() const
Returns the group header background style for this theme.
Definition: theme.h:1004
MessageList::Core::Theme::ContentItem::displaysText
bool displaysText() const
Returns true if this item displays some kind of text.
Definition: theme.h:286
MessageList::Utils::ThemeColumnPropertiesDialog::mIsSenderOrReceiverCheck
QCheckBox * mIsSenderOrReceiverCheck
Definition: themeeditor.h:68
MessageList::Core::Theme::Row::addLeftItem
void addLeftItem(ContentItem *item)
Adds a left aligned item to this row.
Definition: theme.h:493
MessageList::Core::Theme::Column::isSenderOrReceiver
bool isSenderOrReceiver() const
Returns true if this column is marked as "sender/receiver" and we should update its label on-the-fly...
Definition: theme.h:699
MessageList::Utils::ThemePreviewDelegate::~ThemePreviewDelegate
~ThemePreviewDelegate()
Definition: themeeditor.cpp:234
MessageList::Core::Theme::ContentItem::hideWhenDisabled
bool hideWhenDisabled() const
Returns true if this item should be hidden when in disabled state.
Definition: theme.h:363
MessageList::Core::Theme::Column::setVisibleByDefault
void setVisibleByDefault(bool vbd)
Sets the "visible by default" tag for this column.
Definition: theme.h:718
MessageList::Core::Theme::Column
The Column class defines a view column available inside this theme.
Definition: theme.h:564
modelinvariantrowmapper.h
MessageList::Core::Theme::iconSize
int iconSize() const
Returns the currently set icon size.
Definition: theme.h:1037
MessageList::Core::Theme::ContentItem::setFont
void setFont(const QFont &font)
Sets the custom font to be used with this item.
Definition: theme.cpp:166
MessageList::Core::Theme::ContentItem::customColor
const QColor & customColor() const
Returns the custom color set for this item.
Definition: theme.h:437
MessageList::Core::Theme::Column::messageRows
const QList< Row * > & messageRows() const
Returns the list of rows visible in this column for a MessageItem.
Definition: theme.h:773
MessageList::Core::OptionSet::name
const QString & name() const
Returns the name of this OptionSet.
Definition: optionset.h:72
MessageList::Core::Theme::Column::setLabel
void setLabel(const QString &label)
Sets the label for this column.
Definition: theme.h:680
MessageList::Core::Item::type
Type type() const
Returns the type of this item.
Definition: item.cpp:298
MessageList::Utils::ThemePreviewWidget::slotForegroundColorMenuTriggered
void slotForegroundColorMenuTriggered(QAction *act)
Definition: themeeditor.cpp:1055
messageitem.h
MessageList::Core::Theme::ContentItem::isClickable
bool isClickable() const
Returns true if clicking on this kind of item can perform an action.
Definition: theme.h:304
MessageList::Utils::ThemeEditor::~ThemeEditor
~ThemeEditor()
Definition: themeeditor.cpp:1546
MessageList::Utils::ThemePreviewWidget::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *e)
Definition: themeeditor.cpp:785
MessageList::Utils::ThemeColumnPropertiesDialog::mColumn
Core::Theme::Column * mColumn
Definition: themeeditor.h:65
MessageList::Core::Theme::ContentItem::type
Type type() const
Returns the type of this content item.
Definition: theme.h:264
MessageList::Utils::ThemeColumnPropertiesDialog::ThemeColumnPropertiesDialog
ThemeColumnPropertiesDialog(QWidget *parent, Core::Theme::Column *column, const QString &title)
Definition: themeeditor.cpp:69
MessageList::Core::MessageItem::setEncryptionState
void setEncryptionState(EncryptionState state)
Definition: messageitem.cpp:470
MessageList::Utils::ThemePreviewWidget::slotDisabledFlagsMenuTriggered
void slotDisabledFlagsMenuTriggered(QAction *act)
Definition: themeeditor.cpp:1039
MessageList::Core::ThemeDelegate::hitItem
Item * hitItem() const
Returns the Item that was reported as hit by the previous call to hitTest().
Definition: themedelegate.h:108
MessageList::Utils::ThemePreviewWidget::ThemePreviewWidget
ThemePreviewWidget(QWidget *parent)
Definition: themeeditor.cpp:253
MessageList::Core::Theme::ContentItem::canUseCustomColor
bool canUseCustomColor() const
Returns true if this ContentItem can make use of a custom color.
Definition: theme.h:279
MessageList::Utils::ThemeEditor::themeNameChanged
void themeNameChanged()
MessageList::Core::Theme::ContentItem::useCustomColor
bool useCustomColor() const
Returns true if this item uses a custom color.
Definition: theme.h:334
MessageList::Core::ThemeDelegate::hitColumn
const Theme::Column * hitColumn() const
Returns the theme column that was reported as hit by the previous call to hitTest().
Definition: themedelegate.h:125
MessageList::Core::Theme::GroupHeaderBackgroundMode
GroupHeaderBackgroundMode
Which color do we use to paint group header background ?
Definition: theme.h:881
MessageList::Utils::ThemePreviewWidget::slotAddColumn
void slotAddColumn()
Definition: themeeditor.cpp:1267
MessageList::Utils::OptionSetEditor
The base class for the OptionSet editors.
Definition: optionseteditor.h:45
MessageList::Core::Theme::setGroupHeaderBackgroundColor
void setGroupHeaderBackgroundColor(const QColor &clr)
Sets the group header background color for this theme.
Definition: theme.h:996
MessageList::Utils::ThemeContentItemSourceLabel::type
Core::Theme::ContentItem::Type type() const
Definition: themeeditor.cpp:148
MessageList::Utils::ThemePreviewWidget::dragEnterEvent
virtual void dragEnterEvent(QDragEnterEvent *e)
Definition: themeeditor.cpp:468
MessageList::Core::Theme::Row::leftItems
const QList< ContentItem * > & leftItems() const
Returns the list of left aligned items for this row.
Definition: theme.h:481
MessageList::Core::Item::setParent
void setParent(Item *pParent)
Sets the parent for this item.
Definition: item.cpp:397
MessageList::Utils::ThemePreviewWidget::mousePressEvent
virtual void mousePressEvent(QMouseEvent *e)
Definition: themeeditor.cpp:852
MessageList::Utils::ComboBoxUtils::fillIntegerOptionCombo
void fillIntegerOptionCombo(KComboBox *combo, const QList< QPair< QString, int > > &optionDescriptors)
Fills the specified KComboBox with the options available in optionDescriptors.
Definition: comboboxutils.cpp:29
MessageList::Core::Theme::ContentItem::Type
Type
The available ContentItem types.
Definition: theme.h:125
manager.h
MessageList::Core::ThemeDelegate::hitRowIndex
int hitRowIndex() const
Returns the index of the theme row that was reported as hit by the previous call to hitTest()...
Definition: themedelegate.h:151
MessageList::Core::ThemeDelegate::hitRow
const Theme::Row * hitRow() const
Returns the theme row that was reported as hit by the previous call to hitTest(). ...
Definition: themedelegate.h:144
MessageList::Core::ModelInvariantRowMapper::createModelInvariantIndex
void createModelInvariantIndex(int modelIndexRow, ModelInvariantIndex *invariantToFill)
Binds a ModelInvariantIndex structure to the specified CURRENT modelIndexRow.
Definition: modelinvariantrowmapper.cpp:344
MessageList::Core::Theme::viewHeaderPolicy
ViewHeaderPolicy viewHeaderPolicy() const
Returns the currently set ViewHeaderPolicy.
Definition: theme.h:1025
MessageList::Utils::ThemePreviewWidget::slotSoftenActionTriggered
void slotSoftenActionTriggered(bool)
Definition: themeeditor.cpp:1083
MessageList::Core::MessageItem::setSignatureState
void setSignatureState(SignatureState state)
Definition: messageitem.cpp:458
groupheaderitem.h
MessageList::Utils::OptionSetEditor::descriptionEdit
KTextEdit * descriptionEdit() const
Returns the editor for the description of the OptionSet.
Definition: optionseteditor.cpp:76
MessageList::Utils::ThemeEditor::slotIconSizeSpinBoxValueChanged
void slotIconSizeSpinBoxValueChanged(int val)
Definition: themeeditor.cpp:1610
MessageList::Utils::ThemePreviewWidget::dropEvent
virtual void dropEvent(QDropEvent *e)
Definition: themeeditor.cpp:515
MessageList::Utils::ThemeContentItemSourceLabel::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *e)
Definition: themeeditor.cpp:160
MessageList::Utils::ThemeContentItemSourceLabel::startDrag
void startDrag()
Definition: themeeditor.cpp:170
MessageList::Core::OptionSet::setName
void setName(const QString &name)
Sets the name of this OptionSet.
Definition: optionset.h:80
MessageList::Core::Theme::Column::visibleByDefault
bool visibleByDefault() const
Returns true if this column has to be shown by default.
Definition: theme.h:712
MessageList::Core::ThemeDelegate::hitContentItemRect
QRect hitContentItemRect() const
Returns the bounding rect of the content item that was reported as hit by the previous call to hitTes...
Definition: themedelegate.h:193
MessageList::Core::Item
A single item of the MessageList tree managed by MessageList::Model.
Definition: item.h:52
MessageList::Core::FakeItem
A message item that can have a fake tag list and a fake annotation.
Definition: messageitem.h:218
MessageList::Core::Theme::ContentItem::setUseCustomColor
void setUseCustomColor(bool useCustomColor)
Makes this item use the custom color that can be set by setCustomColor().
Definition: theme.h:341
comboboxutils.h
MessageList::Core::ThemeDelegate::hitContentItemRight
bool hitContentItemRight() const
Returns true if the hit theme content item was a right item and false otherwise.
Definition: themedelegate.h:184
MessageList::Core::ThemeDelegate::hitTest
bool hitTest(const QPoint &viewportPoint, bool exact=true)
Performs a hit test on the specified viewport point.
Definition: themedelegate.cpp:1173
MessageList::Core::Theme::ContentItem::setCustomColor
void setCustomColor(const QColor &clr)
Sets the custom color for this item.
Definition: theme.h:444
MessageList::Core::Theme::groupHeaderBackgroundMode
GroupHeaderBackgroundMode groupHeaderBackgroundMode() const
Returns the group header background mode for this theme.
Definition: theme.h:976
MessageList::Core::Theme::setIconSize
void setIconSize(int iconSize)
Sets the icon size for this theme.
Definition: theme.cpp:796
MessageList::Core::Theme::ContentItem::canBeDisabled
bool canBeDisabled() const
Returns true if this ContentItem can be in a "disabled" state.
Definition: theme.h:273
MessageList::Core::Theme::Column::setMessageSorting
void setMessageSorting(SortOrder::MessageSorting ms)
Sets the sort order for messages that we should switch to when clicking on this column's header (if v...
Definition: theme.h:738
MessageList::Utils::ThemePreviewWidget::slotColumnProperties
void slotColumnProperties()
Definition: themeeditor.cpp:1309
MessageList::Utils::ThemePreviewWidget::slotMoveColumnToRight
void slotMoveColumnToRight()
Definition: themeeditor.cpp:1256
MessageList::Core::ThemeDelegate::hitContentItem
const Theme::ContentItem * hitContentItem() const
Returns the theme content item that was reported as hit by the previous call to hitTest().
Definition: themedelegate.h:177
MessageList::Core::Theme::GroupHeaderBackgroundStyle
GroupHeaderBackgroundStyle
How do we paint group header background ?
Definition: theme.h:891
MessageList::Core::Theme::column
Column * column(int idx) const
Returns a pointer to the column at the specified index or 0 if there is no such column.
Definition: theme.h:946
MessageList::Utils::ThemeColumnPropertiesDialog::slotOkButtonClicked
void slotOkButtonClicked()
Definition: themeeditor.cpp:121
MessageList::Core::Theme::ContentItem::setUseCustomFont
void setUseCustomFont(bool useCustomFont)
Makes this item use the custom font that can be set by setCustomFont().
Definition: theme.h:355
QLabel
gThemeContentItemTypeDndMimeDataFormat
static const char * gThemeContentItemTypeDndMimeDataFormat
Definition: themeeditor.cpp:63
themeeditor.h
KComboBox
MessageList::Core::Theme::ContentItem::setSoftenByBlending
void setSoftenByBlending(bool softenByBlending)
Sets the flag that causes this item to be painted "softly".
Definition: theme.h:403
MessageList::Core::Item::setMaxDate
void setMaxDate(time_t date)
Sets the maximum date in the subtree originating from this item.
Definition: item.cpp:437
MessageList::Core::ThemeDelegate::setTheme
void setTheme(const Theme *theme)
Definition: themedelegate.cpp:62
MessageList::Utils::ThemeColumnPropertiesDialog
Definition: themeeditor.h:58
MessageList::Core::Theme::Column::label
const QString & label() const
Returns the label set for this column.
Definition: theme.h:674
MessageList::Utils::ThemeContentItemSourceLabel::ThemeContentItemSourceLabel
ThemeContentItemSourceLabel(QWidget *parent, Core::Theme::ContentItem::Type type)
Definition: themeeditor.cpp:138
MessageList::Core::Theme::Column::groupHeaderRows
const QList< Row * > & groupHeaderRows() const
Returns the list of rows visible in this column for a GroupHeaderItem.
Definition: theme.h:803
MessageList::Utils::ThemePreviewWidget::setTheme
void setTheme(Core::Theme *theme)
Definition: themeeditor.cpp:405
MessageList::Utils::ThemePreviewWidget::setReadOnly
void setReadOnly(bool readOnly)
Definition: themeeditor.cpp:291
MessageList::Utils::ThemePreviewWidget::showEvent
virtual void showEvent(QShowEvent *e)
Definition: themeeditor.cpp:454
MessageList::Core::Theme::Row::insertLeftItem
void insertLeftItem(int idx, ContentItem *item)
Adds a left aligned item at the specified position in this row.
Definition: theme.cpp:268
MessageList::Utils::ThemePreviewWidget::sizeHint
QSize sizeHint() const
Definition: themeeditor.cpp:286
MessageList::Utils::ThemePreviewWidget::~ThemePreviewWidget
~ThemePreviewWidget()
Definition: themeeditor.cpp:282
MessageList::Utils::ThemePreviewWidget::slotMoveColumnToLeft
void slotMoveColumnToLeft()
Definition: themeeditor.cpp:1246
MessageList::Core::Theme
The Theme class defines the visual appearance of the MessageList.
Definition: theme.h:65
MessageList::Core::Theme::groupHeaderBackgroundColor
const QColor & groupHeaderBackgroundColor() const
Returns the group header background color for this theme.
Definition: theme.h:989
MessageList::Core::Theme::Column::setIsSenderOrReceiver
void setIsSenderOrReceiver(bool sor)
Marks this column as containing the "sender/receiver" field.
Definition: theme.h:706
MessageList::Core::OptionSet::readOnly
bool readOnly() const
Definition: optionset.h:118
MessageList::Core::ThemeDelegate
The ThemeDelegate paints the message list view message and group items by using the supplied Theme...
Definition: themedelegate.h:45
MessageList::Core::Theme::ContentItem::softenByBlendingWhenDisabled
bool softenByBlendingWhenDisabled() const
Returns true if this item should be painted in a "soft" fashion when in disabled state.
Definition: theme.h:380
MessageList::Utils::ComboBoxUtils::getIntegerOptionComboValue
int getIntegerOptionComboValue(KComboBox *combo, int defaultValue)
Returns the identifier of the currently selected option in the specified combo.
Definition: comboboxutils.cpp:71
MessageList::Core::Theme::setGroupHeaderBackgroundStyle
void setGroupHeaderBackgroundStyle(GroupHeaderBackgroundStyle groupHeaderBackgroundStyle)
Sets the group header background style for this theme.
Definition: theme.h:1012
MessageList::Core::ThemeDelegate::hitRowIsMessageRow
bool hitRowIsMessageRow() const
Returns true if the hitRow() is a message row, false otherwise.
Definition: themedelegate.h:167
MessageList::Core::Theme::Column::addGroupHeaderRow
void addGroupHeaderRow(Row *row)
Appends a group header row to this theme.
Definition: theme.h:815
MessageList::Core::ThemeDelegate::sizeHintForItemTypeAndColumn
QSize sizeHintForItemTypeAndColumn(Item::Type type, int column, const Item *item=0) const
Returns a heuristic sizeHint() for the specified item type and column.
Definition: themedelegate.cpp:1592
MessageList::Utils::ThemeColumnPropertiesDialog::mMessageSortingCombo
KComboBox * mMessageSortingCombo
Definition: themeeditor.h:69
MessageList::Core::Theme::setViewHeaderPolicy
void setViewHeaderPolicy(ViewHeaderPolicy vhp)
Sets the ViewHeaderPolicy for this theme.
Definition: theme.h:1031
MessageList::Utils::ThemeContentItemSourceLabel
Definition: themeeditor.h:181
MessageList::Utils::ThemeContentItemSourceLabel::~ThemeContentItemSourceLabel
~ThemeContentItemSourceLabel()
Definition: themeeditor.cpp:144
MessageList::Core::MessageItem::Tag
Definition: messageitem.h:53
MessageList::Utils::ThemeColumnPropertiesDialog::mNameEdit
KLineEdit * mNameEdit
Definition: themeeditor.h:66
MessageList::Core::Theme::ContentItem::softenByBlending
bool softenByBlending() const
Returns true if this item should be always painted in a "soft" fashion.
Definition: theme.h:396
MessageList::Core::Theme::Row::insertRightItem
void insertRightItem(int idx, ContentItem *item)
Adds a right aligned item at the specified position in this row.
Definition: theme.cpp:278
MessageList::Utils::ThemePreviewWidget::dragMoveEvent
virtual void dragMoveEvent(QDragMoveEvent *e)
Definition: themeeditor.cpp:502
MessageList::Core::Theme::ContentItem::setHideWhenDisabled
void setHideWhenDisabled(bool hideWhenDisabled)
Sets the flag that causes this item to be hidden when disabled.
Definition: theme.h:372
MessageList::Utils::ThemePreviewWidget::paintEvent
virtual void paintEvent(QPaintEvent *e)
Definition: themeeditor.cpp:1163
MessageList::Utils::ThemePreviewWidget::slotDeleteColumn
void slotDeleteColumn()
Definition: themeeditor.cpp:1329
MessageList::Utils::ThemePreviewDelegate
Definition: themeeditor.h:75
MessageList::Utils::ThemePreviewWidget::slotGroupHeaderBackgroundModeMenuTriggered
void slotGroupHeaderBackgroundModeMenuTriggered(QAction *act)
Definition: themeeditor.cpp:1119
MessageList::Core::Item::setReceiver
void setReceiver(const QString &receiver)
Sets the sender associated to this item.
Definition: item.cpp:457
MessageList::Core::Theme::ViewHeaderPolicy
ViewHeaderPolicy
How do we manage the QHeaderView attacched to our View ?
Definition: theme.h:906
MessageList::Core::Theme::columns
const QList< Column * > & columns() const
Returns the list of columns available in this theme.
Definition: theme.h:940
MessageList::Utils::ThemePreviewDelegate::itemFromIndex
virtual Core::Item * itemFromIndex(const QModelIndex &index) const
Returns the Item for the specified model index.
Definition: themeeditor.cpp:241
MessageList::Core::Item::setSender
void setSender(const QString &sender)
Sets the sender associated to this item.
Definition: item.cpp:447
MessageList::Core::Item::setStatus
void setStatus(const Akonadi::MessageStatus &status)
Sets the status associated to this Item.
Definition: item.cpp:407
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:32 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

messagelist

Skip menu "messagelist"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal