From ddcc75438382242d03141dfe5b3cae667aed4465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= Date: Thu, 17 Aug 2017 13:15:14 +0200 Subject: [PATCH] Move nextUnreadCollection from MailUtils to FolderTreeView FolderTreeView is the only user of the function, so move the code there so that we have as few 'random utility' functions as possible. --- src/folder/foldertreeview.cpp | 114 +++++++++++++++++++++++++++++++--- src/folder/foldertreeview.h | 12 +++- src/util/mailutil.cpp | 106 ------------------------------- src/util/mailutil.h | 8 --- src/util/mailutil_p.h | 11 +--- 5 files changed, 119 insertions(+), 132 deletions(-) diff --git a/src/folder/foldertreeview.cpp b/src/folder/foldertreeview.cpp index 3f91923..7472882 100644 --- a/src/folder/foldertreeview.cpp +++ b/src/folder/foldertreeview.cpp @@ -33,7 +33,8 @@ #include #include -namespace MailCommon { +using namespace MailCommon; + FolderTreeView::FolderTreeView(QWidget *parent, bool showUnreadCount) : Akonadi::EntityTreeView(parent) , mbDisableContextMenuAndExtraColumn(false) @@ -410,9 +411,9 @@ void FolderTreeView::slotFocusLastFolder() void FolderTreeView::selectNextUnreadFolder(bool confirm) { // find next unread collection starting from current position - if (!trySelectNextUnreadFolder(currentIndex(), MailCommon::Util::ForwardSearch, confirm)) { + if (!trySelectNextUnreadFolder(currentIndex(), ForwardSearch, confirm)) { // if there is none, jump to the last collection and try again - trySelectNextUnreadFolder(model()->index(0, 0), MailCommon::Util::ForwardSearch, confirm); + trySelectNextUnreadFolder(model()->index(0, 0), ForwardSearch, confirm); } } @@ -429,18 +430,18 @@ static QModelIndex lastChildOf(QAbstractItemModel *model, const QModelIndex &cur void FolderTreeView::selectPrevUnreadFolder(bool confirm) { // find next unread collection starting from current position - if (!trySelectNextUnreadFolder(currentIndex(), MailCommon::Util::BackwardSearch, confirm)) { + if (!trySelectNextUnreadFolder(currentIndex(), BackwardSearch, confirm)) { // if there is none, jump to top and try again const QModelIndex index = lastChildOf(model(), QModelIndex()); - trySelectNextUnreadFolder(index, MailCommon::Util::BackwardSearch, confirm); + trySelectNextUnreadFolder(index, BackwardSearch, confirm); } } -bool FolderTreeView::trySelectNextUnreadFolder(const QModelIndex ¤t, MailCommon::Util::SearchDirection direction, bool confirm) +bool FolderTreeView::trySelectNextUnreadFolder(const QModelIndex ¤t, SearchDirection direction, bool confirm) { QModelIndex index = current; while (true) { - index = MailCommon::Util::nextUnreadCollection(model(), index, direction); + index = nextUnreadCollection(index, direction); if (!index.isValid()) { return false; @@ -607,4 +608,103 @@ void FolderTreeView::keyboardSearch(const QString &) // FolderSelectionDialog. We don't want it in KMail main window // either because KMail has one-letter keyboard shortcuts. } + +QModelIndex FolderTreeView::indexBelow(const QModelIndex ¤t) const +{ + // if we have children, return first child + if (model()->rowCount(current) > 0) { + return model()->index(0, 0, current); + } + + // if we have siblings, return next sibling + const QModelIndex parent = model()->parent(current); + const QModelIndex sibling = model()->index(current.row() + 1, 0, parent); + + if (sibling.isValid()) { // found valid sibling + return sibling; + } + + if (!parent.isValid()) { // our parent is the tree root and we have no siblings + return QModelIndex(); // we reached the bottom of the tree + } + + // We are the last child, the next index to check is our uncle, parent's first sibling + const QModelIndex parentsSibling = parent.sibling(parent.row() + 1, 0); + if (parentsSibling.isValid()) { + return parentsSibling; + } + + // iterate over our parents back to root until we find a parent with a valid sibling + QModelIndex currentParent = parent; + QModelIndex grandParent = model()->parent(currentParent); + while (currentParent.isValid()) { + // check if the parent has children except from us + if (model()->rowCount(grandParent) > currentParent.row() + 1) { + const auto index = indexBelow(model()->index(currentParent.row() + 1, 0, grandParent)); + if (index.isValid()) { + return index; + } + } + + currentParent = grandParent; + grandParent = model()->parent(currentParent); + } + + return QModelIndex(); // nothing found -> end of tree +} + +QModelIndex FolderTreeView::lastChild(const QModelIndex ¤t) const +{ + if (model()->rowCount(current) == 0) { + return current; + } + + return lastChild(model()->index(model()->rowCount(current) - 1, 0, current)); +} + +QModelIndex FolderTreeView::indexAbove(const QModelIndex ¤t) const +{ + const QModelIndex parent = model()->parent(current); + + if (current.row() == 0) { + // we have no previous siblings -> our parent is the next item above us + return parent; + } + + // find previous sibling + const QModelIndex previousSibling = model()->index(current.row() - 1, 0, parent); + + // the item above us is the last child (or grandchild, or grandgrandchild... etc) + // of our previous sibling + return lastChild(previousSibling); +} + +QModelIndex FolderTreeView::nextUnreadCollection(const QModelIndex ¤t, SearchDirection direction) const +{ + QModelIndex index = current; + while (true) { + if (direction == ForwardSearch) { + index = indexBelow(index); + } else if (direction == BackwardSearch) { + index = indexAbove(index); + } + + if (!index.isValid()) { // reach end or top of the model + return QModelIndex(); + } + + // check if the index is a collection + const auto collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value(); + + if (collection.isValid()) { + // check if it is unread + if (collection.statistics().unreadCount() > 0) { + if (!MailCommon::Util::ignoreNewMailInFolder(collection)) { + return index; // we found the next unread collection + } + } + } + } + + return QModelIndex(); // no unread collection found } diff --git a/src/folder/foldertreeview.h b/src/folder/foldertreeview.h index 4f89cc2..066202e 100644 --- a/src/folder/foldertreeview.h +++ b/src/folder/foldertreeview.h @@ -104,9 +104,19 @@ Q_SIGNALS: void newTabRequested(bool); private: + enum SearchDirection { + ForwardSearch, + BackwardSearch + }; + + QModelIndex indexAbove(const QModelIndex ¤t) const; + QModelIndex indexBelow(const QModelIndex ¤t) const; + QModelIndex lastChild(const QModelIndex ¤t) const; + QModelIndex nextUnreadCollection(const QModelIndex ¤t, SearchDirection direction) const; + bool ignoreUnreadFolder(const Akonadi::Collection &, bool) const; bool allowedToEnterFolder(const Akonadi::Collection &, bool) const; - bool trySelectNextUnreadFolder(const QModelIndex &, MailCommon::Util::SearchDirection, bool); + bool trySelectNextUnreadFolder(const QModelIndex &, SearchDirection, bool); FolderTreeWidget::ToolTipDisplayPolicy mToolTipDisplayPolicy; FolderTreeWidget::SortingPolicy mSortingPolicy; diff --git a/src/util/mailutil.cpp b/src/util/mailutil.cpp index b32a2ff..5e1a3fe 100644 --- a/src/util/mailutil.cpp +++ b/src/util/mailutil.cpp @@ -171,112 +171,6 @@ uint MailCommon::Util::folderIdentity(const Akonadi::Item &item) return id; } -static QModelIndex indexBelow(QAbstractItemModel *model, const QModelIndex ¤t) -{ - // if we have children, return first child - if (model->rowCount(current) > 0) { - return model->index(0, 0, current); - } - - // if we have siblings, return next sibling - const QModelIndex parent = model->parent(current); - const QModelIndex sibling = model->index(current.row() + 1, 0, parent); - - if (sibling.isValid()) { // found valid sibling - return sibling; - } - - if (!parent.isValid()) { // our parent is the tree root and we have no siblings - return QModelIndex(); // we reached the bottom of the tree - } - - // We are the last child, the next index to check is our uncle, parent's first sibling - const QModelIndex parentsSibling = parent.sibling(parent.row() + 1, 0); - if (parentsSibling.isValid()) { - return parentsSibling; - } - - // iterate over our parents back to root until we find a parent with a valid sibling - QModelIndex currentParent = parent; - QModelIndex grandParent = model->parent(currentParent); - while (currentParent.isValid()) { - // check if the parent has children except from us - if (model->rowCount(grandParent) > currentParent.row() + 1) { - const QModelIndex index - = indexBelow(model, model->index(currentParent.row() + 1, 0, grandParent)); - if (index.isValid()) { - return index; - } - } - - currentParent = grandParent; - grandParent = model->parent(currentParent); - } - - return QModelIndex(); // nothing found -> end of tree -} - -static QModelIndex lastChildOfModel(QAbstractItemModel *model, const QModelIndex ¤t) -{ - if (model->rowCount(current) == 0) { - return current; - } - - return lastChildOfModel(model, model->index(model->rowCount(current) - 1, 0, current)); -} - -static QModelIndex indexAbove(QAbstractItemModel *model, const QModelIndex ¤t) -{ - const QModelIndex parent = model->parent(current); - - if (current.row() == 0) { - // we have no previous siblings -> our parent is the next item above us - return parent; - } - - // find previous sibling - const QModelIndex previousSibling = model->index(current.row() - 1, 0, parent); - - // the item above us is the last child (or grandchild, or grandgrandchild... etc) - // of our previous sibling - return lastChildOfModel(model, previousSibling); -} - -QModelIndex MailCommon::Util::nextUnreadCollection(QAbstractItemModel *model, const QModelIndex ¤t, SearchDirection direction, bool (*ignoreCollectionCallback)( - const Akonadi::Collection &collection)) -{ - QModelIndex index = current; - while (true) { - if (direction == MailCommon::Util::ForwardSearch) { - index = indexBelow(model, index); - } else if (direction == MailCommon::Util::BackwardSearch) { - index = indexAbove(model, index); - } - - if (!index.isValid()) { // reach end or top of the model - return QModelIndex(); - } - - // check if the index is a collection - const Akonadi::Collection collection - = index.data(Akonadi::EntityTreeModel::CollectionRole).value(); - - if (collection.isValid()) { - // check if it is unread - if (collection.statistics().unreadCount() > 0) { - if (ignoreCollectionCallback && ignoreCollectionCallback(collection)) { - continue; - } - if (!ignoreNewMailInFolder(collection)) { - return index; // we found the next unread collection - } - } - } - } - - return QModelIndex(); // no unread collection found -} - bool MailCommon::Util::ignoreNewMailInFolder(const Akonadi::Collection &collection) { if (collection.hasAttribute()) { diff --git a/src/util/mailutil.h b/src/util/mailutil.h index ff7325b..bf33cc9 100644 --- a/src/util/mailutil.h +++ b/src/util/mailutil.h @@ -79,14 +79,6 @@ MAILCOMMON_EXPORT Akonadi::AgentInstance::List agentInstances(bool excludeMailTr */ MAILCOMMON_EXPORT uint folderIdentity(const Akonadi::Item &item); -/** - * Describes the direction for searching next unread collection. - */ -enum SearchDirection { - ForwardSearch, - BackwardSearch -}; - MAILCOMMON_EXPORT Akonadi::Collection parentCollectionFromItem(const Akonadi::Item &item); MAILCOMMON_EXPORT QString realFolderPath(const QString &path); diff --git a/src/util/mailutil_p.h b/src/util/mailutil_p.h index 073af20..618d886 100644 --- a/src/util/mailutil_p.h +++ b/src/util/mailutil_p.h @@ -58,18 +58,9 @@ namespace MailCommon { * various places. */ namespace Util { -/** - * Returns the index of the next unread collection following a given index. - * - * @param model The item model to search in. - * @param current The index of the collection where the search will start. - * @param direction The direction of search. - * @param ignoreCollectionCallback A callback method to ignore certain - * collections by returning @c true. - */ -QModelIndex nextUnreadCollection(QAbstractItemModel *model, const QModelIndex ¤t, SearchDirection direction, bool (*ignoreCollectionCallback)(const Akonadi::Collection &collection) = 0); bool ignoreNewMailInFolder(const Akonadi::Collection &collection); + } }