Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit ddcc7543 authored by Daniel Vrátil's avatar Daniel Vrátil 🤖

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.
parent e7f925c2
......@@ -33,7 +33,8 @@
#include <QHeaderView>
#include <QMouseEvent>
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 &current, MailCommon::Util::SearchDirection direction, bool confirm)
bool FolderTreeView::trySelectNextUnreadFolder(const QModelIndex &current, 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 &current) 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 &current) const
{
if (model()->rowCount(current) == 0) {
return current;
}
return lastChild(model()->index(model()->rowCount(current) - 1, 0, current));
}
QModelIndex FolderTreeView::indexAbove(const QModelIndex &current) 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 &current, 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<Akonadi::Collection>();
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
}
......@@ -104,9 +104,19 @@ Q_SIGNALS:
void newTabRequested(bool);
private:
enum SearchDirection {
ForwardSearch,
BackwardSearch
};
QModelIndex indexAbove(const QModelIndex &current) const;
QModelIndex indexBelow(const QModelIndex &current) const;
QModelIndex lastChild(const QModelIndex &current) const;
QModelIndex nextUnreadCollection(const QModelIndex &current, 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;
......
......@@ -171,112 +171,6 @@ uint MailCommon::Util::folderIdentity(const Akonadi::Item &item)
return id;
}
static QModelIndex indexBelow(QAbstractItemModel *model, const QModelIndex &current)
{
// 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 &current)
{
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 &current)
{
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 &current, 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<Akonadi::Collection>();
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<Akonadi::NewMailNotifierAttribute>()) {
......
......@@ -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);
......
......@@ -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 &current, SearchDirection direction, bool (*ignoreCollectionCallback)(const Akonadi::Collection &collection) = 0);
bool ignoreNewMailInFolder(const Akonadi::Collection &collection);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment