diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/notmuchworker.cpp | 24 | ||||
| -rw-r--r-- | src/notmuchworker.h | 28 |
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); |
