diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mainwindow.cpp | 23 | ||||
| -rw-r--r-- | src/mainwindow.h | 10 | ||||
| -rw-r--r-- | src/messagedetailsdialog.cpp | 15 | ||||
| -rw-r--r-- | src/messagedetailsdialog.h | 10 | ||||
| -rw-r--r-- | src/messageview.cpp | 14 | ||||
| -rw-r--r-- | src/messageview.h | 9 |
6 files changed, 56 insertions, 25 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 115646e..e82e61d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1651,13 +1651,30 @@ void MainWindow::onPlaceholderQueryRequested(const QString &query) runCurrentQuery(); } -void MainWindow::runSearchFromPane(const QString &query, bool extend) +void MainWindow::runSearchFromPane(const QString &query, + SearchTerm::SearchMode mode) { if (query.isEmpty()) return; - const QString next = - extend ? SearchTerm::extend(m_queryEdit->text(), query) : query; + QString next; + switch (mode) { + case SearchTerm::SearchMode::Replace: + next = query; + break; + case SearchTerm::SearchMode::Narrow: + next = SearchTerm::extend(m_queryEdit->text(), query); + break; + case SearchTerm::SearchMode::Exclude: + next = SearchTerm::exclude(m_queryEdit->text(), query); + break; + } + + // exclude() returns empty when there is nothing to exclude from, which the + // greyed menu entry should already have prevented. Running it would clear + // the query bar and show the whole Maildir, so refuse instead. + if (next.isEmpty()) + return; // Through the query bar and the existing runner, so the account scope, the // generation counter and the flat-mode reset all behave exactly as they do diff --git a/src/mainwindow.h b/src/mainwindow.h index f54a889..b41f75d 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -34,6 +34,7 @@ // Included rather than forward-declared: SyncPhaseTracker is held by value, so // its size must be known here. MailSync itself stays a forward declaration. #include "mailsync.h" +#include "searchterm.h" // Complete type, not a forward declaration: showTagRulesDialog() defaults its // seed to TagRule(). #include "tagrules.h" @@ -375,10 +376,11 @@ private slots: /// Runs a search asked for from the message pane. /// - /// `extend` narrows the current query rather than replacing it. The panes - /// carry a finished query and no knowledge of the bar; the combining - /// happens here, because only the window can see what the bar holds. - void runSearchFromPane(const QString &query, bool extend); + /// `mode` says whether to replace the query bar, narrow it, or narrow it + /// by everything that is not this value. The panes carry a finished query + /// and no knowledge of the bar; the combining happens here, because only + /// the window can see what the bar holds. + void runSearchFromPane(const QString &query, SearchTerm::SearchMode mode); /// Runs one tagging rule's query in the thread list, so the user can see /// which mail it collects. The rules dialog stays open; the point is to diff --git a/src/messagedetailsdialog.cpp b/src/messagedetailsdialog.cpp index 058814b..e487270 100644 --- a/src/messagedetailsdialog.cpp +++ b/src/messagedetailsdialog.cpp @@ -88,10 +88,16 @@ MessageDetailsDialog::MessageDetailsDialog(const QList<ThreadRenderItem> &items, QMenu menu(this); auto *replace = menu.addAction(tr("Search for this")); connect(replace, &QAction::triggered, this, - [this, row]() { requestSearch(row, false); }); + [this, row]() { + requestSearch( + row, SearchTerm::SearchMode::Replace); + }); auto *narrow = menu.addAction(tr("Add to search")); connect(narrow, &QAction::triggered, this, - [this, row]() { requestSearch(row, true); }); + [this, row]() { + requestSearch( + row, SearchTerm::SearchMode::Narrow); + }); menu.exec(value->mapToGlobal(pos)); }); } @@ -145,9 +151,10 @@ void MessageDetailsDialog::buildRows(const QList<ThreadRenderItem> &items) } } -void MessageDetailsDialog::requestSearch(const HeaderRow &row, bool extend) +void MessageDetailsDialog::requestSearch(const HeaderRow &row, + SearchTerm::SearchMode mode) { if (row.query.isEmpty()) return; - emit searchRequested(row.query, extend); + emit searchRequested(row.query, mode); } diff --git a/src/messagedetailsdialog.h b/src/messagedetailsdialog.h index f865913..b141c39 100644 --- a/src/messagedetailsdialog.h +++ b/src/messagedetailsdialog.h @@ -23,6 +23,7 @@ #include <QString> #include "htmlbuilder.h" +#include "searchterm.h" /// One header of one message, as shown and as searched for. /// @@ -72,12 +73,13 @@ public: /// Emits searchRequested for `row`, or nothing when the row carries no /// searchable query. The menu entries call this; a test can too, without /// popping a menu. - void requestSearch(const HeaderRow &row, bool extend); + void requestSearch(const HeaderRow &row, SearchTerm::SearchMode mode); signals: - /// The user chose a search from a row's menu. `extend` narrows the current - /// query rather than replacing it. - void searchRequested(const QString &query, bool extend); + /// The user chose a search from a row's menu. `mode` says whether to + /// replace the query, narrow it, or narrow it by everything that is not + /// this value. + void searchRequested(const QString &query, SearchTerm::SearchMode mode); private: /// Builds the rows from the thread, one group per message. diff --git a/src/messageview.cpp b/src/messageview.cpp index 2e7e694..26ef7e3 100644 --- a/src/messageview.cpp +++ b/src/messageview.cpp @@ -569,12 +569,14 @@ void MessageView::addSearchEntries(QMenu *menu, const QList<SearchOffer> &offers auto *sub = menu->addMenu(tr("Search for %1").arg(entry.label)); auto *replace = sub->addAction(tr("Search for this")); - connect(replace, &QAction::triggered, this, - [this, entry]() { emit searchRequested(entry.query, false); }); + connect(replace, &QAction::triggered, this, [this, entry]() { + emit searchRequested(entry.query, SearchTerm::SearchMode::Replace); + }); auto *narrow = sub->addAction(tr("Add to search")); - connect(narrow, &QAction::triggered, this, - [this, entry]() { emit searchRequested(entry.query, true); }); + connect(narrow, &QAction::triggered, this, [this, entry]() { + emit searchRequested(entry.query, SearchTerm::SearchMode::Narrow); + }); } } @@ -645,9 +647,9 @@ void MessageView::showDetailsDialog() // from. Closing first leaves no window in which the dialog describes a // thread the pane has already dropped. connect(&dialog, &MessageDetailsDialog::searchRequested, this, - [this, &dialog](const QString &query, bool extend) { + [this, &dialog](const QString &query, SearchTerm::SearchMode mode) { dialog.accept(); - emit searchRequested(query, extend); + emit searchRequested(query, mode); }); dialog.exec(); diff --git a/src/messageview.h b/src/messageview.h index 3e600f0..877064e 100644 --- a/src/messageview.h +++ b/src/messageview.h @@ -182,15 +182,16 @@ signals: /// The user chose a search from one of the pane's context menus. /// - /// `extend` narrows the current query rather than replacing it. The view - /// does not know what the query bar holds and must not: the window owns - /// that field and does the combining. + /// `mode` says whether to replace the query bar, narrow it, or narrow it + /// by everything that is not this value. The view does not know what the + /// query bar holds and must not: the window owns that field and does the + /// combining. /// /// Separate from queryRequested(), which carries a gate against a link in /// a rendered document driving the thread list. These menus are chrome /// built by our own code from values we extracted, so they need no gate, /// and widening the existing signal would change what that gate protects. - void searchRequested(const QString &query, bool extend); + void searchRequested(const QString &query, SearchTerm::SearchMode mode); protected: /// Turns Ctrl+wheel over the body into zoom, and Ctrl+middle-click into a |
