From 59a196ea849c64c51311f56bf62130e74d90b784 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Wed, 26 Aug 2026 19:31:45 +0200 Subject: feat: open the unsynced-changes count to see what it counts Item 119, and item 146 which is the same request recorded again. The status bar's count answers "is my work safe to quit on" and could not say what the work was. The label opens a read-only list on a click. A QLabel has no clicked signal, so the press is taken by MainWindow's existing event filter rather than by replacing the label with a flat QToolButton, which would have brought the style's button metrics into a status bar the label already sits correctly in. The pointing-hand cursor is the affordance, since a status-bar label has room for nothing else. The layout is the user's own: a message appears once with its actions beneath it. PendingChangesDialog::rowsFor() does the grouping over a run of rows sharing an id, which the snapshot has already ordered, so the actions under one message keep the order they were made in. Read-only, deliberately. Retrying or discarding a change from here would be a new mutation path with its own undo question, and the count exists to be understood rather than edited. Three rules the tests pin, each of which is a way the list could disagree with the count it was opened from: - Grouping must not collapse: two actions on one message are two rows. - A thread row stays thread-scoped and reports how many messages it covered. - An id the index no longer holds still opens a run of its own, showing that its subject is unknown rather than folding its actions under the message above it. This is why the row carries startsMessage rather than inferring it from a non-empty subject. The queued call carrying QStringList, QList and QList is covered by a test that drives it across a real thread, since a container whose metatype does not resolve is dropped at runtime and the slot runs with a default. Both survive on Qt 6.11; the test is what says so, and what would fail if that changed. Italian ships with it: five new strings, lupdate clean, lrelease 522 finished and 0 unfinished. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01P88Q3MCSCSQxKDy7pmXh9F --- src/mainwindow.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/mainwindow.h') diff --git a/src/mainwindow.h b/src/mainwindow.h index 532a5ea..6321573 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -123,6 +123,13 @@ public: QVector pendingChangeSnapshot() const; + /// Opens the list behind the unsynced-changes count. + /// + /// Takes the snapshot, asks the worker to resolve its subjects, and shows + /// the dialog when they arrive. Q_INVOKABLE so a test can open it without + /// synthesising a click on a status-bar label. + Q_INVOKABLE void showPendingChanges(); + /// Whether the undo stack still holds anything. Exposed so a test can show /// that a rejected write did not take unrelated history down with it. bool canUndo() const { return m_undoStack.canUndo(); } @@ -618,6 +625,10 @@ private slots: /// 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); + + /// The subjects for the pending-changes list arrived; show the dialog. + void onPendingSubjectsResolved(const QStringList &subjects, + const QList &messageCounts); void onAllTagsReady(const QStringList &tags); /// The Maildir root, answered once at startup. Enables nothing on its own: @@ -1575,6 +1586,13 @@ private: }; QHash m_pendingTagEdits; + /// The snapshot taken when the user clicked the indicator, held while the + /// worker resolves its subjects. Empty when no such request is in flight. + /// + /// One request at a time: a second click before the first answers replaces + /// it, which is right because both would show the same thing. + QVector m_pendingChangeRequest; + /// Marks the open thread read once it has been on screen long enough. /// /// Single-shot and RESTARTED on every selection change, never stacked: -- cgit v1.2.3