diff --git a/messagelist/src/core/item.h b/messagelist/src/core/item.h --- a/messagelist/src/core/item.h +++ b/messagelist/src/core/item.h @@ -358,6 +358,16 @@ * Sets the subject associated to this Item. */ void setSubject(const QString &subject); + + /** + * Returns the folder associated to this Item. + */ + const QString &folder() const; + + /** + * Sets the folder associated to this Item. + */ + void setFolder(const QString &folder); /** * This is meant to be called right after the constructor. diff --git a/messagelist/src/core/item.cpp b/messagelist/src/core/item.cpp --- a/messagelist/src/core/item.cpp +++ b/messagelist/src/core/item.cpp @@ -551,6 +551,16 @@ d_ptr->mSubject = subject; } +const QString &Item::folder() const +{ + return d_ptr->mFolder; +} + +void Item::setFolder(const QString &folder) +{ + d_ptr->mFolder = folder; +} + void MessageList::Core::Item::initialSetup(time_t date, size_t size, const QString &sender, const QString &receiver, bool useReceiver) { d_ptr->mDate = date; diff --git a/messagelist/src/core/item_p.h b/messagelist/src/core/item_p.h --- a/messagelist/src/core/item_p.h +++ b/messagelist/src/core/item_p.h @@ -242,6 +242,7 @@ QString mSender; ///< The sender of the message (or group sender) QString mReceiver; ///< The receiver of the message (or group receiver) QString mSubject; ///< The subject of the message (or group subject) + QString mFolder; ///< The folder of the message qint64 mItemId; ///< The Akonadi item id qint64 mParentCollectionId; ///< The Akonadi ID of collection that this particular item comes from (can be virtual collection) Akonadi::MessageStatus mStatus; ///< The status of the message (may be extended to groups in the future) diff --git a/messagelist/src/core/theme.h b/messagelist/src/core/theme.h --- a/messagelist/src/core/theme.h +++ b/messagelist/src/core/theme.h @@ -212,7 +212,11 @@ /** * Whether the message is an invitation */ - InvitationIcon = 24 | ApplicableToMessageItems | IsIcon + InvitationIcon = 24 | ApplicableToMessageItems | IsIcon, + /** + * Folder of the message + */ + Folder = 25 | DisplaysText | CanUseCustomColor | ApplicableToMessageItems #if 0 TotalMessageCount UnreadMessageCount diff --git a/messagelist/src/core/theme.cpp b/messagelist/src/core/theme.cpp --- a/messagelist/src/core/theme.cpp +++ b/messagelist/src/core/theme.cpp @@ -188,6 +188,8 @@ return i18n("Note Icon"); case InvitationIcon: return i18n("Invitation Icon"); + case Folder: + return i18nc("Description of Type Folder", "Folder"); default: return i18nc("Description for an Unknown Type", "Unknown"); break; @@ -336,6 +338,7 @@ case TagList: case AnnotationIcon: case InvitationIcon: + case Folder: // ok break; default: diff --git a/messagelist/src/core/themedelegate.cpp b/messagelist/src/core/themedelegate.cpp --- a/messagelist/src/core/themedelegate.cpp +++ b/messagelist/src/core/themedelegate.cpp @@ -865,6 +865,9 @@ case Theme::ContentItem::Size: paint_right_aligned_elided_text(item->formattedSize(), ci, painter, l, top, r, layoutDir, font); break; + case Theme::ContentItem::Folder: + paint_right_aligned_elided_text(item->folder(), ci, painter, l, top, r, layoutDir, font); + break; case Theme::ContentItem::GroupHeaderLabel: if (groupHeaderItem) { paint_right_aligned_elided_text(groupHeaderItem->label(), ci, painter, l, top, r, layoutDir, font); @@ -1029,6 +1032,9 @@ case Theme::ContentItem::Size: paint_left_aligned_elided_text(item->formattedSize(), ci, painter, l, top, r, layoutDir, font); break; + case Theme::ContentItem::Folder: + paint_left_aligned_elided_text(item->folder(), ci, painter, l, top, r, layoutDir, font); + break; case Theme::ContentItem::GroupHeaderLabel: if (groupHeaderItem) { paint_left_aligned_elided_text(groupHeaderItem->label(), ci, painter, l, top, r, layoutDir, font); @@ -1283,6 +1289,9 @@ case Theme::ContentItem::Size: compute_bounding_rect_for_right_aligned_elided_text(mHitItem->formattedSize(), ci, l, top, r, mHitContentItemRect, layoutDir, font); break; + case Theme::ContentItem::Folder: + compute_bounding_rect_for_right_aligned_elided_text(mHitItem->folder(), ci, l, top, r, mHitContentItemRect, layoutDir, font); + break; case Theme::ContentItem::GroupHeaderLabel: if (groupHeaderItem) { compute_bounding_rect_for_right_aligned_elided_text(groupHeaderItem->label(), ci, l, top, r, mHitContentItemRect, layoutDir, font); @@ -1428,6 +1437,9 @@ case Theme::ContentItem::Size: compute_bounding_rect_for_left_aligned_elided_text(mHitItem->formattedSize(), ci, l, top, r, mHitContentItemRect, layoutDir, font); break; + case Theme::ContentItem::Folder: + compute_bounding_rect_for_left_aligned_elided_text(mHitItem->folder(), ci, l, top, r, mHitContentItemRect, layoutDir, font); + break; case Theme::ContentItem::GroupHeaderLabel: if (groupHeaderItem) { compute_bounding_rect_for_left_aligned_elided_text(groupHeaderItem->label(), ci, l, top, r, mHitContentItemRect, layoutDir, font); diff --git a/messagelist/src/core/view.cpp b/messagelist/src/core/view.cpp --- a/messagelist/src/core/view.cpp +++ b/messagelist/src/core/view.cpp @@ -2400,9 +2400,11 @@ if (textIsLeftToRight) { tip += htmlCodeForStandardRow.arg(i18n("Status")).arg(status); tip += htmlCodeForStandardRow.arg(i18n("Size")).arg(mi->formattedSize()); + tip += htmlCodeForStandardRow.arg(i18n("Folder")).arg(mi->folder()); } else { tip += htmlCodeForStandardRow.arg(status).arg(i18n("Status")); tip += htmlCodeForStandardRow.arg(mi->formattedSize()).arg(i18n("Size")); + tip += htmlCodeForStandardRow.arg(mi->folder()).arg(i18n("Folder")); } if (mi->hasAnnotation()) { diff --git a/messagelist/src/storagemodel.h b/messagelist/src/storagemodel.h --- a/messagelist/src/storagemodel.h +++ b/messagelist/src/storagemodel.h @@ -78,6 +78,8 @@ Q_REQUIRED_RESULT Akonadi::Item itemForRow(int row) const; Q_REQUIRED_RESULT Akonadi::Collection parentCollectionForRow(int row) const; Q_REQUIRED_RESULT KMime::Message::Ptr messageForRow(int row) const; + + Q_REQUIRED_RESULT Akonadi::Collection collectionForId(Akonadi::Collection::Id colId) const; void resetModelStorage(); diff --git a/messagelist/src/storagemodel.cpp b/messagelist/src/storagemodel.cpp --- a/messagelist/src/storagemodel.cpp +++ b/messagelist/src/storagemodel.cpp @@ -45,6 +45,7 @@ #include #include #include +#include namespace MessageList { class Q_DECL_HIDDEN StorageModel::Private @@ -59,6 +60,8 @@ QAbstractItemModel *mModel = nullptr; QAbstractItemModel *mChildrenFilterModel = nullptr; QItemSelectionModel *mSelectionModel = nullptr; + + QHash mFolderHash; Private(StorageModel *owner) : q(owner) @@ -253,6 +256,19 @@ } mi->setSubject(subject); + + auto it = d->mFolderHash.find(item.storageCollectionId()); + if (it == d->mFolderHash.end()) { + QString folder; + Collection collection = collectionForId(item.storageCollectionId()); + while (collection.parentCollection().isValid()) { + folder = collection.displayName() + QLatin1Char('/') + folder; + collection = collection.parentCollection(); + } + folder.chop(1); + it = d->mFolderHash.insert(item.storageCollectionId(), folder); + } + mi->setFolder(it.value()); updateMessageItemData(mi, row); @@ -427,6 +443,7 @@ void StorageModel::Private::onSelectionChanged() { + mFolderHash.clear(); Q_EMIT q->headerDataChanged(Qt::Horizontal, 0, q->columnCount() - 1); } @@ -488,6 +505,20 @@ return col; } +Akonadi::Collection StorageModel::collectionForId(Akonadi::Collection::Id colId) const +{ + // Get ETM + QAbstractProxyModel *childrenProxy = static_cast(d->mChildrenFilterModel); + QAbstractItemModel* etm = childrenProxy->sourceModel(); + + // get index in EntityTreeModel + const QModelIndex idx = EntityTreeModel::modelIndexForCollection(etm, Collection(colId)); + Q_ASSERT(idx.isValid()); + + // get and return collection + return idx.data(EntityTreeModel::CollectionRole).value(); +} + void StorageModel::resetModelStorage() { beginResetModel(); diff --git a/messagelist/src/utils/themeeditor.cpp b/messagelist/src/utils/themeeditor.cpp --- a/messagelist/src/utils/themeeditor.cpp +++ b/messagelist/src/utils/themeeditor.cpp @@ -205,6 +205,7 @@ mSampleMessageItem->setSender(i18n("Sender")); mSampleMessageItem->setReceiver(i18n("Receiver")); mSampleMessageItem->setSubject(i18n("Very long subject very long subject very long subject very long subject very long subject very long")); + mSampleMessageItem->setFolder(i18n("Folder")); mSampleMessageItem->setSignatureState(MessageItem::FullySigned); mSampleMessageItem->setEncryptionState(MessageItem::FullyEncrypted); @@ -1362,6 +1363,11 @@ cil->setText(Theme::ContentItem::description(cil->type())); cil->setToolTip(Theme::ContentItem::description(cil->type())); gblayout->addWidget(cil, 1, 2); + + cil = new ThemeContentItemSourceLabel(gb, Theme::ContentItem::Folder); + cil->setText(Theme::ContentItem::description(cil->type())); + cil->setToolTip(Theme::ContentItem::description(cil->type())); + gblayout->addWidget(cil, 2, 2); cil = new ThemeContentItemSourceLabel(gb, Theme::ContentItem::CombinedReadRepliedStateIcon); cil->setPixmap(*dummyTheme.pixmap(Theme::IconRepliedAndForwarded));