summaryrefslogtreecommitdiffstats
path: root/common/modelresult.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-03-24 22:15:18 +0100
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-03-24 22:15:18 +0100
commit9ea268a6d0f4054c31b2729ecd6cfcc9d07a2d6a (patch)
tree41fef7daac9e5ae64d61452a3f38c82243d29fdd /common/modelresult.cpp
parent84d70933c0cd0987d5fee5a78f413fec82bb1288 (diff)
downloadsink-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.cpp90
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
30using namespace Sink;
31
32static uint getInternalIdentifer(const QByteArray &resourceId, const QByteArray &entityId)
33{
34 return qHash(resourceId + entityId);
35}
27 36
28static uint qHash(const Sink::ApplicationDomain::ApplicationDomainType &type) 37static 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
35static qint64 getIdentifier(const QModelIndex &idx) 43static qint64 getIdentifier(const QModelIndex &idx)
@@ -44,6 +52,79 @@ template <class T, class Ptr>
44ModelResult<T, Ptr>::ModelResult(const Sink::Query &query, const QList<QByteArray> &propertyColumns, const Sink::Log::Context &ctx) 52ModelResult<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 &notification) {
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
49template <class T, class Ptr> 130template <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()));