diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-15 11:46:58 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-15 11:46:58 +0200 |
| commit | d4e4cebbefdce5f575954594461dc707492b2dd8 (patch) | |
| tree | b71ae3b6f66bf661b60dfc565eb9949f5f778f95 /src/mainwindow.cpp | |
| parent | aecb22de0c6644380ea3b1e909c864fd24501dc7 (diff) | |
| download | qtmaildir-d4e4cebbefdce5f575954594461dc707492b2dd8.tar.gz qtmaildir-d4e4cebbefdce5f575954594461dc707492b2dd8.zip | |
feat(startup): add startup_account, the account the dropdown opens on
Answers "start me in work - Inbox rather than All accounts - Inbox". The key
names an account by its [account.<key>] suffix and the dropdown is set to it
before the startup query runs; because a built-in filter composes with the
dropdown, that is the whole mechanism and the key never reaches a query
builder. Validated on load: a name matching no account is reported and cleared,
since the dropdown has no entry for it and would sit on All accounts without
saying why.
Which side applies the scope depends on what the startup entry is, and getting
it wrong is silent in both directions. A generated filter comes back from
resolvedQuery() already scoped, so letting runQuery() apply the dropdown again
gives path:"work/**" and (path:"work/**" and (tag:inbox)). A saved query does
not, because resolvedQuery() ignores the account key for one, so claiming it
was already scoped leaves it unscoped with the dropdown pointing at Work.
The first of those shipped in this session's working tree and passed its test,
because the assertion used contains() and the double-scoped string contains the
scope too. It asserts the exact query now. The second was found by writing the
test for the case rather than by reading, and is covered by
aStartupAccountAlsoScopesASavedStartupQuery.
The README's startup_query documentation was wrong on two counts after the
previous commit: the fallback is the Unread filter rather than the first query
in the file, and the name can now match a built-in filter.
Diffstat (limited to 'src/mainwindow.cpp')
| -rw-r--r-- | src/mainwindow.cpp | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3ebcbc4..3d7add2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -404,19 +404,46 @@ MainWindow::MainWindow(const Config &config, QWidget *parent) // Not savedQueries().first(): [queries] is read through childKeys(), which // sorts alphabetically, so "first" means whatever happens to sort first // rather than anything the user chose. Config resolves the name. + // BEFORE the startup query runs, so the query below is composed in this + // scope. That is the whole of `startup_account`: a built-in filter composes + // with the dropdown, so setting the dropdown is all that is needed and the + // key never reaches a query builder. + // + // Config has already checked the key names a real account and cleared it if + // not, so findData either matches or this is "All accounts" anyway. + const QString startupAccount = m_config.startupAccount(); + if (!startupAccount.isEmpty()) { + const int index = m_accountBox->findData(startupAccount); + if (index >= 0) + m_accountBox->setCurrentIndex(index); + } + // resolvedQuery(), not startup.query: a generated entry stores no query at // all, since its text is composed from the accounts at run time. Reading // the field directly meant a startup_query naming a built-in filter opened // an empty bar and ran nothing. - // - // No account scope here. The dropdown starts on "All accounts", which is - // the empty key, so this is the unscoped form either way; passing the - // selection would be reading a widget the user has not touched yet. const SavedQuery startup = m_config.startupSavedQuery(); - const QString startupQuery = m_config.resolvedQuery(startup, QString()); + const QString startupQuery = + m_config.resolvedQuery(startup, startupAccount); if (!startupQuery.isEmpty()) { m_queryEdit->setText(startupQuery); - runCurrentQuery(); + + // Which of the two applies the scope depends on what the startup entry + // IS, and getting this wrong is silent in both directions. + // + // A generated filter came back from resolvedQuery() already scoped to + // the startup account, so applying the dropdown again gives + // path:"work/**" and (path:"work/**" and (tag:inbox)) + // which returns exactly the right rows while being the double scope + // this item exists to avoid. + // + // A saved query did NOT: resolvedQuery() ignores the account key for + // one, because a saved query states its own scope. Claiming it was + // already scoped leaves it unscoped for good, with the dropdown sitting + // on Work and the list showing every account. + runQuery(FlatResult::No, + startup.isGenerated() ? AccountScope::AlreadyScoped + : AccountScope::Apply); } } |
