presentation/QuickTaskModel.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QHash> | ||
| 4 | #include <QAbstractListModel> | ||
| 5 | #include <QList> | ||
| 6 | #include <QThreadPool> | ||
| 7 | |||
| 8 | #include "TaskListLayout.h" | ||
| 9 | #include <QTimer> | ||
| 10 | |||
| 11 | // Flat projection of the shared calendar store's tasks for the Quick | ||
| 12 | // frontend (D6 groundwork). A background worker opens its own read-only | ||
| 13 | // store connection and delivers the list with generation fencing — the | ||
| 14 | // QuickCalendarModel pattern. DAV write-back is owned by the session's | ||
| 15 | // CalendarSyncCoordinator; this model supplies immutable editor records. | ||
| 16 | class QuickTaskModel final : public QAbstractListModel { | ||
| 17 | 1 | Q_OBJECT | |
| 18 | Q_PROPERTY(double editorWidth READ editorWidth WRITE setEditorWidth NOTIFY stateChanged) | ||
| 19 | Q_PROPERTY(QString view READ view WRITE setView NOTIFY stateChanged) | ||
| 20 | Q_PROPERTY(QString grouping READ grouping WRITE setGrouping NOTIFY stateChanged) | ||
| 21 | Q_PROPERTY(QString sort READ sort WRITE setSort NOTIFY stateChanged) | ||
| 22 | Q_PROPERTY(bool hideFutureStarts READ hideFutureStarts WRITE setHideFutureStarts NOTIFY stateChanged) | ||
| 23 | // F94-55: the sidebar's tag section is open (remembered). | ||
| 24 | Q_PROPERTY(bool tagsExpanded READ tagsExpanded WRITE setTagsExpanded NOTIFY stateChanged) | ||
| 25 | // F94-37: completed tasks of this view hidden while "show completed" is off. | ||
| 26 | Q_PROPERTY(int hiddenCompleted READ hiddenCompleted NOTIFY countsChanged) | ||
| 27 | Q_PROPERTY(QVariantMap counts READ counts NOTIFY countsChanged) | ||
| 28 | Q_PROPERTY(QVariantMap groupCounts READ groupCounts NOTIFY countsChanged) | ||
| 29 | Q_PROPERTY(QStringList collapsedGroups READ collapsedGroups NOTIFY stateChanged) | ||
| 30 | Q_PROPERTY(int weekStart READ weekStart WRITE setWeekStart NOTIFY stateChanged) | ||
| 31 | Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged) | ||
| 32 | Q_PROPERTY(bool showCompleted READ showCompleted WRITE setShowCompleted NOTIFY showCompletedChanged) | ||
| 33 | // Calendar visibility filter: account-scoped keys from the shared sidebar. | ||
| 34 | // Legacy path-only callers are still accepted. Toggling reloads. | ||
| 35 | Q_PROPERTY(QStringList hiddenCalendars READ hiddenCalendars WRITE setHiddenCalendars NOTIFY hiddenCalendarsChanged) | ||
| 36 | // All calendar paths that currently carry tasks (sidebar filter list). | ||
| 37 | Q_PROPERTY(QStringList taskCalendarPaths READ taskCalendarPaths NOTIFY taskCalendarPathsChanged) | ||
| 38 | // Display names parallel to taskCalendarPaths (same index; falls back | ||
| 39 | // to the path when the calendar metadata carries no name). | ||
| 40 | Q_PROPERTY(QStringList taskCalendarNames READ taskCalendarNames NOTIFY taskCalendarNamesChanged) | ||
| 41 | // F93-16: the search (F, /) in the tasks area — every word must occur | ||
| 42 | // in the title or the notes (case-insensitive). Empty shows all. | ||
| 43 | Q_PROPERTY(QString filterText READ filterText WRITE setFilterText NOTIFY filterTextChanged) | ||
| 44 | public: | ||
| 45 | enum Role { | ||
| 46 | TaskSummary = Qt::UserRole + 1, TaskNotes, TaskDueText, TaskOverdue, | ||
| 47 | TaskProgress, TaskStarred, TaskCompleted, TaskCalendar, TaskPriorityText, TaskColor, TaskIdentity, | ||
| 48 | TaskKey, Group, Depth, HasChildren, Expanded, ChildProgress, ChecklistProgress, | ||
| 49 | DueKind, PriorityLevel, StatusKind, Tags, HasReminder, Recurring, HasLinkedMail, SyncState, ReadOnly, | ||
| 50 | StartsLater, StartText, Orphan | ||
| 51 | }; | ||
| 52 | explicit QuickTaskModel(QString databasePath, QObject *parent = nullptr); | ||
| 53 | ~QuickTaskModel() override; | ||
| 54 | QHash<int, QByteArray> roleNames() const override; | ||
| 55 | int rowCount(const QModelIndex &parent = {}) const override; | ||
| 56 | QVariant data(const QModelIndex &index, int role) const override; | ||
| 57 | 1056 | bool loading() const { return m_loading; } | |
| 58 | 316 | bool showCompleted() const { return m_showCompleted; } | |
| 59 | void setShowCompleted(bool show); | ||
| 60 | Q_INVOKABLE void reload(); | ||
| 61 | 159 | double editorWidth() const { return m_editorWidth; } | |
| 62 | void setEditorWidth(double width); | ||
| 63 | 7186 | QString view() const { return m_options.view; } | |
| 64 | 315 | QString grouping() const { return m_options.grouping; } | |
| 65 | 326 | QString sort() const { return m_options.sort; } | |
| 66 | ✗ | bool hideFutureStarts() const { return m_options.hideFutureStarts; } | |
| 67 | void setHideFutureStarts(bool hide); | ||
| 68 | 828 | bool tagsExpanded() const { return m_tagsExpanded; } | |
| 69 | void setTagsExpanded(bool expanded); | ||
| 70 | 1894 | int weekStart() const { return m_options.weekStart; } | |
| 71 | 11133 | QVariantMap counts() const { return m_counts; } | |
| 72 | 320 | int hiddenCompleted() const { return m_hiddenCompleted; } | |
| 73 | 279 | QVariantMap groupCounts() const { return m_groupCounts; } | |
| 74 | 1950 | QStringList collapsedGroups() const { return m_collapsedGroups; } | |
| 75 | Q_INVOKABLE void toggleGroup(const QString &group); | ||
| 76 | void setView(const QString &view); | ||
| 77 | void setGrouping(const QString &grouping); | ||
| 78 | void setSort(const QString &sort); | ||
| 79 | void setWeekStart(int day); | ||
| 80 | Q_INVOKABLE void toggleParent(const QString &key); | ||
| 81 | Q_INVOKABLE int indexOfTask(const QString &key) const; | ||
| 82 | Q_INVOKABLE void holdCompleted(const QString &key); | ||
| 83 | QVariantMap state() const; | ||
| 84 | void restoreState(const QVariantMap &state); | ||
| 85 | ✗ | QStringList hiddenCalendars() const { return m_hiddenCalendars; } | |
| 86 | void setHiddenCalendars(const QStringList &paths); | ||
| 87 | 670 | QString filterText() const { return m_filterText; } | |
| 88 | void setFilterText(const QString &text); | ||
| 89 | 1 | QStringList taskCalendarPaths() const { return m_taskCalendarPaths; } | |
| 90 | 1 | QStringList taskCalendarNames() const { return m_taskCalendarNames; } | |
| 91 | // Toggle one calendar's visibility (sidebar click). | ||
| 92 | Q_INVOKABLE void toggleCalendar(const QString &path); | ||
| 93 | // D6: full record for the task editor and toggles (immutable server | ||
| 94 | // fields like etag/resourceHref ride along so saves preserve them). | ||
| 95 | QVariantMap taskAt(int row) const; | ||
| 96 | static QVariantMap record(const CalendarTask &task); | ||
| 97 | |||
| 98 | signals: | ||
| 99 | void stateChanged(); | ||
| 100 | void countsChanged(); | ||
| 101 | void loadingChanged(); | ||
| 102 | void showCompletedChanged(); | ||
| 103 | void hiddenCalendarsChanged(); | ||
| 104 | void taskCalendarPathsChanged(); | ||
| 105 | void taskCalendarNamesChanged(); | ||
| 106 | void filterTextChanged(); | ||
| 107 | |||
| 108 | private: | ||
| 109 | void applyTasks(QList<CalendarTask> tasks); | ||
| 110 | void updateCalendarPaths(const QList<CalendarTask> &tasks); | ||
| 111 | QString m_databasePath; | ||
| 112 | QThreadPool m_pool; | ||
| 113 | QList<TaskListLayout::Row> m_rows; | ||
| 114 | TaskListLayout::Options m_options; | ||
| 115 | QHash<QString, quint64> m_graceHolds; // newest hold per key (S106-352) | ||
| 116 | QVariantMap m_counts, m_groupCounts; | ||
| 117 | QStringList m_collapsedGroups{QStringLiteral("completed"), QStringLiteral("cancelled")}; | ||
| 118 | QHash<QString, int> m_indices; | ||
| 119 | void project(); | ||
| 120 | void publish(QList<TaskListLayout::Row> rows); | ||
| 121 | static bool sameDisplay(const TaskListLayout::Row &a, const TaskListLayout::Row &b); | ||
| 122 | QStringList m_hiddenCalendars; | ||
| 123 | QString m_filterText; | ||
| 124 | QList<CalendarTask> m_loaded; // before the text filter | ||
| 125 | QStringList m_taskCalendarPaths; | ||
| 126 | QStringList m_taskCalendarNames; | ||
| 127 | double m_editorWidth = 460; | ||
| 128 | bool m_loading = false; | ||
| 129 | bool m_showCompleted = false; | ||
| 130 | bool m_tagsExpanded = false; | ||
| 131 | int m_hiddenCompleted = 0; | ||
| 132 | quint64 m_generation = 0; | ||
| 133 | }; | ||
| 134 |