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;
129 void CollectionStatisticsDelegate::setProgressAnimationEnabled(
bool enable )
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;
151 void CollectionStatisticsDelegate::initStyleOption( QStyleOptionViewItem *option,
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 )
197 void CollectionStatisticsDelegate::paint( 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() );
232 Q_ASSERT( collection.
isValid() );
236 qint64 unreadCount = qMax( 0LL, statistics.unreadCount() );
237 qint64 totalRecursiveCount = 0;
238 qint64 unreadRecursiveCount = 0;
239 qint64 totalSize = 0;
240 bool needRecursiveCounts =
false;
241 bool needTotalSize =
false;
242 if ( d->drawUnreadAfterFolder && index.column() == 0 ) {
243 needRecursiveCounts =
true;
244 }
else if ( ( index.column() == 1 || index.column() == 2 ) ) {
245 needRecursiveCounts =
true;
246 }
else if ( index.column() == 3 && !expanded ) {
247 needTotalSize =
true;
250 if ( needRecursiveCounts || needTotalSize ) {
251 d->getCountRecursive( firstColumn, totalRecursiveCount, unreadRecursiveCount, totalSize );
255 if ( d->drawUnreadAfterFolder && index.column() == 0 ) {
260 if ( expanded && unreadCount > 0 ) {
261 unread = QString::fromLatin1(
" (%1)" ).arg( unreadCount );
262 }
else if ( !expanded ) {
263 if ( unreadCount != unreadRecursiveCount ) {
264 unread = QString::fromLatin1(
" (%1 + %2)" ).arg( unreadCount ).arg( unreadRecursiveCount - unreadCount );
265 }
else if ( unreadCount > 0 ) {
266 unread = QString::fromLatin1(
" (%1)" ).arg( unreadCount );
270 PainterStateSaver stateSaver( painter );
272 if ( !unread.isEmpty() ) {
273 QFont font = painter->font();
274 font.setBold(
true );
275 painter->setFont( font );
278 const QColor unreadColor = ( option.state & QStyle::State_Selected ) ? d->mSelectedUnreadColor : d->mDeselectedUnreadColor;
279 const QRect iconRect = s->subElementRect( QStyle::SE_ItemViewItemDecoration, &option4, widget );
281 if ( option.decorationPosition == QStyleOptionViewItem::Left ||
282 option.decorationPosition == QStyleOptionViewItem::Right ) {
285 QString folderName = text;
286 QFontMetrics fm( painter->fontMetrics() );
287 const int unreadWidth = fm.width( unread );
288 int folderWidth( fm.width( folderName ) );
289 const bool enoughPlaceForText = ( option.rect.width() > ( folderWidth + unreadWidth + iconRect.width() ) );
291 if ( !enoughPlaceForText && ( folderWidth + unreadWidth > textRect.width() ) ) {
292 folderName = fm.elidedText( folderName, Qt::ElideRight,
293 option.rect.width() - unreadWidth - iconRect.width() );
294 folderWidth = fm.width( folderName );
296 QRect folderRect = textRect;
297 QRect unreadRect = textRect;
298 folderRect.setRight( textRect.left() + folderWidth );
299 unreadRect = QRect( folderRect.right(), folderRect.top(), unreadRect.width(), unreadRect.height() );
300 if ( textColor.isValid() ) {
301 painter->setPen( textColor );
305 painter->drawText( folderRect, Qt::AlignLeft | Qt::AlignVCenter, folderName );
306 painter->setPen( unreadColor );
307 painter->drawText( unreadRect, Qt::AlignLeft | Qt::AlignVCenter, unread );
308 }
else if ( option.decorationPosition == QStyleOptionViewItem::Top ) {
309 if ( unreadCount > 0 ) {
311 painter->setPen( unreadColor );
312 painter->drawText( iconRect, Qt::AlignCenter, QString::number( unreadCount ) );
320 if ( ( index.column() == 1 || index.column() == 2 ) ) {
322 QFont savedFont = painter->font();
324 if ( index.column() == 1 && ( ( !expanded && unreadRecursiveCount > 0 ) || ( expanded && unreadCount > 0 ) ) ) {
325 QFont font = painter->font();
326 font.setBold(
true );
327 painter->setFont( font );
328 sumText = QString::number( expanded ? unreadCount : unreadRecursiveCount );
331 qint64 totalCount = statistics.count();
332 if ( index.column() == 2 && ( ( !expanded && totalRecursiveCount > 0 ) || ( expanded && totalCount > 0 ) ) ) {
333 sumText = QString::number( expanded ? totalCount : totalRecursiveCount );
337 painter->drawText( textRect, Qt::AlignRight | Qt::AlignVCenter, sumText );
338 painter->setFont( savedFont );
343 if ( index.column() == 3 && !expanded ) {
344 if ( textColor.isValid() ) {
345 painter->setPen( textColor );
347 painter->drawText( textRect, option4.displayAlignment | Qt::AlignVCenter, KIO::convertSize( ( KIO::filesize_t)totalSize ) );
351 if ( textColor.isValid() ) {
352 painter->setPen( textColor );
354 painter->drawText( textRect, option4.displayAlignment | Qt::AlignVCenter, text );