21 #include "collectionstatisticsdelegate.h"
22 #include "collectionstatisticsmodel.h"
24 #include <kcolorscheme.h>
26 #include <kio/global.h>
30 #include <QStyleOption>
31 #include <QStyleOptionViewItemV4>
32 #include <QAbstractItemView>
35 #include "entitytreemodel.h"
36 #include "collectionstatistics.h"
37 #include "collection.h"
38 #include "progressspinnerdelegate_p.h"
40 using namespace Akonadi;
50 class CollectionStatisticsDelegatePrivate
53 QAbstractItemView *parent;
54 bool drawUnreadAfterFolder;
55 DelegateAnimator *animator;
56 QColor mSelectedUnreadColor;
57 QColor mDeselectedUnreadColor;
59 CollectionStatisticsDelegatePrivate( QAbstractItemView *treeView )
61 drawUnreadAfterFolder( false ),
67 void getCountRecursive(
const QModelIndex &index, qint64 &totalCount, qint64 &unreadCount, qint64 &totalSize )
const
74 totalCount += qMax( 0LL, statistics.
count() );
75 unreadCount += qMax( 0LL, statistics.
unreadCount() );
76 totalSize += qMax( 0LL, statistics.
size() );
77 if ( index.model()->hasChildren( index ) ) {
78 const int rowCount = index.model()->rowCount( index );
79 for (
int row = 0; row < rowCount; row++ ) {
80 static const int column = 0;
81 getCountRecursive( index.model()->index( row, column, index ), totalCount, unreadCount, totalSize );
89 mSelectedUnreadColor = KColorScheme( QPalette::Active, KColorScheme::Selection )
90 .foreground( KColorScheme::LinkText ).color();
91 mDeselectedUnreadColor = KColorScheme( QPalette::Active, KColorScheme::View )
92 .foreground( KColorScheme::LinkText ).color();
99 : QStyledItemDelegate( parent ),
100 d_ptr( new CollectionStatisticsDelegatePrivate( parent ) )
106 : QStyledItemDelegate( parent ),
107 d_ptr( new CollectionStatisticsDelegatePrivate( parent ) )
120 d->drawUnreadAfterFolder = enable;
126 return d->drawUnreadAfterFolder;
132 if ( enable == ( d->animator != 0 ) ) {
136 Q_ASSERT( !d->animator );
137 Akonadi::DelegateAnimator *animator =
new Akonadi::DelegateAnimator( d->parent );
138 d->animator = animator;
145 bool CollectionStatisticsDelegate::progressAnimationEnabled()
const
148 return d->animator != 0;
152 const QModelIndex &index )
const
156 QStyleOptionViewItemV4 *noTextOption =
157 qstyleoption_cast<QStyleOptionViewItemV4 *>( option );
158 QStyledItemDelegate::initStyleOption( noTextOption, index );
159 if ( option->decorationPosition != QStyleOptionViewItem::Top ) {
160 noTextOption->text.clear();
167 d->animator->pop(index);
171 d->animator->push( index );
173 if ( QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>( option ) ) {
174 v4->icon = d->animator->sequenceFrame( index );
179 class PainterStateSaver
182 PainterStateSaver( QPainter *painter )
198 const QStyleOptionViewItem &option,
199 const QModelIndex &index )
const
202 PainterStateSaver stateSaver( painter );
204 const QColor textColor = index.data( Qt::ForegroundRole ).value<QColor>();
207 QStyledItemDelegate::paint( painter, option, index );
211 QStyleOptionViewItemV4 option4 = option;
212 QStyledItemDelegate::initStyleOption( &option4, index );
213 QString text = option4.text;
216 QStyle *s = d->parent->style();
217 const QWidget *widget = option4.widget;
218 const QRect textRect = s->subElementRect( QStyle::SE_ItemViewItemText, &option4, widget );
222 const QModelIndex firstColumn = index.sibling( index.row(), 0 );
223 QTreeView* treeView = qobject_cast<QTreeView*>( d->parent );
224 bool expanded = treeView && treeView->isExpanded( firstColumn );
226 if ( option.state & QStyle::State_Selected ) {
227 painter->setPen( textColor.isValid() ? textColor : option.palette.highlightedText().color() );
233 kError() <<
"Invalid collection: " << collection;
235 Q_ASSERT( collection.
isValid() );
239 qint64 unreadCount = qMax( 0LL, statistics.unreadCount() );
240 qint64 totalRecursiveCount = 0;
241 qint64 unreadRecursiveCount = 0;
242 qint64 totalSize = 0;
243 bool needRecursiveCounts =
false;
244 bool needTotalSize =
false;
245 if ( d->drawUnreadAfterFolder && index.column() == 0 ) {
246 needRecursiveCounts =
true;
247 }
else if ( ( index.column() == 1 || index.column() == 2 ) ) {
248 needRecursiveCounts =
true;
249 }
else if ( index.column() == 3 && !expanded ) {
250 needTotalSize =
true;
253 if ( needRecursiveCounts || needTotalSize ) {
254 d->getCountRecursive( firstColumn, totalRecursiveCount, unreadRecursiveCount, totalSize );
258 if ( d->drawUnreadAfterFolder && index.column() == 0 ) {
263 if ( expanded && unreadCount > 0 ) {
264 unread = QString::fromLatin1(
" (%1)" ).arg( unreadCount );
265 }
else if ( !expanded ) {
266 if ( unreadCount != unreadRecursiveCount ) {
267 unread = QString::fromLatin1(
" (%1 + %2)" ).arg( unreadCount ).arg( unreadRecursiveCount - unreadCount );
268 }
else if ( unreadCount > 0 ) {
269 unread = QString::fromLatin1(
" (%1)" ).arg( unreadCount );
273 PainterStateSaver stateSaver( painter );
275 if ( !unread.isEmpty() ) {
276 QFont font = painter->font();
277 font.setBold(
true );
278 painter->setFont( font );
281 const QColor unreadColor = ( option.state & QStyle::State_Selected ) ? d->mSelectedUnreadColor : d->mDeselectedUnreadColor;
282 const QRect iconRect = s->subElementRect( QStyle::SE_ItemViewItemDecoration, &option4, widget );
284 if ( option.decorationPosition == QStyleOptionViewItem::Left ||
285 option.decorationPosition == QStyleOptionViewItem::Right ) {
288 QString folderName = text;
289 QFontMetrics fm( painter->fontMetrics() );
290 const int unreadWidth = fm.width( unread );
291 int folderWidth( fm.width( folderName ) );
292 const bool enoughPlaceForText = ( option.rect.width() > ( folderWidth + unreadWidth + iconRect.width() ) );
294 if ( !enoughPlaceForText && ( folderWidth + unreadWidth > textRect.width() ) ) {
295 folderName = fm.elidedText( folderName, Qt::ElideRight,
296 option.rect.width() - unreadWidth - iconRect.width() );
297 folderWidth = fm.width( folderName );
299 QRect folderRect = textRect;
300 QRect unreadRect = textRect;
301 folderRect.setRight( textRect.left() + folderWidth );
302 unreadRect = QRect( folderRect.right(), folderRect.top(), unreadRect.width(), unreadRect.height() );
303 if ( textColor.isValid() ) {
304 painter->setPen( textColor );
308 painter->drawText( folderRect, Qt::AlignLeft | Qt::AlignVCenter, folderName );
309 painter->setPen( unreadColor );
310 painter->drawText( unreadRect, Qt::AlignLeft | Qt::AlignVCenter, unread );
311 }
else if ( option.decorationPosition == QStyleOptionViewItem::Top ) {
312 if ( unreadCount > 0 ) {
314 painter->setPen( unreadColor );
315 painter->drawText( iconRect, Qt::AlignCenter, QString::number( unreadCount ) );
323 if ( ( index.column() == 1 || index.column() == 2 ) ) {
325 QFont savedFont = painter->font();
327 if ( index.column() == 1 && ( ( !expanded && unreadRecursiveCount > 0 ) || ( expanded && unreadCount > 0 ) ) ) {
328 QFont font = painter->font();
329 font.setBold(
true );
330 painter->setFont( font );
331 sumText = QString::number( expanded ? unreadCount : unreadRecursiveCount );
334 qint64 totalCount = statistics.count();
335 if ( index.column() == 2 && ( ( !expanded && totalRecursiveCount > 0 ) || ( expanded && totalCount > 0 ) ) ) {
336 sumText = QString::number( expanded ? totalCount : totalRecursiveCount );
340 painter->drawText( textRect, Qt::AlignRight | Qt::AlignVCenter, sumText );
341 painter->setFont( savedFont );
346 if ( index.column() == 3 && !expanded ) {
347 if ( textColor.isValid() ) {
348 painter->setPen( textColor );
350 painter->drawText( textRect, option4.displayAlignment | Qt::AlignVCenter, KIO::convertSize( ( KIO::filesize_t)totalSize ) );
354 if ( textColor.isValid() ) {
355 painter->setPen( textColor );
357 painter->drawText( textRect, option4.displayAlignment | Qt::AlignVCenter, text );