summaryrefslogtreecommitdiffstats
path: root/src/mainwindow.h
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-04 18:57:20 +0200
committerDanilo M. <danix@danix.xyz>2026-08-04 18:57:20 +0200
commit0b3869c758f4dc54017ff91b5b69bfc263c0da52 (patch)
treea202a583a6f794c743cc838b33da2d1a79cfc07b /src/mainwindow.h
parent1407f70352c05d59fa2e1bb7c59b048b767972e5 (diff)
parentce0753bcb6263dec5a6acb53647ca7b64950f8fd (diff)
downloadqtmaildir-0b3869c758f4dc54017ff91b5b69bfc263c0da52.tar.gz
qtmaildir-0b3869c758f4dc54017ff91b5b69bfc263c0da52.zip
Merge branch 'multiselect-discoverability'
Multi-select discoverability (items 24, 25) and awareness of syncs this window did not start (item 27). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/mainwindow.h')
-rw-r--r--src/mainwindow.h40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/mainwindow.h b/src/mainwindow.h
index d1f7b1c..66044dc 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -28,11 +28,13 @@
#include "config.h"
#include "keymap.h"
+#include "syncmonitor.h"
#include "tagcolors.h"
#include "types.h"
class QAction;
class QLineEdit;
+class QMenu;
class QTableView;
class QLabel;
class QPushButton;
@@ -60,6 +62,12 @@ public:
/// really registered.
QStringList registeredActionNames() const;
+ /// The thread currently shown in the message pane, empty when it is blank.
+ ///
+ /// Empty is what "the pane is blanked" means internally: a late-arriving
+ /// load is discarded rather than painted, so no thread can reappear.
+ QString currentThreadId() const { return m_currentThreadId; }
+
/// The cid: namespace prefix for the nth message of a thread.
///
/// MainWindow is the only producer of this value in the application. It
@@ -95,10 +103,24 @@ private slots:
void onThreadsReady(const QVector<ThreadSummary> &threads, quint64 generation);
void onQueryFinished(int total, quint64 generation);
void onThreadSelected(const QModelIndex &current, const QModelIndex &previous);
+
+ /// Keeps the status bar's selection count and the multi-select guard in
+ /// step with selections that never move the current index.
+ void onSelectionChanged();
+
+ /// Pops up the thread-list context menu, preserving a multi-row selection
+ /// the click lands inside.
+ void showThreadContextMenu(const QPoint &pos);
void onThreadLoaded(const QVector<MessageRef> &messages, quint64 generation);
void onWorkerError(const QString &message);
void onSyncFinished(bool success, int exitCode);
+ /// Reacts to a sync started outside this window, by cron or by hand.
+ ///
+ /// A private slot rather than a plain method so tests can drive it through
+ /// the meta-object without widening the public API.
+ void onExternalSyncStateChanged(SyncMonitor::State state);
+
/// A tag mutation the worker has confirmed reached the database. Counts it
/// as unsynced, since reaching the index is not reaching the mail store.
void onTagsApplied(const TagChange &change);
@@ -153,6 +175,7 @@ private:
/// says "working, duration unknown", which is the truth.
void setSyncBusy(bool busy);
+
/// Opens the tag dialog on the current selection and applies its result.
///
/// The only route to an arbitrary tag: every other tag action writes a
@@ -191,11 +214,24 @@ private:
ThreadListModel *m_model = nullptr;
MessageView *m_messageView = nullptr;
MailSync *m_sync = nullptr;
+
+ /// Watches the sync lock for runs this window did not start.
+ SyncMonitor *m_syncMonitor = nullptr;
+
+ /// True while the lock the monitor can see is held by this window's own
+ /// sync. Latched when the lock is taken, because by the time it is released
+ /// MailSync::isRunning() is already false and can no longer answer "was
+ /// that ours?".
+ bool m_localSyncHoldsLock = false;
QUndoStack m_undoStack;
QLineEdit *m_queryEdit = nullptr;
QueryCompleter *m_queryCompleter = nullptr;
QTableView *m_threadView = nullptr;
+
+ /// Right-click menu for the thread list, holding the same QActions the
+ /// menu bar does.
+ QMenu *m_threadContextMenu = nullptr;
QSplitter *m_splitter = nullptr;
QComboBox *m_accountBox = nullptr;
QPushButton *m_syncButton = nullptr;
@@ -230,6 +266,10 @@ private:
QString m_lastQuery;
QString m_currentThreadId;
+ /// The selection count last written to the status bar, so it can be taken
+ /// back without clobbering a message some other action put there.
+ QString m_selectionMessage;
+
/// Confirmed tag mutations not yet known to have reached the mail store.
///
/// A count of its own rather than QUndoStack::isClean(), which cannot serve