aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/notmuchworker.cpp24
-rw-r--r--src/notmuchworker.h28
2 files changed, 52 insertions, 0 deletions
diff --git a/src/notmuchworker.cpp b/src/notmuchworker.cpp
index 2672f6a..2588f4e 100644
--- a/src/notmuchworker.cpp
+++ b/src/notmuchworker.cpp
@@ -764,6 +764,30 @@ void NotmuchWorker::loadThreadTree(const QString &threadId,
QString NotmuchWorker::threadIdForTesting(const QString &query)
{
+ return firstThreadIdMatching(query);
+}
+
+void NotmuchWorker::resolveThreadForMessage(const QString &messageId)
+{
+ if (messageId.isEmpty()) {
+ emit threadForMessageResolved(messageId, QString());
+ return;
+ }
+ // This id came off another program's command line, and notmuch reads
+ // unquoted query syntax AS syntax. Quoted here rather than through
+ // SearchTerm::quote(): that escapes an embedded quote with a backslash,
+ // which notmuch's (Xapian's) parser does not honour inside a phrase, so
+ // the quote closes the phrase and the rest is parsed as query. notmuch
+ // escapes a quote by DOUBLING it.
+ QString escaped = messageId;
+ escaped.replace(QLatin1Char('"'), QStringLiteral("\"\""));
+ emit threadForMessageResolved(
+ messageId,
+ firstThreadIdMatching(QStringLiteral("id:\"%1\"").arg(escaped)));
+}
+
+QString NotmuchWorker::firstThreadIdMatching(const QString &query)
+{
if (!openReadOnly())
return QString();
diff --git a/src/notmuchworker.h b/src/notmuchworker.h
index b4e9707..3183729 100644
--- a/src/notmuchworker.h
+++ b/src/notmuchworker.h
@@ -138,6 +138,13 @@ public:
/// be reached across the thread boundary by accident.
QString threadIdForTesting(const QString &query);
+private:
+ /// The first thread id matching \p query, or empty. Shared by
+ /// threadIdForTesting() and resolveThreadForMessage().
+ QString firstThreadIdMatching(const QString &query);
+
+public:
+
public slots:
/// Loads ONE message, for a message row selected in the list.
@@ -147,6 +154,21 @@ public slots:
/// reporting.
void loadMessage(const QString &messageId, quint64 generation);
+ /// Answers which thread a Message-ID belongs to (item 200).
+ ///
+ /// For `--message`, which knows an id and needs the conversation: opening
+ /// a message means opening its thread with that message selected, never an
+ /// `id:` query showing one card out of a conversation (item 91).
+ ///
+ /// Answers with an EMPTY thread id when the message is unknown rather than
+ /// staying silent, since the window reports the miss and a slot that never
+ /// replies would leave it waiting forever.
+ ///
+ /// **The id is quoted before it reaches notmuch.** Unlike every other id in
+ /// this class, this one came from argv rather than from notmuch itself, and
+ /// notmuch parses garbage happily while matching nothing.
+ void resolveThreadForMessage(const QString &messageId);
+
/// Applies tag changes. Opens the database read-write, applies, and closes
/// immediately: notmuch's write lock is exclusive process-wide, so holding
/// it would block the user's cron `notmuch new`.
@@ -346,6 +368,12 @@ signals:
quint64 generation);
void messageLoaded(const QVector<MessageRef> &messages, quint64 generation);
+ /// The answer to resolveThreadForMessage(). The message id is echoed back
+ /// so a caller can tell which request this answers; the thread id is empty
+ /// when nothing matched.
+ void threadForMessageResolved(const QString &messageId,
+ const QString &threadId);
+
/// The dashboard's digest. `generation` is the dashboard's own counter,
/// echoed back so a stale answer can be discarded.
void threadDigestLoaded(const ThreadDigest &digest, quint64 generation);