Merge lp:~zsombi/ubuntu-ui-toolkit/20-alarm-model-update into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Cris Dywan
Approved revision: 1210
Merged at revision: 1209
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/20-alarm-model-update
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~zsombi/ubuntu-ui-toolkit/10-alarm-data
Diff against target: 332 lines (+141/-13)
9 files modified
modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp (+46/-1)
modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h (+1/-0)
modules/Ubuntu/Components/plugin/alarmmanager_p.cpp (+1/-1)
modules/Ubuntu/Components/plugin/alarmmanager_p.h (+20/-1)
modules/Ubuntu/Components/plugin/alarmmanager_p_p.h (+1/-1)
modules/Ubuntu/Components/plugin/ucalarmmodel.cpp (+29/-1)
modules/Ubuntu/Components/plugin/ucalarmmodel.h (+1/-0)
tests/unit/tst_alarms/tst_alarms.cpp (+2/-2)
tests/unit_x11/tst_components/tst_alarms.qml (+40/-6)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/20-alarm-model-update
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Cris Dywan Approve
Nekhelesh Ramananthan Pending
Review via email: mp+231867@code.launchpad.net

Commit message

AlamrModel is no longer reset when individual alarm is changed. This avoids UI flickering in Clock app.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1210. By Zsombor Egri

register QOrganizwerItemId comparators for QVariant use

Revision history for this message
Cris Dywan (kalikiana) wrote :

Looks sensible.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

erm I was testing this to see if it causes any regressions in the clock app but it seems it got merged before I could complete?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp'
2--- modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp 2014-08-22 09:25:32 +0000
3+++ modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp 2014-08-22 14:48:35 +0000
4@@ -59,6 +59,9 @@
5 , manager(0)
6 , fetchRequest(0)
7 {
8+ // register QOrganizerItemId comparators so QVariant == operator can compare them
9+ QMetaType::registerComparators<QOrganizerItemId>();
10+
11 QString envManager(qgetenv("ALARM_BACKEND"));
12 if (envManager.isEmpty())
13 envManager = ALARM_MANAGER;
14@@ -93,7 +96,7 @@
15 // connect to manager to receive changes
16 QObject::connect(manager, SIGNAL(dataChanged()), this, SLOT(fetchAlarms()));
17 QObject::connect(manager, SIGNAL(itemsAdded(QList<QOrganizerItemId>)), this, SLOT(fetchAlarms()));
18- QObject::connect(manager, SIGNAL(itemsChanged(QList<QOrganizerItemId>)), this, SLOT(fetchAlarms()));
19+ QObject::connect(manager, SIGNAL(itemsChanged(QList<QOrganizerItemId>)), this, SLOT(updateAlarms(QList<QOrganizerItemId>)));
20 QObject::connect(manager, SIGNAL(itemsRemoved(QList<QOrganizerItemId>)), this, SLOT(fetchAlarms()));
21 }
22
23@@ -307,6 +310,48 @@
24 return adapter->fetch();
25 }
26
27+void AlarmsAdapter::updateAlarms(QList<QOrganizerItemId> list)
28+{
29+ if (list.size() < 0) {
30+ return;
31+ }
32+ QList<QVariant> cookies;
33+ QSet<QOrganizerItemId> parentId;
34+ QOrganizerTodo event;
35+ Q_FOREACH(const QOrganizerItemId &id, list) {
36+ const QOrganizerItem item = manager->item(id);
37+ if (item.type() == QOrganizerItemType::TypeTodoOccurrence) {
38+ QOrganizerTodoOccurrence occurrence = static_cast<QOrganizerTodoOccurrence>(item);
39+ QOrganizerItemId eventId = occurrence.parentId();
40+ if (parentId.contains(eventId)) {
41+ continue;
42+ }
43+ parentId << eventId;
44+ event = static_cast<QOrganizerTodo>(manager->item(eventId));
45+ } else if (item.type() == QOrganizerItemType::TypeTodo){
46+ event = static_cast<QOrganizerTodo>(item);
47+ } else {
48+ continue;
49+ }
50+
51+ // update alarm data
52+ QVariant cookie = QVariant::fromValue<QOrganizerItemId>(event.id());
53+ int index = alarmList.indexOfAlarm(cookie);
54+ if (index < 0) {
55+ qFatal("The Alarm data has been updated with an unregistered item!");
56+ }
57+ AlarmData data = alarmList[index];
58+ if (alarmDataFromOrganizerEvent(event, data) == UCAlarm::NoError) {
59+ adjustAlarmOccurrence(event, data);
60+ }
61+ alarmList[index] = data;
62+
63+ // register cookie for update
64+ cookies << cookie;
65+ }
66+ Q_EMIT q_ptr->alarmsUpdated(cookies);
67+}
68+
69 void AlarmsAdapter::completeFetchAlarms(const QList<QOrganizerItem> &alarms)
70 {
71 alarmList.clear();
72
73=== modified file 'modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h'
74--- modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2014-02-28 09:02:40 +0000
75+++ modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2014-08-22 14:48:35 +0000
76@@ -92,6 +92,7 @@
77
78 public Q_SLOTS:
79 bool fetchAlarms();
80+ void updateAlarms(QList<QOrganizerItemId> list);
81
82 protected:
83 AlarmRequest *fetchRequest;
84
85=== modified file 'modules/Ubuntu/Components/plugin/alarmmanager_p.cpp'
86--- modules/Ubuntu/Components/plugin/alarmmanager_p.cpp 2013-08-29 11:23:22 +0000
87+++ modules/Ubuntu/Components/plugin/alarmmanager_p.cpp 2014-08-22 14:48:35 +0000
88@@ -53,7 +53,7 @@
89 return instance;
90 }
91
92-QList<AlarmData> AlarmManager::alarms() const
93+AlarmList AlarmManager::alarms() const
94 {
95 Q_D(const AlarmManager);
96 return d->alarmList;
97
98=== modified file 'modules/Ubuntu/Components/plugin/alarmmanager_p.h'
99--- modules/Ubuntu/Components/plugin/alarmmanager_p.h 2014-08-06 14:22:14 +0000
100+++ modules/Ubuntu/Components/plugin/alarmmanager_p.h 2014-08-22 14:48:35 +0000
101@@ -123,6 +123,24 @@
102 bool enabled;
103 };
104
105+// list of alarms
106+class AlarmList: public QList<AlarmData>
107+{
108+public:
109+ AlarmList(){}
110+
111+ // returns the index of the alarm matching a cookie, -1 on error
112+ inline int indexOfAlarm(const QVariant &cookie)
113+ {
114+ for (int i = 0; i < size(); i++) {
115+ if (at(i).cookie == cookie) {
116+ return i;
117+ }
118+ }
119+ return -1;
120+ }
121+};
122+
123 class AlarmRequest;
124 class AlarmManagerPrivate;
125 class AlarmManager : public QObject
126@@ -139,10 +157,11 @@
127
128 static AlarmManager &instance();
129
130- QList<AlarmData> alarms() const;
131+ AlarmList alarms() const;
132
133 Q_SIGNALS:
134 void alarmsChanged();
135+ void alarmsUpdated(const QList<QVariant> &cookies);
136
137 private:
138 explicit AlarmManager(QObject *parent = 0);
139
140=== modified file 'modules/Ubuntu/Components/plugin/alarmmanager_p_p.h'
141--- modules/Ubuntu/Components/plugin/alarmmanager_p_p.h 2013-08-23 11:01:37 +0000
142+++ modules/Ubuntu/Components/plugin/alarmmanager_p_p.h 2014-08-22 14:48:35 +0000
143@@ -39,7 +39,7 @@
144 }
145
146 AlarmManager *q_ptr;
147- QList<AlarmData> alarmList;
148+ AlarmList alarmList;
149 bool completed:1;
150
151 virtual bool fetchAlarms() = 0;
152
153=== modified file 'modules/Ubuntu/Components/plugin/ucalarmmodel.cpp'
154--- modules/Ubuntu/Components/plugin/ucalarmmodel.cpp 2014-08-10 14:27:09 +0000
155+++ modules/Ubuntu/Components/plugin/ucalarmmodel.cpp 2014-08-22 14:48:35 +0000
156@@ -21,6 +21,7 @@
157 #include "ucalarm_p.h"
158 #include "alarmmanager_p.h"
159 #include <QtQml/QQmlPropertyMap>
160+#include <QtQml/QQmlInfo>
161
162 /*!
163 * \qmltype AlarmModel
164@@ -132,6 +133,8 @@
165 // the delegates may cause the model data to be invalid (released) as some
166 // backends may do the refresh/element removals synchronously
167 connect(&AlarmManager::instance(), SIGNAL(alarmsChanged()), this, SLOT(refresh()), Qt::QueuedConnection);
168+ // get individual alarm data updates
169+ connect(&AlarmManager::instance(), SIGNAL(alarmsUpdated(QList<QVariant>)), this, SLOT(update(QList<QVariant>)), Qt::QueuedConnection);
170 // fetch alarms
171 refresh();
172 m_ready = true;
173@@ -243,7 +246,7 @@
174 }
175
176 clear();
177- QList<AlarmData> alarms = AlarmManager::instance().alarms();
178+ AlarmList alarms = AlarmManager::instance().alarms();
179 Q_FOREACH(const AlarmData &data, alarms) {
180 UCAlarm *alarm = new UCAlarm(this);
181 UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm);
182@@ -256,3 +259,28 @@
183 endResetModel();
184 }
185 }
186+
187+/*!
188+ * \internal
189+ * Slot updating individual alarms' data.
190+ */
191+void UCAlarmModel::update(const QList<QVariant> cookies)
192+{
193+ AlarmList alarms = AlarmManager::instance().alarms();
194+ Q_FOREACH(const QVariant &cookie, cookies) {
195+ int alarmIndex = alarms.indexOfAlarm(cookie);
196+ AlarmData data = alarms[alarmIndex];
197+
198+ // the index of the m_alarm must be in sync with teh index of the alarms
199+ UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(m_alarms[alarmIndex]);
200+ if (pAlarm->rawData.cookie != cookie) {
201+ qmlInfo(this) << "Updated alarm cookies differ!" << cookie.toString() << pAlarm->rawData.cookie.toString();
202+ } else {
203+ pAlarm->rawData = data;
204+
205+ // create index and emit dataUpdate()
206+ QModelIndex modelIndex = createIndex(alarmIndex, 0);
207+ Q_EMIT dataChanged(modelIndex, modelIndex);
208+ }
209+ }
210+}
211
212=== modified file 'modules/Ubuntu/Components/plugin/ucalarmmodel.h'
213--- modules/Ubuntu/Components/plugin/ucalarmmodel.h 2013-08-23 05:19:46 +0000
214+++ modules/Ubuntu/Components/plugin/ucalarmmodel.h 2014-08-22 14:48:35 +0000
215@@ -47,6 +47,7 @@
216
217 private Q_SLOTS:
218 void refresh();
219+ void update(const QList<QVariant> cookies);
220
221 private:
222 bool m_ready;
223
224=== modified file 'tests/unit/tst_alarms/tst_alarms.cpp'
225--- tests/unit/tst_alarms/tst_alarms.cpp 2014-08-06 14:22:14 +0000
226+++ tests/unit/tst_alarms/tst_alarms.cpp 2014-08-22 14:48:35 +0000
227@@ -69,7 +69,7 @@
228 bool containsAlarm(UCAlarm *alarm, bool trace = false)
229 {
230 UCAlarmPrivate *pAlarm = UCAlarmPrivate::get(alarm);
231- QList<AlarmData> alarms = AlarmManager::instance().alarms();
232+ AlarmList alarms = AlarmManager::instance().alarms();
233 Q_FOREACH(AlarmData i, alarms) {
234 if (trace && (alarm->message() == i.message)) {
235 qDebug() << "----------------------";
236@@ -94,7 +94,7 @@
237
238 bool findAlarm(const QString &message, UCAlarm &result)
239 {
240- QList<AlarmData> alarms = AlarmManager::instance().alarms();
241+ AlarmList alarms = AlarmManager::instance().alarms();
242 Q_FOREACH(AlarmData i, alarms) {
243 if (i.message == message) {
244 UCAlarmPrivate::get(&result)->rawData = i;
245
246=== modified file 'tests/unit_x11/tst_components/tst_alarms.qml'
247--- tests/unit_x11/tst_components/tst_alarms.qml 2014-04-23 08:50:20 +0000
248+++ tests/unit_x11/tst_components/tst_alarms.qml 2014-08-22 14:48:35 +0000
249@@ -52,6 +52,17 @@
250 name: "AlarmAPI"
251 when: windowShown
252
253+ SignalSpy {
254+ id: dataChangedSpy
255+ signalName: "onDataChanged"
256+ target: testModel
257+ }
258+ SignalSpy {
259+ id: beginResetModelSpy
260+ signalName: "onBeginResetModel"
261+ target: testModel
262+ }
263+
264 function clean() {
265 var i = 0;
266 while (i < testModel.count) {
267@@ -74,6 +85,11 @@
268 clean();
269 }
270
271+ function init() {
272+ dataChangedSpy.clear();
273+ beginResetModelSpy.clear();
274+ }
275+
276 function test_createOneTimeFail() {
277 testAlarm.reset();
278 testAlarm.date = new Date();
279@@ -169,20 +185,32 @@
280 compare(testAlarm.error, Alarm.NoError, "alarm canceled");
281 }
282
283- function test_updateAlarm_sameType() {
284+ function test_updateAlarm_sameType_data() {
285+ var date = new Date();
286+ date.setMinutes(date.getMinutes() + 10);
287+ return [
288+ {tag: "LaterDate", referenceDate: date, addMinutes: 10},
289+ {tag: "EarlierDate", referenceDate: date, addMinutes: -5},
290+ ];
291+ }
292+ function test_updateAlarm_sameType(data) {
293+ var date = data.referenceDate;
294 testAlarm.reset();
295 testAlarm.message = "test";
296 testAlarm.type = Alarm.OneTime;
297- var dt = new Date();
298- dt.setMinutes(dt.getMinutes() + 10);
299- testAlarm.date = dt;
300+ testAlarm.date = date;
301
302 testAlarm.save();
303 compare(testAlarm.error, Alarm.NoError, "fist alarm added");
304+ compare(dataChangedSpy.count, 0, "No dataChanged() should be emitted");
305+ compare(beginResetModelSpy.count, 0, "No beginResetModel() should be emitted");
306
307- dt.setDate(dt.getDate() + 2);
308- testAlarm.date = dt;
309+ date.setMinutes(date.getMinutes() + data.addMinutes);
310+ testAlarm.date = date;
311+ testAlarm.save();
312 compare(testAlarm.error, Alarm.NoError, "updated alarm");
313+ compare(beginResetModelSpy.count, 0, "No beginResetModel() should be emitted");
314+ dataChangedSpy.wait();
315 }
316
317 function test_updateAlarm_differentType() {
318@@ -195,8 +223,14 @@
319
320 testAlarm.save();
321 compare(testAlarm.error, Alarm.NoError, "fist alarm added");
322+ compare(dataChangedSpy.count, 0, "No dataChanged() should be emitted");
323+ compare(beginResetModelSpy.count, 0, "No beginResetModel() should be emitted");
324+
325 testAlarm.type = Alarm.Repeating;
326+ testAlarm.save();
327 compare(testAlarm.error, Alarm.NoError, "updated alarm");
328+ compare(beginResetModelSpy.count, 0, "No beginResetModel() should be emitted");
329+ dataChangedSpy.wait();
330 }
331
332 function test_modelRoles() {

Subscribers

People subscribed via source and target branches