summaryrefslogtreecommitdiffstats
path: root/tests/test_keymap.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-03 14:17:09 +0200
committerDanilo M. <danix@danix.xyz>2026-08-04 12:53:19 +0200
commitd7b87856340eefad1fed7d2f246fa49cdcf63d93 (patch)
treeb809a3221d32e0276a3156ac2a2a45ea7f73b825 /tests/test_keymap.cpp
parent8708139212e4f411509e0c11ed9c04de5cf33a22 (diff)
downloadqtmaildir-d7b87856340eefad1fed7d2f246fa49cdcf63d93.tar.gz
qtmaildir-d7b87856340eefad1fed7d2f246fa49cdcf63d93.zip
feat: add menus, a toolbar and a shortcut reference
Actions were a QHash of std::function dispatched by an event filter, which nothing could put in a menu. They are QActions now, bound from KeyMap so a [keys] override reaches the menus as well as the keyboard. Menu bar covers every action; the toolbar carries only Sync, Archive, Delete and Undo. Help > Keyboard shortcuts is generated from the actions, so it shows what the keys really do rather than a copy that drifts. spam and load_remote gained defaults, having been unreachable without a hand-written binding. The event filter is gone. Probing showed QAction shortcuts are dispatched before the focused widget sees the key, so they beat QAbstractItemView's type-to-search without one, and Qt already suppresses plain-letter shortcuts while an editable widget has focus. Dropping the filter's blanket guard also lets Ctrl+Q work while the query bar has focus. registeredActionNames() is derived from the actions rather than hand-maintained, so the two drift tests it needed are replaced by checks that a configured binding reaches its action. No confirmation dialogs: tag mutations still answer to undo.
Diffstat (limited to 'tests/test_keymap.cpp')
-rw-r--r--tests/test_keymap.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/tests/test_keymap.cpp b/tests/test_keymap.cpp
index e63c151..c81eeb0 100644
--- a/tests/test_keymap.cpp
+++ b/tests/test_keymap.cpp
@@ -33,6 +33,7 @@ private slots:
void invalidSequenceIsReported();
void collidingOverridesAreReported();
void bareCapitalMatchesShiftedPress();
+ void userBindingWinsOverDefaultInMenus();
void defaultsDoNotCollide();
void everyDefaultIsAKnownAction();
};
@@ -100,6 +101,38 @@ void TestKeyMap::bareCapitalMatchesShiftedPress()
QVERIFY(caseMap.warnings().isEmpty());
}
+void TestKeyMap::userBindingWinsOverDefaultInMenus()
+{
+ // loadOverrides() adds a binding without removing the default, so two
+ // sequences reach 'archive'. sequenceFor() is what the menus and the
+ // shortcut reference display: it must show the user's, not the built-in
+ // one they were trying to replace.
+ QTemporaryDir dir;
+ const QString path = dir.filePath(QStringLiteral("t.conf"));
+ {
+ QSettings s(path, QSettings::IniFormat);
+ s.beginGroup(QStringLiteral("keys"));
+ s.setValue(QStringLiteral("Ctrl+Alt+A"), QStringLiteral("archive"));
+ s.endGroup();
+ }
+
+ KeyMap map;
+ map.loadDefaults();
+ QSettings s(path, QSettings::IniFormat);
+ map.loadOverrides(s);
+
+ QCOMPARE(map.sequenceFor(QStringLiteral("archive")),
+ QKeySequence(QStringLiteral("Ctrl+Alt+A")));
+
+ // The default still fires; it is only no longer the advertised one.
+ QCOMPARE(map.actionFor(KeyMap::defaultSequenceFor(QStringLiteral("archive"))),
+ QStringLiteral("archive"));
+
+ // An action the user left alone still shows its default.
+ QCOMPARE(map.sequenceFor(QStringLiteral("delete")),
+ KeyMap::defaultSequenceFor(QStringLiteral("delete")));
+}
+
void TestKeyMap::defaultsDoNotCollide()
{
// Two defaults on one sequence means one of them is unreachable, and the