You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

165 lines
5.5 KiB

/*
Copyright (c) 2010-2019 Montel Laurent <montel@kde.org>
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 <Collection>
#include <EntityTreeModel>
#include <Akonadi/KMime/SpecialMailCollections>
#include <AgentManager>
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<Akonadi::Collection::Id, int> 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<Akonadi::Collection>();
const auto rightData = right.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
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;
}
}