00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "collectionstatisticsdelegate.h"
00021 #include "collectionstatisticsmodel.h"
00022
00023 #include <kcolorscheme.h>
00024 #include <kdebug.h>
00025
00026 #include <QtGui/QPainter>
00027 #include <QtGui/QStyle>
00028 #include <QtGui/QStyleOption>
00029 #include <QtGui/QStyleOptionViewItemV4>
00030 #include <QtGui/QTreeView>
00031
00032 #include "entitytreemodel.h"
00033 #include "collectionstatistics.h"
00034 #include "collection.h"
00035 #include "progressspinnerdelegate_p.h"
00036
00037 using namespace Akonadi;
00038
00039 namespace Akonadi {
00040
00041 enum CountType
00042 {
00043 UnreadCount,
00044 TotalCount
00045 };
00046
00047 class CollectionStatisticsDelegatePrivate
00048 {
00049 public:
00050 QTreeView *parent;
00051 bool drawUnreadAfterFolder;
00052 DelegateAnimator *animator;
00053 QColor mSelectedUnreadColor;
00054 QColor mDeselectedUnreadColor;
00055
00056 CollectionStatisticsDelegatePrivate( QTreeView *treeView )
00057 : parent( treeView ),
00058 drawUnreadAfterFolder( false ),
00059 animator( 0 )
00060 {
00061 mSelectedUnreadColor = KColorScheme( QPalette::Active, KColorScheme::Selection )
00062 .foreground( KColorScheme::LinkText ).color();
00063 mDeselectedUnreadColor = KColorScheme( QPalette::Active, KColorScheme::View )
00064 .foreground( KColorScheme::LinkText ).color();
00065 }
00066
00067 template<CountType countType>
00068 qint64 getCountRecursive( const QModelIndex &index ) const
00069 {
00070 Collection collection = qvariant_cast<Collection>( index.data( EntityTreeModel::CollectionRole ) );
00071 Q_ASSERT( collection.isValid() );
00072 CollectionStatistics statistics = collection.statistics();
00073 qint64 count = qMax( 0LL, countType == UnreadCount ? statistics.unreadCount() : statistics.count() );
00074
00075 if ( index.model()->hasChildren( index ) )
00076 {
00077 for ( int row = 0; row < index.model()->rowCount( index ); row++ )
00078 {
00079 static const int column = 0;
00080 count += getCountRecursive<countType>( index.model()->index( row, column, index ) );
00081 }
00082 }
00083 return count;
00084 }
00085 };
00086
00087 }
00088
00089 CollectionStatisticsDelegate::CollectionStatisticsDelegate( QTreeView *parent )
00090 : QStyledItemDelegate( parent ),
00091 d_ptr( new CollectionStatisticsDelegatePrivate( parent ) )
00092 {
00093
00094 }
00095
00096 CollectionStatisticsDelegate::~CollectionStatisticsDelegate()
00097 {
00098 delete d_ptr;
00099 }
00100
00101 void CollectionStatisticsDelegate::setUnreadCountShown( bool enable )
00102 {
00103 Q_D( CollectionStatisticsDelegate );
00104 d->drawUnreadAfterFolder = enable;
00105 }
00106
00107 bool CollectionStatisticsDelegate::unreadCountShown() const
00108 {
00109 Q_D( const CollectionStatisticsDelegate );
00110 return d->drawUnreadAfterFolder;
00111 }
00112
00113 void CollectionStatisticsDelegate::setProgressAnimationEnabled( bool enable )
00114 {
00115 Q_D( CollectionStatisticsDelegate );
00116 if ( enable == ( d->animator != 0 ) )
00117 return;
00118 if ( enable ) {
00119 Q_ASSERT( !d->animator );
00120 Akonadi::DelegateAnimator *animator = new Akonadi::DelegateAnimator( d->parent );
00121 d->animator = animator;
00122 } else {
00123 delete d->animator;
00124 d->animator = 0;
00125 }
00126 }
00127
00128 bool CollectionStatisticsDelegate::progressAnimationEnabled() const
00129 {
00130 Q_D( const CollectionStatisticsDelegate );
00131 return d->animator != 0;
00132 }
00133
00134 void CollectionStatisticsDelegate::initStyleOption( QStyleOptionViewItem *option,
00135 const QModelIndex &index ) const
00136 {
00137 Q_D( const CollectionStatisticsDelegate );
00138
00139 QStyleOptionViewItemV4 *noTextOption =
00140 qstyleoption_cast<QStyleOptionViewItemV4 *>( option );
00141 QStyledItemDelegate::initStyleOption( noTextOption, index );
00142 noTextOption->text.clear();
00143
00144 if ( d->animator ) {
00145
00146 const Akonadi::Collection collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
00147
00148 if (!collection.isValid())
00149 {
00150 d->animator->pop(index);
00151 return;
00152 }
00153
00154 if (index.data(Akonadi::EntityTreeModel::FetchStateRole).toInt() != Akonadi::EntityTreeModel::FetchingState)
00155 {
00156 d->animator->pop(index);
00157 return;
00158 }
00159
00160 d->animator->push(index);
00161
00162 if (QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>(option)) {
00163 v4->icon = d->animator->sequenceFrame(index);
00164 }
00165 }
00166 }
00167
00168 class PainterStateSaver
00169 {
00170 public:
00171 PainterStateSaver( QPainter *painter )
00172 {
00173 mPainter = painter;
00174 mPainter->save();
00175 }
00176
00177 ~PainterStateSaver()
00178 {
00179 mPainter->restore();
00180 }
00181
00182 private:
00183 QPainter *mPainter;
00184 };
00185
00186 void CollectionStatisticsDelegate::paint( QPainter *painter,
00187 const QStyleOptionViewItem &option,
00188 const QModelIndex &index ) const
00189 {
00190 Q_D( const CollectionStatisticsDelegate );
00191 PainterStateSaver stateSaver( painter );
00192
00193
00194
00195 QStyledItemDelegate::paint( painter, option, index );
00196
00197
00198
00199 QStyleOptionViewItemV4 option4 = option;
00200 QStyledItemDelegate::initStyleOption( &option4, index );
00201 QString text = option4.text;
00202
00203
00204 QStyle *s = d->parent->style();
00205 const QWidget *widget = option4.widget;
00206 QRect textRect = s->subElementRect( QStyle::SE_ItemViewItemText, &option4, widget );
00207
00208
00209
00210 QModelIndex firstColumn = index.model()->index( index.row(), 0, index.parent() );
00211 bool expanded = d->parent->isExpanded( firstColumn );
00212
00213 if ( option.state & QStyle::State_Selected ) {
00214 painter->setPen( option.palette.highlightedText().color() );
00215 }
00216
00217 Collection collection = index.sibling( index.row(), 0 ).data( EntityTreeModel::CollectionRole ).value<Collection>();
00218
00219 Q_ASSERT(collection.isValid());
00220
00221 CollectionStatistics statistics = collection.statistics();
00222
00223 qint64 unreadCount = qMax( 0LL, statistics.unreadCount() );
00224 qint64 unreadRecursiveCount = d->getCountRecursive<UnreadCount>( index.sibling( index.row(), 0 ) );
00225
00226
00227 if ( d->drawUnreadAfterFolder && index.column() == 0 ) {
00228
00229
00230 QString unread;
00231
00232 if ( expanded && unreadCount > 0 )
00233 unread = QString( QLatin1String( " (%1)" ) ).arg( unreadCount );
00234 else if ( !expanded ) {
00235 if ( unreadCount != unreadRecursiveCount )
00236 unread = QString( QLatin1String( " (%1 + %2)" ) ).arg( unreadCount ).arg( unreadRecursiveCount - unreadCount );
00237 else if ( unreadCount > 0 )
00238 unread = QString( QLatin1String( " (%1)" ) ).arg( unreadCount );
00239 }
00240
00241 PainterStateSaver stateSaver( painter );
00242
00243 if ( !unread.isEmpty() ) {
00244 QFont font = painter->font();
00245 font.setBold( true );
00246 painter->setFont( font );
00247 }
00248
00249
00250
00251 QString folderName = text;
00252 QFontMetrics fm( painter->fontMetrics() );
00253 int unreadWidth = fm.width( unread );
00254 if ( fm.width( folderName ) + unreadWidth > textRect.width() ) {
00255 folderName = fm.elidedText( folderName, Qt::ElideRight,
00256 textRect.width() - unreadWidth );
00257 }
00258 int folderWidth = fm.width( folderName );
00259 QRect folderRect = textRect;
00260 QRect unreadRect = textRect;
00261 folderRect.setRight( textRect.left() + folderWidth );
00262 unreadRect.setLeft( folderRect.right() );
00263
00264
00265 painter->drawText( folderRect, Qt::AlignLeft, folderName );
00266
00267 const QColor unreadColor = (option.state & QStyle::State_Selected) ? d->mSelectedUnreadColor : d->mDeselectedUnreadColor;
00268 painter->setPen( unreadColor );
00269 painter->drawText( unreadRect, Qt::AlignLeft, unread );
00270
00271 return;
00272 }
00273
00274
00275
00276 if ( ( index.column() == 1 || index.column() == 2 ) ) {
00277
00278 PainterStateSaver stateSaver( painter );
00279
00280 QStyleOptionViewItem opt = option;
00281
00282 QString sumText;
00283 if ( index.column() == 1 && ( ( !expanded && unreadRecursiveCount > 0 ) || ( expanded && unreadCount > 0 ) ) ) {
00284 QFont font = painter->font();
00285 font.setBold( true );
00286 painter->setFont( font );
00287 sumText = QString::number( expanded ? unreadCount : unreadRecursiveCount );
00288 } else {
00289
00290 qint64 totalCount = statistics.unreadCount();
00291 qint64 totalRecursiveCount = d->getCountRecursive<TotalCount>( index.sibling( index.row(), 0 ) );
00292 if (index.column() == 2 && ( ( !expanded && totalRecursiveCount > 0 ) || ( expanded && totalCount > 0 ) ) ) {
00293 sumText = QString::number( expanded ? totalCount : totalRecursiveCount );
00294 }
00295 }
00296
00297 painter->drawText( textRect, Qt::AlignRight, sumText );
00298
00299 return;
00300 }
00301
00302 painter->drawText( textRect, option4.displayAlignment, text );
00303 }
00304
00305 #include "collectionstatisticsdelegate.moc"