diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-03-24 22:15:18 +0100 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-03-24 22:15:18 +0100 |
commit | 9ea268a6d0f4054c31b2729ecd6cfcc9d07a2d6a (patch) | |
tree | 41fef7daac9e5ae64d61452a3f38c82243d29fdd /common/modelresult.cpp | |
parent | 84d70933c0cd0987d5fee5a78f413fec82bb1288 (diff) | |
download | sink-9ea268a6d0f4054c31b2729ecd6cfcc9d07a2d6a.tar.gz sink-9ea268a6d0f4054c31b2729ecd6cfcc9d07a2d6a.zip |
Implemented notification support in the model.
This will allow us to fold things like progress and sync status directly
into the model. Usecases are mail download progress and folder sync
progress.
Ideally we would also solve the resource/account state through this.
Diffstat (limited to 'common/modelresult.cpp')
-rw-r--r-- | common/modelresult.cpp | 90 |
1 files changed, 87 insertions, 3 deletions
diff --git a/common/modelresult.cpp b/common/modelresult.cpp index 904766d..3edbec7 100644 --- a/common/modelresult.cpp +++ b/common/modelresult.cpp | |||
@@ -24,12 +24,20 @@ | |||
24 | #include <QPointer> | 24 | #include <QPointer> |
25 | 25 | ||
26 | #include "log.h" | 26 | #include "log.h" |
27 | #include "notifier.h" | ||
28 | #include "notification.h" | ||
29 | |||
30 | using namespace Sink; | ||
31 | |||
32 | static uint getInternalIdentifer(const QByteArray &resourceId, const QByteArray &entityId) | ||
33 | { | ||
34 | return qHash(resourceId + entityId); | ||
35 | } | ||
27 | 36 | ||
28 | static uint qHash(const Sink::ApplicationDomain::ApplicationDomainType &type) | 37 | static uint qHash(const Sink::ApplicationDomain::ApplicationDomainType &type) |
29 | { | 38 | { |
30 | // Q_ASSERT(!type.resourceInstanceIdentifier().isEmpty()); | ||
31 | Q_ASSERT(!type.identifier().isEmpty()); | 39 | Q_ASSERT(!type.identifier().isEmpty()); |
32 | return qHash(type.resourceInstanceIdentifier() + type.identifier()); | 40 | return getInternalIdentifer(type.resourceInstanceIdentifier(), type.identifier()); |
33 | } | 41 | } |
34 | 42 | ||
35 | static qint64 getIdentifier(const QModelIndex &idx) | 43 | static qint64 getIdentifier(const QModelIndex &idx) |
@@ -44,6 +52,79 @@ template <class T, class Ptr> | |||
44 | ModelResult<T, Ptr>::ModelResult(const Sink::Query &query, const QList<QByteArray> &propertyColumns, const Sink::Log::Context &ctx) | 52 | ModelResult<T, Ptr>::ModelResult(const Sink::Query &query, const QList<QByteArray> &propertyColumns, const Sink::Log::Context &ctx) |
45 | : QAbstractItemModel(), mLogCtx(ctx.subContext("modelresult")), mPropertyColumns(propertyColumns), mQuery(query) | 53 | : QAbstractItemModel(), mLogCtx(ctx.subContext("modelresult")), mPropertyColumns(propertyColumns), mQuery(query) |
46 | { | 54 | { |
55 | if (query.flags().testFlag(Sink::Query::UpdateStatus)) { | ||
56 | mNotifier.reset(new Sink::Notifier{query}); | ||
57 | mNotifier->registerHandler([this](const Notification ¬ification) { | ||
58 | switch (notification.type) { | ||
59 | case Notification::Status: | ||
60 | case Notification::Warning: | ||
61 | case Notification::Error: | ||
62 | case Notification::Info: | ||
63 | case Notification::Progress: | ||
64 | //These are the notifications we care about | ||
65 | break; | ||
66 | default: | ||
67 | //We're not interested | ||
68 | return; | ||
69 | }; | ||
70 | if (notification.resource.isEmpty()|| notification.entities.isEmpty()) { | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | QVector<qint64> idList; | ||
75 | for (const auto &entity : notification.entities) { | ||
76 | auto id = getInternalIdentifer(notification.resource, entity); | ||
77 | if (mEntities.contains(id)) { | ||
78 | idList << id; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | if (idList.isEmpty()) { | ||
83 | //We don't have this entity in our model | ||
84 | return; | ||
85 | } | ||
86 | const int newStatus = [&] { | ||
87 | if (notification.type == Notification::Warning || notification.type == Notification::Error) { | ||
88 | return ApplicationDomain::SyncStatus::SyncError; | ||
89 | } | ||
90 | if (notification.type == Notification::Info) { | ||
91 | switch (notification.code) { | ||
92 | case ApplicationDomain::SyncInProgress: | ||
93 | return ApplicationDomain::SyncInProgress; | ||
94 | case ApplicationDomain::SyncSuccess: | ||
95 | return ApplicationDomain::SyncSuccess; | ||
96 | case ApplicationDomain::SyncError: | ||
97 | return ApplicationDomain::SyncError; | ||
98 | case ApplicationDomain::NoSyncStatus: | ||
99 | break; | ||
100 | } | ||
101 | return ApplicationDomain::NoSyncStatus; | ||
102 | } | ||
103 | if (notification.type == Notification::Progress) { | ||
104 | return ApplicationDomain::SyncStatus::SyncInProgress; | ||
105 | } | ||
106 | return ApplicationDomain::NoSyncStatus; | ||
107 | }(); | ||
108 | |||
109 | for (const auto id : idList) { | ||
110 | const auto oldStatus = mEntityStatus.value(id); | ||
111 | QVector<int> changedRoles; | ||
112 | if (oldStatus != newStatus) { | ||
113 | mEntityStatus.insert(id, newStatus); | ||
114 | changedRoles << StatusRole; | ||
115 | } | ||
116 | |||
117 | if (notification.type == Notification::Progress) { | ||
118 | changedRoles << ProgressRole; | ||
119 | } else if (notification.type == Notification::Warning || notification.type == Notification::Error) { | ||
120 | changedRoles << WarningRole; | ||
121 | } | ||
122 | |||
123 | const auto idx = createIndexFromId(id); | ||
124 | emit dataChanged(idx, idx, changedRoles); | ||
125 | } | ||
126 | }); | ||
127 | } | ||
47 | } | 128 | } |
48 | 129 | ||
49 | template <class T, class Ptr> | 130 | template <class T, class Ptr> |
@@ -60,7 +141,7 @@ qint64 ModelResult<T, Ptr>::parentId(const Ptr &value) | |||
60 | if (!mQuery.parentProperty().isEmpty()) { | 141 | if (!mQuery.parentProperty().isEmpty()) { |
61 | const auto identifier = value->getProperty(mQuery.parentProperty()).toByteArray(); | 142 | const auto identifier = value->getProperty(mQuery.parentProperty()).toByteArray(); |
62 | if (!identifier.isEmpty()) { | 143 | if (!identifier.isEmpty()) { |
63 | return qHash(T(value->resourceInstanceIdentifier(), identifier, 0, QSharedPointer<Sink::ApplicationDomain::BufferAdaptor>())); | 144 | return getInternalIdentifer(value->resourceInstanceIdentifier(), identifier); |
64 | } | 145 | } |
65 | } | 146 | } |
66 | return 0; | 147 | return 0; |
@@ -106,6 +187,9 @@ QVariant ModelResult<T, Ptr>::data(const QModelIndex &index, int role) const | |||
106 | if (role == ChildrenFetchedRole) { | 187 | if (role == ChildrenFetchedRole) { |
107 | return childrenFetched(index); | 188 | return childrenFetched(index); |
108 | } | 189 | } |
190 | if (role == StatusRole) { | ||
191 | return mEntityStatus.value(index.internalId()); | ||
192 | } | ||
109 | if (role == Qt::DisplayRole && index.isValid()) { | 193 | if (role == Qt::DisplayRole && index.isValid()) { |
110 | if (index.column() < mPropertyColumns.size()) { | 194 | if (index.column() < mPropertyColumns.size()) { |
111 | Q_ASSERT(mEntities.contains(index.internalId())); | 195 | Q_ASSERT(mEntities.contains(index.internalId())); |