presentation/ComposeSessionStore.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "ComposeSession.h" | ||
| 4 | |||
| 5 | #include <QAbstractListModel> | ||
| 6 | #include <QHash> | ||
| 7 | #include <QPointer> | ||
| 8 | #include <memory> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | // Sprint 108 S108.9.1 (D-3, §4.3b): every open composer of this profile — | ||
| 12 | // new mails in tabs, replies inline in a reader, drafts in windows — and | ||
| 13 | // the drafts that wait in the undo window after *Send*. The list feeds the | ||
| 14 | // compose tabs and the status line's *open drafts* chip; sessions survive a | ||
| 15 | // restart through their draft directories (ComposeDraftFiles). | ||
| 16 | class ComposeSessionStore : public QAbstractListModel { | ||
| 17 | Q_OBJECT | ||
| 18 | Q_PROPERTY(int count READ rowCountProperty NOTIFY changed) | ||
| 19 | Q_PROPERTY(int openDrafts READ openDrafts NOTIFY changed) | ||
| 20 | |||
| 21 | public: | ||
| 22 | enum Roles { SessionRole = Qt::UserRole + 1, SessionIdRole, TitleRole, PlaceRole, KindRole, DirtyRole }; | ||
| 23 | |||
| 24 | explicit ComposeSessionStore(QObject *parent = nullptr); | ||
| 25 | ~ComposeSessionStore() override; | ||
| 26 | |||
| 27 | int rowCount(const QModelIndex &parent = {}) const override; | ||
| 28 | QVariant data(const QModelIndex &index, int role) const override; | ||
| 29 | QHash<int, QByteArray> roleNames() const override; | ||
| 30 | 1161 | int rowCountProperty() const { return int(m_sessions.size()); } | |
| 31 | int openDrafts() const; | ||
| 32 | |||
| 33 | // The dependencies every new session gets (the backend sets them). | ||
| 34 | 798 | void setDeps(ComposeSession::Deps deps) { m_deps = std::move(deps); } | |
| 35 | const ComposeSession::Deps &deps() const { return m_deps; } | ||
| 36 | |||
| 37 | // A new composer: kind new/reply/replyAll/forward/resumed; place tab, | ||
| 38 | // inline or window; for inline replies the mail it belongs to. | ||
| 39 | ComposeSession *create(const QString &kind, const QVariantMap &prefill, const QString &place, | ||
| 40 | const QVariantMap &mailReference = {}, const ComposeSession::Quote "e = {}); | ||
| 41 | Q_INVOKABLE QObject *createSession(const QString &kind, const QVariantMap &prefill, const QString &place); | ||
| 42 | Q_INVOKABLE QObject *session(const QString &sessionId) const; | ||
| 43 | // The inline reply of a mail (§4.12: a second reply focuses the first). | ||
| 44 | Q_INVOKABLE QObject *sessionForMail(const QString &accountId, qint64 folderId, qint64 uid) const; | ||
| 45 | // The same for a workspace selection map ({accountId, folderId, uid} as | ||
| 46 | // strings: UIDs beyond 2^53 lose precision as JavaScript numbers). | ||
| 47 | Q_INVOKABLE QObject *sessionForReference(const QVariantMap &reference) const; | ||
| 48 | Q_INVOKABLE void setPlace(const QString &sessionId, const QString &place); | ||
| 49 | Q_INVOKABLE QString sessionIdAt(int row) const; | ||
| 50 | // The bin (D-28): the session leaves its place at once but its draft | ||
| 51 | // stays for the undo window; *Undo* brings it back where it was, the | ||
| 52 | // end of the window deletes the draft (local and server copy). | ||
| 53 | Q_INVOKABLE void discardWithUndo(const QString &sessionId, int undoMilliseconds = 8000); | ||
| 54 | Q_INVOKABLE QObject *undoDiscard(); | ||
| 55 | // Quit and account switch: every open session writes its draft now; | ||
| 56 | // false when one of them could not be written. | ||
| 57 | Q_INVOKABLE bool saveAll(); | ||
| 58 | // Quit: the discard in its undo window becomes final. | ||
| 59 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 795 times.
|
795 | void flushDiscard() { if (!m_discardedId.isEmpty()) finishDiscard(); } |
| 60 | QList<ComposeSession *> sessions() const; | ||
| 61 | |||
| 62 | // Restore after a restart: every saved draft that was open. | ||
| 63 | int restoreOpenSessions(); | ||
| 64 | // The mail an inline reply belongs to left the view: the draft moves into | ||
| 65 | // a window (D-3) and the session says why. | ||
| 66 | void mailLeft(const QString &accountId, qint64 folderId, qint64 uid); | ||
| 67 | |||
| 68 | // Outbox hand-over: the session waits (hidden) while its message is in the | ||
| 69 | // undo window; *Undo* brings it back, transmission ends it. | ||
| 70 | void parkForOutbox(ComposeSession *session, qint64 outboxId); | ||
| 71 | ComposeSession *reopenFromOutbox(qint64 outboxId); | ||
| 72 | void outboxFinished(qint64 outboxId); | ||
| 73 | // Outbox *Delete*: the waiting message and its draft go, without reopening. | ||
| 74 | bool discardFromOutbox(qint64 outboxId); | ||
| 75 | |||
| 76 | signals: | ||
| 77 | void changed(); | ||
| 78 | void sessionOpened(QObject *session); | ||
| 79 | void sessionReopened(QObject *session); | ||
| 80 | void sessionClosed(const QString &sessionId, const QString &reason); | ||
| 81 | |||
| 82 | private: | ||
| 83 | ComposeSession::Deps m_deps; | ||
| 84 | std::vector<std::unique_ptr<ComposeSession>> m_sessions; | ||
| 85 | QHash<qint64, QString> m_outboxSessions; // outbox id → parked session id | ||
| 86 | QString m_discardedId; // the session in its discard undo window | ||
| 87 | QString m_discardedPlace; | ||
| 88 | QVariantMap m_discardedReference; | ||
| 89 | void finishDiscard(); | ||
| 90 | void adopt(std::unique_ptr<ComposeSession> session); | ||
| 91 | void removeSession(const QString &sessionId, bool deleteDraft); | ||
| 92 | int indexOf(const QString &sessionId) const; | ||
| 93 | }; | ||
| 94 |