aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/keymap.cpp13
-rw-r--r--src/mainwindow.cpp33
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