data/SieveMailboxName.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QHash> | ||
| 4 | #include <QList> | ||
| 5 | #include <QString> | ||
| 6 | #include <QStringList> | ||
| 7 | |||
| 8 | // MailJD folder ↔ Sieve mailbox name (Sprint 95 S95.1.8, SR-04). | ||
| 9 | // | ||
| 10 | // `fileinto` takes the mailbox name as UTF-8 with the server's hierarchy | ||
| 11 | // delimiter and namespace prefix — the IMAP LIST name decoded from | ||
| 12 | // modified UTF-7 (RFC 5228 §4.1, RFC 3501 §5.1.3), e.g. "INBOX.Projekte. | ||
| 13 | // Übersicht" on a server with an "INBOX." namespace, "Projekte/Übersicht" | ||
| 14 | // on one with "/". MailJD keeps the raw IMAP path per folder; the caller | ||
| 15 | // decodes it (ImapResponseParser::decodeMailboxName) and registers both. | ||
| 16 | // | ||
| 17 | // Invariants: | ||
| 18 | // - Lookups are exact; "INBOX" matches case-insensitively (RFC 3501). | ||
| 19 | // - suggestionFor() only proposes an existing folder whose name differs | ||
| 20 | // in delimiters or a missing/extra "INBOX" prefix — the defect found on | ||
| 21 | // the reference server ("Notifications.Startups" vs | ||
| 22 | // "Notifications/Startups", SPRINT-95 §1.4). | ||
| 23 | class SieveMailboxDirectory { | ||
| 24 | public: | ||
| 25 | struct Folder { | ||
| 26 | QString imapPath; // raw LIST name (modified UTF-7) | ||
| 27 | QString sieveName; // decoded UTF-8 full path | ||
| 28 | QString delimiter; // "." or "/" (may be empty for flat servers) | ||
| 29 | QString specialUse; // "\\Junk", "\\Trash", … or empty | ||
| 30 | }; | ||
| 31 | |||
| 32 | void addFolder(const QString &imapPath, const QString &decodedPath, const QString &delimiter, | ||
| 33 | const QStringList &flags); | ||
| 34 | 1056 | bool isEmpty() const { return m_folders.isEmpty(); } | |
| 35 | int size() const { return m_folders.size(); } | ||
| 36 | |||
| 37 | QString sieveName(const QString &imapPath) const; // empty when unknown | ||
| 38 | QString imapPath(const QString &sieveName) const; // empty when unknown | ||
| 39 |
1/1✓ Branch 2 → 3 taken 1329 times.
|
1329 | bool exists(const QString &sieveName) const { return !imapPath(sieveName).isEmpty(); } |
| 40 | QString specialUseOf(const QString &imapPath) const; | ||
| 41 | QString folderForSpecialUse(const QString &specialUse) const; // imap path | ||
| 42 | QString suggestionFor(const QString &missingSieveName) const; // sieve name | ||
| 43 | QString delimiter() const; // the most common delimiter, "/" when unknown | ||
| 44 | QStringList sieveNames() const; | ||
| 45 | |||
| 46 | private: | ||
| 47 | static QString normalizedKey(const QString &name); | ||
| 48 | static QString canonical(const QString &name); | ||
| 49 | |||
| 50 | QList<Folder> m_folders; | ||
| 51 | QHash<QString, int> m_byImapPath; | ||
| 52 | QHash<QString, int> m_bySieveName; // canonical() | ||
| 53 | }; | ||
| 54 |