diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/keymap.cpp | 13 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 33 |
2 files changed, 45 insertions, 1 deletions
diff --git a/src/keymap.cpp b/src/keymap.cpp index a16a700..29a5f71 100644 --- a/src/keymap.cpp +++ b/src/keymap.cpp @@ -38,6 +38,7 @@ QStringList KeyMap::knownActions() QStringLiteral("complete_query"), QStringLiteral("select_all"), QStringLiteral("clear_pane"), + QStringLiteral("clear_selection"), QStringLiteral("toggle_html"), QStringLiteral("load_remote"), QStringLiteral("message_details"), @@ -85,7 +86,17 @@ QList<QPair<QString, QString>> KeyMap::defaultBindings() // Escape is not claimed by anything else at window level. The query // completer handles its own Escape while its popup is up, and a popup // consumes the key before a window shortcut sees it. - { QStringLiteral("Esc"), QStringLiteral("clear_pane") }, + // + // It clears the SELECTION as well as the pane (item 50). Deselecting is + // what Escape means nearly everywhere else, and blanking a pane while + // leaving the row highlighted reads as half an action. + // + // clear_pane keeps the narrower behaviour on Shift+Esc: same key, and + // the modifier reads as "less than the plain one". It needs SOME + // default rather than being left unbound, since every action carries + // one and everyActionHasAShortcut enforces exactly that. + { QStringLiteral("Esc"), QStringLiteral("clear_selection") }, + { QStringLiteral("Shift+Esc"), QStringLiteral("clear_pane") }, { QStringLiteral("Ctrl+H"), QStringLiteral("toggle_html") }, { QStringLiteral("Ctrl+M"), QStringLiteral("load_remote") }, // Shifted because Ctrl+D is delete. Both are "D for details/delete" diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5af6624..3f8a53d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -787,6 +787,39 @@ void MainWindow::registerActions() m_markReadTimer->stop(); m_markReadThreadId.clear(); }); + addAction(QStringLiteral("clear_selection"), tr("Clear &selection"), + tr("Blank the message pane and deselect every thread"), + [this]() { + // Item 50, and the user's wording was "two actions instead of one": + // clear_pane above still blanks without touching the selection, this + // one does both. Esc defaults here, since deselecting is what Esc means + // nearly everywhere else. + // + // BOTH LINES BELOW ARE LOAD-BEARING, AND SO IS THEIR PLACE ABOVE THE + // BLANKING. clearSelection() leaves currentIndex() VALID, and + // onSelectionChanged() then takes its "one or fewer rows" branch, finds + // a current row whose id differs from m_currentThreadId, and calls + // onThreadSelected for it: the thread is re-adopted and a loadThread + // sent for the row that was just being cleared. + // + // Clearing the selection FIRST means that runs while m_currentThreadId + // still names the displayed thread, so the ids match and nothing is + // reloaded; setCurrentIndex() then stops any later collapse-to-one-row + // reaching the same row again. + // + // All four arrangements were tried against + // clearSelectionBlanksThePaneAndDeselects, and only this one passes: + // dropping setCurrentIndex() fails, and moving either line after the + // blanking fails. + m_threadView->clearSelection(); + m_threadView->setCurrentIndex(QModelIndex()); + + m_currentThreadId.clear(); + m_messageView->clear(); + showPlaceholderPane(); + m_markReadTimer->stop(); + m_markReadThreadId.clear(); + }); addAction(QStringLiteral("select_all"), tr("Select &all threads"), tr("Select every thread in the current result list"), [this]() { // A registered action rather than the view's built-in SelectAll key, so |
