diff --git a/src/folder/foldertreewidgetproxymodel.cpp b/src/folder/foldertreewidgetproxymodel.cpp index aac6456..b6e7f96 100644 --- a/src/folder/foldertreewidgetproxymodel.cpp +++ b/src/folder/foldertreewidgetproxymodel.cpp @@ -1,300 +1,300 @@ /* Copyright (c) 2009-2019 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "foldertreewidgetproxymodel.h" #include "foldersettings.h" #include "kernel/mailkernel.h" #include "util/mailutil.h" #include #include #include #include #include #include #include #include #include #include #include namespace MailCommon { class FolderTreeWidgetProxyModel::Private { public: Private(FolderTreeWidgetProxyModel *qq) : q(qq) { } bool checkQuotaExcedded(const QModelIndex &index, qreal &percentage) { if (index.model()->hasChildren(index)) { const int rowCount = index.model()->rowCount(index); for (int row = 0; row < rowCount; row++) { const QModelIndex firstIndex = q->mapToSource(index.model()->index(row, 0, index)); const Akonadi::Collection collectionFirst = q->sourceModel()->data( firstIndex, Akonadi::EntityTreeModel::CollectionRole).value(); if (collectionFirst.isValid() && collectionFirst.hasAttribute()) { const Akonadi::CollectionQuotaAttribute *quota = collectionFirst.attribute(); if (quota->currentValue() > -1 && quota->maximumValue() > 0) { percentage = (100.0 * quota->currentValue()) / quota->maximumValue(); if (percentage >= threshold) { return true; } } } } } return false; } QSet includedMimeTypes; Akonadi::MimeTypeChecker checker; QColor brokenAccountColor; qreal threshold = 0.0; FolderTreeWidgetProxyModel *q; bool enableCheck = false; bool hideVirtualFolder = false; bool hideSpecificFolder = false; bool hideOutboxFolder = false; }; FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModel(QObject *parent, FolderTreeWidgetProxyModelOptions option) : Akonadi::EntityRightsFilterModel(parent) , d(new Private(this)) { setDynamicSortFilter(true); setFilterCaseSensitivity(Qt::CaseInsensitive); if (option & HideVirtualFolder) { d->hideVirtualFolder = true; } if (option & HideSpecificFolder) { d->hideSpecificFolder = true; } if (option & HideOutboxFolder) { d->hideOutboxFolder = true; } readConfig(); } FolderTreeWidgetProxyModel::~FolderTreeWidgetProxyModel() { delete d; } void FolderTreeWidgetProxyModel::setWarningThreshold(qreal threshold) { d->threshold = threshold; } void FolderTreeWidgetProxyModel::readConfig() { invalidate(); } Qt::ItemFlags FolderTreeWidgetProxyModel::flags(const QModelIndex &index) const { if (d->enableCheck) { const QModelIndex sourceIndex = mapToSource(index); const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0); const Akonadi::Collection collection = sourceModel()->data(rowIndex, Akonadi::EntityTreeModel::CollectionRole).value(); if (!MailCommon::Util::isVirtualCollection(collection)) { const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(collection.resource()); if (instance.status() == Akonadi::AgentInstance::Broken) { return KRecursiveFilterProxyModel::flags(sourceIndex) & ~(Qt::ItemIsSelectable | Qt::ItemIsEnabled); } } return Akonadi::EntityRightsFilterModel::flags(index); } return QSortFilterProxyModel::flags(index); } void FolderTreeWidgetProxyModel::setEnabledCheck(bool enable) { if (d->enableCheck == enable) { return; } d->enableCheck = enable; if (enable) { setAccessRights(Akonadi::Collection::CanCreateItem | Akonadi::Collection::CanCreateCollection); } } bool FolderTreeWidgetProxyModel::enabledCheck() const { return d->enableCheck; } void FolderTreeWidgetProxyModel::setHideVirtualFolder(bool exclude) { if (d->hideVirtualFolder != exclude) { d->hideVirtualFolder = exclude; invalidate(); } } bool FolderTreeWidgetProxyModel::hideVirtualFolder() const { return d->hideVirtualFolder; } void FolderTreeWidgetProxyModel::setHideSpecificFolder(bool hide) { if (d->hideSpecificFolder != hide) { d->hideSpecificFolder = hide; invalidate(); } } bool FolderTreeWidgetProxyModel::hideSpecificFolder() const { return d->hideSpecificFolder; } void FolderTreeWidgetProxyModel::setHideOutboxFolder(bool hide) { if (d->hideOutboxFolder != hide) { d->hideOutboxFolder = hide; invalidate(); } } bool FolderTreeWidgetProxyModel::hideOutboxFolder() const { return d->hideOutboxFolder; } bool FolderTreeWidgetProxyModel::acceptRow(int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex modelIndex = sourceModel()->index(sourceRow, 0, sourceParent); const Akonadi::Collection collection = sourceModel()->data( modelIndex, Akonadi::EntityTreeModel::CollectionRole).value(); if (!d->checker.isWantedCollection(collection)) { return false; } if (d->hideVirtualFolder) { if (Util::isVirtualCollection(collection)) { return false; } } if (d->hideSpecificFolder) { const QSharedPointer col = FolderSettings::forCollection(collection, false); if (col && col->hideInSelectionDialog()) { return false; } } if (d->hideOutboxFolder) { if (collection == Kernel::self()->outboxCollectionFolder()) { return false; } } return KRecursiveFilterProxyModel::acceptRow(sourceRow, sourceParent); } QVariant FolderTreeWidgetProxyModel::data(const QModelIndex &index, int role) const { if (role == Qt::ForegroundRole) { const QModelIndex sourceIndex = mapToSource(index); const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0); const Akonadi::Collection collection = sourceModel()->data( rowIndex, Akonadi::EntityTreeModel::CollectionRole).value(); if (!MailCommon::Util::isVirtualCollection(collection)) { const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(collection.resource()); if (instance.status() == Akonadi::AgentInstance::Broken) { if (!d->brokenAccountColor.isValid()) { const KColorScheme scheme(QPalette::Active, KColorScheme::View); d->brokenAccountColor = scheme.foreground(KColorScheme::NegativeText).color(); } return d->brokenAccountColor; } } } else if (role == Qt::DisplayRole) { const QModelIndex sourceIndex = mapToSource(index); const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0); const Akonadi::Collection collection = sourceModel()->data( rowIndex, Akonadi::EntityTreeModel::CollectionRole).value(); if (!MailCommon::Util::isVirtualCollection(collection)) { const Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance(collection.resource()); if (collection.parentCollection() == Akonadi::Collection::root()) { if (!instance.isOnline()) { return i18n("%1 (Offline)", Akonadi::EntityRightsFilterModel::data(index, role).toString()); } qreal percentage = 0.0; if (d->checkQuotaExcedded(index, percentage)) { return i18n("%1 (Reached %2% quota)", Akonadi::EntityRightsFilterModel::data(index, role).toString(), static_cast(percentage)); } } } } else if (role == Qt::DecorationRole) { const QModelIndex sourceIndex = mapToSource(index); const QModelIndex rowIndex = sourceIndex.sibling(sourceIndex.row(), 0); const Akonadi::Collection collection = sourceModel()->data( rowIndex, Akonadi::EntityTreeModel::CollectionRole).value(); if (!MailCommon::Util::isVirtualCollection(collection)) { if (collection.parentCollection() == Akonadi::Collection::root()) { qreal percentage = 0.0; if (d->checkQuotaExcedded(index, percentage)) { return QIcon::fromTheme(QStringLiteral("emblem-warning")); } } } } return Akonadi::EntityRightsFilterModel::data(index, role); } void FolderTreeWidgetProxyModel::updatePalette() { if (d->brokenAccountColor.isValid()) { KColorScheme scheme(QPalette::Active, KColorScheme::View); d->brokenAccountColor = scheme.foreground(KColorScheme::NegativeText).color(); invalidate(); } } void FolderTreeWidgetProxyModel::addContentMimeTypeInclusionFilter(const QString &mimeType) { d->includedMimeTypes << mimeType; - d->checker.setWantedMimeTypes(d->includedMimeTypes.toList()); + d->checker.setWantedMimeTypes(d->includedMimeTypes.values()); invalidateFilter(); } } diff --git a/src/search/searchrule/searchrulestatus.cpp b/src/search/searchrule/searchrulestatus.cpp index 82e0676..d6205a8 100644 --- a/src/search/searchrule/searchrulestatus.cpp +++ b/src/search/searchrule/searchrulestatus.cpp @@ -1,176 +1,176 @@ /* Copyright (c) 2015-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 "searchrulestatus.h" #include "filter/filterlog.h" using MailCommon::FilterLog; #include using namespace MailCommon; struct _statusNames { const char *name; Akonadi::MessageStatus status; }; static struct _statusNames statusNames[] = { { "Important", Akonadi::MessageStatus::statusImportant() }, { "Unread", Akonadi::MessageStatus::statusUnread() }, { "Read", Akonadi::MessageStatus::statusRead() }, { "Deleted", Akonadi::MessageStatus::statusDeleted() }, { "Replied", Akonadi::MessageStatus::statusReplied() }, { "Forwarded", Akonadi::MessageStatus::statusForwarded() }, { "Queued", Akonadi::MessageStatus::statusQueued() }, { "Sent", Akonadi::MessageStatus::statusSent() }, { "Watched", Akonadi::MessageStatus::statusWatched() }, { "Ignored", Akonadi::MessageStatus::statusIgnored() }, { "Action Item", Akonadi::MessageStatus::statusToAct() }, { "Spam", Akonadi::MessageStatus::statusSpam() }, { "Ham", Akonadi::MessageStatus::statusHam() }, { "Has Attachment", Akonadi::MessageStatus::statusHasAttachment() } }; QString englishNameForStatus(Akonadi::MessageStatus status) { for (const _statusNames &statusName : statusNames) { if (statusName.status == status) { return QString::fromLatin1(statusName.name); } } return QString(); } SearchRuleStatus::SearchRuleStatus(const QByteArray &field, Function func, const QString &aContents) : SearchRule(field, func, aContents) { // the values are always in english, both from the conf file as well as // the patternedit gui mStatus = statusFromEnglishName(aContents); } SearchRuleStatus::SearchRuleStatus(Akonadi::MessageStatus status, Function func) : SearchRule("", func, englishNameForStatus(status)) { mStatus = status; } Akonadi::MessageStatus SearchRuleStatus::statusFromEnglishName(const QString &aStatusString) { for (const _statusNames &statusName : statusNames) { if (!aStatusString.compare(QString::fromLatin1(statusName.name))) { return statusName.status; } } Akonadi::MessageStatus unknown; return unknown; } QString SearchRuleStatus::informationAboutNotValidRules() const { //TODO return QStringLiteral(""); } bool SearchRuleStatus::isEmpty() const { return field().trimmed().isEmpty() || contents().isEmpty(); } bool SearchRuleStatus::matches(const Akonadi::Item &item) const { Akonadi::MessageStatus status; status.setStatusFromFlags(item.flags()); bool rc = false; switch (function()) { case FuncEquals: // fallthrough. So that " 'is' 'read'" works case FuncContains: if (status & mStatus) { rc = true; } break; case FuncNotEqual: // fallthrough. So that " 'is not' 'read'" works case FuncContainsNot: if (!(status & mStatus)) { rc = true; } break; // FIXME what about the remaining funcs, how can they make sense for // stati? default: break; } if (FilterLog::instance()->isLogging()) { QString msg = (rc ? QStringLiteral("1 = ") : QStringLiteral("0 = ")); msg += FilterLog::recode(asString()); FilterLog::instance()->add(msg, FilterLog::RuleResult); } return rc; } SearchRule::RequiredPart SearchRuleStatus::requiredPart() const { return SearchRule::Envelope; } void SearchRuleStatus::addQueryTerms(Akonadi::SearchTerm &groupTerm, bool &emptyIsNotAnError) const { using namespace Akonadi; emptyIsNotAnError = true; //TODO double check that isRead also works if (!mStatus.statusFlags().isEmpty()) { - EmailSearchTerm term(EmailSearchTerm::MessageStatus, mStatus.statusFlags().toList().first(), akonadiComparator()); + EmailSearchTerm term(EmailSearchTerm::MessageStatus, mStatus.statusFlags().values().first(), akonadiComparator()); term.setIsNegated(isNegated()); groupTerm.addSubTerm(term); } else { //Special case Unread Akonadi::MessageStatus status; status.setRead(true); - EmailSearchTerm term(EmailSearchTerm::MessageStatus, status.statusFlags().toList().first(), akonadiComparator()); + EmailSearchTerm term(EmailSearchTerm::MessageStatus, status.statusFlags().values().first(), akonadiComparator()); term.setIsNegated(!isNegated()); groupTerm.addSubTerm(term); } }