diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-13 19:40:27 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-13 19:40:27 +0200 |
| commit | 8268bb478dbdf9f23b35c5114c5d13bc98254659 (patch) | |
| tree | 5a827e34a164aac02b5f9f221e6c9d750286c2c1 | |
| parent | 59f5161500ef670421cbba9665bd4aadbbb9ad30 (diff) | |
| download | qtmaildir-8268bb478dbdf9f23b35c5114c5d13bc98254659.tar.gz qtmaildir-8268bb478dbdf9f23b35c5114c5d13bc98254659.zip | |
fix(queries): give Save query a clearer icon and a label
document-save is the floppy/disk shape. It means "write a file somewhere",
which leaves the user to guess what is being written, and next to a row of
saved-query buttons it reads as an unrelated control. Saving a query is
bookmarking a search, so bookmark-new is the icon every desktop already uses
for "keep this for later". Verified to resolve with real art in the desktop's
actual theme rather than assumed present.
The button also shows its label now instead of the icon alone. It sits among
text buttons, and an icon on its own next to them reads as a different kind of
control; it is also the one action whose meaning an icon cannot carry, since
"save" is a familiar shape whose question is always "save what?". The toolbar
is unaffected and still follows the desktop's own button style.
The label is the button's own text rather than the action's. "&Save query..."
is menu phrasing, and setDefaultAction copies it verbatim, so the button
rendered an accelerator ampersand and the ellipsis that promises a dialog. The
action keeps both for the menu it lives in, and the test asserts the override
survives setDefaultAction rather than trusting that it does.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| -rw-r--r-- | src/mainwindow.cpp | 19 | ||||
| -rw-r--r-- | tests/test_mainwindow.cpp | 18 |
2 files changed, 35 insertions, 2 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 61c883e..f06b308 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -353,7 +353,18 @@ MainWindow::MainWindow(const Config &config, QWidget *parent) // action's text, icon, tooltip and ENABLED state, so it cannot end up // offering to save an empty query while the menu entry refuses. m_saveQueryButton->setDefaultAction(save); - m_saveQueryButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + // Icon AND text, unlike the toolbar, which follows the desktop's + // button style. This button sits in a row of text buttons, the saved + // queries, and an icon on its own next to them reads as a different + // kind of control than it is. It is also the one action whose meaning + // an icon alone does not carry: "save" is a shape everyone knows and + // the question is always "save WHAT". + m_saveQueryButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + // Its own text, not the action's: "&Save query..." is menu phrasing, + // and a button rendering the ampersand's accelerator and the ellipsis + // that promises a dialog reads as a menu entry that escaped. The + // action keeps both for the menu it lives in. + m_saveQueryButton->setText(tr("Save")); auto updateSaveState = [this, save]() { save->setEnabled(!m_queryEdit->text().trimmed().isEmpty()); @@ -1066,7 +1077,11 @@ void MainWindow::buildMenus() // the selection's tags. { QStringLiteral("tag_rules"), QStringLiteral("configure") }, { QStringLiteral("complete_query"), QStringLiteral("edit-find-replace") }, - { QStringLiteral("save_query"), QStringLiteral("document-save") }, + // NOT "document-save": that is the floppy/disk shape, which reads as + // "write a file somewhere" and asks the user to guess what is being + // written. Saving a query is bookmarking a search, and bookmark-new is + // the icon set every desktop already uses for "keep this for later". + { QStringLiteral("save_query"), QStringLiteral("bookmark-new") }, { QStringLiteral("select_all"), QStringLiteral("edit-select-all") }, { QStringLiteral("clear_pane"), QStringLiteral("edit-clear") }, { QStringLiteral("clear_selection"), QStringLiteral("edit-clear-all") }, diff --git a/tests/test_mainwindow.cpp b/tests/test_mainwindow.cpp index 080e4cd..42d7d78 100644 --- a/tests/test_mainwindow.cpp +++ b/tests/test_mainwindow.cpp @@ -52,6 +52,7 @@ #include <QImage> #include <QPainter> +#include <QToolButton> #include <QHBoxLayout> #include <QComboBox> #include <QScrollBar> @@ -5560,6 +5561,23 @@ void TestMainWindow::thereIsASaveButtonBesideTheQueryBar() window.findChild<QAbstractButton *>(QStringLiteral("saveQueryButton")); QVERIFY2(button, "no Save query button beside the query bar"); + // Icon AND text. An icon alone was the first version and read as + // ambiguous: "save" is a familiar shape whose meaning is always "save + // what?". + auto *toolButton = qobject_cast<QToolButton *>(button); + QVERIFY(toolButton); + QCOMPARE(toolButton->toolButtonStyle(), Qt::ToolButtonTextBesideIcon); + QVERIFY2(!button->icon().isNull(), "the button has no icon"); + QVERIFY2(!button->text().isEmpty(), "the button has no text"); + + // Button phrasing, not the menu's: no accelerator ampersand, and no + // ellipsis. setDefaultAction copies the action's text, so this asserts the + // override survived it. + QVERIFY2(!button->text().contains(QLatin1Char('&')), + "the menu accelerator leaked onto the button"); + QVERIFY2(!button->text().contains(QStringLiteral("...")), + "the menu's ellipsis leaked onto the button"); + auto *queryEdit = window.findChild<QLineEdit *>(QStringLiteral("queryEdit")); QVERIFY(queryEdit); |
