[kde-doc-english] [trojita] src: GUI: remember expanded/collapsed mailboxes

Jan Kundrát jkt at kde.org
Fri Jun 10 13:06:50 UTC 2016


Git commit 6fd4529e23f127308a3e178b1c3089aba9dcabdf by Jan Kundrát.
Committed on 03/06/2016 at 17:33.
Pushed by gerrit into branch 'master'.

GUI: remember expanded/collapsed mailboxes

The code now remembers the expanded/collapsed state of the mailbox tree
view, and will restore them upon network reconnect and/or application
restart.

Change-Id: I08e2eb397f1f286962eb0fda7fd47c607b9ffd27

M  +1    -0    src/Common/SettingsNames.cpp
M  +1    -0    src/Common/SettingsNames.h
M  +60   -2    src/Gui/MailBoxTreeView.cpp
M  +22   -3    src/Gui/MailBoxTreeView.h
M  +4    -0    src/Gui/Window.cpp
M  +3    -3    src/Imap/Model/MailboxFinder.cpp
M  +2    -2    src/Imap/Model/MailboxFinder.h

http://commits.kde.org/trojita/6fd4529e23f127308a3e178b1c3089aba9dcabdf

diff --git a/src/Common/SettingsNames.cpp b/src/Common/SettingsNames.cpp
index e07ad61..de4117d 100644
--- a/src/Common/SettingsNames.cpp
+++ b/src/Common/SettingsNames.cpp
@@ -98,6 +98,7 @@ const QString SettingsNames::guiSizesInMainWinWhenCompact = QStringLiteral("gui/
 const QString SettingsNames::guiSizesInMainWinWhenWide = QStringLiteral("gui/sizeInMainWinWhenWide-%1");
 const QString SettingsNames::guiSizesInaMainWinWhenOneAtATime = QStringLiteral("gui/sizeInMainWinWhenOneAtATime-%1");
 const QString SettingsNames::guiAllowRawSearch = QStringLiteral("gui/allowRawSearch");
+const QString SettingsNames::guiExpandedMailboxes = QStringLiteral("gui/expandedMailboxes");
 const QString SettingsNames::appLoadHomepage = QStringLiteral("app.updates.checkEnabled");
 const QString SettingsNames::knownEmailsKey = QStringLiteral("addressBook/knownEmails");
 const QString SettingsNames::addressbookPlugin = QStringLiteral("plugin/addressbook");
diff --git a/src/Common/SettingsNames.h b/src/Common/SettingsNames.h
index 0402cfa..45c3d9d 100644
--- a/src/Common/SettingsNames.h
+++ b/src/Common/SettingsNames.h
@@ -49,6 +49,7 @@ struct SettingsNames {
     static const QString guiMainWindowLayout, guiMainWindowLayoutCompact, guiMainWindowLayoutWide, guiMainWindowLayoutOneAtTime;
     static const QString guiSizesInMainWinWhenCompact, guiSizesInMainWinWhenWide, guiSizesInaMainWinWhenOneAtATime;
     static const QString guiAllowRawSearch;
+    static const QString guiExpandedMailboxes;
     static const QString appLoadHomepage;
     static const QString guiShowSystray, guiOnSystrayClose, guiStartMinimized;
     static const QString knownEmailsKey;
diff --git a/src/Gui/MailBoxTreeView.cpp b/src/Gui/MailBoxTreeView.cpp
index 3d9565c..8cec5cc 100644
--- a/src/Gui/MailBoxTreeView.cpp
+++ b/src/Gui/MailBoxTreeView.cpp
@@ -1,4 +1,5 @@
 /* Copyright (C) 2012 Thomas Gahr <thomas.gahr at physik.uni-muenchen.de>
+   Copyright (C) 2006 - 2016 Jan Kundrát <jkt at kde.org>
 
    This file is part of the Trojita Qt IMAP e-mail client,
    http://trojita.flaska.net/
@@ -20,17 +21,19 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "MailBoxTreeView.h"
-
 #include <QDragMoveEvent>
 #include <QDropEvent>
 #include <QMenu>
+#include "Gui/MailBoxTreeView.h"
+#include "Imap/Model/ItemRoles.h"
+#include "Imap/Model/MailboxFinder.h"
 #include "UiUtils/IconLoader.h"
 
 namespace Gui {
 
 MailBoxTreeView::MailBoxTreeView(QWidget *parent)
     : QTreeView(parent)
+    , m_mailboxFinder(nullptr)
 {
     setUniformRowHeights(true);
     setContextMenuPolicy(Qt::CustomContextMenu);
@@ -41,6 +44,40 @@ MailBoxTreeView::MailBoxTreeView(QWidget *parent)
     setHeaderHidden(true);
     // I wonder what's the best value to use here. Unfortunately, the default is to disable auto expanding.
     setAutoExpandDelay(800);
+
+    // Track expansion/collapsing so that we remember this state despite the asynchronous nature of mailbox loading
+    connect(this, &QTreeView::expanded, this, [this](const QModelIndex &what) {
+        auto name = what.data(Imap::Mailbox::RoleMailboxName).toString();
+        if (!m_desiredExpansionState.contains(name)) {
+            m_desiredExpansionState.insert(name);
+            emit mailboxExpansionChanged(m_desiredExpansionState.toList());
+        }
+    });
+    connect(this, &QTreeView::collapsed, this, [this](const QModelIndex &what) {
+        auto name = what.data(Imap::Mailbox::RoleMailboxName).toString();
+        if (m_desiredExpansionState.remove(name)) {
+            emit mailboxExpansionChanged(m_desiredExpansionState.toList());
+        }
+    });
+}
+
+/** \reimp
+
+The MailboxFinder has to be kept up-to-speed about these changes.
+*/
+void MailBoxTreeView::setModel(QAbstractItemModel *model)
+{
+    delete m_mailboxFinder;
+    m_mailboxFinder = new Imap::Mailbox::MailboxFinder(this, model);
+    connect(m_mailboxFinder, &Imap::Mailbox::MailboxFinder::mailboxFound,
+            this, [this](const QString &, const QModelIndex &index) {
+        expand(index);
+    });
+    connect(model, &QAbstractItemModel::layoutChanged, this, &MailBoxTreeView::resetWatchedMailboxes);
+    connect(model, &QAbstractItemModel::rowsRemoved, this, &MailBoxTreeView::resetWatchedMailboxes);
+    connect(model, &QAbstractItemModel::modelReset, this, &MailBoxTreeView::resetWatchedMailboxes);
+    QTreeView::setModel(model);
+    resetWatchedMailboxes();
 }
 
 /** @short Reimplemented for more consistent handling of modifiers
@@ -95,4 +132,25 @@ void MailBoxTreeView::dropEvent(QDropEvent *event)
     QTreeView::dropEvent(event);
 }
 
+/** @short Specify which mailboxes should be expanded
+
+The mailboxes might appear and disappear at any time, so let's make sure that
+they are properly expanded/collapsed once they pop in.
+*/
+void MailBoxTreeView::setDesiredExpansion(const QStringList &mailboxNames)
+{
+    m_desiredExpansionState = mailboxNames.toSet();
+    resetWatchedMailboxes();
+}
+
+/** @short Ensure that we watch stuff that we need to watch */
+void MailBoxTreeView::resetWatchedMailboxes()
+{
+    if (m_mailboxFinder) {
+        for (const auto &mailbox: m_desiredExpansionState) {
+            m_mailboxFinder->addMailbox(mailbox);
+        }
+    }
+}
+
 }
diff --git a/src/Gui/MailBoxTreeView.h b/src/Gui/MailBoxTreeView.h
index ddff392..7bbe8a2 100644
--- a/src/Gui/MailBoxTreeView.h
+++ b/src/Gui/MailBoxTreeView.h
@@ -1,4 +1,5 @@
 /* Copyright (C) 2012 Thomas Gahr <thomas.gahr at physik.uni-muenchen.de>
+   Copyright (C) 2006 - 2016 Jan Kundrát <jkt at kde.org>
 
    This file is part of the Trojita Qt IMAP e-mail client,
    http://trojita.flaska.net/
@@ -25,18 +26,36 @@
 
 #include <QTreeView>
 
-namespace Gui{
+namespace Imap {
+namespace Mailbox {
+class MailboxFinder;
+}
+}
 
-/** @short Subclassed for more consistent and intuitive handling of Drag&Drop
-*/
+namespace Gui {
+
+/** @short Show mailboxes in a tree view */
 class MailBoxTreeView : public QTreeView
 {
     Q_OBJECT
 public:
     explicit MailBoxTreeView(QWidget *parent = nullptr);
+    void setDesiredExpansion(const QStringList &mailboxNames);
+    void setModel(QAbstractItemModel *model) override;
+signals:
+    /** @short User has changed their mind about the expanded/collapsed state of the mailbox tree
+
+    Stuff which gets reported here might refer to mailboxes which do not even exist. At the same time,
+    the code will not forget about those mailboxes which "aren't there yet".
+    */
+    void mailboxExpansionChanged(const QStringList &mailboxNames);
 protected:
     void dragMoveEvent(QDragMoveEvent *event) override;
     void dropEvent(QDropEvent *event) override;
+    void resetWatchedMailboxes();
+private:
+    Imap::Mailbox::MailboxFinder *m_mailboxFinder;
+    QSet<QString> m_desiredExpansionState;
 };
 }
 
diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp
index 0845a7e..18390ba 100644
--- a/src/Gui/Window.cpp
+++ b/src/Gui/Window.cpp
@@ -718,7 +718,11 @@ void MainWindow::createWidgets()
     connect(m_delayedStateSaving, &QTimer::timeout, this, &MainWindow::saveSizesAndState);
 
     mboxTree = new MailBoxTreeView();
+    mboxTree->setDesiredExpansion(m_settings->value(Common::SettingsNames::guiExpandedMailboxes).toStringList());
     connect(mboxTree, &QWidget::customContextMenuRequested, this, &MainWindow::showContextMenuMboxTree);
+    connect(mboxTree, &MailBoxTreeView::mailboxExpansionChanged, this, [this](const QStringList &mailboxNames) {
+        m_settings->setValue(Common::SettingsNames::guiExpandedMailboxes, mailboxNames);
+    });
 
     msgListWidget = new MessageListWidget();
     msgListWidget->tree->setContextMenuPolicy(Qt::CustomContextMenu);
diff --git a/src/Imap/Model/MailboxFinder.cpp b/src/Imap/Model/MailboxFinder.cpp
index aa7844b..c6a627c 100644
--- a/src/Imap/Model/MailboxFinder.cpp
+++ b/src/Imap/Model/MailboxFinder.cpp
@@ -49,13 +49,13 @@ MailboxFinder::MailboxFinder(QObject *parent, QAbstractItemModel *model)
 
 void MailboxFinder::addMailbox(const QString &mailbox)
 {
-    m_watchedNames.append(mailbox);
+    m_pending.insert(mailbox);
     EMIT_LATER_NOARG(this, checkArrivals);
 }
 
 void MailboxFinder::checkArrivals()
 {
-    Q_FOREACH(const QString &mailbox, m_watchedNames) {
+    Q_FOREACH(const QString &mailbox, m_pending) {
         QModelIndex root;
         bool cont = false;
 
@@ -77,7 +77,7 @@ void MailboxFinder::checkArrivals()
 
                 if (possibleName == mailbox) {
                     // found it
-                    m_watchedNames.removeAll(mailbox);
+                    m_pending.remove(mailbox);
                     emit mailboxFound(mailbox, index);
                     break;
                 } else if (mailbox.startsWith(possibleName + separator)) {
diff --git a/src/Imap/Model/MailboxFinder.h b/src/Imap/Model/MailboxFinder.h
index ebe66b6..d6d8104 100644
--- a/src/Imap/Model/MailboxFinder.h
+++ b/src/Imap/Model/MailboxFinder.h
@@ -31,7 +31,7 @@
 #define TROJITA_IMAP_MAILBOXFINDER_H
 
 #include <QModelIndex>
-#include <QStringList>
+#include <QSet>
 
 namespace Imap {
 
@@ -74,7 +74,7 @@ private slots:
 
 private:
     QAbstractItemModel *m_model;
-    QStringList m_watchedNames;
+    QSet<QString> m_pending;
 };
 
 }



More information about the kde-doc-english mailing list