Merge lp:~bfiller/history-service/rtm-14.09-sim-presence into lp:history-service/rtm-14.09
- rtm-14.09-sim-presence
- Merge into rtm-14.09
Proposed by
Bill Filler
Status: | Merged |
---|---|
Approved by: | Bill Filler |
Approved revision: | 164 |
Merged at revision: | 164 |
Proposed branch: | lp:~bfiller/history-service/rtm-14.09-sim-presence |
Merge into: | lp:history-service/rtm-14.09 |
Diff against target: |
884 lines (+517/-56) 11 files modified
Ubuntu/History/CMakeLists.txt (+2/-0) Ubuntu/History/historyeventmodel.cpp (+34/-20) Ubuntu/History/historyeventmodel.h (+18/-14) Ubuntu/History/historygroupedeventsmodel.cpp (+346/-0) Ubuntu/History/historygroupedeventsmodel.h (+82/-0) Ubuntu/History/historyqmlplugin.cpp (+2/-0) Ubuntu/History/historythreadmodel.cpp (+23/-21) Ubuntu/History/historythreadmodel.h (+2/-1) src/event.cpp (+6/-0) src/event.h (+1/-0) src/types.h (+1/-0) |
To merge this branch: | bzr merge lp:~bfiller/history-service/rtm-14.09-sim-presence |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phablet Team | Pending | ||
Review via email: mp+231916@code.launchpad.net |
Commit message
sim presence and call grouping merge from trunk
Description of the change
sim presence and call grouping merge from trunk
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Ubuntu/History/CMakeLists.txt' | |||
2 | --- Ubuntu/History/CMakeLists.txt 2014-07-14 23:05:23 +0000 | |||
3 | +++ Ubuntu/History/CMakeLists.txt 2014-08-22 15:31:10 +0000 | |||
4 | @@ -2,6 +2,7 @@ | |||
5 | 2 | 2 | ||
6 | 3 | set(plugin_SRCS | 3 | set(plugin_SRCS |
7 | 4 | historyeventmodel.cpp | 4 | historyeventmodel.cpp |
8 | 5 | historygroupedeventsmodel.cpp | ||
9 | 5 | historythreadgroupingproxymodel.cpp | 6 | historythreadgroupingproxymodel.cpp |
10 | 6 | historyqmltexteventattachment.cpp | 7 | historyqmltexteventattachment.cpp |
11 | 7 | historyqmlfilter.cpp | 8 | historyqmlfilter.cpp |
12 | @@ -15,6 +16,7 @@ | |||
13 | 15 | 16 | ||
14 | 16 | set(plugin_HDRS | 17 | set(plugin_HDRS |
15 | 17 | historyeventmodel.h | 18 | historyeventmodel.h |
16 | 19 | historygroupedeventsmodel.h | ||
17 | 18 | historythreadgroupingproxymodel.h | 20 | historythreadgroupingproxymodel.h |
18 | 19 | historyqmltexteventattachment.h | 21 | historyqmltexteventattachment.h |
19 | 20 | historyqmlfilter.h | 22 | historyqmlfilter.h |
20 | 21 | 23 | ||
21 | === modified file 'Ubuntu/History/historyeventmodel.cpp' | |||
22 | --- Ubuntu/History/historyeventmodel.cpp 2014-08-07 19:22:31 +0000 | |||
23 | +++ Ubuntu/History/historyeventmodel.cpp 2014-08-22 15:31:10 +0000 | |||
24 | @@ -37,7 +37,8 @@ | |||
25 | 37 | 37 | ||
26 | 38 | HistoryEventModel::HistoryEventModel(QObject *parent) : | 38 | HistoryEventModel::HistoryEventModel(QObject *parent) : |
27 | 39 | QAbstractListModel(parent), mCanFetchMore(true), mFilter(0), | 39 | QAbstractListModel(parent), mCanFetchMore(true), mFilter(0), |
29 | 40 | mSort(0), mType(HistoryThreadModel::EventTypeText), mEventWritingTimer(0), mFetchTimer(0) | 40 | mSort(new HistoryQmlSort(this)), mType(HistoryThreadModel::EventTypeText), |
30 | 41 | mEventWritingTimer(0), mUpdateTimer(0) | ||
31 | 41 | { | 42 | { |
32 | 42 | connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged())); | 43 | connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged())); |
33 | 43 | connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged())); | 44 | connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged())); |
34 | @@ -63,7 +64,7 @@ | |||
35 | 63 | mRoles[CallDurationRole] = "callDuration"; | 64 | mRoles[CallDurationRole] = "callDuration"; |
36 | 64 | 65 | ||
37 | 65 | // create the view and get some objects | 66 | // create the view and get some objects |
39 | 66 | updateQuery(); | 67 | triggerQueryUpdate(); |
40 | 67 | } | 68 | } |
41 | 68 | 69 | ||
42 | 69 | int HistoryEventModel::rowCount(const QModelIndex &parent) const | 70 | int HistoryEventModel::rowCount(const QModelIndex &parent) const |
43 | @@ -81,7 +82,11 @@ | |||
44 | 81 | return QVariant(); | 82 | return QVariant(); |
45 | 82 | } | 83 | } |
46 | 83 | 84 | ||
48 | 84 | History::Event event = mEvents[index.row()]; | 85 | return eventData(mEvents[index.row()], role); |
49 | 86 | } | ||
50 | 87 | |||
51 | 88 | QVariant HistoryEventModel::eventData(const History::Event &event, int role) const | ||
52 | 89 | { | ||
53 | 85 | History::TextEvent textEvent; | 90 | History::TextEvent textEvent; |
54 | 86 | History::VoiceEvent voiceEvent; | 91 | History::VoiceEvent voiceEvent; |
55 | 87 | History::Thread thread; | 92 | History::Thread thread; |
56 | @@ -194,7 +199,7 @@ | |||
57 | 194 | return; | 199 | return; |
58 | 195 | } | 200 | } |
59 | 196 | 201 | ||
61 | 197 | History::Events events = mView->nextPage(); | 202 | History::Events events = fetchNextPage(); |
62 | 198 | 203 | ||
63 | 199 | qDebug() << "Got events:" << events.count(); | 204 | qDebug() << "Got events:" << events.count(); |
64 | 200 | if (events.isEmpty()) { | 205 | if (events.isEmpty()) { |
65 | @@ -227,11 +232,11 @@ | |||
66 | 227 | if (mFilter) { | 232 | if (mFilter) { |
67 | 228 | connect(mFilter, | 233 | connect(mFilter, |
68 | 229 | SIGNAL(filterChanged()), | 234 | SIGNAL(filterChanged()), |
70 | 230 | SLOT(updateQuery())); | 235 | SLOT(triggerQueryUpdate())); |
71 | 231 | } | 236 | } |
72 | 232 | 237 | ||
73 | 233 | Q_EMIT filterChanged(); | 238 | Q_EMIT filterChanged(); |
75 | 234 | updateQuery(); | 239 | triggerQueryUpdate(); |
76 | 235 | } | 240 | } |
77 | 236 | 241 | ||
78 | 237 | HistoryQmlSort *HistoryEventModel::sort() const | 242 | HistoryQmlSort *HistoryEventModel::sort() const |
79 | @@ -250,11 +255,11 @@ | |||
80 | 250 | if (mSort) { | 255 | if (mSort) { |
81 | 251 | connect(mSort, | 256 | connect(mSort, |
82 | 252 | SIGNAL(sortChanged()), | 257 | SIGNAL(sortChanged()), |
84 | 253 | SLOT(updateQuery())); | 258 | SLOT(triggerQueryUpdate())); |
85 | 254 | } | 259 | } |
86 | 255 | 260 | ||
87 | 256 | Q_EMIT sortChanged(); | 261 | Q_EMIT sortChanged(); |
89 | 257 | updateQuery(); | 262 | triggerQueryUpdate(); |
90 | 258 | } | 263 | } |
91 | 259 | 264 | ||
92 | 260 | HistoryThreadModel::EventType HistoryEventModel::type() const | 265 | HistoryThreadModel::EventType HistoryEventModel::type() const |
93 | @@ -266,7 +271,7 @@ | |||
94 | 266 | { | 271 | { |
95 | 267 | mType = value; | 272 | mType = value; |
96 | 268 | Q_EMIT typeChanged(); | 273 | Q_EMIT typeChanged(); |
98 | 269 | updateQuery(); | 274 | triggerQueryUpdate(); |
99 | 270 | } | 275 | } |
100 | 271 | 276 | ||
101 | 272 | QString HistoryEventModel::threadIdForParticipants(const QString &accountId, int eventType, const QStringList &participants, int matchFlags, bool create) | 277 | QString HistoryEventModel::threadIdForParticipants(const QString &accountId, int eventType, const QStringList &participants, int matchFlags, bool create) |
102 | @@ -378,7 +383,7 @@ | |||
103 | 378 | SLOT(onEventsRemoved(History::Events))); | 383 | SLOT(onEventsRemoved(History::Events))); |
104 | 379 | connect(mView.data(), | 384 | connect(mView.data(), |
105 | 380 | SIGNAL(invalidated()), | 385 | SIGNAL(invalidated()), |
107 | 381 | SLOT(updateQuery())); | 386 | SLOT(triggerQueryUpdate())); |
108 | 382 | 387 | ||
109 | 383 | mCanFetchMore = true; | 388 | mCanFetchMore = true; |
110 | 384 | Q_EMIT canFetchMoreChanged(); | 389 | Q_EMIT canFetchMoreChanged(); |
111 | @@ -391,12 +396,7 @@ | |||
112 | 391 | } | 396 | } |
113 | 392 | mAttachmentCache.clear(); | 397 | mAttachmentCache.clear(); |
114 | 393 | 398 | ||
121 | 394 | if (mFetchTimer) { | 399 | fetchMore(QModelIndex()); |
116 | 395 | killTimer(mFetchTimer); | ||
117 | 396 | } | ||
118 | 397 | |||
119 | 398 | // delay the loading of the model data until the settings settle down | ||
120 | 399 | mFetchTimer = startTimer(100); | ||
122 | 400 | } | 400 | } |
123 | 401 | 401 | ||
124 | 402 | void HistoryEventModel::onEventsAdded(const History::Events &events) | 402 | void HistoryEventModel::onEventsAdded(const History::Events &events) |
125 | @@ -474,13 +474,18 @@ | |||
126 | 474 | qDebug() << "... succeeded!"; | 474 | qDebug() << "... succeeded!"; |
127 | 475 | mEventWritingQueue.clear(); | 475 | mEventWritingQueue.clear(); |
128 | 476 | } | 476 | } |
133 | 477 | } else if (event->timerId() == mFetchTimer) { | 477 | } else if (event->timerId() == mUpdateTimer) { |
134 | 478 | killTimer(mFetchTimer); | 478 | killTimer(mUpdateTimer); |
135 | 479 | mFetchTimer = 0; | 479 | mUpdateTimer = 0; |
136 | 480 | fetchMore(QModelIndex()); | 480 | updateQuery(); |
137 | 481 | } | 481 | } |
138 | 482 | } | 482 | } |
139 | 483 | 483 | ||
140 | 484 | History::Events HistoryEventModel::fetchNextPage() | ||
141 | 485 | { | ||
142 | 486 | return mView->nextPage(); | ||
143 | 487 | } | ||
144 | 488 | |||
145 | 484 | QVariant HistoryEventModel::get(int row) const | 489 | QVariant HistoryEventModel::get(int row) const |
146 | 485 | { | 490 | { |
147 | 486 | if (row >= this->rowCount() || row < 0) { | 491 | if (row >= this->rowCount() || row < 0) { |
148 | @@ -489,3 +494,12 @@ | |||
149 | 489 | 494 | ||
150 | 490 | return QVariant(mEvents[row].properties()); | 495 | return QVariant(mEvents[row].properties()); |
151 | 491 | } | 496 | } |
152 | 497 | |||
153 | 498 | void HistoryEventModel::triggerQueryUpdate() | ||
154 | 499 | { | ||
155 | 500 | if (mUpdateTimer) { | ||
156 | 501 | killTimer(mUpdateTimer); | ||
157 | 502 | } | ||
158 | 503 | // delay the loading of the model data until the settings settle down | ||
159 | 504 | mUpdateTimer = startTimer(100); | ||
160 | 505 | } | ||
161 | 492 | 506 | ||
162 | === modified file 'Ubuntu/History/historyeventmodel.h' | |||
163 | --- Ubuntu/History/historyeventmodel.h 2014-08-07 19:22:31 +0000 | |||
164 | +++ Ubuntu/History/historyeventmodel.h 2014-08-22 15:31:10 +0000 | |||
165 | @@ -53,18 +53,20 @@ | |||
166 | 53 | TextReadSubjectRole, | 53 | TextReadSubjectRole, |
167 | 54 | TextMessageAttachmentsRole, | 54 | TextMessageAttachmentsRole, |
168 | 55 | CallMissedRole, | 55 | CallMissedRole, |
170 | 56 | CallDurationRole | 56 | CallDurationRole, |
171 | 57 | LastRole | ||
172 | 57 | }; | 58 | }; |
173 | 58 | 59 | ||
174 | 59 | explicit HistoryEventModel(QObject *parent = 0); | 60 | explicit HistoryEventModel(QObject *parent = 0); |
175 | 60 | 61 | ||
183 | 61 | int rowCount(const QModelIndex &parent = QModelIndex()) const; | 62 | virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; |
184 | 62 | QVariant data(const QModelIndex &index, int role) const; | 63 | virtual QVariant data(const QModelIndex &index, int role) const; |
185 | 63 | 64 | QVariant eventData(const History::Event &event, int role) const; | |
186 | 64 | Q_INVOKABLE bool canFetchMore(const QModelIndex &parent = QModelIndex()) const; | 65 | |
187 | 65 | Q_INVOKABLE void fetchMore(const QModelIndex &parent = QModelIndex()); | 66 | Q_INVOKABLE virtual bool canFetchMore(const QModelIndex &parent = QModelIndex()) const; |
188 | 66 | 67 | Q_INVOKABLE virtual void fetchMore(const QModelIndex &parent = QModelIndex()); | |
189 | 67 | QHash<int, QByteArray> roleNames() const; | 68 | |
190 | 69 | virtual QHash<int, QByteArray> roleNames() const; | ||
191 | 68 | 70 | ||
192 | 69 | HistoryQmlFilter *filter() const; | 71 | HistoryQmlFilter *filter() const; |
193 | 70 | void setFilter(HistoryQmlFilter *value); | 72 | void setFilter(HistoryQmlFilter *value); |
194 | @@ -85,7 +87,7 @@ | |||
195 | 85 | Q_INVOKABLE bool markEventAsRead(const QString &accountId, const QString &threadId, const QString &eventId, int eventType); | 87 | Q_INVOKABLE bool markEventAsRead(const QString &accountId, const QString &threadId, const QString &eventId, int eventType); |
196 | 86 | 88 | ||
197 | 87 | Q_INVOKABLE bool removeEventAttachment(const QString &accountId, const QString &threadId, const QString &eventId, int eventType, const QString &attachmentId); | 89 | Q_INVOKABLE bool removeEventAttachment(const QString &accountId, const QString &threadId, const QString &eventId, int eventType, const QString &attachmentId); |
199 | 88 | Q_INVOKABLE QVariant get(int row) const; | 90 | Q_INVOKABLE virtual QVariant get(int row) const; |
200 | 89 | 91 | ||
201 | 90 | Q_SIGNALS: | 92 | Q_SIGNALS: |
202 | 91 | void countChanged(); | 93 | void countChanged(); |
203 | @@ -95,13 +97,15 @@ | |||
204 | 95 | void canFetchMoreChanged(); | 97 | void canFetchMoreChanged(); |
205 | 96 | 98 | ||
206 | 97 | protected Q_SLOTS: | 99 | protected Q_SLOTS: |
211 | 98 | void updateQuery(); | 100 | void triggerQueryUpdate(); |
212 | 99 | void onEventsAdded(const History::Events &events); | 101 | virtual void updateQuery(); |
213 | 100 | void onEventsModified(const History::Events &events); | 102 | virtual void onEventsAdded(const History::Events &events); |
214 | 101 | void onEventsRemoved(const History::Events &events); | 103 | virtual void onEventsModified(const History::Events &events); |
215 | 104 | virtual void onEventsRemoved(const History::Events &events); | ||
216 | 102 | 105 | ||
217 | 103 | protected: | 106 | protected: |
218 | 104 | void timerEvent(QTimerEvent *event); | 107 | void timerEvent(QTimerEvent *event); |
219 | 108 | History::Events fetchNextPage(); | ||
220 | 105 | 109 | ||
221 | 106 | private: | 110 | private: |
222 | 107 | History::EventViewPtr mView; | 111 | History::EventViewPtr mView; |
223 | @@ -114,7 +118,7 @@ | |||
224 | 114 | mutable QMap<History::TextEvent, QList<QVariant> > mAttachmentCache; | 118 | mutable QMap<History::TextEvent, QList<QVariant> > mAttachmentCache; |
225 | 115 | History::Events mEventWritingQueue; | 119 | History::Events mEventWritingQueue; |
226 | 116 | int mEventWritingTimer; | 120 | int mEventWritingTimer; |
228 | 117 | int mFetchTimer; | 121 | int mUpdateTimer; |
229 | 118 | }; | 122 | }; |
230 | 119 | 123 | ||
231 | 120 | #endif // HISTORYEVENTMODEL_H | 124 | #endif // HISTORYEVENTMODEL_H |
232 | 121 | 125 | ||
233 | === added file 'Ubuntu/History/historygroupedeventsmodel.cpp' | |||
234 | --- Ubuntu/History/historygroupedeventsmodel.cpp 1970-01-01 00:00:00 +0000 | |||
235 | +++ Ubuntu/History/historygroupedeventsmodel.cpp 2014-08-22 15:31:10 +0000 | |||
236 | @@ -0,0 +1,346 @@ | |||
237 | 1 | /* | ||
238 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
239 | 3 | * | ||
240 | 4 | * Authors: | ||
241 | 5 | * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com> | ||
242 | 6 | * | ||
243 | 7 | * This file is part of history-service. | ||
244 | 8 | * | ||
245 | 9 | * history-service is free software; you can redistribute it and/or modify | ||
246 | 10 | * it under the terms of the GNU General Public License as published by | ||
247 | 11 | * the Free Software Foundation; version 3. | ||
248 | 12 | * | ||
249 | 13 | * history-service is distributed in the hope that it will be useful, | ||
250 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
251 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
252 | 16 | * GNU General Public License for more details. | ||
253 | 17 | * | ||
254 | 18 | * You should have received a copy of the GNU General Public License | ||
255 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
256 | 20 | */ | ||
257 | 21 | |||
258 | 22 | #include "historygroupedeventsmodel.h" | ||
259 | 23 | #include "phoneutils_p.h" | ||
260 | 24 | #include "sort.h" | ||
261 | 25 | #include "historyqmlsort.h" | ||
262 | 26 | |||
263 | 27 | HistoryGroupedEventsModel::HistoryGroupedEventsModel(QObject *parent) : | ||
264 | 28 | HistoryEventModel(parent) | ||
265 | 29 | { | ||
266 | 30 | } | ||
267 | 31 | |||
268 | 32 | int HistoryGroupedEventsModel::rowCount(const QModelIndex &parent) const | ||
269 | 33 | { | ||
270 | 34 | if (parent.isValid()) { | ||
271 | 35 | return 0; | ||
272 | 36 | } | ||
273 | 37 | |||
274 | 38 | return mEventGroups.count(); | ||
275 | 39 | } | ||
276 | 40 | |||
277 | 41 | QVariant HistoryGroupedEventsModel::data(const QModelIndex &index, int role) const | ||
278 | 42 | { | ||
279 | 43 | if (!index.isValid() || index.row() < 0 || index.row() >= mEventGroups.count()) { | ||
280 | 44 | return QVariant(); | ||
281 | 45 | } | ||
282 | 46 | |||
283 | 47 | HistoryEventGroup group = mEventGroups[index.row()]; | ||
284 | 48 | QVariant result; | ||
285 | 49 | QVariantList events; | ||
286 | 50 | |||
287 | 51 | switch (role) { | ||
288 | 52 | case EventsRole: | ||
289 | 53 | Q_FOREACH(const History::Event &event, group.events) { | ||
290 | 54 | events << event.properties(); | ||
291 | 55 | } | ||
292 | 56 | result = events; | ||
293 | 57 | break; | ||
294 | 58 | case EventCountRole: | ||
295 | 59 | result = group.events.count(); | ||
296 | 60 | break; | ||
297 | 61 | default: | ||
298 | 62 | result = eventData(group.displayedEvent, role); | ||
299 | 63 | break; | ||
300 | 64 | } | ||
301 | 65 | |||
302 | 66 | return result; | ||
303 | 67 | } | ||
304 | 68 | |||
305 | 69 | void HistoryGroupedEventsModel::fetchMore(const QModelIndex &parent) | ||
306 | 70 | { | ||
307 | 71 | if (!canFetchMore(parent)) { | ||
308 | 72 | return; | ||
309 | 73 | } | ||
310 | 74 | |||
311 | 75 | History::Events events = fetchNextPage(); | ||
312 | 76 | |||
313 | 77 | // History already deliver us the events in the right order | ||
314 | 78 | // but we might have added new entries in the added, removed, modified events. | ||
315 | 79 | // still, it is less expensive to do a sequential search starting from the bottom | ||
316 | 80 | // than to do a binary search for each event, as it is very likely that the entries | ||
317 | 81 | // belong to the bottom part of the model. | ||
318 | 82 | Q_FOREACH(const History::Event event, events) { | ||
319 | 83 | bool found = false; | ||
320 | 84 | int pos = mEventGroups.count() -1; | ||
321 | 85 | for (; pos >= 0; pos--) { | ||
322 | 86 | HistoryEventGroup &group = mEventGroups[pos]; | ||
323 | 87 | if (areOfSameGroup(event, group.displayedEvent)) { | ||
324 | 88 | found = true; | ||
325 | 89 | addEventToGroup(event, group, pos); | ||
326 | 90 | break; | ||
327 | 91 | } else if (isAscending() ? lessThan(group.displayedEvent, event) : lessThan(event, group.displayedEvent)) { | ||
328 | 92 | break; | ||
329 | 93 | } | ||
330 | 94 | } | ||
331 | 95 | |||
332 | 96 | if (!found) { | ||
333 | 97 | // the item goes into a new group right after the position found above | ||
334 | 98 | pos++; | ||
335 | 99 | HistoryEventGroup group; | ||
336 | 100 | group.displayedEvent = event; | ||
337 | 101 | group.events << event; | ||
338 | 102 | beginInsertRows(QModelIndex(), pos, pos); | ||
339 | 103 | mEventGroups.insert(pos, group); | ||
340 | 104 | endInsertRows(); | ||
341 | 105 | } | ||
342 | 106 | } | ||
343 | 107 | } | ||
344 | 108 | |||
345 | 109 | QHash<int, QByteArray> HistoryGroupedEventsModel::roleNames() const | ||
346 | 110 | { | ||
347 | 111 | QHash<int, QByteArray> roles = HistoryEventModel::roleNames(); | ||
348 | 112 | roles[EventsRole] = "events"; | ||
349 | 113 | roles[EventCountRole] = "eventCount"; | ||
350 | 114 | return roles; | ||
351 | 115 | } | ||
352 | 116 | |||
353 | 117 | void HistoryGroupedEventsModel::updateQuery() | ||
354 | 118 | { | ||
355 | 119 | // remove all event groups from the model | ||
356 | 120 | if (!mEventGroups.isEmpty()) { | ||
357 | 121 | beginRemoveRows(QModelIndex(), 0, mEventGroups.count() - 1); | ||
358 | 122 | mEventGroups.clear(); | ||
359 | 123 | endRemoveRows(); | ||
360 | 124 | } | ||
361 | 125 | |||
362 | 126 | // and ask HistoryEventModel to update the query and fetch items again | ||
363 | 127 | HistoryEventModel::updateQuery(); | ||
364 | 128 | } | ||
365 | 129 | |||
366 | 130 | void HistoryGroupedEventsModel::onEventsAdded(const History::Events &events) | ||
367 | 131 | { | ||
368 | 132 | if (!events.count()) { | ||
369 | 133 | return; | ||
370 | 134 | } | ||
371 | 135 | |||
372 | 136 | Q_FOREACH(const History::Event &event, events) { | ||
373 | 137 | int pos = positionForEvent(event); | ||
374 | 138 | |||
375 | 139 | // check if the event belongs to the group at the position | ||
376 | 140 | if (pos >= 0 && pos < mEventGroups.count()) { | ||
377 | 141 | HistoryEventGroup &group = mEventGroups[pos]; | ||
378 | 142 | if (areOfSameGroup(event, group.displayedEvent)) { | ||
379 | 143 | addEventToGroup(event, group, pos); | ||
380 | 144 | continue; | ||
381 | 145 | } | ||
382 | 146 | } | ||
383 | 147 | |||
384 | 148 | // else, we just create a new group | ||
385 | 149 | beginInsertRows(QModelIndex(), pos, pos); | ||
386 | 150 | HistoryEventGroup group; | ||
387 | 151 | group.displayedEvent = event; | ||
388 | 152 | group.events << event; | ||
389 | 153 | mEventGroups.insert(pos, group); | ||
390 | 154 | endInsertRows(); | ||
391 | 155 | |||
392 | 156 | } | ||
393 | 157 | } | ||
394 | 158 | |||
395 | 159 | void HistoryGroupedEventsModel::onEventsModified(const History::Events &events) | ||
396 | 160 | { | ||
397 | 161 | // FIXME: we are not yet handling events changing the property used for sorting | ||
398 | 162 | // so for now the behavior is to find the item and check if it needs inserting or | ||
399 | 163 | // updating in the group, which is exactly what onEventsAdded() does, so: | ||
400 | 164 | onEventsAdded(events); | ||
401 | 165 | } | ||
402 | 166 | |||
403 | 167 | void HistoryGroupedEventsModel::onEventsRemoved(const History::Events &events) | ||
404 | 168 | { | ||
405 | 169 | Q_FOREACH(const History::Event &event, events) { | ||
406 | 170 | int pos = positionForEvent(event); | ||
407 | 171 | if (pos < 0 || pos >= rowCount()) { | ||
408 | 172 | continue; | ||
409 | 173 | } | ||
410 | 174 | HistoryEventGroup &group = mEventGroups[pos]; | ||
411 | 175 | if (!group.events.contains(event)) { | ||
412 | 176 | continue; | ||
413 | 177 | } | ||
414 | 178 | removeEventFromGroup(event, group, pos); | ||
415 | 179 | } | ||
416 | 180 | } | ||
417 | 181 | |||
418 | 182 | bool HistoryGroupedEventsModel::compareParticipants(const QStringList &list1, const QStringList &list2) | ||
419 | 183 | { | ||
420 | 184 | if (list1.count() != list2.count()) { | ||
421 | 185 | return false; | ||
422 | 186 | } | ||
423 | 187 | |||
424 | 188 | int found = 0; | ||
425 | 189 | Q_FOREACH(const QString &participant, list1) { | ||
426 | 190 | Q_FOREACH(const QString &item, list2) { | ||
427 | 191 | if (PhoneUtils::comparePhoneNumbers(participant, item)) { | ||
428 | 192 | found++; | ||
429 | 193 | break; | ||
430 | 194 | } | ||
431 | 195 | } | ||
432 | 196 | } | ||
433 | 197 | |||
434 | 198 | return found == list1.count(); | ||
435 | 199 | } | ||
436 | 200 | |||
437 | 201 | bool HistoryGroupedEventsModel::areOfSameGroup(const History::Event &event1, const History::Event &event2) | ||
438 | 202 | { | ||
439 | 203 | QVariantMap props1 = event1.properties(); | ||
440 | 204 | QVariantMap props2 = event2.properties(); | ||
441 | 205 | |||
442 | 206 | Q_FOREACH(const QString &property, mGroupingProperties) { | ||
443 | 207 | // first check if the property exists in the maps | ||
444 | 208 | if (!props1.contains(property) || !props2.contains(property)) { | ||
445 | 209 | return false; | ||
446 | 210 | } | ||
447 | 211 | |||
448 | 212 | // now check if the values are the same | ||
449 | 213 | if (property == History::FieldParticipants) { | ||
450 | 214 | if (!compareParticipants(props1[property].toStringList(), | ||
451 | 215 | props2[property].toStringList())) { | ||
452 | 216 | return false; | ||
453 | 217 | } | ||
454 | 218 | } else if (props1[property] != props2[property]) { | ||
455 | 219 | return false; | ||
456 | 220 | } | ||
457 | 221 | } | ||
458 | 222 | |||
459 | 223 | // if it didn't fail before, the events are indeed of the same group | ||
460 | 224 | return true; | ||
461 | 225 | } | ||
462 | 226 | |||
463 | 227 | void HistoryGroupedEventsModel::addEventToGroup(const History::Event &event, HistoryEventGroup &group, int row) | ||
464 | 228 | { | ||
465 | 229 | if (!group.events.contains(event)) { | ||
466 | 230 | // insert the event in the correct position according to the sort criteria | ||
467 | 231 | bool append = true; | ||
468 | 232 | for (int i = 0; i < group.events.count(); ++i) { | ||
469 | 233 | History::Event &otherEvent = group.events[i]; | ||
470 | 234 | if (isAscending() ? lessThan(event, otherEvent) : lessThan(otherEvent, event)) { | ||
471 | 235 | group.events.insert(i, event); | ||
472 | 236 | append = false; | ||
473 | 237 | break; | ||
474 | 238 | } | ||
475 | 239 | } | ||
476 | 240 | |||
477 | 241 | // if it is not above any item, just append it | ||
478 | 242 | if (append) { | ||
479 | 243 | group.events.append(event); | ||
480 | 244 | } | ||
481 | 245 | } | ||
482 | 246 | |||
483 | 247 | // now check if the displayed event should be updated | ||
484 | 248 | History::Event &firstEvent = group.events.first(); | ||
485 | 249 | if (group.displayedEvent != firstEvent) { | ||
486 | 250 | group.displayedEvent = firstEvent; | ||
487 | 251 | QModelIndex idx(index(row)); | ||
488 | 252 | Q_EMIT dataChanged(idx, idx); | ||
489 | 253 | } | ||
490 | 254 | } | ||
491 | 255 | |||
492 | 256 | void HistoryGroupedEventsModel::removeEventFromGroup(const History::Event &event, HistoryEventGroup &group, int row) | ||
493 | 257 | { | ||
494 | 258 | if (group.events.contains(event)) { | ||
495 | 259 | group.events.removeOne(event); | ||
496 | 260 | } | ||
497 | 261 | |||
498 | 262 | if (group.events.isEmpty()) { | ||
499 | 263 | beginRemoveRows(QModelIndex(), row, row); | ||
500 | 264 | mEventGroups.removeAt(row); | ||
501 | 265 | endRemoveRows(); | ||
502 | 266 | return; | ||
503 | 267 | } | ||
504 | 268 | |||
505 | 269 | if (group.displayedEvent == event) { | ||
506 | 270 | // check what is the event that should be displayed | ||
507 | 271 | group.displayedEvent = group.events.first(); | ||
508 | 272 | Q_FOREACH(const History::Event &other, group.events) { | ||
509 | 273 | if (isAscending() ? lessThan(other, group.displayedEvent) : lessThan(group.displayedEvent, other)) { | ||
510 | 274 | group.displayedEvent = other; | ||
511 | 275 | } | ||
512 | 276 | } | ||
513 | 277 | } | ||
514 | 278 | QModelIndex idx = index(row); | ||
515 | 279 | Q_EMIT dataChanged(idx, idx); | ||
516 | 280 | } | ||
517 | 281 | |||
518 | 282 | bool HistoryGroupedEventsModel::lessThan(const History::Event &left, const History::Event &right) const | ||
519 | 283 | { | ||
520 | 284 | |||
521 | 285 | QVariant leftValue = left.properties()[sort()->sortField()]; | ||
522 | 286 | QVariant rightValue = right.properties()[sort()->sortField()]; | ||
523 | 287 | return leftValue < rightValue; | ||
524 | 288 | } | ||
525 | 289 | |||
526 | 290 | int HistoryGroupedEventsModel::positionForEvent(const History::Event &event) const | ||
527 | 291 | { | ||
528 | 292 | // do a binary search for the item position on the list | ||
529 | 293 | int lowerBound = 0; | ||
530 | 294 | int upperBound = mEventGroups.count() - 1; | ||
531 | 295 | if (upperBound < 0) { | ||
532 | 296 | return 0; | ||
533 | 297 | } | ||
534 | 298 | |||
535 | 299 | while (true) { | ||
536 | 300 | int pos = (upperBound + lowerBound) / 2; | ||
537 | 301 | const History::Event &posEvent = mEventGroups[pos].displayedEvent; | ||
538 | 302 | if (lowerBound == pos) { | ||
539 | 303 | if (isAscending() ? lessThan(event, posEvent) : lessThan(posEvent, event)) { | ||
540 | 304 | return pos; | ||
541 | 305 | } | ||
542 | 306 | } | ||
543 | 307 | if (isAscending() ? lessThan(posEvent, event) : lessThan(event, posEvent)) { | ||
544 | 308 | lowerBound = pos + 1; // its in the upper | ||
545 | 309 | if (lowerBound > upperBound) { | ||
546 | 310 | return pos += 1; | ||
547 | 311 | } | ||
548 | 312 | } else if (lowerBound > upperBound) { | ||
549 | 313 | return pos; | ||
550 | 314 | } else { | ||
551 | 315 | upperBound = pos - 1; // its in the lower | ||
552 | 316 | } | ||
553 | 317 | } | ||
554 | 318 | |||
555 | 319 | } | ||
556 | 320 | |||
557 | 321 | QVariant HistoryGroupedEventsModel::get(int row) const | ||
558 | 322 | { | ||
559 | 323 | if (row >= rowCount() || row < 0) { | ||
560 | 324 | return QVariant(); | ||
561 | 325 | } | ||
562 | 326 | |||
563 | 327 | return data(index(row), EventsRole); | ||
564 | 328 | } | ||
565 | 329 | |||
566 | 330 | |||
567 | 331 | QStringList HistoryGroupedEventsModel::groupingProperties() const | ||
568 | 332 | { | ||
569 | 333 | return mGroupingProperties; | ||
570 | 334 | } | ||
571 | 335 | |||
572 | 336 | void HistoryGroupedEventsModel::setGroupingProperties(const QStringList &properties) | ||
573 | 337 | { | ||
574 | 338 | mGroupingProperties = properties; | ||
575 | 339 | Q_EMIT groupingPropertiesChanged(); | ||
576 | 340 | triggerQueryUpdate(); | ||
577 | 341 | } | ||
578 | 342 | |||
579 | 343 | bool HistoryGroupedEventsModel::isAscending() const | ||
580 | 344 | { | ||
581 | 345 | return sort() && sort()->sort().sortOrder() == Qt::AscendingOrder; | ||
582 | 346 | } | ||
583 | 0 | 347 | ||
584 | === added file 'Ubuntu/History/historygroupedeventsmodel.h' | |||
585 | --- Ubuntu/History/historygroupedeventsmodel.h 1970-01-01 00:00:00 +0000 | |||
586 | +++ Ubuntu/History/historygroupedeventsmodel.h 2014-08-22 15:31:10 +0000 | |||
587 | @@ -0,0 +1,82 @@ | |||
588 | 1 | /* | ||
589 | 2 | * Copyright (C) 2014 Canonical, Ltd. | ||
590 | 3 | * | ||
591 | 4 | * Authors: | ||
592 | 5 | * Gustavo Pichorim Boiko <gustavo.boiko@canonical.com> | ||
593 | 6 | * | ||
594 | 7 | * This file is part of history-service. | ||
595 | 8 | * | ||
596 | 9 | * history-service is free software; you can redistribute it and/or modify | ||
597 | 10 | * it under the terms of the GNU General Public License as published by | ||
598 | 11 | * the Free Software Foundation; version 3. | ||
599 | 12 | * | ||
600 | 13 | * history-service is distributed in the hope that it will be useful, | ||
601 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
602 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
603 | 16 | * GNU General Public License for more details. | ||
604 | 17 | * | ||
605 | 18 | * You should have received a copy of the GNU General Public License | ||
606 | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
607 | 20 | */ | ||
608 | 21 | |||
609 | 22 | #ifndef HISTORYGROUPEDEVENTSMODEL_H | ||
610 | 23 | #define HISTORYGROUPEDEVENTSMODEL_H | ||
611 | 24 | |||
612 | 25 | #include "historyeventmodel.h" | ||
613 | 26 | |||
614 | 27 | typedef struct { | ||
615 | 28 | History::Events events; | ||
616 | 29 | History::Event displayedEvent; | ||
617 | 30 | } HistoryEventGroup; | ||
618 | 31 | |||
619 | 32 | class HistoryGroupedEventsModel : public HistoryEventModel | ||
620 | 33 | { | ||
621 | 34 | Q_OBJECT | ||
622 | 35 | Q_PROPERTY(QStringList groupingProperties | ||
623 | 36 | READ groupingProperties | ||
624 | 37 | WRITE setGroupingProperties | ||
625 | 38 | NOTIFY groupingPropertiesChanged) | ||
626 | 39 | Q_ENUMS(GroupedRole) | ||
627 | 40 | public: | ||
628 | 41 | enum GroupedRole { | ||
629 | 42 | EventsRole = HistoryEventModel::LastRole, | ||
630 | 43 | EventCountRole | ||
631 | 44 | }; | ||
632 | 45 | |||
633 | 46 | explicit HistoryGroupedEventsModel(QObject *parent = 0); | ||
634 | 47 | |||
635 | 48 | // reimplemented from HistoryEventModel | ||
636 | 49 | int rowCount(const QModelIndex &parent = QModelIndex()) const; | ||
637 | 50 | QVariant data(const QModelIndex &index, int role) const; | ||
638 | 51 | Q_INVOKABLE void fetchMore(const QModelIndex &parent = QModelIndex()); | ||
639 | 52 | QHash<int, QByteArray> roleNames() const; | ||
640 | 53 | Q_INVOKABLE QVariant get(int row) const; | ||
641 | 54 | |||
642 | 55 | QStringList groupingProperties() const; | ||
643 | 56 | void setGroupingProperties(const QStringList &properties); | ||
644 | 57 | |||
645 | 58 | bool isAscending() const; | ||
646 | 59 | |||
647 | 60 | Q_SIGNALS: | ||
648 | 61 | void groupingPropertiesChanged(); | ||
649 | 62 | |||
650 | 63 | protected Q_SLOTS: | ||
651 | 64 | void updateQuery(); | ||
652 | 65 | void onEventsAdded(const History::Events &events); | ||
653 | 66 | void onEventsModified(const History::Events &events); | ||
654 | 67 | void onEventsRemoved(const History::Events &events); | ||
655 | 68 | |||
656 | 69 | protected: | ||
657 | 70 | bool compareParticipants(const QStringList &list1, const QStringList &list2); | ||
658 | 71 | bool areOfSameGroup(const History::Event &event1, const History::Event &event2); | ||
659 | 72 | void addEventToGroup(const History::Event &event, HistoryEventGroup &group, int row); | ||
660 | 73 | void removeEventFromGroup(const History::Event &event, HistoryEventGroup &group, int row); | ||
661 | 74 | bool lessThan(const History::Event &left, const History::Event &right) const; | ||
662 | 75 | int positionForEvent(const History::Event &event) const; | ||
663 | 76 | |||
664 | 77 | private: | ||
665 | 78 | QStringList mGroupingProperties; | ||
666 | 79 | QList<HistoryEventGroup> mEventGroups; | ||
667 | 80 | }; | ||
668 | 81 | |||
669 | 82 | #endif // HISTORYGROUPEDEVENTSMODEL_H | ||
670 | 0 | 83 | ||
671 | === modified file 'Ubuntu/History/historyqmlplugin.cpp' | |||
672 | --- Ubuntu/History/historyqmlplugin.cpp 2014-07-14 23:05:23 +0000 | |||
673 | +++ Ubuntu/History/historyqmlplugin.cpp 2014-08-22 15:31:10 +0000 | |||
674 | @@ -27,6 +27,7 @@ | |||
675 | 27 | #include "historythreadmodel.h" | 27 | #include "historythreadmodel.h" |
676 | 28 | #include "historythreadgroupingproxymodel.h" | 28 | #include "historythreadgroupingproxymodel.h" |
677 | 29 | #include "historyeventmodel.h" | 29 | #include "historyeventmodel.h" |
678 | 30 | #include "historygroupedeventsmodel.h" | ||
679 | 30 | #include "historyqmltexteventattachment.h" | 31 | #include "historyqmltexteventattachment.h" |
680 | 31 | #include "sortproxymodel.h" | 32 | #include "sortproxymodel.h" |
681 | 32 | #include <QQmlEngine> | 33 | #include <QQmlEngine> |
682 | @@ -43,6 +44,7 @@ | |||
683 | 43 | { | 44 | { |
684 | 44 | // @uri History | 45 | // @uri History |
685 | 45 | qmlRegisterType<HistoryEventModel>(uri, 0, 1, "HistoryEventModel"); | 46 | qmlRegisterType<HistoryEventModel>(uri, 0, 1, "HistoryEventModel"); |
686 | 47 | qmlRegisterType<HistoryGroupedEventsModel>(uri, 0, 1, "HistoryGroupedEventsModel"); | ||
687 | 46 | qmlRegisterType<HistoryThreadModel>(uri, 0, 1, "HistoryThreadModel"); | 48 | qmlRegisterType<HistoryThreadModel>(uri, 0, 1, "HistoryThreadModel"); |
688 | 47 | qmlRegisterType<HistoryQmlFilter>(uri, 0, 1, "HistoryFilter"); | 49 | qmlRegisterType<HistoryQmlFilter>(uri, 0, 1, "HistoryFilter"); |
689 | 48 | qmlRegisterType<HistoryQmlIntersectionFilter>(uri, 0, 1, "HistoryIntersectionFilter"); | 50 | qmlRegisterType<HistoryQmlIntersectionFilter>(uri, 0, 1, "HistoryIntersectionFilter"); |
690 | 49 | 51 | ||
691 | === modified file 'Ubuntu/History/historythreadmodel.cpp' | |||
692 | --- Ubuntu/History/historythreadmodel.cpp 2014-08-07 19:22:31 +0000 | |||
693 | +++ Ubuntu/History/historythreadmodel.cpp 2014-08-22 15:31:10 +0000 | |||
694 | @@ -35,7 +35,8 @@ | |||
695 | 35 | Q_DECLARE_METATYPE(History::TextEventAttachments) | 35 | Q_DECLARE_METATYPE(History::TextEventAttachments) |
696 | 36 | 36 | ||
697 | 37 | HistoryThreadModel::HistoryThreadModel(QObject *parent) : | 37 | HistoryThreadModel::HistoryThreadModel(QObject *parent) : |
699 | 38 | QAbstractListModel(parent), mCanFetchMore(true), mFilter(0), mSort(0), mType(EventTypeText), mFetchTimer(0) | 38 | QAbstractListModel(parent), mCanFetchMore(true), mFilter(0), mSort(0), |
700 | 39 | mType(EventTypeText), mUpdateTimer(0) | ||
701 | 39 | { | 40 | { |
702 | 40 | // configure the roles | 41 | // configure the roles |
703 | 41 | mRoles[AccountIdRole] = "accountId"; | 42 | mRoles[AccountIdRole] = "accountId"; |
704 | @@ -66,7 +67,7 @@ | |||
705 | 66 | connect(this, SIGNAL(modelReset()), SIGNAL(countChanged())); | 67 | connect(this, SIGNAL(modelReset()), SIGNAL(countChanged())); |
706 | 67 | 68 | ||
707 | 68 | // create the results view | 69 | // create the results view |
709 | 69 | updateQuery(); | 70 | triggerQueryUpdate(); |
710 | 70 | } | 71 | } |
711 | 71 | 72 | ||
712 | 72 | int HistoryThreadModel::rowCount(const QModelIndex &parent) const | 73 | int HistoryThreadModel::rowCount(const QModelIndex &parent) const |
713 | @@ -213,7 +214,7 @@ | |||
714 | 213 | 214 | ||
715 | 214 | void HistoryThreadModel::fetchMore(const QModelIndex &parent) | 215 | void HistoryThreadModel::fetchMore(const QModelIndex &parent) |
716 | 215 | { | 216 | { |
718 | 216 | if (parent.isValid()) { | 217 | if (parent.isValid() || mThreadView.isNull()) { |
719 | 217 | return; | 218 | return; |
720 | 218 | } | 219 | } |
721 | 219 | 220 | ||
722 | @@ -249,11 +250,11 @@ | |||
723 | 249 | if (mFilter) { | 250 | if (mFilter) { |
724 | 250 | connect(mFilter, | 251 | connect(mFilter, |
725 | 251 | SIGNAL(filterChanged()), | 252 | SIGNAL(filterChanged()), |
727 | 252 | SLOT(updateQuery())); | 253 | SLOT(triggerQueryUpdate())); |
728 | 253 | } | 254 | } |
729 | 254 | 255 | ||
730 | 255 | Q_EMIT filterChanged(); | 256 | Q_EMIT filterChanged(); |
732 | 256 | updateQuery(); | 257 | triggerQueryUpdate(); |
733 | 257 | } | 258 | } |
734 | 258 | 259 | ||
735 | 259 | HistoryQmlSort *HistoryThreadModel::sort() const | 260 | HistoryQmlSort *HistoryThreadModel::sort() const |
736 | @@ -272,11 +273,11 @@ | |||
737 | 272 | if (mSort) { | 273 | if (mSort) { |
738 | 273 | connect(mSort, | 274 | connect(mSort, |
739 | 274 | SIGNAL(sortChanged()), | 275 | SIGNAL(sortChanged()), |
741 | 275 | SLOT(updateQuery())); | 276 | SLOT(triggerQueryUpdate())); |
742 | 276 | } | 277 | } |
743 | 277 | 278 | ||
744 | 278 | Q_EMIT sortChanged(); | 279 | Q_EMIT sortChanged(); |
746 | 279 | updateQuery(); | 280 | triggerQueryUpdate(); |
747 | 280 | } | 281 | } |
748 | 281 | 282 | ||
749 | 282 | HistoryThreadModel::EventType HistoryThreadModel::type() const | 283 | HistoryThreadModel::EventType HistoryThreadModel::type() const |
750 | @@ -288,7 +289,7 @@ | |||
751 | 288 | { | 289 | { |
752 | 289 | mType = value; | 290 | mType = value; |
753 | 290 | Q_EMIT typeChanged(); | 291 | Q_EMIT typeChanged(); |
755 | 291 | updateQuery(); | 292 | triggerQueryUpdate(); |
756 | 292 | } | 293 | } |
757 | 293 | 294 | ||
758 | 294 | QString HistoryThreadModel::threadIdForParticipants(const QString &accountId, int eventType, const QStringList &participants, int matchFlags, bool create) | 295 | QString HistoryThreadModel::threadIdForParticipants(const QString &accountId, int eventType, const QStringList &participants, int matchFlags, bool create) |
759 | @@ -324,6 +325,14 @@ | |||
760 | 324 | return mThreads[row].properties(); | 325 | return mThreads[row].properties(); |
761 | 325 | } | 326 | } |
762 | 326 | 327 | ||
763 | 328 | void HistoryThreadModel::triggerQueryUpdate() | ||
764 | 329 | { | ||
765 | 330 | if (mUpdateTimer) { | ||
766 | 331 | killTimer(mUpdateTimer); | ||
767 | 332 | } | ||
768 | 333 | mUpdateTimer = startTimer(100); | ||
769 | 334 | } | ||
770 | 335 | |||
771 | 327 | void HistoryThreadModel::updateQuery() | 336 | void HistoryThreadModel::updateQuery() |
772 | 328 | { | 337 | { |
773 | 329 | // remove all events from the model | 338 | // remove all events from the model |
774 | @@ -363,7 +372,7 @@ | |||
775 | 363 | SLOT(onThreadsRemoved(History::Threads))); | 372 | SLOT(onThreadsRemoved(History::Threads))); |
776 | 364 | connect(mThreadView.data(), | 373 | connect(mThreadView.data(), |
777 | 365 | SIGNAL(invalidated()), | 374 | SIGNAL(invalidated()), |
779 | 366 | SLOT(updateQuery())); | 375 | SLOT(triggerQueryUpdate())); |
780 | 367 | 376 | ||
781 | 368 | Q_FOREACH(const QVariant &attachment, mAttachmentCache) { | 377 | Q_FOREACH(const QVariant &attachment, mAttachmentCache) { |
782 | 369 | HistoryQmlTextEventAttachment *qmlAttachment = attachment.value<HistoryQmlTextEventAttachment *>(); | 378 | HistoryQmlTextEventAttachment *qmlAttachment = attachment.value<HistoryQmlTextEventAttachment *>(); |
783 | @@ -373,16 +382,10 @@ | |||
784 | 373 | } | 382 | } |
785 | 374 | mAttachmentCache.clear(); | 383 | mAttachmentCache.clear(); |
786 | 375 | 384 | ||
787 | 376 | if (mFetchTimer) { | ||
788 | 377 | killTimer(mFetchTimer); | ||
789 | 378 | } | ||
790 | 379 | |||
791 | 380 | // and fetch again | 385 | // and fetch again |
792 | 381 | mCanFetchMore = true; | 386 | mCanFetchMore = true; |
793 | 382 | Q_EMIT canFetchMoreChanged(); | 387 | Q_EMIT canFetchMoreChanged(); |
797 | 383 | 388 | fetchMore(QModelIndex()); | |
795 | 384 | // delay the loading just to give the settings some time to settle down | ||
796 | 385 | mFetchTimer = startTimer(100); | ||
798 | 386 | } | 389 | } |
799 | 387 | 390 | ||
800 | 388 | void HistoryThreadModel::onThreadsAdded(const History::Threads &threads) | 391 | void HistoryThreadModel::onThreadsAdded(const History::Threads &threads) |
801 | @@ -430,10 +433,9 @@ | |||
802 | 430 | 433 | ||
803 | 431 | void HistoryThreadModel::timerEvent(QTimerEvent *event) | 434 | void HistoryThreadModel::timerEvent(QTimerEvent *event) |
804 | 432 | { | 435 | { |
810 | 433 | if (event->timerId() == mFetchTimer) { | 436 | if (event->timerId() == mUpdateTimer) { |
811 | 434 | killTimer(mFetchTimer); | 437 | killTimer(mUpdateTimer); |
812 | 435 | mFetchTimer = 0; | 438 | mUpdateTimer = 0; |
813 | 436 | 439 | updateQuery(); | |
809 | 437 | fetchMore(QModelIndex()); | ||
814 | 438 | } | 440 | } |
815 | 439 | } | 441 | } |
816 | 440 | 442 | ||
817 | === modified file 'Ubuntu/History/historythreadmodel.h' | |||
818 | --- Ubuntu/History/historythreadmodel.h 2014-08-07 19:22:31 +0000 | |||
819 | +++ Ubuntu/History/historythreadmodel.h 2014-08-22 15:31:10 +0000 | |||
820 | @@ -125,6 +125,7 @@ | |||
821 | 125 | void canFetchMoreChanged(); | 125 | void canFetchMoreChanged(); |
822 | 126 | 126 | ||
823 | 127 | protected Q_SLOTS: | 127 | protected Q_SLOTS: |
824 | 128 | void triggerQueryUpdate(); | ||
825 | 128 | void updateQuery(); | 129 | void updateQuery(); |
826 | 129 | void onThreadsAdded(const History::Threads &threads); | 130 | void onThreadsAdded(const History::Threads &threads); |
827 | 130 | void onThreadsModified(const History::Threads &threads); | 131 | void onThreadsModified(const History::Threads &threads); |
828 | @@ -142,7 +143,7 @@ | |||
829 | 142 | EventType mType; | 143 | EventType mType; |
830 | 143 | QHash<int, QByteArray> mRoles; | 144 | QHash<int, QByteArray> mRoles; |
831 | 144 | mutable QMap<History::TextEvent, QList<QVariant> > mAttachmentCache; | 145 | mutable QMap<History::TextEvent, QList<QVariant> > mAttachmentCache; |
833 | 145 | int mFetchTimer; | 146 | int mUpdateTimer; |
834 | 146 | }; | 147 | }; |
835 | 147 | 148 | ||
836 | 148 | #endif // HISTORYTHREADMODEL_H | 149 | #endif // HISTORYTHREADMODEL_H |
837 | 149 | 150 | ||
838 | === modified file 'src/event.cpp' | |||
839 | --- src/event.cpp 2013-09-26 21:06:50 +0000 | |||
840 | +++ src/event.cpp 2014-08-22 15:31:10 +0000 | |||
841 | @@ -55,6 +55,7 @@ | |||
842 | 55 | map[FieldEventId] = eventId; | 55 | map[FieldEventId] = eventId; |
843 | 56 | map[FieldSenderId] = senderId; | 56 | map[FieldSenderId] = senderId; |
844 | 57 | map[FieldTimestamp] = timestamp.toString(Qt::ISODate); | 57 | map[FieldTimestamp] = timestamp.toString(Qt::ISODate); |
845 | 58 | map[FieldDate] = timestamp.date().toString(Qt::ISODate); | ||
846 | 58 | map[FieldNewEvent] = newEvent; | 59 | map[FieldNewEvent] = newEvent; |
847 | 59 | map[FieldType] = type(); | 60 | map[FieldType] = type(); |
848 | 60 | map[FieldParticipants] = participants; | 61 | map[FieldParticipants] = participants; |
849 | @@ -243,6 +244,11 @@ | |||
850 | 243 | return true; | 244 | return true; |
851 | 244 | } | 245 | } |
852 | 245 | 246 | ||
853 | 247 | bool Event::operator!=(const Event &other) const | ||
854 | 248 | { | ||
855 | 249 | return !(*this == other); | ||
856 | 250 | } | ||
857 | 251 | |||
858 | 246 | bool Event::operator<(const Event &other) const | 252 | bool Event::operator<(const Event &other) const |
859 | 247 | { | 253 | { |
860 | 248 | QString selfData = accountId() + threadId() + eventId(); | 254 | QString selfData = accountId() + threadId() + eventId(); |
861 | 249 | 255 | ||
862 | === modified file 'src/event.h' | |||
863 | --- src/event.h 2013-09-26 21:06:50 +0000 | |||
864 | +++ src/event.h 2014-08-22 15:31:10 +0000 | |||
865 | @@ -56,6 +56,7 @@ | |||
866 | 56 | QVariantMap properties() const; | 56 | QVariantMap properties() const; |
867 | 57 | bool isNull() const; | 57 | bool isNull() const; |
868 | 58 | bool operator==(const Event &other) const; | 58 | bool operator==(const Event &other) const; |
869 | 59 | bool operator!=(const Event &other) const; | ||
870 | 59 | bool operator<(const Event &other) const; | 60 | bool operator<(const Event &other) const; |
871 | 60 | 61 | ||
872 | 61 | protected: | 62 | protected: |
873 | 62 | 63 | ||
874 | === modified file 'src/types.h' | |||
875 | --- src/types.h 2014-06-25 11:45:09 +0000 | |||
876 | +++ src/types.h 2014-08-22 15:31:10 +0000 | |||
877 | @@ -106,6 +106,7 @@ | |||
878 | 106 | static const char* FieldUnreadCount = "unreadCount"; | 106 | static const char* FieldUnreadCount = "unreadCount"; |
879 | 107 | static const char* FieldSenderId = "senderId"; | 107 | static const char* FieldSenderId = "senderId"; |
880 | 108 | static const char* FieldTimestamp = "timestamp"; | 108 | static const char* FieldTimestamp = "timestamp"; |
881 | 109 | static const char* FieldDate = "date"; | ||
882 | 109 | static const char* FieldNewEvent = "newEvent"; | 110 | static const char* FieldNewEvent = "newEvent"; |
883 | 110 | 111 | ||
884 | 111 | // text event fields | 112 | // text event fields |