Merge lp:~zsombi/ubuntu-ui-toolkit/alarm-regression-fix into lp:ubuntu-ui-toolkit/staging
- alarm-regression-fix
- Merge into staging
Proposed by
Zsombor Egri
Status: | Merged |
---|---|
Approved by: | Cris Dywan |
Approved revision: | 1420 |
Merged at revision: | 1422 |
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/alarm-regression-fix |
Merge into: | lp:ubuntu-ui-toolkit/staging |
Diff against target: |
627 lines (+185/-91) 10 files modified
modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp (+19/-15) modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h (+33/-12) modules/Ubuntu/Components/plugin/alarmmanager_p.cpp (+7/-8) modules/Ubuntu/Components/plugin/alarmmanager_p.h (+1/-1) modules/Ubuntu/Components/plugin/alarmmanager_p_p.h (+1/-3) modules/Ubuntu/Components/plugin/ucalarm.cpp (+2/-0) modules/Ubuntu/Components/plugin/ucalarmmodel.cpp (+3/-2) tests/resources/alarm/AlarmDays.qml (+4/-4) tests/resources/alarm/Alarms.qml (+55/-43) tests/unit_x11/tst_components/tst_alarms.qml (+60/-3) |
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/alarm-regression-fix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Cris Dywan | Pending | ||
Review via email:
|
Commit message
Alarm services regression fix.
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Needs Fixing
(continuous-integration)
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Cris Dywan (kalikiana) wrote : | # |
Looks to make sense (after a very long look, that is :-D)
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) : | # |
review:
Approve
(continuous-integration)
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-11-19 14:32:29 +0000 |
3 | +++ modules/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp 2015-02-26 15:11:20 +0000 |
4 | @@ -369,6 +369,13 @@ |
5 | } |
6 | } |
7 | |
8 | +void AlarmDataAdapter::copyData(const UCAlarm &other) |
9 | +{ |
10 | + AlarmDataAdapter *pOther = static_cast<AlarmDataAdapter*>(AlarmDataAdapter::get(&other)); |
11 | + setData(pOther->data()); |
12 | +} |
13 | + |
14 | + |
15 | /*----------------------------------------------------------------------------- |
16 | * Adaptation layer for Alarms. |
17 | */ |
18 | @@ -508,18 +515,16 @@ |
19 | return; |
20 | } |
21 | QJsonArray data; |
22 | - UCAlarm alarm; |
23 | - AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm)); |
24 | for(int i = 0; i < alarmList.count(); i++) { |
25 | // create an UCAlarm and set its event to ease conversions |
26 | - pAlarm->setData(alarmList[i]); |
27 | + const UCAlarm *alarm = alarmList[i]; |
28 | QJsonObject object; |
29 | - object["message"] = alarm.message(); |
30 | - object["date"] = alarm.date().toString(); |
31 | - object["sound"] = alarm.sound().toString(); |
32 | - object["type"] = QJsonValue(alarm.type()); |
33 | - object["days"] = QJsonValue(alarm.daysOfWeek()); |
34 | - object["enabled"] = QJsonValue(alarm.enabled()); |
35 | + object["message"] = alarm->message(); |
36 | + object["date"] = alarm->date().toString(); |
37 | + object["sound"] = alarm->sound().toString(); |
38 | + object["type"] = QJsonValue(alarm->type()); |
39 | + object["days"] = QJsonValue(alarm->daysOfWeek()); |
40 | + object["enabled"] = QJsonValue(alarm->enabled()); |
41 | data.append(object); |
42 | |
43 | } |
44 | @@ -640,11 +645,10 @@ |
45 | return alarmList.count(); |
46 | } |
47 | |
48 | -void AlarmsAdapter::getAlarmAt(const UCAlarm &alarm, int index) const |
49 | +UCAlarm *AlarmsAdapter::getAlarmAt(int index) const |
50 | { |
51 | Q_ASSERT(index >= 0 && index < alarmList.count()); |
52 | - AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm)); |
53 | - pAlarm->setData(alarmList[index]); |
54 | + return const_cast<UCAlarm*>(alarmList[index]); |
55 | } |
56 | |
57 | bool AlarmsAdapter::findAlarm(const UCAlarm &alarm, const QVariant &cookie) const |
58 | @@ -693,7 +697,7 @@ |
59 | adjustAlarmOccurrence(*pAlarm); |
60 | |
61 | // insert and get the index |
62 | - int index = alarmList.insert(pAlarm->data()); |
63 | + int index = alarmList.insert(alarm); |
64 | Q_EMIT q_ptr->alarmInsertStarted(index); |
65 | Q_EMIT q_ptr->alarmInsertFinished(); |
66 | } |
67 | @@ -717,7 +721,7 @@ |
68 | AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm)); |
69 | pAlarm->setData(event); |
70 | adjustAlarmOccurrence(*pAlarm); |
71 | - int newIndex = alarmList.update(index, pAlarm->data()); |
72 | + int newIndex = alarmList.update(index, alarm); |
73 | if (newIndex == index) { |
74 | Q_EMIT q_ptr->alarmUpdated(index); |
75 | } else { |
76 | @@ -774,7 +778,7 @@ |
77 | AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm)); |
78 | pAlarm->setData(event); |
79 | adjustAlarmOccurrence(*pAlarm); |
80 | - alarmList.insert(pAlarm->data()); |
81 | + alarmList.insert(alarm); |
82 | } |
83 | |
84 | completed = true; |
85 | |
86 | === modified file 'modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h' |
87 | --- modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2014-10-13 10:11:43 +0000 |
88 | +++ modules/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2015-02-26 15:11:20 +0000 |
89 | @@ -69,6 +69,7 @@ |
90 | return event; |
91 | } |
92 | void setData(const QOrganizerTodo &data); |
93 | + void copyData(const UCAlarm &other); |
94 | |
95 | protected: |
96 | QOrganizerTodo event; |
97 | @@ -87,6 +88,7 @@ |
98 | |
99 | void clear() |
100 | { |
101 | + qDeleteAll(data); |
102 | data.clear(); |
103 | idHash.clear(); |
104 | } |
105 | @@ -94,24 +96,36 @@ |
106 | { |
107 | return data.count(); |
108 | } |
109 | - const QOrganizerTodo operator[](int index) const |
110 | + const UCAlarm *operator[](int index) const |
111 | { |
112 | QPair<QDateTime, QOrganizerItemId> key = data.keys()[index]; |
113 | return data.value(key); |
114 | } |
115 | // update event at index, returns the new event index |
116 | - int update(int index, const QOrganizerTodo &alarm) |
117 | + int update(int index, const UCAlarm &alarm) |
118 | { |
119 | - removeAt(index); |
120 | - return insert(alarm); |
121 | + // take alarm from previous index, update its data and insert it again |
122 | + UCAlarm *oldAlarm = takeAt(index); |
123 | + // copy the other alarm data |
124 | + AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(AlarmDataAdapter::get(oldAlarm)); |
125 | + pAlarm->copyData(alarm); |
126 | + // and insert it back |
127 | + QDateTime dt = oldAlarm->date(); |
128 | + QOrganizerItemId id = oldAlarm->cookie().value<QOrganizerItemId>(); |
129 | + idHash.insert(id, dt); |
130 | + data.insert(QPair<QDateTime, QOrganizerItemId>(dt, id), oldAlarm); |
131 | + return indexOf(id); |
132 | } |
133 | // insert an alarm event into the list |
134 | - int insert(const QOrganizerTodo &alarm) |
135 | + int insert(const UCAlarm &alarm) |
136 | { |
137 | - QDateTime dt = AlarmUtils::normalizeDate(alarm.startDateTime()); |
138 | - idHash.insert(alarm.id(), dt); |
139 | - data.insert(QPair<QDateTime, QOrganizerItemId>(dt, alarm.id()), alarm); |
140 | - return indexOf(alarm.id()); |
141 | + QDateTime dt = alarm.date(); |
142 | + QOrganizerItemId id = alarm.cookie().value<QOrganizerItemId>(); |
143 | + idHash.insert(id, dt); |
144 | + UCAlarm *newAlarm = new UCAlarm; |
145 | + static_cast<AlarmDataAdapter*>(AlarmDataAdapter::get(newAlarm))->copyData(alarm); |
146 | + data.insert(QPair<QDateTime, QOrganizerItemId>(dt, id), newAlarm); |
147 | + return indexOf(id); |
148 | } |
149 | // returns the index of the alarm matching the id, -1 on error |
150 | int indexOf(const QOrganizerItemId &id) |
151 | @@ -123,14 +137,21 @@ |
152 | // remove alarm at index |
153 | void removeAt(int index) |
154 | { |
155 | + UCAlarm *alarm = takeAt(index); |
156 | + delete alarm; |
157 | + } |
158 | + // removes alarm data at index and returns the alarm pointer |
159 | + UCAlarm *takeAt(int index) |
160 | + { |
161 | QPair<QDateTime, QOrganizerItemId> key = data.keys()[index]; |
162 | - data.remove(key); |
163 | + UCAlarm *alarm = data.take(key); |
164 | idHash.remove(key.second); |
165 | + return alarm; |
166 | } |
167 | |
168 | private: |
169 | // ordered map by occurrence date + event id, ascending |
170 | - QMap< QPair<QDateTime, QOrganizerItemId>, QOrganizerTodo> data; |
171 | + QMap< QPair<QDateTime, QOrganizerItemId>, UCAlarm*> data; |
172 | // alarms ordered based on even id |
173 | QHash<QOrganizerItemId, QDateTime> idHash; |
174 | }; |
175 | @@ -158,7 +179,7 @@ |
176 | |
177 | void init(); |
178 | int alarmCount(); |
179 | - void getAlarmAt(const UCAlarm &alarm, int index) const; |
180 | + UCAlarm *getAlarmAt(int index) const; |
181 | bool findAlarm(const UCAlarm &alarm, const QVariant &cookie) const; |
182 | void adjustAlarmOccurrence(AlarmDataAdapter &alarm); |
183 | |
184 | |
185 | === modified file 'modules/Ubuntu/Components/plugin/alarmmanager_p.cpp' |
186 | --- modules/Ubuntu/Components/plugin/alarmmanager_p.cpp 2014-10-10 10:27:35 +0000 |
187 | +++ modules/Ubuntu/Components/plugin/alarmmanager_p.cpp 2015-02-26 15:11:20 +0000 |
188 | @@ -23,7 +23,6 @@ |
189 | |
190 | AlarmManagerPrivate::AlarmManagerPrivate(AlarmManager *qq) |
191 | : q_ptr(qq) |
192 | - , alarmHolder(0) |
193 | , completed(false) |
194 | { |
195 | } |
196 | @@ -50,7 +49,6 @@ |
197 | static AlarmManager instance; |
198 | if (!instance.d_ptr->completed) { |
199 | instance.d_ptr->init(); |
200 | - instance.d_ptr->alarmHolder = new UCAlarm(&instance); |
201 | } |
202 | return instance; |
203 | } |
204 | @@ -65,18 +63,19 @@ |
205 | return d_ptr->alarmCount(); |
206 | } |
207 | |
208 | -UCAlarm *AlarmManager::alarmAt(int index) const |
209 | +UCAlarm *AlarmManager::alarmAt(int index) |
210 | { |
211 | - d_ptr->getAlarmAt(*d_ptr->alarmHolder, index); |
212 | - return d_ptr->alarmHolder; |
213 | + return d_ptr->getAlarmAt(index); |
214 | } |
215 | |
216 | +// the function returns an un-cached alarm for testing purposes |
217 | UCAlarm *AlarmManager::findAlarm(const QVariant &cookie) const |
218 | { |
219 | - if (!d_ptr->findAlarm(*d_ptr->alarmHolder, cookie)) { |
220 | + static UCAlarm alarm; |
221 | + if (!d_ptr->findAlarm(alarm, cookie)) { |
222 | return 0; |
223 | - }; |
224 | - return d_ptr->alarmHolder; |
225 | + } |
226 | + return &alarm; |
227 | } |
228 | |
229 | bool AlarmManager::verifyChange(UCAlarm *alarm, Change change, const QVariant &newData) |
230 | |
231 | === modified file 'modules/Ubuntu/Components/plugin/alarmmanager_p.h' |
232 | --- modules/Ubuntu/Components/plugin/alarmmanager_p.h 2014-10-13 10:53:48 +0000 |
233 | +++ modules/Ubuntu/Components/plugin/alarmmanager_p.h 2015-02-26 15:11:20 +0000 |
234 | @@ -98,7 +98,7 @@ |
235 | |
236 | bool fetchAlarms(); |
237 | int alarmCount(); |
238 | - UCAlarm *alarmAt(int index) const; |
239 | + UCAlarm *alarmAt(int index); |
240 | UCAlarm *findAlarm(const QVariant &cookie) const; |
241 | |
242 | bool verifyChange(UCAlarm *alarm, Change change, const QVariant &newData); |
243 | |
244 | === modified file 'modules/Ubuntu/Components/plugin/alarmmanager_p_p.h' |
245 | --- modules/Ubuntu/Components/plugin/alarmmanager_p_p.h 2014-10-10 10:27:35 +0000 |
246 | +++ modules/Ubuntu/Components/plugin/alarmmanager_p_p.h 2015-02-26 15:11:20 +0000 |
247 | @@ -40,14 +40,12 @@ |
248 | } |
249 | |
250 | AlarmManager *q_ptr; |
251 | - // used by alarmAt() and findAlarm() methods |
252 | - UCAlarm *alarmHolder; |
253 | bool completed:1; |
254 | |
255 | virtual void init() = 0; |
256 | virtual bool fetchAlarms() = 0; |
257 | virtual int alarmCount() = 0; |
258 | - virtual void getAlarmAt(const UCAlarm &alarm, int index) const = 0; |
259 | + virtual UCAlarm *getAlarmAt(int index) const = 0; |
260 | virtual bool findAlarm(const UCAlarm &alarm, const QVariant &cookie) const = 0; |
261 | |
262 | // function to verify whether the given alarm property has a given value set |
263 | |
264 | === modified file 'modules/Ubuntu/Components/plugin/ucalarm.cpp' |
265 | --- modules/Ubuntu/Components/plugin/ucalarm.cpp 2014-11-20 06:36:45 +0000 |
266 | +++ modules/Ubuntu/Components/plugin/ucalarm.cpp 2015-02-26 15:11:20 +0000 |
267 | @@ -278,6 +278,8 @@ |
268 | * The \l reset function clears the properties of the alarm bringing them to the |
269 | * default values. In this way the same alarm component can be used to save several |
270 | * alarms at the same time. |
271 | + * \note Do not call reset function on an alarm event object when that was returned |
272 | + * by the \l AlarmModel::get function, as that will reset the alarm cache data! |
273 | */ |
274 | |
275 | UCAlarm::UCAlarm(QObject *parent) |
276 | |
277 | === modified file 'modules/Ubuntu/Components/plugin/ucalarmmodel.cpp' |
278 | --- modules/Ubuntu/Components/plugin/ucalarmmodel.cpp 2014-11-20 13:26:50 +0000 |
279 | +++ modules/Ubuntu/Components/plugin/ucalarmmodel.cpp 2015-02-26 15:11:20 +0000 |
280 | @@ -205,8 +205,9 @@ |
281 | * } |
282 | * \endcode |
283 | * |
284 | - * \b Warning: The returned object is not guarantied to remain valid, it should |
285 | - * not be used in property bindings. |
286 | + * \note The returned object is not guarantied to remain valid, it should not be |
287 | + * used in property bindings. Also, \l {Alarm::reset}{reset()} should not be called |
288 | + * either as the call will clear the alarm data from the cache. |
289 | * |
290 | * \sa Alarm |
291 | */ |
292 | |
293 | === modified file 'tests/resources/alarm/AlarmDays.qml' |
294 | --- tests/resources/alarm/AlarmDays.qml 2014-11-20 06:36:45 +0000 |
295 | +++ tests/resources/alarm/AlarmDays.qml 2015-02-26 15:11:20 +0000 |
296 | @@ -22,7 +22,7 @@ |
297 | Dialog { |
298 | id:root |
299 | |
300 | - property var alarm |
301 | + property string property |
302 | |
303 | title: "Choose days" |
304 | |
305 | @@ -63,12 +63,12 @@ |
306 | Standard { |
307 | text: day |
308 | control: CheckBox { |
309 | - checked: (alarm.daysOfWeek & flag) == flag |
310 | + checked: caller && ((caller[property] & flag) == flag) |
311 | onCheckedChanged: { |
312 | if (checked) { |
313 | - alarm.daysOfWeek |= flag; |
314 | + caller[property] |= flag; |
315 | } else { |
316 | - alarm.daysOfWeek &= ~flag; |
317 | + caller[property] &= ~flag; |
318 | } |
319 | } |
320 | } |
321 | |
322 | === modified file 'tests/resources/alarm/Alarms.qml' |
323 | --- tests/resources/alarm/Alarms.qml 2014-11-20 13:12:58 +0000 |
324 | +++ tests/resources/alarm/Alarms.qml 2015-02-26 15:11:20 +0000 |
325 | @@ -15,7 +15,7 @@ |
326 | */ |
327 | |
328 | import QtQuick 2.0 |
329 | -import Ubuntu.Components 1.1 |
330 | +import Ubuntu.Components 1.2 // due to ListItem |
331 | import Ubuntu.Components.ListItems 1.0 |
332 | import Ubuntu.Components.Popups 1.0 |
333 | import Ubuntu.Components.Pickers 1.0 |
334 | @@ -25,24 +25,26 @@ |
335 | width: units.gu(40) |
336 | height: units.gu(71) |
337 | objectName: "mainView" |
338 | - useDeprecatedToolbar: false |
339 | |
340 | AlarmModel{ |
341 | id: alarmModel |
342 | } |
343 | |
344 | Alarm { |
345 | - id: alarm |
346 | + id: stockAlarm |
347 | onStatusChanged: { |
348 | print("operation " + operation + ", status= " + status + ", error=" + error); |
349 | if (status !== Alarm.Ready) |
350 | return; |
351 | if ((operation > Alarm.NoOperation) && (operation < Alarm.Reseting)) { |
352 | reset(); |
353 | + alarm = stockAlarm; |
354 | } |
355 | } |
356 | } |
357 | |
358 | + property Alarm alarm: stockAlarm |
359 | + |
360 | Page { |
361 | title: "Alarm test" |
362 | Column { |
363 | @@ -83,21 +85,17 @@ |
364 | Standard { |
365 | text: "Enabled" |
366 | control: Switch { |
367 | - id: enabled |
368 | + id: enabledSwitch |
369 | objectName: "alarm_enabled" |
370 | checked: alarm.enabled |
371 | - onCheckedChanged: { |
372 | - if (checked != alarm.enabled) { |
373 | - alarm.enabled = checked; |
374 | - } |
375 | - } |
376 | } |
377 | } |
378 | ItemSelector { |
379 | id: recurence |
380 | text: "Recurence" |
381 | model: ["OneTime", "Daily", "Weekly"] |
382 | - selectedIndex: { |
383 | + selectedIndex: setRecurence(alarm) |
384 | + function setRecurence(alarm) { |
385 | if (alarm.type == Alarm.OneTime) |
386 | return 0; |
387 | else if (alarm.type == Alarm.Repeating) { |
388 | @@ -107,32 +105,18 @@ |
389 | return 2; |
390 | } |
391 | } |
392 | - onSelectedIndexChanged: { |
393 | - switch (selectedIndex) { |
394 | - case 0: |
395 | - alarm.type = Alarm.OneTime; |
396 | - break; |
397 | - case 1: |
398 | - alarm.type = Alarm.Repeating; |
399 | - alarm.daysOfWeek = Alarm.Daily; |
400 | - break; |
401 | - case 2: |
402 | - alarm.type = Alarm.Repeating; |
403 | - alarm.daysOfWeek = Alarm.AutoDetect; |
404 | - break; |
405 | - } |
406 | - } |
407 | } |
408 | |
409 | MultiValue { |
410 | id: days |
411 | text: "Occurrence" |
412 | - values: getValues() |
413 | + values: getValues(alarm) |
414 | visible: recurence.selectedIndex === 2 |
415 | + property int daysOfWeek: alarm.daysOfWeek |
416 | onClicked: { |
417 | - PopupUtils.open(Qt.resolvedUrl("AlarmDays.qml"), days, {"alarm": alarm}); |
418 | + PopupUtils.open(Qt.resolvedUrl("AlarmDays.qml"), days, {property: "daysOfWeek"}); |
419 | } |
420 | - function getValues() { |
421 | + function getValues(alarm) { |
422 | var v = []; |
423 | if (alarm.daysOfWeek & Alarm.Monday) v.push("Monday"); |
424 | if (alarm.daysOfWeek & Alarm.Tuesday) v.push("Tuesday"); |
425 | @@ -154,8 +138,22 @@ |
426 | var date = new Date(); |
427 | date.setTime(timeChooser.time.getTime()); |
428 | date.setDate(dateChooser.date.getDate()); |
429 | - print("DATE", date, dateChooser.date.toDateString()) |
430 | alarm.date = date; |
431 | + alarm.enabled = enabledSwitch.checked; |
432 | + switch (recurence.selectedIndex) { |
433 | + case 0: |
434 | + alarm.type = Alarm.OneTime; |
435 | + alarm.daysOfWeek = Alarm.AutoDetect; |
436 | + break; |
437 | + case 1: |
438 | + alarm.type = Alarm.Repeating; |
439 | + alarm.daysOfWeek = Alarm.Daily; |
440 | + break; |
441 | + case 2: |
442 | + alarm.type = Alarm.Repeating; |
443 | + alarm.daysOfWeek = days.daysOfWeek; |
444 | + break; |
445 | + } |
446 | alarm.save(); |
447 | } |
448 | } |
449 | @@ -165,6 +163,7 @@ |
450 | control: Button { |
451 | text: "Reset" |
452 | onClicked: { |
453 | + alarm = stockAlarm; |
454 | alarm.reset(); |
455 | } |
456 | } |
457 | @@ -177,14 +176,31 @@ |
458 | height: units.gu(20) |
459 | clip: true |
460 | model: alarmModel |
461 | - delegate: Standard { |
462 | - text: message + recurring(model) + "\n" + model.date |
463 | + ListItemActions { |
464 | + id: leading |
465 | + actions: Action { |
466 | + iconName: "delete" |
467 | + onTriggered: { |
468 | + var data = alarmModel.get(value); |
469 | + data.cancel(); |
470 | + } |
471 | + } |
472 | + } |
473 | + delegate: ListItem { |
474 | + Label { |
475 | + text: message + recurring(model) + "\n" + model.date |
476 | + } |
477 | function recurring(alarmData) { |
478 | return (alarmData.type === Alarm.Repeating) ? "[Repeating]" : "[Onetime]"; |
479 | } |
480 | |
481 | - removable: true |
482 | - control: Switch { |
483 | + leadingActions: leading |
484 | + |
485 | + Switch { |
486 | + anchors { |
487 | + verticalCenter: parent.verticalCenter |
488 | + right: parent.right |
489 | + } |
490 | checked: model.enabled |
491 | onCheckedChanged: { |
492 | if (checked != model.enabled) { |
493 | @@ -196,17 +212,13 @@ |
494 | } |
495 | } |
496 | } |
497 | - onItemRemoved: { |
498 | - var data = alarmModel.get(index); |
499 | - data.cancel(); |
500 | - } |
501 | onClicked: { |
502 | - var data = alarmModel.get(index); |
503 | - alarm.message = data.message; |
504 | - alarm.date = data.date; |
505 | - alarm.type = data.type; |
506 | - alarm.daysOfWeek = data.daysOfWeek; |
507 | - alarm.enabled = data.enabled; |
508 | + alarm = alarmModel.get(index); |
509 | + dateChooser.date = alarm.date; |
510 | + timeChooser.time = alarm.date; |
511 | + message.text = alarm.message; |
512 | + enabledSwitch.checked = alarm.enabled; |
513 | + recurence.selectedIndex = recurence.setRecurence(alarm); |
514 | } |
515 | |
516 | Connections { |
517 | |
518 | === modified file 'tests/unit_x11/tst_components/tst_alarms.qml' |
519 | --- tests/unit_x11/tst_components/tst_alarms.qml 2014-10-13 12:03:37 +0000 |
520 | +++ tests/unit_x11/tst_components/tst_alarms.qml 2015-02-26 15:11:20 +0000 |
521 | @@ -21,8 +21,8 @@ |
522 | |
523 | Item { |
524 | id: root |
525 | - width: 100 |
526 | - height: 100 |
527 | + width: units.gu(40) |
528 | + height: units.gu(71) |
529 | |
530 | Alarm { |
531 | id: testAlarm |
532 | @@ -36,6 +36,7 @@ |
533 | id: roleTest |
534 | model: testModel |
535 | delegate: Item { |
536 | + height: units.gu(7) |
537 | objectName: "roleItem" |
538 | property var roleModel: model |
539 | property bool roleEnabled: model.enabled |
540 | @@ -44,9 +45,15 @@ |
541 | property int roleType: type |
542 | property int roleDaysOfWeek: daysOfWeek |
543 | property url roleSound: sound |
544 | + |
545 | + Label { |
546 | + text: model.date + model.message + model.sound + model.type + model.daysOfWeek + model.enabled |
547 | + } |
548 | } |
549 | } |
550 | |
551 | + property Alarm workAlarm: testAlarm |
552 | + |
553 | UbuntuTestCase { |
554 | id: testCase |
555 | name: "AlarmAPI" |
556 | @@ -63,7 +70,8 @@ |
557 | modelSpy.signalName = "rowsRemoved"; |
558 | while (i < testModel.count) { |
559 | var alarm = testModel.get(i); |
560 | - if (alarm.message === "test") { |
561 | + // tests start with "test" string |
562 | + if (alarm.message.search("test") == 0) { |
563 | alarm.cancel(); |
564 | modelSpy.wait(); |
565 | modelSpy.clear(); |
566 | @@ -74,6 +82,10 @@ |
567 | } |
568 | } |
569 | |
570 | + function normalizeDate(date) { |
571 | + return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0); |
572 | + } |
573 | + |
574 | function initTestCase() { |
575 | // AlarmModel initiates a fetch, wait till that one completes |
576 | modelSpy.wait(); |
577 | @@ -275,5 +287,50 @@ |
578 | verify(item.roleDaysOfWeek !== undefined, "daysOfWeek is defined"); |
579 | verify(item.roleSound !== undefined, "sound is defined"); |
580 | } |
581 | + |
582 | + // guarding bug #1401883 |
583 | + // changed alarm data retrieved from model, when used in bindings, resets the |
584 | + // model data |
585 | + function test_model_role_binding_bug1401883_data() { |
586 | + var dt1 = new Date(); |
587 | + dt1.setMinutes(dt1.getMinutes() + 2); |
588 | + var dt2 = new Date(dt1); |
589 | + dt2.setMinutes(dt2.getMinutes() + 2); |
590 | + return [ |
591 | + {tag: "Message", role: "message", firstValue: "test", updatedValue: "test_other"}, |
592 | + {tag: "Enabled", role: "enabled", firstValue: true, updatedValue: false}, |
593 | + {tag: "Date", role: "date", firstValue: dt1, updatedValue: dt2}, |
594 | + {tag: "Type", role: "type", firstValue: Alarm.Daily, updatedValue: Alarm.OneTime}, |
595 | + ]; |
596 | + } |
597 | + function test_model_role_binding_bug1401883(data) { |
598 | + // create a new test alarm and make sure we set the mandatory fields |
599 | + testAlarm.reset(); |
600 | + var dt = new Date(); |
601 | + dt.setMinutes(dt.getMinutes() + 1); |
602 | + testAlarm.date = dt; |
603 | + testAlarm.message = "test"; |
604 | + |
605 | + testAlarm[data.role] = data.firstValue; |
606 | + modelSpy.signalName = "rowsInserted"; |
607 | + modelSpy.clear(); |
608 | + testAlarm.save(); |
609 | + modelSpy.wait(); |
610 | + waitForRendering(roleTest); |
611 | + |
612 | + // change the date |
613 | + var alarmData = testModel.get(0); |
614 | + modelSpy.signalName = "dataChanged"; |
615 | + modelSpy.clear(); |
616 | + alarmData[data.role] = data.updatedValue; |
617 | + alarmData.save(); |
618 | + modelSpy.wait(500); |
619 | + |
620 | + if (data.role === "date") { |
621 | + compare(normalizeDate(testModel.get(0).date), normalizeDate(data.updatedValue), "Date differs"); |
622 | + } else { |
623 | + compare(testModel.get(0)[data.role], data.updatedValue, data.tag + " differs"); |
624 | + } |
625 | + } |
626 | } |
627 | } |
FAILED: Continuous integration, rev:1420 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1485/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 1553 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/212/ console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/215 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/215/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/212 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 1384 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 1551 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 1551/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 18389
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/1485/ rebuild
http://