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"
49class CollectionStatisticsDelegatePrivate
52 QAbstractItemView *parent;
53 bool drawUnreadAfterFolder;
54 DelegateAnimator *animator;
55 QColor mSelectedUnreadColor;
56 QColor mDeselectedUnreadColor;
58 CollectionStatisticsDelegatePrivate(QAbstractItemView *treeView)
60 , drawUnreadAfterFolder(false)
66 void getCountRecursive(
const QModelIndex &index, qint64 &totalCount, qint64 &unreadCount, qint64 &totalSize)
const
71 if (collection.isValid()) {
73 totalCount += qMax(0LL, statistics.
count());
75 totalSize += qMax(0LL, statistics.
size());
76 if (index.model()->hasChildren(index)) {
77 const int rowCount = index.model()->rowCount(index);
78 for (
int row = 0; row < rowCount; row++) {
79 static const int column = 0;
80 getCountRecursive(index.model()->index(row, column, index), totalCount, unreadCount, totalSize);
88 mSelectedUnreadColor = KColorScheme(QPalette::Active, KColorScheme::Selection)
89 .foreground(KColorScheme::LinkText).color();
90 mDeselectedUnreadColor = KColorScheme(QPalette::Active, KColorScheme::View)
91 .foreground(KColorScheme::LinkText).color();
98 : QStyledItemDelegate(parent)
99 , d_ptr(new CollectionStatisticsDelegatePrivate(parent))
105 : QStyledItemDelegate(parent)
106 , d_ptr(new CollectionStatisticsDelegatePrivate(parent))
119 d->drawUnreadAfterFolder = enable;
125 return d->drawUnreadAfterFolder;
131 if (enable == (d->animator != 0)) {
135 Q_ASSERT(!d->animator);
136 Akonadi::DelegateAnimator *animator =
new Akonadi::DelegateAnimator(d->parent);
137 d->animator = animator;
144bool CollectionStatisticsDelegate::progressAnimationEnabled()
const
147 return d->animator != 0;
151 const QModelIndex &index)
const
155 QStyleOptionViewItemV4 *noTextOption =
156 qstyleoption_cast<QStyleOptionViewItemV4 *>(option);
157 QStyledItemDelegate::initStyleOption(noTextOption, index);
158 if (option->decorationPosition != QStyleOptionViewItem::Top) {
159 noTextOption->text.clear();
166 d->animator->pop(index);
170 d->animator->push(index);
172 if (QStyleOptionViewItemV4 *v4 = qstyleoption_cast<QStyleOptionViewItemV4 *>(option)) {
173 v4->icon = d->animator->sequenceFrame(index);
178class PainterStateSaver
181 PainterStateSaver(QPainter *painter)
197 const QStyleOptionViewItem &option,
198 const QModelIndex &index)
const
201 PainterStateSaver stateSaver(painter);
203 const QColor textColor = index.data(Qt::ForegroundRole).value<QColor>();
206 QStyledItemDelegate::paint(painter, option, index);
210 QStyleOptionViewItemV4 option4 = option;
211 QStyledItemDelegate::initStyleOption(&option4, index);
212 QString text = option4.text;
215 QStyle *s = d->parent->style();
216 const QWidget *widget = option4.widget;
217 const QRect textRect = s->subElementRect(QStyle::SE_ItemViewItemText, &option4, widget);
221 const QModelIndex firstColumn = index.sibling(index.row(), 0);
222 QTreeView *treeView = qobject_cast<QTreeView *>(d->parent);
223 bool expanded = treeView && treeView->isExpanded(firstColumn);
225 if (option.state & QStyle::State_Selected) {
226 painter->setPen(textColor.isValid() ? textColor : option.palette.highlightedText().color());
231 if (!collection.isValid()) {
232 kError() <<
"Invalid collection: " << collection;
238 qint64 unreadCount = qMax(0LL, statistics.
unreadCount());
239 qint64 totalRecursiveCount = 0;
240 qint64 unreadRecursiveCount = 0;
241 qint64 totalSize = 0;
242 bool needRecursiveCounts =
false;
243 bool needTotalSize =
false;
244 if (d->drawUnreadAfterFolder && index.column() == 0) {
245 needRecursiveCounts =
true;
246 }
else if ((index.column() == 1 || index.column() == 2)) {
247 needRecursiveCounts =
true;
248 }
else if (index.column() == 3 && !expanded) {
249 needTotalSize =
true;
252 if (needRecursiveCounts || needTotalSize) {
253 d->getCountRecursive(firstColumn, totalRecursiveCount, unreadRecursiveCount, totalSize);
257 if (d->drawUnreadAfterFolder && index.column() == 0) {
262 if (expanded && unreadCount > 0) {
263 unread = QString::fromLatin1(
" (%1)").arg(unreadCount);
264 }
else if (!expanded) {
265 if (unreadCount != unreadRecursiveCount) {
266 unread = QString::fromLatin1(
" (%1 + %2)").arg(unreadCount).arg(unreadRecursiveCount - unreadCount);
267 }
else if (unreadCount > 0) {
268 unread = QString::fromLatin1(
" (%1)").arg(unreadCount);
272 PainterStateSaver stateSaver(painter);
274 if (!unread.isEmpty()) {
275 QFont font = painter->font();
277 painter->setFont(font);
280 const QColor unreadColor = (option.state & QStyle::State_Selected) ? d->mSelectedUnreadColor : d->mDeselectedUnreadColor;
281 const QRect iconRect = s->subElementRect(QStyle::SE_ItemViewItemDecoration, &option4, widget);
283 if (option.decorationPosition == QStyleOptionViewItem::Left ||
284 option.decorationPosition == QStyleOptionViewItem::Right) {
287 QString folderName = text;
288 QFontMetrics fm(painter->fontMetrics());
289 const int unreadWidth = fm.width(unread);
290 int folderWidth(fm.width(folderName));
291 const bool enoughPlaceForText = (option.rect.width() > (folderWidth + unreadWidth + iconRect.width()));
293 if (!enoughPlaceForText && (folderWidth + unreadWidth > textRect.width())) {
294 folderName = fm.elidedText(folderName, Qt::ElideRight,
295 option.rect.width() - unreadWidth - iconRect.width());
296 folderWidth = fm.width(folderName);
298 QRect folderRect = textRect;
299 QRect unreadRect = textRect;
300 folderRect.setRight(textRect.left() + folderWidth);
301 unreadRect = QRect(folderRect.right(), folderRect.top(), unreadRect.width(), unreadRect.height());
302 if (textColor.isValid()) {
303 painter->setPen(textColor);
307 painter->drawText(folderRect, Qt::AlignLeft | Qt::AlignVCenter, folderName);
308 painter->setPen(unreadColor);
309 painter->drawText(unreadRect, Qt::AlignLeft | Qt::AlignVCenter, unread);
310 }
else if (option.decorationPosition == QStyleOptionViewItem::Top) {
311 if (unreadCount > 0) {
313 painter->setPen(unreadColor);
314 painter->drawText(iconRect, Qt::AlignCenter, QString::number(unreadCount));
322 if ((index.column() == 1 || index.column() == 2)) {
324 QFont savedFont = painter->font();
326 if (index.column() == 1 && ((!expanded && unreadRecursiveCount > 0) || (expanded && unreadCount > 0))) {
327 QFont font = painter->font();
329 painter->setFont(font);
330 sumText = QString::number(expanded ? unreadCount : unreadRecursiveCount);
333 qint64 totalCount = statistics.
count();
334 if (index.column() == 2 && ((!expanded && totalRecursiveCount > 0) || (expanded && totalCount > 0))) {
335 sumText = QString::number(expanded ? totalCount : totalRecursiveCount);
339 painter->drawText(textRect, Qt::AlignRight | Qt::AlignVCenter, sumText);
340 painter->setFont(savedFont);
345 if (index.column() == 3 && !expanded) {
346 if (textColor.isValid()) {
347 painter->setPen(textColor);
349 painter->drawText(textRect, option4.displayAlignment | Qt::AlignVCenter, KIO::convertSize((KIO::filesize_t)totalSize));
353 if (textColor.isValid()) {
354 painter->setPen(textColor);
356 painter->drawText(textRect, option4.displayAlignment | Qt::AlignVCenter, text);
A delegate that draws unread and total count for CollectionStatisticsModel.
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
bool unreadCountShown() const
Returns whether the unread count is drawn next to the folder name.
void setUnreadCountShown(bool enable)
Sets whether the unread count is drawn next to the folder name.
~CollectionStatisticsDelegate()
Destroys the collection statistics delegate.
void setProgressAnimationEnabled(bool enable)
CollectionStatisticsDelegate(QAbstractItemView *parent)
Creates a new collection statistics delegate.
Provides statistics information of a Collection.
qint64 unreadCount() const
Returns the number of unread items in this collection or -1 if this information is not available.
qint64 count() const
Returns the number of items in this collection or -1 if this information is not available.
qint64 size() const
Returns the total size of the items in this collection or -1 if this information is not available.
Represents a collection of PIM items.
@ FetchingState
There is a fetch of items in this collection in progress.
@ CollectionRole
The collection.
@ FetchStateRole
Returns the FetchState of a particular item.
FreeBusyManager::Singleton.