• 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
  • core
themedelegate.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 "core/themedelegate.h"
22 #include "core/messageitem.h"
23 #include "core/groupheaderitem.h"
24 #include "core/manager.h"
25 
26 #include "messagecore/utils/stringutil.h"
27 
28 #include <QStyle>
29 #include <QPainter>
30 #include <QFont>
31 #include <QFontMetrics>
32 #include <QAbstractItemView>
33 #include <QPixmap>
34 #include <QLinearGradient>
35 #include <KColorScheme>
36 #include <KGlobalSettings>
37 #include <KGlobal>
38 
39 using namespace MessageList::Core;
40 
41 static const int gGroupHeaderOuterVerticalMargin = 1;
42 static const int gGroupHeaderOuterHorizontalMargin = 1;
43 static const int gGroupHeaderInnerVerticalMargin = 1;
44 static const int gGroupHeaderInnerHorizontalMargin = 1;
45 static const int gMessageVerticalMargin = 2;
46 static const int gMessageHorizontalMargin = 2;
47 static const int gHorizontalItemSpacing = 2;
48 
49 
50 ThemeDelegate::ThemeDelegate( QAbstractItemView * parent )
51  : QStyledItemDelegate( parent )
52 {
53  mItemView = parent;
54  mTheme = 0;
55  connect( KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()), this, SLOT(slotGeneralFontChanged()) );
56 }
57 
58 ThemeDelegate::~ThemeDelegate()
59 {
60 }
61 
62 void ThemeDelegate::setTheme( const Theme * theme )
63 {
64  mTheme = theme;
65 
66  if ( !mTheme )
67  return; // hum
68 
69  // Rebuild the group header background color cache
70  switch( mTheme->groupHeaderBackgroundMode() )
71  {
72  case Theme::Transparent:
73  mGroupHeaderBackgroundColor = QColor(); // invalid
74  break;
75  case Theme::CustomColor:
76  mGroupHeaderBackgroundColor = mTheme->groupHeaderBackgroundColor();
77  break;
78  case Theme::AutoColor:
79  {
80  QPalette pal = mItemView->palette();
81  QColor txt = pal.color( QPalette::Normal, QPalette::Text );
82  QColor bck = pal.color( QPalette::Normal, QPalette::Base );
83  mGroupHeaderBackgroundColor = QColor(
84  ( txt.red() + ( bck.red() * 3 ) ) / 4,
85  ( txt.green() + ( bck.green() * 3 ) ) / 4,
86  ( txt.blue() + ( bck.blue() * 3 ) ) / 4
87  );
88  }
89  break;
90  }
91  mItemView->reset();
92 
93 }
94 
95 static QFontMetrics cachedFontMetrics( const QFont &font )
96 {
97  static QHash<QString, QFontMetrics*> fontMetricsCache;
98  const QString fontKey = font.key();
99 
100  if ( !fontMetricsCache.contains( fontKey ) ) {
101  QFontMetrics *metrics = new QFontMetrics( font );
102  fontMetricsCache.insert( fontKey, metrics );
103  }
104 
105  return *fontMetricsCache[ fontKey ];
106 }
107 
108 static int cachedFontHeightKey( const QFont &font, const QString &fontKey )
109 {
110  static QHash<QString, int> fontHeightCache;
111 
112  if ( !fontHeightCache.contains( fontKey ) ) {
113  fontHeightCache.insert( fontKey, cachedFontMetrics( font ).height() );
114  }
115 
116  return fontHeightCache[ fontKey ];
117 }
118 
119 
120 static inline void paint_right_aligned_elided_text( const QString &text, Theme::ContentItem * ci, QPainter * painter, int &left, int top, int &right, Qt::LayoutDirection layoutDir, const QFont &font )
121 {
122  painter->setFont( font );
123  const QFontMetrics fontMetrics = cachedFontMetrics( font );
124  const int w = right - left;
125  const QString elidedText = fontMetrics.elidedText( text, layoutDir == Qt::LeftToRight ? Qt::ElideLeft : Qt::ElideRight, w );
126  const QRect rct( left, top, w, fontMetrics.height() );
127  QRect outRct;
128 
129  if ( ci->softenByBlending() )
130  {
131  qreal oldOpacity = painter->opacity();
132  painter->setOpacity( 0.6 );
133  painter->drawText( rct, Qt::AlignTop | Qt::AlignRight | Qt::TextSingleLine, elidedText, &outRct );
134  painter->setOpacity( oldOpacity );
135  } else {
136  painter->drawText( rct, Qt::AlignTop | Qt::AlignRight | Qt::TextSingleLine, elidedText, &outRct );
137  }
138  if ( layoutDir == Qt::LeftToRight )
139  right -= outRct.width() + gHorizontalItemSpacing;
140  else
141  left += outRct.width() + gHorizontalItemSpacing;
142 }
143 
144 static inline void compute_bounding_rect_for_right_aligned_elided_text( const QString &text, int &left, int top, int &right, QRect &outRect, Qt::LayoutDirection layoutDir, const QFont &font )
145 {
146  const QFontMetrics fontMetrics = cachedFontMetrics( font );
147  const int w = right - left;
148  const QString elidedText = fontMetrics.elidedText( text, layoutDir == Qt::LeftToRight ? Qt::ElideLeft : Qt::ElideRight, w );
149  const QRect rct( left, top, w, fontMetrics.height() );
150  const Qt::AlignmentFlag af = layoutDir == Qt::LeftToRight ? Qt::AlignRight : Qt::AlignLeft;
151  outRect = fontMetrics.boundingRect( rct, Qt::AlignTop | af | Qt::TextSingleLine, elidedText );
152  if ( layoutDir == Qt::LeftToRight )
153  right -= outRect.width() + gHorizontalItemSpacing;
154  else
155  left += outRect.width() + gHorizontalItemSpacing;
156 }
157 
158 
159 static inline void paint_left_aligned_elided_text( const QString &text, Theme::ContentItem * ci, QPainter * painter, int &left, int top, int &right, Qt::LayoutDirection layoutDir, const QFont &font )
160 {
161  painter->setFont( font );
162  const QFontMetrics fontMetrics = cachedFontMetrics( font );
163  const int w = right - left;
164  const QString elidedText = fontMetrics.elidedText( text, layoutDir == Qt::LeftToRight ? Qt::ElideRight : Qt::ElideLeft, w );
165  const QRect rct( left, top, w, fontMetrics.height() );
166  QRect outRct;
167  if ( ci->softenByBlending() )
168  {
169  qreal oldOpacity = painter->opacity();
170  painter->setOpacity( 0.6 );
171  painter->drawText( rct, Qt::AlignTop | Qt::AlignLeft | Qt::TextSingleLine, elidedText, &outRct );
172  painter->setOpacity( oldOpacity );
173  } else {
174  painter->drawText( rct, Qt::AlignTop | Qt::AlignLeft | Qt::TextSingleLine, elidedText, &outRct );
175  }
176  if ( layoutDir == Qt::LeftToRight )
177  left += outRct.width() + gHorizontalItemSpacing;
178  else
179  right -= outRct.width() + gHorizontalItemSpacing;
180 }
181 
182 static inline void compute_bounding_rect_for_left_aligned_elided_text( const QString &text, int &left, int top, int &right, QRect &outRect, Qt::LayoutDirection layoutDir, const QFont &font )
183 {
184  const QFontMetrics fontMetrics = cachedFontMetrics( font );
185  const int w = right - left;
186  const QString elidedText = fontMetrics.elidedText( text, layoutDir == Qt::LeftToRight ? Qt::ElideRight : Qt::ElideLeft, w );
187  const QRect rct( left, top, w, fontMetrics.height() );
188  const Qt::AlignmentFlag af = layoutDir == Qt::LeftToRight ? Qt::AlignLeft : Qt::AlignRight;
189  outRect = fontMetrics.boundingRect( rct, Qt::AlignTop | af | Qt::TextSingleLine, elidedText );
190  if ( layoutDir == Qt::LeftToRight )
191  left += outRect.width() + gHorizontalItemSpacing;
192  else
193  right -= outRect.width() + gHorizontalItemSpacing;
194 }
195 
196 static inline const QPixmap * get_read_state_icon( Item * item )
197 {
198  if ( item->status().isQueued() )
199  return Manager::instance()->pixmapMessageQueued();
200  else if ( item->status().isSent() )
201  return Manager::instance()->pixmapMessageSent();
202  else if ( item->status().isRead() )
203  return Manager::instance()->pixmapMessageRead();
204  else if ( !item->status().isRead() )
205  return Manager::instance()->pixmapMessageUnread();
206  else if ( item->status().isDeleted() )
207  return Manager::instance()->pixmapMessageDeleted();
208 
209  // Uhm... should never happen.. but fallback to "read"...
210  return Manager::instance()->pixmapMessageRead();
211 }
212 
213 static inline const QPixmap * get_combined_read_replied_state_icon( MessageItem * messageItem )
214 {
215  if ( messageItem->status().isReplied() )
216  {
217  if ( messageItem->status().isForwarded() )
218  return Manager::instance()->pixmapMessageRepliedAndForwarded();
219  return Manager::instance()->pixmapMessageReplied();
220  }
221  if ( messageItem->status().isForwarded() )
222  return Manager::instance()->pixmapMessageForwarded();
223 
224  return get_read_state_icon( messageItem );
225 }
226 
227 static inline const QPixmap * get_encryption_state_icon( MessageItem * messageItem, bool *treatAsEnabled )
228 {
229  switch( messageItem->encryptionState() )
230  {
231  case MessageItem::FullyEncrypted:
232  *treatAsEnabled = true;
233  return Manager::instance()->pixmapMessageFullyEncrypted();
234  break;
235  case MessageItem::PartiallyEncrypted:
236  *treatAsEnabled = true;
237  return Manager::instance()->pixmapMessagePartiallyEncrypted();
238  break;
239  case MessageItem::EncryptionStateUnknown:
240  *treatAsEnabled = false;
241  return Manager::instance()->pixmapMessageUndefinedEncrypted();
242  break;
243  case MessageItem::NotEncrypted:
244  *treatAsEnabled = false;
245  return Manager::instance()->pixmapMessageNotEncrypted();
246  break;
247  default:
248  // should never happen
249  Q_ASSERT( false );
250  break;
251  }
252 
253  *treatAsEnabled = false;
254  return Manager::instance()->pixmapMessageUndefinedEncrypted();
255 }
256 
257 static inline const QPixmap * get_signature_state_icon( MessageItem * messageItem, bool *treatAsEnabled )
258 {
259  switch( messageItem->signatureState() )
260  {
261  case MessageItem::FullySigned:
262  *treatAsEnabled = true;
263  return Manager::instance()->pixmapMessageFullySigned();
264  break;
265  case MessageItem::PartiallySigned:
266  *treatAsEnabled = true;
267  return Manager::instance()->pixmapMessagePartiallySigned();
268  break;
269  case MessageItem::SignatureStateUnknown:
270  *treatAsEnabled = false;
271  return Manager::instance()->pixmapMessageUndefinedSigned();
272  break;
273  case MessageItem::NotSigned:
274  *treatAsEnabled = false;
275  return Manager::instance()->pixmapMessageNotSigned();
276  break;
277  default:
278  // should never happen
279  Q_ASSERT( false );
280  break;
281  }
282 
283  *treatAsEnabled = false;
284  return Manager::instance()->pixmapMessageUndefinedSigned();
285 }
286 
287 static inline const QPixmap * get_replied_state_icon( MessageItem * messageItem )
288 {
289  if ( messageItem->status().isReplied() )
290  {
291  if ( messageItem->status().isForwarded() )
292  return Manager::instance()->pixmapMessageRepliedAndForwarded();
293  return Manager::instance()->pixmapMessageReplied();
294  }
295  if ( messageItem->status().isForwarded() )
296  return Manager::instance()->pixmapMessageForwarded();
297 
298  return 0;
299 }
300 
301 static inline const QPixmap * get_spam_ham_state_icon( MessageItem * messageItem )
302 {
303  if ( messageItem->status().isSpam() )
304  return Manager::instance()->pixmapMessageSpam();
305  if ( messageItem->status().isHam() )
306  return Manager::instance()->pixmapMessageHam();
307  return 0;
308 }
309 
310 static inline const QPixmap * get_watched_ignored_state_icon( MessageItem * messageItem )
311 {
312  if ( messageItem->status().isIgnored() )
313  return Manager::instance()->pixmapMessageIgnored();
314  if ( messageItem->status().isWatched() )
315  return Manager::instance()->pixmapMessageWatched();
316  return 0;
317 }
318 
319 static inline void paint_vertical_line( QPainter * painter, int &left, int top, int &right, int bottom, bool alignOnRight )
320 {
321  if ( alignOnRight )
322  {
323  right -= 1;
324  if ( right < 0 )
325  return;
326  painter->drawLine( right, top, right, bottom );
327  right -= 2;
328  right -= gHorizontalItemSpacing;
329  } else {
330  left += 1;
331  if ( left > right )
332  return;
333  painter->drawLine( left, top, left, bottom );
334  left += 2 + gHorizontalItemSpacing;
335  }
336 }
337 
338 static inline void compute_bounding_rect_for_vertical_line( int &left, int top, int &right, int bottom, QRect &outRect, bool alignOnRight )
339 {
340  if ( alignOnRight )
341  {
342  right -= 3;
343  outRect = QRect( right, top, 3, bottom - top );
344  right -= gHorizontalItemSpacing;
345  } else {
346  outRect = QRect( left, top, 3, bottom - top );
347  left += 3 + gHorizontalItemSpacing;
348  }
349 }
350 
351 static inline void paint_horizontal_spacer( int &left, int, int &right, int, bool alignOnRight )
352 {
353  if ( alignOnRight )
354  {
355  right -= 3 + gHorizontalItemSpacing;
356  } else {
357  left += 3 + gHorizontalItemSpacing;
358  }
359 }
360 
361 static inline void compute_bounding_rect_for_horizontal_spacer( int &left, int top, int &right, int bottom, QRect &outRect, bool alignOnRight )
362 {
363  if ( alignOnRight )
364  {
365  right -= 3;
366  outRect = QRect( right, top, 3, bottom - top );
367  right -= gHorizontalItemSpacing;
368  } else {
369  outRect = QRect( left, top, 3, bottom - top );
370  left += 3 + gHorizontalItemSpacing;
371  }
372 }
373 
374 static inline void paint_permanent_icon( const QPixmap * pix, Theme::ContentItem *,
375  QPainter * painter, int &left, int top, int &right,
376  bool alignOnRight, int iconSize )
377 {
378  if ( alignOnRight )
379  {
380  right -= iconSize; // this icon is always present
381  if ( right < 0 )
382  return;
383  painter->drawPixmap( right, top, iconSize, iconSize, *pix );
384  right -= gHorizontalItemSpacing;
385  } else {
386  if ( left > ( right - iconSize ) )
387  return;
388  painter->drawPixmap( left, top, iconSize, iconSize, *pix );
389  left += iconSize + gHorizontalItemSpacing;
390  }
391 }
392 
393 static inline void compute_bounding_rect_for_permanent_icon( Theme::ContentItem *, int &left,
394  int top, int &right,
395  QRect &outRect, bool alignOnRight,
396  int iconSize )
397 {
398  if ( alignOnRight )
399  {
400  right -= iconSize; // this icon is always present
401  outRect = QRect( right, top, iconSize, iconSize );
402  right -= gHorizontalItemSpacing;
403  } else {
404  outRect = QRect( left, top, iconSize, iconSize );
405  left += iconSize + gHorizontalItemSpacing;
406  }
407 }
408 
409 
410 static inline void paint_boolean_state_icon( bool enabled, const QPixmap * pix,
411  Theme::ContentItem * ci, QPainter * painter, int &left,
412  int top, int &right, bool alignOnRight,
413  int iconSize )
414 {
415  if ( enabled )
416  {
417  paint_permanent_icon( pix, ci, painter, left, top, right, alignOnRight, iconSize );
418  return;
419  }
420 
421  // off -> icon disabled
422  if ( ci->hideWhenDisabled() )
423  return; // doesn't even take space
424 
425  if ( ci->softenByBlendingWhenDisabled() )
426  {
427  // still paint, but very soft
428  qreal oldOpacity = painter->opacity();
429  painter->setOpacity( 0.1 );
430  paint_permanent_icon( pix, ci, painter, left, top, right, alignOnRight, iconSize );
431  painter->setOpacity( oldOpacity );
432  return;
433  }
434 
435  // just takes space
436  if ( alignOnRight )
437  right -= iconSize + gHorizontalItemSpacing;
438  else
439  left += iconSize + gHorizontalItemSpacing;
440 }
441 
442 static inline void compute_bounding_rect_for_boolean_state_icon( bool enabled, Theme::ContentItem * ci,
443  int &left, int top, int &right,
444  QRect &outRect, bool alignOnRight,
445  int iconSize )
446 {
447  if ( ( !enabled ) && ci->hideWhenDisabled() )
448  {
449  outRect = QRect();
450  return; // doesn't even take space
451  }
452 
453  compute_bounding_rect_for_permanent_icon( ci, left, top, right, outRect, alignOnRight, iconSize );
454 }
455 
456 static inline void paint_tag_list( const QList< MessageItem::Tag * > &tagList, QPainter * painter,
457  int &left, int top, int &right, bool alignOnRight, int iconSize )
458 {
459  if ( alignOnRight )
460  {
461  foreach( const MessageItem::Tag *tag, tagList ) {
462  right -= iconSize; // this icon is always present
463  if ( right < 0 )
464  return;
465  painter->drawPixmap( right, top, iconSize, iconSize, tag->pixmap() );
466  right -= gHorizontalItemSpacing;
467  }
468  } else {
469  foreach( const MessageItem::Tag *tag, tagList ) {
470  if ( left > right - iconSize )
471  return;
472  painter->drawPixmap( left, top, iconSize, iconSize, tag->pixmap() );
473  left += iconSize + gHorizontalItemSpacing;
474  }
475  }
476 }
477 
478 static inline void compute_bounding_rect_for_tag_list( const QList< MessageItem::Tag * > &tagList,
479  int &left, int top, int &right, QRect &outRect,
480  bool alignOnRight, int iconSize )
481 {
482  int width = tagList.count() * ( iconSize + gHorizontalItemSpacing );
483  if ( alignOnRight )
484  {
485  right -= width;
486  outRect = QRect( right, top, width, iconSize );
487  } else {
488  outRect = QRect( left, top, width, iconSize );
489  left += width;
490  }
491 }
492 
493 static inline void compute_size_hint_for_item( Theme::ContentItem * ci,
494  int &maxh, int &totalw, int iconSize, const Item *item )
495 {
496  if ( ci->displaysText() )
497  {
498  const QFont font = ThemeDelegate::itemFont( ci, item );
499  const QString fontKey = ThemeDelegate::itemFontKey( ci, item );
500  const int fontHeight = cachedFontHeightKey( font, fontKey );
501  if ( fontHeight > maxh )
502  maxh = fontHeight;
503  totalw += ci->displaysLongText() ? 128 : 64;
504  return;
505  }
506 
507  if ( ci->isIcon() )
508  {
509  totalw += iconSize + gHorizontalItemSpacing;
510  if ( maxh < iconSize )
511  maxh = iconSize;
512  return;
513  }
514 
515  if ( ci->isSpacer() )
516  {
517  if ( 18 > maxh )
518  maxh = 18;
519  totalw += 3 + gHorizontalItemSpacing;
520  return;
521  }
522 
523  // should never be reached
524  if ( 18 > maxh )
525  maxh = 18;
526  totalw += gHorizontalItemSpacing;
527 }
528 
529 static inline QSize compute_size_hint_for_row( const Theme::Row * r, int iconSize, const Item *item )
530 {
531  int maxh = 8; // at least 8 pixels for a pixmap
532  int totalw = 0;
533 
534  // right aligned stuff first
535  const QList< Theme::ContentItem * > * items = &( r->rightItems() );
536  QList< Theme::ContentItem * >::ConstIterator itemit, endItemIt;
537 
538  for ( itemit = items->begin(), endItemIt = items->end(); itemit != endItemIt; ++itemit )
539  compute_size_hint_for_item( const_cast< Theme::ContentItem * >( *itemit ), maxh, totalw, iconSize, item );
540 
541  // then left aligned stuff
542  items = &( r->leftItems() );
543 
544  for ( itemit = items->begin(), endItemIt = items->end(); itemit != endItemIt; ++itemit )
545  compute_size_hint_for_item( const_cast< Theme::ContentItem * >( *itemit ), maxh, totalw, iconSize, item );
546 
547  return QSize( totalw, maxh );
548 }
549 
550 void ThemeDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
551 {
552  if ( !index.isValid() )
553  return; // bleah
554 
555  Item * item = itemFromIndex( index );
556  if ( !item )
557  return; // hm...
558 
559  QStyleOptionViewItemV4 opt = option;
560  initStyleOption( &opt, index );
561 
562  opt.text.clear(); // draw no text for me, please.. I'll do it in a while
563 
564  // Set background color of control if necessary
565  if ( item->type() == Item::Message ) {
566  MessageItem * msgItem = static_cast< MessageItem * >( item );
567  if ( msgItem->backgroundColor().isValid() )
568  opt.backgroundBrush = QBrush( msgItem->backgroundColor() );
569  }
570 
571  QStyle * style = mItemView->style();
572  style->drawControl( QStyle::CE_ItemViewItem, &opt, painter, mItemView );
573 
574  if ( !mTheme )
575  return; // hm hm...
576 
577  const Theme::Column * skcolumn = mTheme->column( index.column() );
578  if ( !skcolumn )
579  return; // bleah
580 
581  const QList< Theme::Row * > * rows; // I'd like to have it as reference, but gcc complains...
582 
583  MessageItem * messageItem = 0;
584  GroupHeaderItem * groupHeaderItem = 0;
585 
586  int top = opt.rect.top();
587  int right = opt.rect.left() + opt.rect.width(); // don't use opt.rect.right() since it's screwed
588  int left = opt.rect.left();
589 
590  // Storing the changed members one by one is faster than saving the painter state
591  QFont oldFont = painter->font();
592  QPen oldPen = painter->pen();
593  qreal oldOpacity = painter->opacity();
594 
595  QPen defaultPen;
596  bool usingNonDefaultTextColor = false;
597 
598  switch ( item->type() )
599  {
600  case Item::Message:
601  {
602  rows = &( skcolumn->messageRows() );
603  messageItem = static_cast< MessageItem * >( item );
604 
605 
606  if (
607  ( ! ( opt.state & QStyle::State_Enabled ) ) ||
608  messageItem->aboutToBeRemoved() ||
609  ( ! messageItem->isValid() )
610  )
611  {
612  painter->setOpacity( 0.5 );
613  defaultPen = QPen( opt.palette.brush( QPalette::Disabled, QPalette::Text ), 0 );
614  } else {
615 
616  QPalette::ColorGroup cg;
617 
618  if ( opt.state & QStyle::State_Active )
619  cg = QPalette::Normal;
620  else
621  cg = QPalette::Inactive;
622 
623  if ( opt.state & QStyle::State_Selected )
624  {
625  defaultPen = QPen( opt.palette.brush( cg, QPalette::HighlightedText ), 0 );
626  } else {
627  if ( messageItem->textColor().isValid() )
628  {
629  usingNonDefaultTextColor = true;
630  defaultPen = QPen( messageItem->textColor(), 0 );
631  } else {
632  defaultPen = QPen( opt.palette.brush( cg, QPalette::Text ), 0 );
633  }
634  }
635  }
636 
637  top += gMessageVerticalMargin;
638  right -= gMessageHorizontalMargin;
639  left += gMessageHorizontalMargin;
640  }
641  break;
642  case Item::GroupHeader:
643  {
644  rows = &( skcolumn->groupHeaderRows() );
645  groupHeaderItem = static_cast< GroupHeaderItem * >( item );
646 
647  QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
648 
649  if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
650  cg = QPalette::Inactive;
651 
652  QPalette::ColorRole cr;
653 
654  top += gGroupHeaderOuterVerticalMargin;
655  right -= gGroupHeaderOuterHorizontalMargin;
656  left += gGroupHeaderOuterHorizontalMargin;
657 
658  switch ( mTheme->groupHeaderBackgroundMode() )
659  {
660  case Theme::Transparent:
661  cr = ( opt.state & QStyle::State_Selected ) ? QPalette::HighlightedText : QPalette::Text;
662  defaultPen = QPen( opt.palette.brush( cg, cr ), 0 );
663  break;
664  case Theme::AutoColor:
665  case Theme::CustomColor:
666  switch ( mTheme->groupHeaderBackgroundStyle() )
667  {
668  case Theme::PlainRect:
669  {
670  painter->fillRect(
671  QRect( left, top, right - left, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
672  QBrush( mGroupHeaderBackgroundColor )
673  );
674  }
675  break;
676  case Theme::PlainJoinedRect:
677  {
678  int rleft = ( opt.viewItemPosition == QStyleOptionViewItemV4::Beginning ) || ( opt.viewItemPosition == QStyleOptionViewItemV4::OnlyOne ) ? left : opt.rect.left();
679  int rright = ( opt.viewItemPosition == QStyleOptionViewItemV4::End ) || ( opt.viewItemPosition == QStyleOptionViewItemV4::OnlyOne ) ? right : opt.rect.left() + opt.rect.width();
680  painter->fillRect(
681  QRect( rleft, top, rright - rleft, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
682  QBrush( mGroupHeaderBackgroundColor )
683  );
684  }
685  break;
686  case Theme::RoundedJoinedRect:
687  {
688  if ( opt.viewItemPosition == QStyleOptionViewItemV4::Middle )
689  {
690  painter->fillRect(
691  QRect( opt.rect.left(), top, opt.rect.width(), opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
692  QBrush( mGroupHeaderBackgroundColor )
693  );
694  break; // don't fall through
695  }
696  if ( opt.viewItemPosition == QStyleOptionViewItemV4::Beginning )
697  {
698  painter->fillRect(
699  QRect( opt.rect.left() + opt.rect.width() - 10, top, 10, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
700  QBrush( mGroupHeaderBackgroundColor )
701  );
702  } else if ( opt.viewItemPosition == QStyleOptionViewItemV4::End )
703  {
704  painter->fillRect(
705  QRect( opt.rect.left(), top, 10 , opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
706  QBrush( mGroupHeaderBackgroundColor )
707  );
708  }
709  // fall through anyway
710  }
711  case Theme::RoundedRect:
712  {
713  painter->setPen( Qt::NoPen );
714  bool hadAntialiasing = painter->renderHints() & QPainter::Antialiasing;
715  if ( !hadAntialiasing )
716  painter->setRenderHint( QPainter::Antialiasing, true );
717  painter->setBrush( QBrush( mGroupHeaderBackgroundColor ) );
718  painter->setBackgroundMode( Qt::OpaqueMode );
719  int w = right - left;
720  if ( w > 0 )
721  painter->drawRoundedRect(
722  QRect( left, top, w, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
723  4.0, 4.0
724  );
725  if ( !hadAntialiasing )
726  painter->setRenderHint( QPainter::Antialiasing, false );
727  painter->setBackgroundMode( Qt::TransparentMode );
728  }
729  break;
730  case Theme::GradientJoinedRect:
731  {
732  // FIXME: Could cache this brush
733  QLinearGradient gradient( 0, top, 0, top + opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) );
734  gradient.setColorAt( 0.0, KColorScheme::shade( mGroupHeaderBackgroundColor, KColorScheme::LightShade, 0.3 ) );
735  gradient.setColorAt( 1.0, mGroupHeaderBackgroundColor );
736  if ( opt.viewItemPosition == QStyleOptionViewItemV4::Middle )
737  {
738  painter->fillRect(
739  QRect( opt.rect.left(), top, opt.rect.width(), opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
740  QBrush( gradient )
741  );
742  break; // don't fall through
743  }
744  if ( opt.viewItemPosition == QStyleOptionViewItemV4::Beginning )
745  {
746  painter->fillRect(
747  QRect( opt.rect.left() + opt.rect.width() - 10, top, 10, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
748  QBrush( gradient )
749  );
750  } else if ( opt.viewItemPosition == QStyleOptionViewItemV4::End )
751  {
752  painter->fillRect(
753  QRect( opt.rect.left(), top, 10 , opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
754  QBrush( gradient )
755  );
756  }
757  // fall through anyway
758  }
759  case Theme::GradientRect:
760  {
761  // FIXME: Could cache this brush
762  QLinearGradient gradient( 0, top, 0, top + opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) );
763  gradient.setColorAt( 0.0, KColorScheme::shade( mGroupHeaderBackgroundColor, KColorScheme::LightShade, 0.3 ) );
764  gradient.setColorAt( 1.0, mGroupHeaderBackgroundColor );
765  painter->setPen( Qt::NoPen );
766  bool hadAntialiasing = painter->renderHints() & QPainter::Antialiasing;
767  if ( !hadAntialiasing )
768  painter->setRenderHint( QPainter::Antialiasing, true );
769  painter->setBrush( QBrush( gradient ) );
770  painter->setBackgroundMode( Qt::OpaqueMode );
771  int w = right - left;
772  if ( w > 0 )
773  painter->drawRoundedRect(
774  QRect( left, top, w, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) ),
775  4.0, 4.0
776  );
777  if ( !hadAntialiasing )
778  painter->setRenderHint( QPainter::Antialiasing, false );
779  painter->setBackgroundMode( Qt::TransparentMode );
780  }
781  break;
782  case Theme::StyledRect:
783  {
784  // oxygen, for instance, has a nice graphics for selected items
785  opt.rect = QRect( left, top, right - left, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) );
786  opt.state |= QStyle::State_Selected;
787  opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
788  opt.palette.setColor( cg ,QPalette::Highlight, mGroupHeaderBackgroundColor );
789  style->drawControl( QStyle::CE_ItemViewItem, &opt, painter, mItemView );
790  }
791  break;
792  case Theme::StyledJoinedRect:
793  {
794  int rleft = ( opt.viewItemPosition == QStyleOptionViewItemV4::Beginning ) || ( opt.viewItemPosition == QStyleOptionViewItemV4::OnlyOne ) ? left : opt.rect.left();
795  int rright = ( opt.viewItemPosition == QStyleOptionViewItemV4::End ) || ( opt.viewItemPosition == QStyleOptionViewItemV4::OnlyOne ) ? right : opt.rect.left() + opt.rect.width();
796  opt.rect = QRect( rleft, top, rright - rleft, opt.rect.height() - ( gGroupHeaderInnerVerticalMargin * 2 ) );
797  opt.state |= QStyle::State_Selected;
798  opt.palette.setColor( cg ,QPalette::Highlight, mGroupHeaderBackgroundColor );
799  style->drawControl( QStyle::CE_ItemViewItem, &opt, painter, mItemView );
800  }
801  break;
802  }
803 
804  defaultPen = QPen( opt.palette.brush( cg, QPalette::Text ), 0 );
805  break;
806  }
807  top += gGroupHeaderInnerVerticalMargin;
808  right -= gGroupHeaderInnerHorizontalMargin;
809  left += gGroupHeaderInnerHorizontalMargin;
810  }
811  break;
812  default:
813  Q_ASSERT( false );
814  return; // bug
815  break;
816  }
817 
818  Qt::LayoutDirection layoutDir = mItemView->layoutDirection();
819 
820  QList< Theme::Row * >::ConstIterator end( rows->constEnd() );
821  for ( QList< Theme::Row * >::ConstIterator rowit = rows->constBegin(); rowit != end; ++rowit )
822  {
823  QSize rowSizeHint = compute_size_hint_for_row( ( *rowit ), mTheme->iconSize(), item );
824 
825  int bottom = top + rowSizeHint.height();
826 
827  // paint right aligned stuff first
828  const QList< Theme::ContentItem * > * items = &( ( *rowit )->rightItems() );
829 
830  int r = right;
831  int l = left;
832  QList< Theme::ContentItem * >::ConstIterator endit( items->constEnd() );
833  for ( QList< Theme::ContentItem * >::ConstIterator itemit = items->constBegin(); itemit != endit ; ++itemit )
834  {
835  Theme::ContentItem * ci = const_cast< Theme::ContentItem * >( *itemit );
836 
837  if ( ci->canUseCustomColor() )
838  {
839  if ( ci->useCustomColor() && ( !(opt.state & QStyle::State_Selected) ) )
840  {
841  if ( usingNonDefaultTextColor )
842  {
843  // merge the colors
844  QColor nonDefault = defaultPen.color();
845  QColor custom = ci->customColor();
846  QColor merged(
847  ( nonDefault.red() + custom.red() ) >> 1,
848  ( nonDefault.green() + custom.green() ) >> 1,
849  ( nonDefault.blue() + custom.blue() ) >> 1
850  );
851  painter->setPen( QPen( merged ) );
852  } else {
853  painter->setPen( QPen( ci->customColor() ) );
854  }
855  } else
856  painter->setPen( defaultPen );
857  } // otherwise setting a pen is useless at this time
858 
859  QFont font = itemFont( ci, item );
860 
861  switch ( ci->type() )
862  {
863  case Theme::ContentItem::Subject:
864  paint_right_aligned_elided_text( item->subject(), ci, painter, l, top, r, layoutDir, font );
865  break;
866  case Theme::ContentItem::SenderOrReceiver:
867  paint_right_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( item->senderOrReceiver() ),
868  ci, painter, l, top, r, layoutDir, font );
869  break;
870  case Theme::ContentItem::Receiver:
871  paint_right_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( item->receiver() ),
872  ci, painter, l, top, r, layoutDir, font );
873  break;
874  case Theme::ContentItem::Sender:
875  paint_right_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( item->sender() ),
876  ci, painter, l, top, r, layoutDir, font );
877  break;
878  case Theme::ContentItem::Date:
879  paint_right_aligned_elided_text( item->formattedDate(), ci, painter, l, top, r, layoutDir, font );
880  break;
881  case Theme::ContentItem::MostRecentDate:
882  paint_right_aligned_elided_text( item->formattedMaxDate(), ci, painter, l, top, r, layoutDir, font );
883  break;
884  case Theme::ContentItem::Size:
885  paint_right_aligned_elided_text( item->formattedSize(), ci, painter, l, top, r, layoutDir, font );
886  break;
887  case Theme::ContentItem::GroupHeaderLabel:
888  if ( groupHeaderItem )
889  paint_right_aligned_elided_text( groupHeaderItem->label(), ci, painter, l, top, r, layoutDir, font );
890  break;
891  case Theme::ContentItem::ReadStateIcon:
892  paint_permanent_icon( get_read_state_icon( item ), ci, painter, l, top, r,
893  layoutDir == Qt::LeftToRight, mTheme->iconSize() );
894  break;
895  case Theme::ContentItem::CombinedReadRepliedStateIcon:
896  if ( messageItem )
897  paint_permanent_icon( get_combined_read_replied_state_icon( messageItem ), ci, painter,
898  l, top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
899  break;
900  case Theme::ContentItem::ExpandedStateIcon:
901  {
902  const QPixmap * pix = item->childItemCount() > 0 ? ((option.state & QStyle::State_Open) ? Manager::instance()->pixmapShowLess() : Manager::instance()->pixmapShowMore()) : 0;
903  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapShowMore(),
904  ci, painter, l, top, r, layoutDir == Qt::LeftToRight,
905  mTheme->iconSize() );
906  }
907  break;
908  case Theme::ContentItem::RepliedStateIcon:
909  if ( messageItem )
910  {
911  const QPixmap * pix = get_replied_state_icon( messageItem );
912  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapMessageReplied(),
913  ci, painter, l, top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
914  }
915  break;
916  case Theme::ContentItem::EncryptionStateIcon:
917  if ( messageItem )
918  {
919  bool enabled;
920  const QPixmap * pix = get_encryption_state_icon( messageItem, &enabled );
921  paint_boolean_state_icon( enabled, pix, ci, painter, l, top, r,
922  layoutDir == Qt::LeftToRight, mTheme->iconSize() );
923  }
924  break;
925  case Theme::ContentItem::SignatureStateIcon:
926  if ( messageItem )
927  {
928  bool enabled;
929  const QPixmap * pix = get_signature_state_icon( messageItem, &enabled );
930  paint_boolean_state_icon( enabled, pix, ci, painter, l, top, r,
931  layoutDir == Qt::LeftToRight, mTheme->iconSize() );
932  }
933  break;
934  case Theme::ContentItem::SpamHamStateIcon:
935  if ( messageItem )
936  {
937  const QPixmap * pix = get_spam_ham_state_icon( messageItem );
938  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapMessageSpam(),
939  ci, painter, l, top, r, layoutDir == Qt::LeftToRight,
940  mTheme->iconSize() );
941  }
942  break;
943  case Theme::ContentItem::WatchedIgnoredStateIcon:
944  if ( messageItem )
945  {
946  const QPixmap * pix = get_watched_ignored_state_icon( messageItem );
947  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapMessageWatched(),
948  ci, painter, l, top, r, layoutDir == Qt::LeftToRight,
949  mTheme->iconSize() );
950  }
951  break;
952  case Theme::ContentItem::AttachmentStateIcon:
953  if ( messageItem )
954  paint_boolean_state_icon( messageItem->status().hasAttachment(),
955  Manager::instance()->pixmapMessageAttachment(), ci, painter,
956  l, top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
957  break;
958  case Theme::ContentItem::AnnotationIcon:
959  if ( messageItem )
960  paint_boolean_state_icon( messageItem->hasAnnotation(),
961  Manager::instance()->pixmapMessageAnnotation(), ci, painter,
962  l, top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
963  break;
964  case Theme::ContentItem::InvitationIcon:
965  if ( messageItem )
966  paint_boolean_state_icon( messageItem->status().hasInvitation(),
967  Manager::instance()->pixmapMessageInvitation(), ci, painter,
968  l, top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
969  break;
970  case Theme::ContentItem::ActionItemStateIcon:
971  if ( messageItem )
972  paint_boolean_state_icon( messageItem->status().isToAct(),
973  Manager::instance()->pixmapMessageActionItem(), ci, painter,
974  l, top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
975  break;
976  case Theme::ContentItem::ImportantStateIcon:
977  if ( messageItem )
978  paint_boolean_state_icon( messageItem->status().isImportant(),
979  Manager::instance()->pixmapMessageImportant(), ci, painter, l,
980  top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
981  break;
982  case Theme::ContentItem::VerticalLine:
983  paint_vertical_line( painter, l, top, r, bottom, layoutDir == Qt::LeftToRight );
984  break;
985  case Theme::ContentItem::HorizontalSpacer:
986  paint_horizontal_spacer( l, top, r, bottom, layoutDir == Qt::LeftToRight );
987  break;
988  case Theme::ContentItem::TagList:
989  if ( messageItem )
990  {
991  const QList< MessageItem::Tag * > tagList = messageItem->tagList();
992  paint_tag_list( tagList, painter, l, top, r, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
993  }
994  break;
995  }
996  }
997 
998  // then paint left aligned stuff
999  items = &( ( *rowit )->leftItems() );
1000 
1001  QList< Theme::ContentItem * >::ConstIterator endItem( items->constEnd() );
1002  for ( QList< Theme::ContentItem * >::ConstIterator itemit = items->constBegin(); itemit != endItem ; ++itemit )
1003  {
1004  Theme::ContentItem * ci = const_cast< Theme::ContentItem * >( *itemit );
1005 
1006  if ( ci->canUseCustomColor() )
1007  {
1008  if ( ci->useCustomColor() && ( !(opt.state & QStyle::State_Selected) ) )
1009  {
1010  if ( usingNonDefaultTextColor )
1011  {
1012  // merge the colors
1013  QColor nonDefault = defaultPen.color();
1014  QColor custom = ci->customColor();
1015  QColor merged(
1016  ( nonDefault.red() + custom.red() ) >> 1,
1017  ( nonDefault.green() + custom.green() ) >> 1,
1018  ( nonDefault.blue() + custom.blue() ) >> 1
1019  );
1020  painter->setPen( QPen( merged ) );
1021  } else {
1022  painter->setPen( QPen( ci->customColor() ) );
1023  }
1024  } else {
1025  painter->setPen( defaultPen );
1026  }
1027  } // otherwise setting a pen is useless at this time
1028 
1029  QFont font = itemFont( ci, item );
1030 
1031  switch ( ci->type() )
1032  {
1033  case Theme::ContentItem::Subject:
1034  paint_left_aligned_elided_text( item->subject(), ci, painter, l, top, r, layoutDir, font );
1035  break;
1036  case Theme::ContentItem::SenderOrReceiver:
1037  paint_left_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( item->senderOrReceiver() ),
1038  ci, painter, l, top, r, layoutDir, font );
1039  break;
1040  case Theme::ContentItem::Receiver:
1041  paint_left_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( item->receiver() ),
1042  ci, painter, l, top, r, layoutDir, font );
1043  break;
1044  case Theme::ContentItem::Sender:
1045  paint_left_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( item->sender() ),
1046  ci, painter, l, top, r, layoutDir, font );
1047  break;
1048  case Theme::ContentItem::Date:
1049  paint_left_aligned_elided_text( item->formattedDate(), ci, painter, l, top, r, layoutDir, font );
1050  break;
1051  case Theme::ContentItem::MostRecentDate:
1052  paint_left_aligned_elided_text( item->formattedMaxDate(), ci, painter, l, top, r, layoutDir, font );
1053  break;
1054  case Theme::ContentItem::Size:
1055  paint_left_aligned_elided_text( item->formattedSize(), ci, painter, l, top, r, layoutDir, font );
1056  break;
1057  case Theme::ContentItem::GroupHeaderLabel:
1058  if ( groupHeaderItem )
1059  paint_left_aligned_elided_text( groupHeaderItem->label(), ci, painter, l, top, r, layoutDir, font );
1060  break;
1061  case Theme::ContentItem::ReadStateIcon:
1062  paint_permanent_icon( get_read_state_icon( item ), ci, painter, l, top, r,
1063  layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1064  break;
1065  case Theme::ContentItem::CombinedReadRepliedStateIcon:
1066  if ( messageItem )
1067  paint_permanent_icon( get_combined_read_replied_state_icon( messageItem ), ci, painter,
1068  l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1069  break;
1070  case Theme::ContentItem::ExpandedStateIcon:
1071  {
1072  const QPixmap * pix = item->childItemCount() > 0 ? ((option.state & QStyle::State_Open) ? Manager::instance()->pixmapShowLess() : Manager::instance()->pixmapShowMore()) : 0;
1073  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapShowMore(),
1074  ci, painter, l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1075  }
1076  break;
1077  case Theme::ContentItem::RepliedStateIcon:
1078  if ( messageItem )
1079  {
1080  const QPixmap * pix = get_replied_state_icon( messageItem );
1081  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapMessageReplied(),
1082  ci, painter, l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1083  }
1084  break;
1085  case Theme::ContentItem::EncryptionStateIcon:
1086  if ( messageItem )
1087  {
1088  bool enabled;
1089  const QPixmap * pix = get_encryption_state_icon( messageItem, &enabled );
1090  paint_boolean_state_icon( enabled, pix, ci, painter, l, top, r,
1091  layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1092  }
1093  break;
1094  case Theme::ContentItem::SignatureStateIcon:
1095  if ( messageItem )
1096  {
1097  bool enabled;
1098  const QPixmap * pix = get_signature_state_icon( messageItem, &enabled );
1099  paint_boolean_state_icon( enabled, pix, ci, painter, l, top, r,
1100  layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1101  }
1102  break;
1103  case Theme::ContentItem::SpamHamStateIcon:
1104  if ( messageItem )
1105  {
1106  const QPixmap * pix = get_spam_ham_state_icon( messageItem );
1107  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapMessageSpam(),
1108  ci, painter, l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1109  }
1110  break;
1111  case Theme::ContentItem::WatchedIgnoredStateIcon:
1112  if ( messageItem )
1113  {
1114  const QPixmap * pix = get_watched_ignored_state_icon( messageItem );
1115  paint_boolean_state_icon( pix != 0, pix ? pix : Manager::instance()->pixmapMessageWatched(),
1116  ci, painter, l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1117  }
1118  break;
1119  case Theme::ContentItem::AttachmentStateIcon:
1120  if ( messageItem )
1121  paint_boolean_state_icon( messageItem->status().hasAttachment(),
1122  Manager::instance()->pixmapMessageAttachment(), ci, painter,
1123  l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1124  break;
1125  case Theme::ContentItem::AnnotationIcon:
1126  if ( messageItem )
1127  paint_boolean_state_icon( messageItem->hasAnnotation(),
1128  Manager::instance()->pixmapMessageAnnotation(), ci, painter,
1129  l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1130  break;
1131  case Theme::ContentItem::InvitationIcon:
1132  if ( messageItem )
1133  paint_boolean_state_icon( messageItem->status().hasInvitation(),
1134  Manager::instance()->pixmapMessageInvitation(), ci, painter,
1135  l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1136  break;
1137  case Theme::ContentItem::ActionItemStateIcon:
1138  if ( messageItem )
1139  paint_boolean_state_icon( messageItem->status().isToAct(),
1140  Manager::instance()->pixmapMessageActionItem(), ci, painter,
1141  l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1142  break;
1143  case Theme::ContentItem::ImportantStateIcon:
1144  if ( messageItem )
1145  paint_boolean_state_icon( messageItem->status().isImportant(),
1146  Manager::instance()->pixmapMessageImportant(), ci, painter, l,
1147  top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1148  break;
1149  case Theme::ContentItem::VerticalLine:
1150  paint_vertical_line( painter, l, top, r, bottom, layoutDir != Qt::LeftToRight );
1151  break;
1152  case Theme::ContentItem::HorizontalSpacer:
1153  paint_horizontal_spacer( l, top, r, bottom, layoutDir != Qt::LeftToRight );
1154  break;
1155  case Theme::ContentItem::TagList:
1156  if ( messageItem )
1157  {
1158  const QList< MessageItem::Tag * > tagList = messageItem->tagList();
1159  paint_tag_list( tagList, painter, l, top, r, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1160  }
1161  break;
1162  }
1163  }
1164 
1165  top = bottom;
1166  }
1167 
1168  painter->setFont( oldFont );
1169  painter->setPen( oldPen );
1170  painter->setOpacity( oldOpacity );
1171 }
1172 
1173 bool ThemeDelegate::hitTest( const QPoint &viewportPoint, bool exact )
1174 {
1175  mHitItem = 0;
1176  mHitColumn = 0;
1177  mHitRow = 0;
1178  mHitContentItem = 0;
1179 
1180  if ( !mTheme )
1181  return false; // hm hm...
1182 
1183  mHitIndex = mItemView->indexAt( viewportPoint );
1184 
1185  if ( !mHitIndex.isValid() )
1186  return false; // bleah
1187 
1188  mHitItem = itemFromIndex( mHitIndex );
1189  if ( !mHitItem )
1190  return false; // hm...
1191 
1192  mHitItemRect = mItemView->visualRect( mHitIndex );
1193 
1194  mHitColumn = mTheme->column( mHitIndex.column() );
1195  if ( !mHitColumn )
1196  return false; // bleah
1197 
1198  const QList< Theme::Row * > * rows; // I'd like to have it as reference, but gcc complains...
1199 
1200  MessageItem * messageItem = 0;
1201  GroupHeaderItem * groupHeaderItem = 0;
1202 
1203  int top = mHitItemRect.top();
1204  int right = mHitItemRect.right();
1205  int left = mHitItemRect.left();
1206 
1207  mHitRow = 0;
1208  mHitRowIndex = -1;
1209  mHitContentItem = 0;
1210 
1211  switch ( mHitItem->type() )
1212  {
1213  case Item::Message:
1214  mHitRowIsMessageRow = true;
1215  rows = &( mHitColumn->messageRows() );
1216  messageItem = static_cast< MessageItem * >( mHitItem );
1217  // FIXME: paint eventual background here
1218 
1219  top += gMessageVerticalMargin;
1220  right -= gMessageHorizontalMargin;
1221  left += gMessageHorizontalMargin;
1222  break;
1223  case Item::GroupHeader:
1224  mHitRowIsMessageRow = false;
1225  rows = &( mHitColumn->groupHeaderRows() );
1226  groupHeaderItem = static_cast< GroupHeaderItem * >( mHitItem );
1227 
1228  top += gGroupHeaderOuterVerticalMargin + gGroupHeaderInnerVerticalMargin;
1229  right -= gGroupHeaderOuterHorizontalMargin + gGroupHeaderInnerHorizontalMargin;
1230  left += gGroupHeaderOuterHorizontalMargin + gGroupHeaderInnerHorizontalMargin;
1231  break;
1232  default:
1233  return false; // bug
1234  break;
1235  }
1236 
1237  int rowIdx = 0;
1238  int bestInexactDistance = 0xffffff;
1239  bool bestInexactItemRight = false;
1240  QRect bestInexactRect;
1241  const Theme::ContentItem * bestInexactContentItem = 0;
1242 
1243  Qt::LayoutDirection layoutDir = mItemView->layoutDirection();
1244 
1245  QList< Theme::Row * >::ConstIterator end( rows->constEnd() );
1246  for ( QList< Theme::Row * >::ConstIterator rowit = rows->constBegin(); rowit != end; ++rowit )
1247  {
1248  QSize rowSizeHint = compute_size_hint_for_row( ( *rowit ), mTheme->iconSize(), mHitItem );
1249 
1250  if ( ( viewportPoint.y() < top ) && ( rowIdx > 0 ) )
1251  break; // not this row (tough we should have already found it... probably clicked upper margin)
1252 
1253  int bottom = top + rowSizeHint.height();
1254 
1255  if ( viewportPoint.y() > bottom )
1256  {
1257  top += rowSizeHint.height();
1258  rowIdx++;
1259  continue; // not this row
1260  }
1261 
1262  bestInexactItemRight = false;
1263  bestInexactDistance = 0xffffff;
1264  bestInexactContentItem = 0;
1265 
1266  // this row!
1267  mHitRow = *rowit;
1268  mHitRowIndex = rowIdx;
1269  mHitRowRect = QRect( left, top, right - left, bottom - top );
1270 
1271  // check right aligned stuff first
1272  const QList< Theme::ContentItem * > * items = &( mHitRow->rightItems() );
1273  QList< Theme::ContentItem * >::ConstIterator itemit;
1274 
1275  mHitContentItemRight = true;
1276 
1277  int r = right;
1278  int l = left;
1279  QList< Theme::ContentItem * >::ConstIterator itemEnd( items->end() );
1280 
1281  for ( itemit = items->begin(); itemit != itemEnd ; ++itemit )
1282  {
1283  Theme::ContentItem * ci = const_cast< Theme::ContentItem * >( *itemit );
1284 
1285  mHitContentItemRect = QRect();
1286 
1287  QFont font = itemFont( ci, mHitItem );
1288 
1289  switch ( ci->type() )
1290  {
1291  case Theme::ContentItem::Subject:
1292  compute_bounding_rect_for_right_aligned_elided_text( mHitItem->subject(), l, top, r, mHitContentItemRect, layoutDir, font );
1293  break;
1294  case Theme::ContentItem::SenderOrReceiver:
1295  compute_bounding_rect_for_right_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( mHitItem->senderOrReceiver() ),
1296  l, top, r, mHitContentItemRect, layoutDir, font );
1297  break;
1298  case Theme::ContentItem::Receiver:
1299  compute_bounding_rect_for_right_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( mHitItem->receiver() ),
1300  l, top, r, mHitContentItemRect, layoutDir, font );
1301  break;
1302  case Theme::ContentItem::Sender:
1303  compute_bounding_rect_for_right_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( mHitItem->sender() ),
1304  l, top, r, mHitContentItemRect, layoutDir, font );
1305  break;
1306  case Theme::ContentItem::Date:
1307  compute_bounding_rect_for_right_aligned_elided_text( mHitItem->formattedDate(), l, top, r, mHitContentItemRect, layoutDir, font );
1308  break;
1309  case Theme::ContentItem::MostRecentDate:
1310  compute_bounding_rect_for_right_aligned_elided_text( mHitItem->formattedMaxDate(), l, top, r, mHitContentItemRect, layoutDir, font );
1311  break;
1312  case Theme::ContentItem::Size:
1313  compute_bounding_rect_for_right_aligned_elided_text( mHitItem->formattedSize(), l, top, r, mHitContentItemRect, layoutDir, font );
1314  break;
1315  case Theme::ContentItem::GroupHeaderLabel:
1316  if ( groupHeaderItem )
1317  compute_bounding_rect_for_right_aligned_elided_text( groupHeaderItem->label(), l, top, r, mHitContentItemRect, layoutDir, font );
1318  break;
1319  case Theme::ContentItem::ReadStateIcon:
1320  compute_bounding_rect_for_permanent_icon( ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1321  break;
1322  case Theme::ContentItem::CombinedReadRepliedStateIcon:
1323  compute_bounding_rect_for_permanent_icon( ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1324  break;
1325  case Theme::ContentItem::ExpandedStateIcon:
1326  compute_bounding_rect_for_boolean_state_icon( mHitItem->childItemCount() > 0, ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1327  break;
1328  case Theme::ContentItem::RepliedStateIcon:
1329  if ( messageItem )
1330  {
1331  const QPixmap * pix = get_replied_state_icon( messageItem );
1332  compute_bounding_rect_for_boolean_state_icon( pix != 0, ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1333  }
1334  break;
1335  case Theme::ContentItem::EncryptionStateIcon:
1336  if ( messageItem )
1337  {
1338  bool enabled;
1339  get_encryption_state_icon( messageItem, &enabled );
1340  compute_bounding_rect_for_boolean_state_icon( enabled, ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1341  }
1342  break;
1343  case Theme::ContentItem::SignatureStateIcon:
1344  if ( messageItem )
1345  {
1346  bool enabled;
1347  get_signature_state_icon( messageItem, &enabled );
1348  compute_bounding_rect_for_boolean_state_icon( enabled, ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1349  }
1350  break;
1351  case Theme::ContentItem::SpamHamStateIcon:
1352  if ( messageItem )
1353  {
1354  const QPixmap * pix = get_spam_ham_state_icon( messageItem );
1355  compute_bounding_rect_for_boolean_state_icon( pix != 0, ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1356  }
1357  break;
1358  case Theme::ContentItem::WatchedIgnoredStateIcon:
1359  if ( messageItem )
1360  {
1361  const QPixmap * pix = get_watched_ignored_state_icon( messageItem );
1362  compute_bounding_rect_for_boolean_state_icon( pix != 0, ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1363  }
1364  break;
1365  case Theme::ContentItem::AttachmentStateIcon:
1366  if ( messageItem )
1367  compute_bounding_rect_for_boolean_state_icon( messageItem->status().hasAttachment(), ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1368  break;
1369  case Theme::ContentItem::AnnotationIcon:
1370  if ( messageItem )
1371  compute_bounding_rect_for_boolean_state_icon( messageItem->hasAnnotation(), ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1372  break;
1373  case Theme::ContentItem::InvitationIcon:
1374  if ( messageItem )
1375  compute_bounding_rect_for_boolean_state_icon( messageItem->status().hasInvitation(), ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1376  break;
1377  case Theme::ContentItem::ActionItemStateIcon:
1378  if ( messageItem )
1379  compute_bounding_rect_for_boolean_state_icon( messageItem->status().isToAct(), ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1380  break;
1381  case Theme::ContentItem::ImportantStateIcon:
1382  if ( messageItem )
1383  compute_bounding_rect_for_boolean_state_icon( messageItem->status().isImportant(), ci, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1384  break;
1385  case Theme::ContentItem::VerticalLine:
1386  compute_bounding_rect_for_vertical_line( l, top, r, bottom, mHitContentItemRect, layoutDir == Qt::LeftToRight );
1387  break;
1388  case Theme::ContentItem::HorizontalSpacer:
1389  compute_bounding_rect_for_horizontal_spacer( l, top, r, bottom, mHitContentItemRect, layoutDir == Qt::LeftToRight );
1390  break;
1391  case Theme::ContentItem::TagList:
1392  if ( messageItem )
1393  {
1394  const QList< MessageItem::Tag * > tagList = messageItem->tagList();
1395  compute_bounding_rect_for_tag_list( tagList, l, top, r, mHitContentItemRect, layoutDir == Qt::LeftToRight, mTheme->iconSize() );
1396  }
1397  break;
1398  }
1399 
1400  if ( mHitContentItemRect.isValid() )
1401  {
1402  if ( mHitContentItemRect.contains( viewportPoint ) )
1403  {
1404  // caught!
1405  mHitContentItem = ci;
1406  return true;
1407  }
1408  if ( !exact )
1409  {
1410  QRect inexactRect( mHitContentItemRect.left(), mHitRowRect.top(), mHitContentItemRect.width(), mHitRowRect.height() );
1411  if ( inexactRect.contains( viewportPoint ) )
1412  {
1413  mHitContentItem = ci;
1414  return true;
1415  }
1416 
1417  int inexactDistance = viewportPoint.x() > inexactRect.right() ? viewportPoint.x() - inexactRect.right() : inexactRect.left() - viewportPoint.x();
1418  if ( inexactDistance < bestInexactDistance )
1419  {
1420  bestInexactDistance = inexactDistance;
1421  bestInexactRect = mHitContentItemRect;
1422  bestInexactItemRight = true;
1423  bestInexactContentItem = ci;
1424  }
1425  }
1426  }
1427  }
1428 
1429  // then check left aligned stuff
1430  items = &( mHitRow->leftItems() );
1431 
1432  mHitContentItemRight = false;
1433 
1434  for ( itemit = items->constBegin(); itemit != items->constEnd() ; ++itemit )
1435  {
1436  Theme::ContentItem * ci = const_cast< Theme::ContentItem * >( *itemit );
1437 
1438  mHitContentItemRect = QRect();
1439 
1440  QFont font = itemFont( ci, mHitItem );
1441 
1442  switch ( ci->type() )
1443  {
1444  case Theme::ContentItem::Subject:
1445  compute_bounding_rect_for_left_aligned_elided_text( mHitItem->subject(), l, top, r, mHitContentItemRect, layoutDir, font );
1446  break;
1447  case Theme::ContentItem::SenderOrReceiver:
1448  compute_bounding_rect_for_left_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( mHitItem->senderOrReceiver() ),
1449  l, top, r, mHitContentItemRect, layoutDir, font );
1450  break;
1451  case Theme::ContentItem::Receiver:
1452  compute_bounding_rect_for_left_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( mHitItem->receiver() ),
1453  l, top, r, mHitContentItemRect, layoutDir, font );
1454  break;
1455  case Theme::ContentItem::Sender:
1456  compute_bounding_rect_for_left_aligned_elided_text( MessageCore::StringUtil::stripEmailAddr( mHitItem->sender() ),
1457  l, top, r, mHitContentItemRect, layoutDir, font );
1458  break;
1459  case Theme::ContentItem::Date:
1460  compute_bounding_rect_for_left_aligned_elided_text( mHitItem->formattedDate(), l, top, r, mHitContentItemRect, layoutDir, font );
1461  break;
1462  case Theme::ContentItem::MostRecentDate:
1463  compute_bounding_rect_for_left_aligned_elided_text( mHitItem->formattedMaxDate(), l, top, r, mHitContentItemRect, layoutDir, font );
1464  break;
1465  case Theme::ContentItem::Size:
1466  compute_bounding_rect_for_left_aligned_elided_text( mHitItem->formattedSize(), l, top, r, mHitContentItemRect, layoutDir, font );
1467  break;
1468  case Theme::ContentItem::GroupHeaderLabel:
1469  if ( groupHeaderItem )
1470  compute_bounding_rect_for_left_aligned_elided_text( groupHeaderItem->label(), l, top, r, mHitContentItemRect, layoutDir, font );
1471  break;
1472  case Theme::ContentItem::ReadStateIcon:
1473  compute_bounding_rect_for_permanent_icon( ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1474  break;
1475  case Theme::ContentItem::CombinedReadRepliedStateIcon:
1476  compute_bounding_rect_for_permanent_icon( ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1477  break;
1478  case Theme::ContentItem::ExpandedStateIcon:
1479  compute_bounding_rect_for_boolean_state_icon( mHitItem->childItemCount() > 0, ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1480  break;
1481  case Theme::ContentItem::RepliedStateIcon:
1482  if ( messageItem )
1483  {
1484  const QPixmap * pix = get_replied_state_icon( messageItem );
1485  compute_bounding_rect_for_boolean_state_icon( pix != 0, ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1486  }
1487  break;
1488  case Theme::ContentItem::EncryptionStateIcon:
1489  if ( messageItem )
1490  {
1491  bool enabled;
1492  get_encryption_state_icon( messageItem, &enabled );
1493  compute_bounding_rect_for_boolean_state_icon( enabled, ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1494  }
1495  break;
1496  case Theme::ContentItem::SignatureStateIcon:
1497  if ( messageItem )
1498  {
1499  bool enabled;
1500  get_signature_state_icon( messageItem, &enabled );
1501  compute_bounding_rect_for_boolean_state_icon( enabled, ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1502  }
1503  break;
1504  case Theme::ContentItem::SpamHamStateIcon:
1505  if ( messageItem )
1506  {
1507  const QPixmap * pix = get_spam_ham_state_icon( messageItem );
1508  compute_bounding_rect_for_boolean_state_icon( pix != 0, ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1509  }
1510  break;
1511  case Theme::ContentItem::WatchedIgnoredStateIcon:
1512  if ( messageItem )
1513  {
1514  const QPixmap * pix = get_watched_ignored_state_icon( messageItem );
1515  compute_bounding_rect_for_boolean_state_icon( pix != 0, ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1516  }
1517  break;
1518  case Theme::ContentItem::AttachmentStateIcon:
1519  if ( messageItem )
1520  compute_bounding_rect_for_boolean_state_icon( messageItem->status().hasAttachment(), ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1521  break;
1522  case Theme::ContentItem::AnnotationIcon:
1523  if ( messageItem )
1524  compute_bounding_rect_for_boolean_state_icon( messageItem->hasAnnotation(), ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1525  break;
1526  case Theme::ContentItem::InvitationIcon:
1527  if ( messageItem )
1528  compute_bounding_rect_for_boolean_state_icon( messageItem->status().hasInvitation(), ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1529  break;
1530  case Theme::ContentItem::ActionItemStateIcon:
1531  if ( messageItem )
1532  compute_bounding_rect_for_boolean_state_icon( messageItem->status().isToAct(), ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1533  break;
1534  case Theme::ContentItem::ImportantStateIcon:
1535  if ( messageItem )
1536  compute_bounding_rect_for_boolean_state_icon( messageItem->status().isImportant(), ci, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1537  break;
1538  case Theme::ContentItem::VerticalLine:
1539  compute_bounding_rect_for_vertical_line( l, top, r, bottom, mHitContentItemRect, layoutDir != Qt::LeftToRight );
1540  break;
1541  case Theme::ContentItem::HorizontalSpacer:
1542  compute_bounding_rect_for_horizontal_spacer( l, top, r, bottom, mHitContentItemRect, layoutDir != Qt::LeftToRight );
1543  break;
1544  case Theme::ContentItem::TagList:
1545  if ( messageItem )
1546  {
1547  const QList< MessageItem::Tag * > tagList = messageItem->tagList();
1548  compute_bounding_rect_for_tag_list( tagList, l, top, r, mHitContentItemRect, layoutDir != Qt::LeftToRight, mTheme->iconSize() );
1549  }
1550  break;
1551  }
1552 
1553  if ( mHitContentItemRect.isValid() )
1554  {
1555  if ( mHitContentItemRect.contains( viewportPoint ) )
1556  {
1557  // caught!
1558  mHitContentItem = ci;
1559  return true;
1560  }
1561  if ( !exact )
1562  {
1563  QRect inexactRect( mHitContentItemRect.left(), mHitRowRect.top(), mHitContentItemRect.width(), mHitRowRect.height() );
1564  if ( inexactRect.contains( viewportPoint ) )
1565  {
1566  mHitContentItem = ci;
1567  return true;
1568  }
1569 
1570  int inexactDistance = viewportPoint.x() > inexactRect.right() ? viewportPoint.x() - inexactRect.right() : inexactRect.left() - viewportPoint.x();
1571  if ( inexactDistance < bestInexactDistance )
1572  {
1573  bestInexactDistance = inexactDistance;
1574  bestInexactRect = mHitContentItemRect;
1575  bestInexactItemRight = false;
1576  bestInexactContentItem = ci;
1577  }
1578  }
1579  }
1580  }
1581 
1582  top += rowSizeHint.height();
1583  rowIdx++;
1584  }
1585 
1586  mHitContentItem = bestInexactContentItem;
1587  mHitContentItemRight = bestInexactItemRight;
1588  mHitContentItemRect = bestInexactRect;
1589  return true;
1590 }
1591 
1592 QSize ThemeDelegate::sizeHintForItemTypeAndColumn( Item::Type type, int column, const Item *item ) const
1593 {
1594  if ( !mTheme )
1595  return QSize( 16, 16 ); // bleah
1596 
1597  const Theme::Column * skcolumn = mTheme->column( column );
1598  if ( !skcolumn )
1599  return QSize( 16, 16 ); // bleah
1600 
1601  const QList< Theme::Row * > * rows; // I'd like to have it as reference, but gcc complains...
1602 
1603  // The sizeHint() is layout direction independent.
1604 
1605  int marginw;
1606  int marginh;
1607 
1608  switch ( type )
1609  {
1610  case Item::Message:
1611  {
1612  rows = &( skcolumn->messageRows() );
1613 
1614  marginh = gMessageVerticalMargin << 1;
1615  marginw = gMessageHorizontalMargin << 1;
1616  }
1617  break;
1618  case Item::GroupHeader:
1619  {
1620  rows = &( skcolumn->groupHeaderRows() );
1621 
1622  marginh = ( gGroupHeaderOuterVerticalMargin + gGroupHeaderInnerVerticalMargin ) << 1;
1623  marginw = ( gGroupHeaderOuterVerticalMargin + gGroupHeaderInnerVerticalMargin ) << 1;
1624  }
1625  break;
1626  default:
1627  return QSize( 16, 16 ); // bug
1628  break;
1629  }
1630 
1631  int totalh = 0;
1632  int maxw = 0;
1633 
1634  for ( QList< Theme::Row * >::ConstIterator rowit = rows->constBegin(), endRowIt = rows->constEnd(); rowit != endRowIt; ++rowit )
1635  {
1636  QSize sh = compute_size_hint_for_row( ( *rowit ), mTheme->iconSize(), item );
1637  totalh += sh.height();
1638  if ( sh.width() > maxw )
1639  maxw = sh.width();
1640  }
1641 
1642  return QSize( maxw + marginw , totalh + marginh );
1643 }
1644 
1645 QSize ThemeDelegate::sizeHint( const QStyleOptionViewItem &, const QModelIndex & index ) const
1646 {
1647  if ( !mTheme )
1648  return QSize( 16, 16 ); // hm hm...
1649 
1650  if ( !index.isValid() )
1651  return QSize( 16, 16 ); // bleah
1652 
1653  Item * item = itemFromIndex( index );
1654  if ( !item )
1655  return QSize( 16, 16 ); // hm...
1656 
1657  //Item::Type type = item->type();
1658 
1659  return sizeHintForItemTypeAndColumn( item->type(), index.column(), item );
1660 }
1661 
1662 QFont ThemeDelegate::itemFont( const Theme::ContentItem *ci, const Item *item )
1663 {
1664  if ( ci && ci->useCustomFont() )
1665  return ci->font();
1666 
1667  if ( item && ( item->type() == Item::Message ) )
1668  return static_cast< const MessageItem * >( item )->font();
1669 
1670  return KGlobalSettings::generalFont();
1671 }
1672 
1673 class ThemeDelegateStaticData
1674 {
1675 public:
1676  ThemeDelegateStaticData()
1677  : mGeneralFontKey(KGlobalSettings::generalFont().key()) {}
1678  QString mGeneralFontKey;
1679 };
1680 
1681 K_GLOBAL_STATIC(ThemeDelegateStaticData, s_static)
1682 
1683 QString ThemeDelegate::itemFontKey( const Theme::ContentItem *ci, const Item *item )
1684 {
1685  if ( ci && ci->useCustomFont() )
1686  return ci->fontKey();
1687 
1688  if ( item && ( item->type() == Item::Message ) )
1689  return static_cast< const MessageItem * >( item )->fontKey();
1690 
1691  return s_static->mGeneralFontKey;
1692 }
1693 
1694 // Store the new fontKey when the generalFont changes.
1695 void ThemeDelegate::slotGeneralFontChanged()
1696 {
1697  s_static->mGeneralFontKey = KGlobalSettings::generalFont().key();
1698 }
1699 
1700 
1701 #include "themedelegate.moc"
MessageList::Core::Theme::ContentItem
The ContentItem class defines a content item inside a Row.
Definition: theme.h:73
MessageList::Core::Theme::ContentItem::InvitationIcon
Whether the message is an invitation.
Definition: theme.h:223
MessageList::Core::Manager::pixmapMessageIgnored
const QPixmap * pixmapMessageIgnored() const
Definition: manager.h:146
MessageList::Core::Theme::ContentItem::isIcon
bool isIcon() const
Returns true if this item displays an icon.
Definition: theme.h:299
MessageList::Core::Manager::pixmapMessagePartiallyEncrypted
const QPixmap * pixmapMessagePartiallyEncrypted() const
Definition: manager.h:162
MessageList::Core::Manager::pixmapMessageSent
const QPixmap * pixmapMessageSent() const
Definition: manager.h:138
MessageList::Core::ThemeDelegate::~ThemeDelegate
~ThemeDelegate()
Definition: themedelegate.cpp:58
MessageList::Core::Theme::ContentItem::ExpandedStateIcon
The Expanded state icon for group headers.
Definition: theme.h:186
MessageList::Core::MessageItem::Tag::pixmap
QPixmap pixmap() const
Definition: messageitem.cpp:75
gMessageVerticalMargin
static const int gMessageVerticalMargin
Definition: themedelegate.cpp:45
paint_right_aligned_elided_text
static void paint_right_aligned_elided_text(const QString &text, Theme::ContentItem *ci, QPainter *painter, int &left, int top, int &right, Qt::LayoutDirection layoutDir, const QFont &font)
Definition: themedelegate.cpp:120
MessageList::Core::Manager::pixmapMessageUnread
const QPixmap * pixmapMessageUnread() const
Definition: manager.h:124
MessageList::Core::ThemeDelegate::itemFont
static QFont itemFont(const Theme::ContentItem *ci, const Item *item)
return the font to paint given item with, checking global kmail settings and theme settings ...
Definition: themedelegate.cpp:1662
MessageList::Core::GroupHeaderItem
Definition: groupheaderitem.h:34
MessageList::Core::Theme::ContentItem::ReadStateIcon
The icon that displays the unread/read state (never disabled)
Definition: theme.h:154
MessageList::Core::Item::Type
Type
The type of the Item.
Definition: item.h:61
paint_boolean_state_icon
static void paint_boolean_state_icon(bool enabled, const QPixmap *pix, Theme::ContentItem *ci, QPainter *painter, int &left, int top, int &right, bool alignOnRight, int iconSize)
Definition: themedelegate.cpp:410
MessageList::Core::ThemeDelegate::ThemeDelegate
ThemeDelegate(QAbstractItemView *parent)
Definition: themedelegate.cpp:50
compute_bounding_rect_for_vertical_line
static void compute_bounding_rect_for_vertical_line(int &left, int top, int &right, int bottom, QRect &outRect, bool alignOnRight)
Definition: themedelegate.cpp:338
MessageList::Core::MessageItem::PartiallySigned
Definition: messageitem.h:95
compute_bounding_rect_for_boolean_state_icon
static void compute_bounding_rect_for_boolean_state_icon(bool enabled, Theme::ContentItem *ci, int &left, int top, int &right, QRect &outRect, bool alignOnRight, int iconSize)
Definition: themedelegate.cpp:442
MessageList::Core::MessageItem
Definition: messageitem.h:50
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::Core::GroupHeaderItem::label
const QString & label() const
Definition: groupheaderitem.cpp:35
MessageList::Core::Manager::pixmapMessageForwarded
const QPixmap * pixmapMessageForwarded() const
Definition: manager.h:140
MessageList::Core::Theme::ContentItem::useCustomFont
bool useCustomFont() const
Returns true if this item uses a custom font.
Definition: theme.h:348
MessageList::Core::Manager::pixmapMessageUndefinedEncrypted
const QPixmap * pixmapMessageUndefinedEncrypted() const
Definition: manager.h:164
MessageList::Core::Theme::ContentItem::font
const QFont & font() const
Returns the font used by this item.
Definition: theme.h:419
MessageList::Core::Item::senderOrReceiver
const QString & senderOrReceiver() const
Returns the sender or the receiver, depending on the underlying StorageModel settings.
Definition: item.cpp:462
MessageList::Core::Theme::ContentItem::CombinedReadRepliedStateIcon
The combined icon that displays the unread/read/replied/forwarded state (never disabled) ...
Definition: theme.h:210
compute_bounding_rect_for_horizontal_spacer
static void compute_bounding_rect_for_horizontal_spacer(int &left, int top, int &right, int bottom, QRect &outRect, bool alignOnRight)
Definition: themedelegate.cpp:361
MessageList::Core::Manager::pixmapMessageSpam
const QPixmap * pixmapMessageSpam() const
Definition: manager.h:148
cachedFontMetrics
static QFontMetrics cachedFontMetrics(const QFont &font)
Definition: themedelegate.cpp:95
MessageList::Core::Theme::Row
The Row class defines a row of items inside a Column.
Definition: theme.h:466
MessageList::Core::Item::childItemCount
int childItemCount() const
Returns the number of children of this Item.
Definition: item.cpp:163
MessageList::Core::MessageItem::encryptionState
EncryptionState encryptionState() const
Definition: messageitem.cpp:464
MessageList::Core::Manager::pixmapMessageNotEncrypted
const QPixmap * pixmapMessageNotEncrypted() const
Definition: manager.h:166
MessageList::Core::Item::formattedSize
QString formattedSize() const
A string with a text rappresentation of size().
Definition: item.cpp:255
MessageList::Core::Theme::ContentItem::AttachmentStateIcon
The icon that displays the atachment state (may be disabled)
Definition: theme.h:158
MessageList::Core::Manager::pixmapMessageHam
const QPixmap * pixmapMessageHam() const
Definition: manager.h:150
MessageList::Core::ThemeDelegate::sizeHint
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Reimplemented from QStyledItemDelegate.
Definition: themedelegate.cpp:1645
MessageList::Core::Item::receiver
const QString & receiver() const
Returns the receiver associated to this item.
Definition: item.cpp:452
MessageList::Core::Manager::pixmapMessageAnnotation
const QPixmap * pixmapMessageAnnotation() const
Definition: manager.h:170
MessageList::Core::Theme::ContentItem::Sender
From: strip, always.
Definition: theme.h:142
MessageList::Core::Item::subject
const QString & subject() const
Returns the subject associated to this Item.
Definition: item.cpp:472
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::Core::MessageItem::PartiallyEncrypted
Definition: messageitem.h:87
gGroupHeaderInnerVerticalMargin
static const int gGroupHeaderInnerVerticalMargin
Definition: themedelegate.cpp:43
MessageList::Core::Manager::pixmapMessageAttachment
const QPixmap * pixmapMessageAttachment() const
Definition: manager.h:168
MessageList::Core::Theme::ContentItem::ImportantStateIcon
The Important tag icon.
Definition: theme.h:174
MessageList::Core::Theme::ContentItem::hideWhenDisabled
bool hideWhenDisabled() const
Returns true if this item should be hidden when in disabled state.
Definition: theme.h:363
QStyledItemDelegate
MessageList::Core::Theme::ContentItem::AnnotationIcon
Whether the message has a annotation/note.
Definition: theme.h:218
get_read_state_icon
static const QPixmap * get_read_state_icon(Item *item)
Definition: themedelegate.cpp:196
MessageList::Core::ModelInvariantIndex::isValid
bool isValid() const
Returns true if this ModelInvariantIndex is valid, that is, it has been attacched to a ModelInvariant...
Definition: modelinvariantindex.cpp:42
gGroupHeaderOuterVerticalMargin
static const int gGroupHeaderOuterVerticalMargin
Definition: themedelegate.cpp:41
gMessageHorizontalMargin
static const int gMessageHorizontalMargin
Definition: themedelegate.cpp:46
MessageList::Core::Theme::Column
The Column class defines a view column available inside this theme.
Definition: theme.h:564
MessageList::Core::Theme::StyledJoinedRect
One big styled rect per column.
Definition: theme.h:900
MessageList::Core::Manager::pixmapMessageFullySigned
const QPixmap * pixmapMessageFullySigned() const
Definition: manager.h:152
MessageList::Core::Theme::iconSize
int iconSize() const
Returns the currently set icon size.
Definition: theme.h:1037
MessageList::Core::ThemeDelegate::itemFontKey
static QString itemFontKey(const Theme::ContentItem *ci, const Item *item)
return the font key to paint given item with, checking global kmail settings and theme settings ...
Definition: themedelegate.cpp:1683
MessageList::Core::Item::formattedMaxDate
QString formattedMaxDate() const
A string with a text rappresentation of maxDate() obtained via Manager.
Definition: item.cpp:268
compute_bounding_rect_for_permanent_icon
static void compute_bounding_rect_for_permanent_icon(Theme::ContentItem *, int &left, int top, int &right, QRect &outRect, bool alignOnRight, int iconSize)
Definition: themedelegate.cpp:393
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::Theme::ContentItem::RepliedStateIcon
The icon that displays the replied/forwarded state (may be disabled)
Definition: theme.h:162
gGroupHeaderInnerHorizontalMargin
static const int gGroupHeaderInnerHorizontalMargin
Definition: themedelegate.cpp:44
MessageList::Core::Item::type
Type type() const
Returns the type of this item.
Definition: item.cpp:298
compute_size_hint_for_row
static QSize compute_size_hint_for_row(const Theme::Row *r, int iconSize, const Item *item)
Definition: themedelegate.cpp:529
MessageList::Core::Manager::pixmapShowMore
const QPixmap * pixmapShowMore() const
Definition: manager.h:174
MessageList::Core::MessageItem::hasAnnotation
virtual bool hasAnnotation() const
Returns true if this message has an annotation.
Definition: messageitem.cpp:286
MessageList::Core::Theme::Transparent
No background at all: use style default.
Definition: theme.h:883
get_watched_ignored_state_icon
static const QPixmap * get_watched_ignored_state_icon(MessageItem *messageItem)
Definition: themedelegate.cpp:310
messageitem.h
MessageList::Core::Theme::PlainRect
One plain rect per column.
Definition: theme.h:893
get_spam_ham_state_icon
static const QPixmap * get_spam_ham_state_icon(MessageItem *messageItem)
Definition: themedelegate.cpp:301
MessageList::Core::ThemeDelegate::paint
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Reimplemented from QStyledItemDelegate.
Definition: themedelegate.cpp:550
MessageList::Core::Manager::pixmapMessageWatched
const QPixmap * pixmapMessageWatched() const
Definition: manager.h:144
MessageList::Core::Theme::GradientJoinedRect
One big rounded gradient rect for all the columns.
Definition: theme.h:898
MessageList::Core::Theme::ContentItem::type
Type type() const
Returns the type of this content item.
Definition: theme.h:264
MessageList::Core::Theme::ContentItem::Subject
Display the subject of the message item.
Definition: theme.h:130
MessageList::Core::Theme::ContentItem::canUseCustomColor
bool canUseCustomColor() const
Returns true if this ContentItem can make use of a custom color.
Definition: theme.h:279
paint_horizontal_spacer
static void paint_horizontal_spacer(int &left, int, int &right, int, bool alignOnRight)
Definition: themedelegate.cpp:351
MessageList::Core::MessageItem::aboutToBeRemoved
bool aboutToBeRemoved() const
Definition: messageitem.cpp:536
MessageList::Core::MessageItem::signatureState
SignatureState signatureState() const
Definition: messageitem.cpp:452
MessageList::Core::Theme::ContentItem::useCustomColor
bool useCustomColor() const
Returns true if this item uses a custom color.
Definition: theme.h:334
MessageList::Core::MessageItem::textColor
QColor textColor() const
Definition: messageitem.cpp:362
MessageList::Core::Manager::pixmapMessageRepliedAndForwarded
const QPixmap * pixmapMessageRepliedAndForwarded() const
Definition: manager.h:132
compute_bounding_rect_for_right_aligned_elided_text
static void compute_bounding_rect_for_right_aligned_elided_text(const QString &text, int &left, int top, int &right, QRect &outRect, Qt::LayoutDirection layoutDir, const QFont &font)
Definition: themedelegate.cpp:144
MessageList::Core::Theme::ContentItem::Date
Formatted date time of the message/group.
Definition: theme.h:134
MessageList::Core::Theme::Row::leftItems
const QList< ContentItem * > & leftItems() const
Returns the list of left aligned items for this row.
Definition: theme.h:481
get_encryption_state_icon
static const QPixmap * get_encryption_state_icon(MessageItem *messageItem, bool *treatAsEnabled)
Definition: themedelegate.cpp:227
get_combined_read_replied_state_icon
static const QPixmap * get_combined_read_replied_state_icon(MessageItem *messageItem)
Definition: themedelegate.cpp:213
MessageList::Core::Theme::ContentItem::HorizontalSpacer
A small empty spacer usable as separator.
Definition: theme.h:202
MessageList::Core::Manager::instance
static Manager * instance()
Definition: manager.h:111
MessageList::Core::Theme::ContentItem::TagList
The list of MessageItem::Tag entries.
Definition: theme.h:214
MessageList::Core::Manager::pixmapMessageUndefinedSigned
const QPixmap * pixmapMessageUndefinedSigned() const
Definition: manager.h:156
manager.h
MessageList::Core::Item::GroupHeader
This item is a GroupHeaderItem.
Definition: item.h:63
MessageList::Core::Theme::ContentItem::Receiver
To: strip, always.
Definition: theme.h:146
compute_size_hint_for_item
static void compute_size_hint_for_item(Theme::ContentItem *ci, int &maxh, int &totalw, int iconSize, const Item *item)
Definition: themedelegate.cpp:493
groupheaderitem.h
MessageList::Core::Theme::ContentItem::Size
Formatted size of the message.
Definition: theme.h:150
MessageList::Core::Theme::ContentItem::displaysLongText
bool displaysLongText() const
Returns true if this item displays a long text.
Definition: theme.h:293
MessageList::Core::Item::formattedDate
QString formattedDate() const
A string with a text rappresentation of date() obtained via Manager.
Definition: item.cpp:260
MessageList::Core::Theme::CustomColor
Use a custom color.
Definition: theme.h:885
compute_bounding_rect_for_tag_list
static void compute_bounding_rect_for_tag_list(const QList< MessageItem::Tag * > &tagList, int &left, int top, int &right, QRect &outRect, bool alignOnRight, int iconSize)
Definition: themedelegate.cpp:478
MessageList::Core::Item::Message
This item is a MessageItem.
Definition: item.h:64
MessageList::Core::Theme::ContentItem::SenderOrReceiver
From: or To: strip, depending on the folder settings.
Definition: theme.h:138
MessageList::Core::Item
A single item of the MessageList tree managed by MessageList::Model.
Definition: item.h:52
MessageList::Core::Manager::pixmapMessageReplied
const QPixmap * pixmapMessageReplied() const
Definition: manager.h:130
MessageList::Core::Manager::pixmapShowLess
const QPixmap * pixmapShowLess() const
Definition: manager.h:176
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::Manager::pixmapMessageQueued
const QPixmap * pixmapMessageQueued() const
Definition: manager.h:134
MessageList::Core::MessageItem::NotSigned
Definition: messageitem.h:94
MessageList::Core::Theme::groupHeaderBackgroundMode
GroupHeaderBackgroundMode groupHeaderBackgroundMode() const
Returns the group header background mode for this theme.
Definition: theme.h:976
MessageList::Core::Manager::pixmapMessageNotSigned
const QPixmap * pixmapMessageNotSigned() const
Definition: manager.h:158
MessageList::Core::MessageItem::backgroundColor
QColor backgroundColor() const
Definition: messageitem.cpp:382
MessageList::Core::Manager::pixmapMessageImportant
const QPixmap * pixmapMessageImportant() const
Definition: manager.h:142
MessageList::Core::ThemeDelegate::itemFromIndex
virtual Item * itemFromIndex(const QModelIndex &index) const =0
Returns the Item for the specified model index.
MessageList::Core::MessageItem::tagList
virtual QList< Tag * > tagList() const
Returns the list of tags for this item.
Definition: messageitem.cpp:280
gGroupHeaderOuterHorizontalMargin
static const int gGroupHeaderOuterHorizontalMargin
Definition: themedelegate.cpp:42
MessageList::Core::Theme::RoundedJoinedRect
One big rounded rect for all the columns.
Definition: theme.h:896
MessageList::Core::Theme::ContentItem::SpamHamStateIcon
The Spam/Ham state icon.
Definition: theme.h:178
MessageList::Core::Theme::PlainJoinedRect
One big plain rect for all the columns.
Definition: theme.h:894
MessageList::Core::MessageItem::EncryptionStateUnknown
Definition: messageitem.h:89
MessageList::Core::ThemeDelegate::theme
const Theme * theme() const
Definition: themedelegate.h:73
cachedFontHeightKey
static int cachedFontHeightKey(const QFont &font, const QString &fontKey)
Definition: themedelegate.cpp:108
MessageList::Core::Manager::pixmapMessageActionItem
const QPixmap * pixmapMessageActionItem() const
Definition: manager.h:136
MessageList::Core::Theme::ContentItem::ActionItemStateIcon
The ActionItem state icon.
Definition: theme.h:170
MessageList::Core::Theme::ContentItem::VerticalLine
A vertical separation line.
Definition: theme.h:198
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
themedelegate.h
MessageList::Core::Item::sender
const QString & sender() const
Returns the sender associated to this item.
Definition: item.cpp:442
get_signature_state_icon
static const QPixmap * get_signature_state_icon(MessageItem *messageItem, bool *treatAsEnabled)
Definition: themedelegate.cpp:257
compute_bounding_rect_for_left_aligned_elided_text
static void compute_bounding_rect_for_left_aligned_elided_text(const QString &text, int &left, int top, int &right, QRect &outRect, Qt::LayoutDirection layoutDir, const QFont &font)
Definition: themedelegate.cpp:182
MessageList::Core::ThemeDelegate::setTheme
void setTheme(const Theme *theme)
Definition: themedelegate.cpp:62
gHorizontalItemSpacing
static const int gHorizontalItemSpacing
Definition: themedelegate.cpp:47
paint_tag_list
static void paint_tag_list(const QList< MessageItem::Tag * > &tagList, QPainter *painter, int &left, int top, int &right, bool alignOnRight, int iconSize)
Definition: themedelegate.cpp:456
MessageList::Core::Manager::pixmapMessageFullyEncrypted
const QPixmap * pixmapMessageFullyEncrypted() const
Definition: manager.h:160
MessageList::Core::MessageItem::SignatureStateUnknown
Definition: messageitem.h:97
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::Core::Item::status
const Akonadi::MessageStatus & status() const
Returns the status associated to this Item.
Definition: item.cpp:402
MessageList::Core::Theme::ContentItem::SignatureStateIcon
The Signature state icon for messages.
Definition: theme.h:194
MessageList::Core::MessageItem::NotEncrypted
Definition: messageitem.h:86
MessageList::Core::Theme
The Theme class defines the visual appearance of the MessageList.
Definition: theme.h:65
paint_vertical_line
static void paint_vertical_line(QPainter *painter, int &left, int top, int &right, int bottom, bool alignOnRight)
Definition: themedelegate.cpp:319
MessageList::Core::Manager::pixmapMessageRead
const QPixmap * pixmapMessageRead() const
Definition: manager.h:126
MessageList::Core::Theme::groupHeaderBackgroundColor
const QColor & groupHeaderBackgroundColor() const
Returns the group header background color for this theme.
Definition: theme.h:989
MessageList::Core::Theme::ContentItem::GroupHeaderLabel
The group header label.
Definition: theme.h:166
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::Core::Theme::ContentItem::WatchedIgnoredStateIcon
The Watched/Ignored state icon.
Definition: theme.h:182
MessageList::Core::Theme::ContentItem::EncryptionStateIcon
The Encryption state icon for messages.
Definition: theme.h:190
MessageList::Core::Theme::ContentItem::MostRecentDate
The date of the most recent message in subtree.
Definition: theme.h:206
MessageList::Core::MessageItem::FullyEncrypted
Definition: messageitem.h:88
MessageList::Core::Theme::AutoColor
Automatically determine the color (somewhere in the middle between background and text) ...
Definition: theme.h:884
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::Core::Theme::ContentItem::isSpacer
bool isSpacer() const
Returns true if this item is a small spacer.
Definition: theme.h:310
MessageList::Core::Manager::pixmapMessageDeleted
const QPixmap * pixmapMessageDeleted() const
Definition: manager.h:128
get_replied_state_icon
static const QPixmap * get_replied_state_icon(MessageItem *messageItem)
Definition: themedelegate.cpp:287
paint_left_aligned_elided_text
static void paint_left_aligned_elided_text(const QString &text, Theme::ContentItem *ci, QPainter *painter, int &left, int top, int &right, Qt::LayoutDirection layoutDir, const QFont &font)
Definition: themedelegate.cpp:159
MessageList::Core::MessageItem::Tag
Definition: messageitem.h:53
MessageList::Core::Theme::GradientRect
One rounded gradient filled rect per column.
Definition: theme.h:897
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::StyledRect
One styled rect per column.
Definition: theme.h:899
paint_permanent_icon
static void paint_permanent_icon(const QPixmap *pix, Theme::ContentItem *, QPainter *painter, int &left, int top, int &right, bool alignOnRight, int iconSize)
Definition: themedelegate.cpp:374
MessageList::Core::Manager::pixmapMessageInvitation
const QPixmap * pixmapMessageInvitation() const
Definition: manager.h:172
MessageList::Core::Manager::pixmapMessagePartiallySigned
const QPixmap * pixmapMessagePartiallySigned() const
Definition: manager.h:154
MessageList::Core::Theme::RoundedRect
One rounded rect per column.
Definition: theme.h:895
MessageList::Core::MessageItem::FullySigned
Definition: messageitem.h:96
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