/* Copyright (c) 2010-2019 Montel Laurent This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "entitycollectionorderproxymodel.h" #include "kernel/mailkernel.h" #include "util/mailutil.h" #include "mailcommon_debug.h" #include #include #include #include namespace MailCommon { class Q_DECL_HIDDEN EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModelPrivate { public: EntityCollectionOrderProxyModelPrivate() : manualSortingActive(false) { } int collectionRank(const Akonadi::Collection &collection) { const Akonadi::Collection::Id id = collection.id(); const int cachedRank = collectionRanks.value(id, -1); if (cachedRank != -1) { return cachedRank; } int rank = 100; if (Kernel::folderIsInbox(collection)) { rank = 1; } else if (Kernel::self()->folderIsDraftOrOutbox(collection)) { if (Kernel::self()->folderIsDrafts(collection)) { rank = 5; } else { rank = 2; } } else if (Kernel::self()->folderIsSentMailFolder(collection)) { rank = 3; } else if (Kernel::self()->folderIsTrash(collection)) { rank = 4; } else if (Kernel::self()->folderIsTemplates(collection)) { rank = 6; } else if (MailCommon::Util::isVirtualCollection(collection)) { rank = 200; } else if (collection.parentCollection() == Akonadi::Collection::root() && MailCommon::Util::isUnifiedMailboxesAgent(collection)) { // special treatment for Unified Mailboxes: they are *always* on top rank = 0; } else if (!topLevelOrder.isEmpty()) { if (collection.parentCollection() == Akonadi::Collection::root()) { const QString resource = collection.resource(); if (resource.isEmpty()) { qCDebug(MAILCOMMON_LOG) << " collection has not resource: " << collection; //Don't save in collectionranks because we don't have resource name => pb. return rank; } const int order = topLevelOrder.indexOf(resource); if (order != -1) { rank = order + 1; /* top-level rank "0" belongs to Unified Mailboxes */ } } } collectionRanks.insert(id, rank); return rank; } QMap collectionRanks; QStringList topLevelOrder; bool manualSortingActive; }; EntityCollectionOrderProxyModel::EntityCollectionOrderProxyModel(QObject *parent) : EntityOrderProxyModel(parent) , d(new EntityCollectionOrderProxyModelPrivate()) { setSortCaseSensitivity(Qt::CaseInsensitive); connect(Akonadi::SpecialMailCollections::self(), &Akonadi::SpecialMailCollections::defaultCollectionsChanged, this, &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged); connect(Akonadi::SpecialMailCollections::self(), &Akonadi::SpecialMailCollections::collectionsChanged, this, &EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged); } EntityCollectionOrderProxyModel::~EntityCollectionOrderProxyModel() { if (d->manualSortingActive) { saveOrder(); } delete d; } void EntityCollectionOrderProxyModel::slotSpecialCollectionsChanged() { if (!d->manualSortingActive) { d->collectionRanks.clear(); invalidate(); } } void EntityCollectionOrderProxyModel::setTopLevelOrder(const QStringList &list) { d->topLevelOrder = list; clearRanks(); } void EntityCollectionOrderProxyModel::clearRanks() { d->collectionRanks.clear(); invalidate(); } bool EntityCollectionOrderProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { const auto leftData = left.data(Akonadi::EntityTreeModel::CollectionRole).value(); const auto rightData = right.data(Akonadi::EntityTreeModel::CollectionRole).value(); if (!d->manualSortingActive) { const int rankLeft = d->collectionRank(leftData); const int rankRight = d->collectionRank(rightData); if (rankLeft < rankRight) { return true; } else if (rankLeft > rankRight) { return false; } return QSortFilterProxyModel::lessThan(left, right); } if (MailCommon::Util::isUnifiedMailboxesAgent(leftData)) { return true; } else { return EntityOrderProxyModel::lessThan(left, right); } } void EntityCollectionOrderProxyModel::setManualSortingActive(bool active) { if (d->manualSortingActive == active) { return; } d->manualSortingActive = active; d->collectionRanks.clear(); invalidate(); } bool EntityCollectionOrderProxyModel::isManualSortingActive() const { return d->manualSortingActive; } }