Merge lp:~zsombi/ubuntu-ui-toolkit/expose-alarm-id into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Work in progress
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/expose-alarm-id
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 639 lines (+268/-31)
14 files modified
components.api (+5/-3)
src/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp (+149/-18)
src/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h (+19/-0)
src/Ubuntu/Components/plugin/alarmmanager_p.cpp (+5/-0)
src/Ubuntu/Components/plugin/alarmmanager_p.h (+2/-0)
src/Ubuntu/Components/plugin/alarmmanager_p_p.h (+1/-0)
src/Ubuntu/Components/plugin/plugin.cpp (+2/-0)
src/Ubuntu/Components/plugin/ucalarm.cpp (+12/-1)
src/Ubuntu/Components/plugin/ucalarm.h (+3/-0)
src/Ubuntu/Components/plugin/ucalarm_p.h (+2/-0)
src/Ubuntu/Components/plugin/ucalarmmodel.cpp (+25/-9)
src/Ubuntu/Components/plugin/ucalarmmodel.h (+4/-0)
tests/resources/alarm/Alarms.qml (+2/-0)
tests/unit/tst_alarms/tst_alarms.cpp (+37/-0)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/expose-alarm-id
Reviewer Review Type Date Requested Status
Cris Dywan Needs Information
PS Jenkins bot continuous-integration Needs Fixing
Nekhelesh Ramananthan Pending
Review via email: mp+254084@code.launchpad.net

Commit message

Exposing Alarm.identifier and AlarmModel.find(identifier) API. Introduces alarm data versioning, introducing the version 1.1, all previous data being of version 1.0. Handles alarm data upgrades.

Description of the change

Exposing Alarm.identifier and AlarmModel.find(identifier) API. Introduces alarm data versioning, introducing the version 1.1, all previous data being of version 1.0. Handles alarm data upgrades.

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

442 UCAlarm::~UCAlarm()
443 {
444 + if (!objectName().isEmpty()) {
445 + qDebug() << "DESTROYING" << objectName();
446 + }

Forgotten debug line? Or if this was intentional it should be a critical.

review: Approve
Revision history for this message
Zsombor Egri (zsombi) wrote :

> 442 UCAlarm::~UCAlarm()
> 443 {
> 444 + if (!objectName().isEmpty()) {
> 445 + qDebug() << "DESTROYING" << objectName();
> 446 + }
>
> Forgotten debug line? Or if this was intentional it should be a critical.

Fixed. Thanks!

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

Thanks!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1436. By Zsombor Egri

staging sync

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Cris Dywan (kalikiana) wrote :

What's up with this?

review: Needs Information

Unmerged revisions

1436. By Zsombor Egri

staging sync

1435. By Zsombor Egri

staging sync

1434. By Zsombor Egri

rogue debug removed

1433. By Zsombor Egri

staging merge

1432. By Zsombor Egri

alarms returned by get() and find() invokables are hashed to avoid OOM situation

1431. By Zsombor Egri

tests

1430. By Zsombor Egri

move JSON conversions into AlarmDataAdapter; data version handling added

1429. By Zsombor Egri

moving common code in separate functions

1428. By Zsombor Egri

store alarm ID as separate extended detail from activation URL; use private getter fro identifier, should be applied for the entire property set to simplify the code

1427. By Zsombor Egri

AlarmModel.find added

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'components.api'
--- components.api 2015-07-24 13:31:03 +0000
+++ components.api 2015-07-27 08:49:11 +0000
@@ -81,11 +81,12 @@
81Ubuntu.Components.ActivityIndicator 1.3: AnimatedItem81Ubuntu.Components.ActivityIndicator 1.3: AnimatedItem
82 property bool onScreen82 property bool onScreen
83 property bool running83 property bool running
84Ubuntu.Components.Alarm 1.0 0.1: QtObject84Ubuntu.Components.Alarm 1.2 1.0 0.1: QtObject
85 property QDateTime date85 property QDateTime date
86 property DaysOfWeek daysOfWeek86 property DaysOfWeek daysOfWeek
87 property bool enabled87 property bool enabled
88 readonly property int error88 readonly property int error
89 readonly property string identifier 1.2
89 property string message90 property string message
90 function save()91 function save()
91 function cancel()92 function cancel()
@@ -134,10 +135,11 @@
134 Fail135 Fail
135 InProgress136 InProgress
136 Ready137 Ready
137Ubuntu.Components.AlarmModel 1.0 0.1: QAbstractListModel138Ubuntu.Components.AlarmModel 1.2 1.0 0.1: QAbstractListModel
138 readonly property int count139 readonly property int count
139 function refresh() 1.0140 function refresh() 1.2
140 function UCAlarm* get(int index)141 function UCAlarm* get(int index)
142 function UCAlarm* find(string alarmId) 1.2
141Ubuntu.Components.Argument 1.0 0.1: QtObject143Ubuntu.Components.Argument 1.0 0.1: QtObject
142 property string help144 property string help
143 function var at(int i)145 function var at(int i)
144146
=== modified file 'src/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp'
--- src/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp 2015-03-24 16:51:39 +0000
+++ src/Ubuntu/Components/plugin/adapters/alarmsadapter_organizer.cpp 2015-07-27 08:49:11 +0000
@@ -29,6 +29,8 @@
29#include <QtCore/QJsonDocument>29#include <QtCore/QJsonDocument>
30#include <QtCore/QJsonObject>30#include <QtCore/QJsonObject>
31#include <QtCore/QJsonArray>31#include <QtCore/QJsonArray>
32#include <QtCore/QUuid>
33#include <QtCore/QUrlQuery>
32#include <QtCore/QDebug>34#include <QtCore/QDebug>
3335
34#define ALARM_DATABASE "%1/alarms.json"36#define ALARM_DATABASE "%1/alarms.json"
@@ -43,11 +45,46 @@
43#define ALARM_COLLECTION "Alarms"45#define ALARM_COLLECTION "Alarms"
4446
45// special tags used as workaround for bug #136170247// special tags used as workaround for bug #1361702
46const char *tagAlarmService = "x-canonical-alarm";48const char *tagAlarmService = "x-canonical-alarm";
47const char *tagDisabledAlarm = "x-canonical-disabled";49const char *tagDisabledAlarm = "x-canonical-disabled";
50const char *tagAlarmVersion = "x-canonical-alarm-version";
51const char *tagAlarmId = "x-canonical-alarm-id";
52const char *tagActivationUrl = "x-canonical-activation-url";
53
54const char *currentAlarmsVersion= "1.1";
4855
49QTORGANIZER_USE_NAMESPACE56QTORGANIZER_USE_NAMESPACE
5057
58QString getEventDetail(const QOrganizerItem &item, const char *detailTag)
59{
60 QList<QOrganizerItemDetail> details = item.details(QOrganizerItemDetail::TypeExtendedDetail);
61 for (int i = 0; i < details.count(); i++) {
62 QOrganizerItemDetail detail = details[i];
63 if (detail.value(QOrganizerItemExtendedDetail::FieldName).toString() == QLatin1String(detailTag)) {
64 return detail.value(QOrganizerItemExtendedDetail::FieldData).toString();
65 }
66 }
67 return QString();
68}
69
70void setEventDetail(QOrganizerItem &item, const char *detailTag, const QString &data)
71{
72 // remove all previous identifiers from event
73 QList<QOrganizerItemDetail> details = item.details(QOrganizerItemDetail::TypeExtendedDetail);
74 for (int i = 0; i < details.count(); i++) {
75 QOrganizerItemDetail detail = details[i];
76 if (detail.value(QOrganizerItemExtendedDetail::FieldName).toString() == QLatin1String(detailTag)) {
77 item.removeDetail(&detail);
78 break;
79 }
80 }
81 // save the new detail
82 QOrganizerItemExtendedDetail exData;
83 exData.setName(detailTag);
84 exData.setData(data);
85 item.saveDetail(&exData);
86}
87
51/*-----------------------------------------------------------------------------88/*-----------------------------------------------------------------------------
52 * Adaptation layer for Alarm Data.89 * Adaptation layer for Alarm Data.
53 */90 */
@@ -171,6 +208,43 @@
171 return true;208 return true;
172}209}
173210
211// retrieve the identifier
212QString AlarmDataAdapter::identifier()
213{
214 QString alarmId = getEventDetail(event, tagAlarmId);
215 return alarmId;
216}
217
218// creates a new identifier and sets it to the event
219void AlarmDataAdapter::resetIdentifier(const QString &savedId)
220{
221 QString alarmId = savedId.isNull() ? QUuid::createUuid().toString() : savedId;
222 setEventDetail(event, tagAlarmId, alarmId);
223 changes |= AlarmManager::Identifier;
224
225 // update activation url as well
226 QUrl url("alarm://open");
227 QUrlQuery query;
228 query.addQueryItem("alarmId", alarmId);
229 url.setQuery(query);
230 setEventDetail(event, tagActivationUrl, url.toString());
231}
232
233// upgrade alarm data to the current version; returns true if upgare was needed
234bool AlarmDataAdapter::upgradeAlarmData()
235{
236 QString version = getEventDetail(event, tagAlarmVersion);
237 if (version.isEmpty() || version == QStringLiteral("1.0")) {
238 // version 1.0, upgrade
239 resetIdentifier();
240 // finally upgare to the current version
241 setEventDetail(event, tagAlarmVersion, currentAlarmsVersion);
242 return true;
243 }
244 return false;
245}
246
247
174QVariant AlarmDataAdapter::cookie() const248QVariant AlarmDataAdapter::cookie() const
175{249{
176 return QVariant::fromValue(event.id());250 return QVariant::fromValue(event.id());
@@ -214,6 +288,12 @@
214 if (event.id().managerUri().isEmpty()) {288 if (event.id().managerUri().isEmpty()) {
215 changes = AlarmManager::AllFields;289 changes = AlarmManager::AllFields;
216 }290 }
291
292 // make sure the alarm has an identifier set
293 if (identifier().isEmpty()) {
294 resetIdentifier();
295 }
296
217 QOrganizerItemSaveRequest *saveRequest = new QOrganizerItemSaveRequest(q_ptr);297 QOrganizerItemSaveRequest *saveRequest = new QOrganizerItemSaveRequest(q_ptr);
218 saveRequest->setItem(event);298 saveRequest->setItem(event);
219 request = saveRequest;299 request = saveRequest;
@@ -375,6 +455,37 @@
375 }455 }
376}456}
377457
458void AlarmDataAdapter::eventFromJson(const QJsonObject &object)
459{
460 q_ptr->setMessage(object["message"].toString());
461 q_ptr->setDate(QDateTime::fromString(object["date"].toString()));
462 q_ptr->setSound(object["sound"].toString());
463 q_ptr->setType(static_cast<UCAlarm::AlarmType>(object["type"].toInt()));
464 q_ptr->setDaysOfWeek(static_cast<UCAlarm::DaysOfWeek>(object["days"].toInt()));
465 q_ptr->setEnabled(object["enabled"].toBool());
466 setEventDetail(event, tagAlarmId, object[tagAlarmId].toString());
467 setEventDetail(event, tagActivationUrl, object[tagActivationUrl].toString());
468 setEventDetail(event, tagAlarmVersion, object[tagAlarmVersion].toString());
469 // call checkAlarm to complete field checks (i.e. type vs daysOfWeek, kick date, etc)
470 checkAlarm();
471}
472
473QJsonObject AlarmDataAdapter::eventToJson()
474{
475 QJsonObject object;
476 object[tagAlarmVersion] = QJsonValue(currentAlarmsVersion);
477 object["message"] = message();
478 object["date"] = date().toString();
479 object["sound"] = sound().toString();
480 object["type"] = QJsonValue(type());
481 object["days"] = QJsonValue(daysOfWeek());
482 object["enabled"] = QJsonValue(enabled());
483 object[tagAlarmId] = QJsonValue(identifier());
484 object[tagActivationUrl] = QJsonValue(getEventDetail(event, tagActivationUrl));
485 return object;
486}
487
488
378/*-----------------------------------------------------------------------------489/*-----------------------------------------------------------------------------
379 * Adaptation layer for Alarms.490 * Adaptation layer for Alarms.
380 */491 */
@@ -475,6 +586,9 @@
475 if (!file.open(QFile::ReadOnly)) {586 if (!file.open(QFile::ReadOnly)) {
476 return;587 return;
477 }588 }
589 // block the manager signals till we load the alarm data into memory
590 manager->blockSignals(true);
591
478 QByteArray data = file.readAll();592 QByteArray data = file.readAll();
479 QJsonDocument document(QJsonDocument::fromJson(data));593 QJsonDocument document(QJsonDocument::fromJson(data));
480 QJsonArray array = document.array();594 QJsonArray array = document.array();
@@ -483,20 +597,14 @@
483597
484 // use UCAlarm to save store JSON data598 // use UCAlarm to save store JSON data
485 UCAlarm alarm;599 UCAlarm alarm;
486 alarm.setMessage(object["message"].toString());
487 alarm.setDate(QDateTime::fromString(object["date"].toString()));
488 alarm.setSound(object["sound"].toString());
489 alarm.setType(static_cast<UCAlarm::AlarmType>(object["type"].toInt()));
490 alarm.setDaysOfWeek(static_cast<UCAlarm::DaysOfWeek>(object["days"].toInt()));
491 alarm.setEnabled(object["enabled"].toBool());
492
493 AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm));600 AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm));
494 // call checkAlarm to complete field checks (i.e. type vs daysOfWeek, kick date, etc)601 pAlarm->eventFromJson(object);
495 pAlarm->checkAlarm();
496 QOrganizerTodo event = pAlarm->data();602 QOrganizerTodo event = pAlarm->data();
497 manager->saveItem(&event);603 manager->saveItem(&event);
498 }604 }
499 file.close();605 file.close();
606 // unblock signals
607 manager->blockSignals(false);
500}608}
501609
502// save fallback manager data only610// save fallback manager data only
@@ -517,13 +625,8 @@
517 for(int i = 0; i < alarmList.count(); i++) {625 for(int i = 0; i < alarmList.count(); i++) {
518 // create an UCAlarm and set its event to ease conversions626 // create an UCAlarm and set its event to ease conversions
519 const UCAlarm *alarm = alarmList[i];627 const UCAlarm *alarm = alarmList[i];
520 QJsonObject object;628 AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(alarm));
521 object["message"] = alarm->message();629 QJsonObject object = pAlarm->eventToJson();
522 object["date"] = alarm->date().toString();
523 object["sound"] = alarm->sound().toString();
524 object["type"] = QJsonValue(alarm->type());
525 object["days"] = QJsonValue(alarm->daysOfWeek());
526 object["enabled"] = QJsonValue(alarm->enabled());
527 data.append(object);630 data.append(object);
528631
529 }632 }
@@ -662,6 +765,12 @@
662 return false;765 return false;
663}766}
664767
768UCAlarm *AlarmsAdapter::findAlarm(const QString &alarmId) const
769{
770 Q_ASSERT(!alarmId.isEmpty());
771 return const_cast<UCAlarm*>(alarmList.find(alarmId));
772}
773
665// returns a todo event from an ID, which can be an occurence774// returns a todo event from an ID, which can be an occurence
666QOrganizerTodo AlarmsAdapter::todoItem(const QOrganizerItemId &id)775QOrganizerTodo AlarmsAdapter::todoItem(const QOrganizerItemId &id)
667{776{
@@ -756,6 +865,12 @@
756865
757 QSet<QOrganizerItemId> parentId;866 QSet<QOrganizerItemId> parentId;
758 QOrganizerTodo event;867 QOrganizerTodo event;
868 bool upgraded = false;
869
870 // disable manager signals till we fetch the alarms so in case we must upgrade
871 // an alarm we won't get update signals
872 manager->blockSignals(true);
873
759 Q_FOREACH(const QOrganizerItem &item, fetchRequest->items()) {874 Q_FOREACH(const QOrganizerItem &item, fetchRequest->items()) {
760 // repeating alarms may be fetched as occurences, therefore check their parent event875 // repeating alarms may be fetched as occurences, therefore check their parent event
761 if (item.type() == QOrganizerItemType::TypeTodoOccurrence) {876 if (item.type() == QOrganizerItemType::TypeTodoOccurrence) {
@@ -776,10 +891,26 @@
776 UCAlarm alarm;891 UCAlarm alarm;
777 AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm));892 AlarmDataAdapter *pAlarm = static_cast<AlarmDataAdapter*>(UCAlarmPrivate::get(&alarm));
778 pAlarm->setData(event);893 pAlarm->setData(event);
894 // check if we need to upgrade the event to the current version
895 if (pAlarm->upgradeAlarmData()) {
896 // use synchronous save so we omit async signal replies
897 event = pAlarm->data();
898 manager->saveItem(&event);
899 saveAlarms();
900 upgraded = true;
901 }
779 adjustAlarmOccurrence(*pAlarm);902 adjustAlarmOccurrence(*pAlarm);
780 alarmList.insert(alarm);903 alarmList.insert(alarm);
781 }904 }
782905
906 // save upgrades
907 if (upgraded) {
908 saveAlarms();
909 }
910
911 // re-enable manager signals
912 manager->blockSignals(false);
913
783 completed = true;914 completed = true;
784 Q_EMIT q_ptr->alarmsRefreshed();915 Q_EMIT q_ptr->alarmsRefreshed();
785}916}
786917
=== modified file 'src/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h'
--- src/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2015-03-24 16:51:39 +0000
+++ src/Ubuntu/Components/plugin/adapters/alarmsadapter_p.h 2015-07-27 08:49:11 +0000
@@ -49,6 +49,8 @@
49 bool setDaysOfWeek(UCAlarm::DaysOfWeek days);49 bool setDaysOfWeek(UCAlarm::DaysOfWeek days);
50 QUrl sound() const;50 QUrl sound() const;
51 bool setSound(const QUrl &sound);51 bool setSound(const QUrl &sound);
52 QString identifier();
53 void resetIdentifier(const QString &savedId = QString());
52 QVariant cookie() const;54 QVariant cookie() const;
53 UCAlarm::Error checkAlarm();55 UCAlarm::Error checkAlarm();
5456
@@ -62,6 +64,7 @@
6264
63// adaptation specific data65// adaptation specific data
64 void adjustDowSettings(UCAlarm::AlarmType type, UCAlarm::DaysOfWeek days);66 void adjustDowSettings(UCAlarm::AlarmType type, UCAlarm::DaysOfWeek days);
67 bool upgradeAlarmData();
65 static QSet<Qt::DayOfWeek> daysToSet(int days);68 static QSet<Qt::DayOfWeek> daysToSet(int days);
66 static UCAlarm::DaysOfWeek daysFromSet(const QSet<Qt::DayOfWeek> &set);69 static UCAlarm::DaysOfWeek daysFromSet(const QSet<Qt::DayOfWeek> &set);
6770
@@ -71,6 +74,9 @@
71 }74 }
72 void setData(const QOrganizerTodo &data);75 void setData(const QOrganizerTodo &data);
7376
77 void eventFromJson(const QJsonObject &object);
78 QJsonObject eventToJson();
79
74protected:80protected:
75 QOrganizerTodo event;81 QOrganizerTodo event;
76 UCAlarm::AlarmType alarmType;82 UCAlarm::AlarmType alarmType;
@@ -140,6 +146,18 @@
140 UCAlarm *alarm = takeAt(index);146 UCAlarm *alarm = takeAt(index);
141 delete alarm;147 delete alarm;
142 }148 }
149 // find an alarm from its ID
150 const UCAlarm *find(const QString &alarmId) const
151 {
152 QMapIterator< QPair<QDateTime, QOrganizerItemId>, UCAlarm* > i(data);
153 while (i.hasNext()) {
154 i.next();
155 if (UCAlarmPrivate::get(i.value())->identifier() == alarmId) {
156 return i.value();
157 }
158 }
159 return NULL;
160 }
143161
144protected:162protected:
145 // removes alarm data at index and returns the alarm pointer163 // removes alarm data at index and returns the alarm pointer
@@ -183,6 +201,7 @@
183 int alarmCount();201 int alarmCount();
184 UCAlarm *getAlarmAt(int index) const;202 UCAlarm *getAlarmAt(int index) const;
185 bool findAlarm(const UCAlarm &alarm, const QVariant &cookie) const;203 bool findAlarm(const UCAlarm &alarm, const QVariant &cookie) const;
204 UCAlarm *findAlarm(const QString &alarmId) const;
186 void adjustAlarmOccurrence(AlarmDataAdapter &alarm);205 void adjustAlarmOccurrence(AlarmDataAdapter &alarm);
187206
188 void loadAlarms();207 void loadAlarms();
189208
=== modified file 'src/Ubuntu/Components/plugin/alarmmanager_p.cpp'
--- src/Ubuntu/Components/plugin/alarmmanager_p.cpp 2015-02-26 15:09:23 +0000
+++ src/Ubuntu/Components/plugin/alarmmanager_p.cpp 2015-07-27 08:49:11 +0000
@@ -78,6 +78,11 @@
78 return &alarm;78 return &alarm;
79}79}
8080
81UCAlarm *AlarmManager::findAlarm(const QString &alarmId) const
82{
83 return d_ptr->findAlarm(alarmId);
84}
85
81bool AlarmManager::verifyChange(UCAlarm *alarm, Change change, const QVariant &newData)86bool AlarmManager::verifyChange(UCAlarm *alarm, Change change, const QVariant &newData)
82{87{
83 return d_ptr->verifyChange(alarm, change, newData);88 return d_ptr->verifyChange(alarm, change, newData);
8489
=== modified file 'src/Ubuntu/Components/plugin/alarmmanager_p.h'
--- src/Ubuntu/Components/plugin/alarmmanager_p.h 2015-02-26 10:27:56 +0000
+++ src/Ubuntu/Components/plugin/alarmmanager_p.h 2015-07-27 08:49:11 +0000
@@ -89,6 +89,7 @@
89 Sound = 0x0008,89 Sound = 0x0008,
90 Type = 0x0010,90 Type = 0x0010,
91 Days = 0x0020,91 Days = 0x0020,
92 Identifier = 0x0040,
92 AllFields = 0x00FF93 AllFields = 0x00FF
93 };94 };
9495
@@ -100,6 +101,7 @@
100 int alarmCount();101 int alarmCount();
101 UCAlarm *alarmAt(int index);102 UCAlarm *alarmAt(int index);
102 UCAlarm *findAlarm(const QVariant &cookie) const;103 UCAlarm *findAlarm(const QVariant &cookie) const;
104 UCAlarm *findAlarm(const QString &alarmId) const;
103105
104 bool verifyChange(UCAlarm *alarm, Change change, const QVariant &newData);106 bool verifyChange(UCAlarm *alarm, Change change, const QVariant &newData);
105 static UCAlarmPrivate *createAlarmData(UCAlarm *alarm);107 static UCAlarmPrivate *createAlarmData(UCAlarm *alarm);
106108
=== modified file 'src/Ubuntu/Components/plugin/alarmmanager_p_p.h'
--- src/Ubuntu/Components/plugin/alarmmanager_p_p.h 2015-02-26 15:09:23 +0000
+++ src/Ubuntu/Components/plugin/alarmmanager_p_p.h 2015-07-27 08:49:11 +0000
@@ -47,6 +47,7 @@
47 virtual int alarmCount() = 0;47 virtual int alarmCount() = 0;
48 virtual UCAlarm *getAlarmAt(int index) const = 0;48 virtual UCAlarm *getAlarmAt(int index) const = 0;
49 virtual bool findAlarm(const UCAlarm &alarm, const QVariant &cookie) const = 0;49 virtual bool findAlarm(const UCAlarm &alarm, const QVariant &cookie) const = 0;
50 virtual UCAlarm *findAlarm(const QString &alarmId) const = 0;
5051
51 // function to verify whether the given alarm property has a given value set52 // function to verify whether the given alarm property has a given value set
52 // used for testing purposes53 // used for testing purposes
5354
=== modified file 'src/Ubuntu/Components/plugin/plugin.cpp'
--- src/Ubuntu/Components/plugin/plugin.cpp 2015-07-19 17:44:46 +0000
+++ src/Ubuntu/Components/plugin/plugin.cpp 2015-07-27 08:49:11 +0000
@@ -197,6 +197,8 @@
197 qmlRegisterType<UCServiceProperties, 1>(uri, 1, 1, "ServiceProperties");197 qmlRegisterType<UCServiceProperties, 1>(uri, 1, 1, "ServiceProperties");
198198
199 // register 1.2 only API199 // register 1.2 only API
200 qmlRegisterType<UCAlarm, 1>(uri, 1, 2, "Alarm");
201 qmlRegisterType<UCAlarmModel, 1>(uri, 1, 2, "AlarmModel");
200 qmlRegisterType<UCListItem>(uri, 1, 2, "ListItem");202 qmlRegisterType<UCListItem>(uri, 1, 2, "ListItem");
201 qmlRegisterType<UCListItemDivider>();203 qmlRegisterType<UCListItemDivider>();
202 qmlRegisterUncreatableType<UCSwipeEvent>(uri, 1, 2, "SwipeEvent", "This is an event object.");204 qmlRegisterUncreatableType<UCSwipeEvent>(uri, 1, 2, "SwipeEvent", "This is an event object.");
203205
=== modified file 'src/Ubuntu/Components/plugin/ucalarm.cpp'
--- src/Ubuntu/Components/plugin/ucalarm.cpp 2015-03-03 13:47:48 +0000
+++ src/Ubuntu/Components/plugin/ucalarm.cpp 2015-07-27 08:49:11 +0000
@@ -41,6 +41,7 @@
41 setMessage(UbuntuI18n::instance().tr("Alarm"));41 setMessage(UbuntuI18n::instance().tr("Alarm"));
42 setType(UCAlarm::OneTime);42 setType(UCAlarm::OneTime);
43 setDaysOfWeek(UCAlarm::AutoDetect);43 setDaysOfWeek(UCAlarm::AutoDetect);
44 resetIdentifier();
44}45}
4546
46void UCAlarmPrivate::_q_syncStatus(int operation, int status, int error) {47void UCAlarmPrivate::_q_syncStatus(int operation, int status, int error) {
@@ -64,6 +65,8 @@
64 Q_EMIT q->typeChanged();65 Q_EMIT q->typeChanged();
65 if (changes & AlarmManager::Days)66 if (changes & AlarmManager::Days)
66 Q_EMIT q->daysOfWeekChanged();67 Q_EMIT q->daysOfWeekChanged();
68 if (changes & AlarmManager::Identifier)
69 Q_EMIT q->identifierChanged();
67 changes = 0;70 changes = 0;
68 }71 }
6972
@@ -482,7 +485,7 @@
482 * The property holds the alarm's sound to be played when the alarm is triggered.485 * The property holds the alarm's sound to be played when the alarm is triggered.
483 * An empty url will mean to play the default sound.486 * An empty url will mean to play the default sound.
484 *487 *
485 * The defaul tvalue is an empty url.488 * The default value is an empty url.
486 */489 */
487QUrl UCAlarm::sound() const490QUrl UCAlarm::sound() const
488{491{
@@ -497,6 +500,14 @@
497}500}
498501
499/*!502/*!
503 * \qmlproperty string Alarm::identifier
504 * \readonly
505 * \since Ubuntu.Components 1.2
506 * The property specifies the unique identifier of the alarm. The identifier is
507 * set when created or when \l reset.
508 */
509
510/*!
500 * \qmlproperty Error Alarm::error511 * \qmlproperty Error Alarm::error
501 * The property holds the error code occurred during the last performed operation.512 * The property holds the error code occurred during the last performed operation.
502 *513 *
503514
=== modified file 'src/Ubuntu/Components/plugin/ucalarm.h'
--- src/Ubuntu/Components/plugin/ucalarm.h 2014-10-09 13:02:27 +0000
+++ src/Ubuntu/Components/plugin/ucalarm.h 2015-07-27 08:49:11 +0000
@@ -37,6 +37,7 @@
3737
38 Q_PROPERTY(int error READ error NOTIFY errorChanged)38 Q_PROPERTY(int error READ error NOTIFY errorChanged)
39 Q_PROPERTY(Status status READ status NOTIFY statusChanged)39 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
40 Q_PRIVATE_PROPERTY(d_ptr, QString identifier READ identifier NOTIFY identifierChanged REVISION 1)
4041
41 Q_ENUMS(Status Operation Error AlarmType DayOfWeek)42 Q_ENUMS(Status Operation Error AlarmType DayOfWeek)
42 Q_FLAGS(DaysOfWeek)43 Q_FLAGS(DaysOfWeek)
@@ -121,6 +122,8 @@
121 void errorChanged();122 void errorChanged();
122 void statusChanged(Operation operation);123 void statusChanged(Operation operation);
123124
125 Q_REVISION(1) void identifierChanged();
126
124public Q_SLOTS:127public Q_SLOTS:
125 void save();128 void save();
126 void cancel();129 void cancel();
127130
=== modified file 'src/Ubuntu/Components/plugin/ucalarm_p.h'
--- src/Ubuntu/Components/plugin/ucalarm_p.h 2015-03-24 16:51:39 +0000
+++ src/Ubuntu/Components/plugin/ucalarm_p.h 2015-07-27 08:49:11 +0000
@@ -51,6 +51,8 @@
51 virtual bool setDaysOfWeek(UCAlarm::DaysOfWeek days) = 0;51 virtual bool setDaysOfWeek(UCAlarm::DaysOfWeek days) = 0;
52 virtual QUrl sound() const = 0;52 virtual QUrl sound() const = 0;
53 virtual bool setSound(const QUrl &sound) = 0;53 virtual bool setSound(const QUrl &sound) = 0;
54 virtual QString identifier() = 0;
55 virtual void resetIdentifier(const QString &savedId = QString()) = 0;
54 virtual QVariant cookie() const = 0;56 virtual QVariant cookie() const = 0;
55 virtual UCAlarm::Error checkAlarm() = 0;57 virtual UCAlarm::Error checkAlarm() = 0;
5658
5759
=== modified file 'src/Ubuntu/Components/plugin/ucalarmmodel.cpp'
--- src/Ubuntu/Components/plugin/ucalarmmodel.cpp 2015-06-16 13:15:41 +0000
+++ src/Ubuntu/Components/plugin/ucalarmmodel.cpp 2015-07-27 08:49:11 +0000
@@ -22,7 +22,6 @@
22#include "alarmmanager_p.h"22#include "alarmmanager_p.h"
23#include <QtQml/QQmlPropertyMap>23#include <QtQml/QQmlPropertyMap>
24#include <QtQml/QQmlInfo>24#include <QtQml/QQmlInfo>
25#include <QtQml/QQmlEngine>
2625
27/*!26/*!
28 * \qmltype AlarmModel27 * \qmltype AlarmModel
@@ -156,6 +155,19 @@
156 refresh();155 refresh();
157}156}
158157
158UCAlarm *UCAlarmModel::hashedAlarm(UCAlarm *alarm)
159{
160 UCAlarm *result = 0;
161 const QString &id = UCAlarmPrivate::get(alarm)->identifier();
162 result = alarmHash.value(id).data();
163 if (!result) {
164 result = new UCAlarm(this);
165 UCAlarmPrivate::get(result)->copyAlarmData(*alarm);
166 alarmHash.insert(id, QPointer<UCAlarm>(result));
167 }
168 return result;
169}
170
159int UCAlarmModel::rowCount(const QModelIndex &parent) const171int UCAlarmModel::rowCount(const QModelIndex &parent) const
160{172{
161 Q_UNUSED(parent);173 Q_UNUSED(parent);
@@ -215,14 +227,18 @@
215 */227 */
216UCAlarm* UCAlarmModel::get(int index)228UCAlarm* UCAlarmModel::get(int index)
217{229{
218 UCAlarm *alarm = AlarmManager::instance().alarmAt(index);230 return hashedAlarm(AlarmManager::instance().alarmAt(index));
219 if (alarm) {231}
220 UCAlarm *tempAlarm = new UCAlarm(this);232
221 UCAlarmPrivate::get(tempAlarm)->copyAlarmData(*alarm);233/*!
222 alarm = tempAlarm;234 * \qmlmethod Alarm AlarmModel::find(string alarmId)
223 QQmlEngine::setObjectOwnership(tempAlarm, QQmlEngine::JavaScriptOwnership);235 * \since Ubuntu.Components 1.2
224 }236 * The function returns the alarm identified by the \c alarmId. The \c alarmId
225 return alarm;237 * cannot be an empty string. Returns null on error.
238 */
239UCAlarm *UCAlarmModel::find(const QString &alarmId)
240{
241 return hashedAlarm(AlarmManager::instance().findAlarm(alarmId));
226}242}
227243
228/*!244/*!
229245
=== modified file 'src/Ubuntu/Components/plugin/ucalarmmodel.h'
--- src/Ubuntu/Components/plugin/ucalarmmodel.h 2015-06-16 11:34:02 +0000
+++ src/Ubuntu/Components/plugin/ucalarmmodel.h 2015-07-27 08:49:11 +0000
@@ -43,6 +43,7 @@
4343
44 // invokables44 // invokables
45 Q_INVOKABLE UCAlarm *get(int index);45 Q_INVOKABLE UCAlarm *get(int index);
46 Q_REVISION(1) Q_INVOKABLE UCAlarm *find(const QString &alarmId);
4647
47 // property getters48 // property getters
48 int count() const;49 int count() const;
@@ -65,7 +66,10 @@
65 void moveFinished();66 void moveFinished();
6667
67private:68private:
69 QHash<QString, QPointer<UCAlarm> > alarmHash;
68 bool m_moved:1;70 bool m_moved:1;
71
72 UCAlarm *hashedAlarm(UCAlarm *alarm);
69};73};
7074
71#endif // UCALARMSMODEL_H75#endif // UCALARMSMODEL_H
7276
=== modified file 'tests/resources/alarm/Alarms.qml'
--- tests/resources/alarm/Alarms.qml 2015-03-03 13:20:06 +0000
+++ tests/resources/alarm/Alarms.qml 2015-07-27 08:49:11 +0000
@@ -26,6 +26,8 @@
26 height: units.gu(71)26 height: units.gu(71)
27 objectName: "mainView"27 objectName: "mainView"
2828
29 applicationName: "com.canonical.alarmtest"
30
29 AlarmModel{31 AlarmModel{
30 id: alarmModel32 id: alarmModel
31 }33 }
3234
=== modified file 'tests/unit/tst_alarms/tst_alarms.cpp'
--- tests/unit/tst_alarms/tst_alarms.cpp 2014-11-20 06:36:45 +0000
+++ tests/unit/tst_alarms/tst_alarms.cpp 2015-07-27 08:49:11 +0000
@@ -103,6 +103,15 @@
103 return false;103 return false;
104 }104 }
105105
106 QString createOneTime(const QString &message)
107 {
108 UCAlarm alarm(QDateTime::currentDateTime(), UCAlarm::AutoDetect, "test_" + message);
109 alarm.setSound(QUrl("file:///usr/share/sounds/ubuntu/ringtones/Bliss.ogg"));
110 alarm.save();
111 waitForInsert();
112 return UCAlarmPrivate::get(&alarm)->identifier();
113 }
114
106private Q_SLOTS:115private Q_SLOTS:
107116
108 void initTestCase()117 void initTestCase()
@@ -583,6 +592,34 @@
583 // check the tags592 // check the tags
584 QVERIFY(AlarmManager::instance().verifyChange(&alarm, AlarmManager::Enabled, enabled));593 QVERIFY(AlarmManager::instance().verifyChange(&alarm, AlarmManager::Enabled, enabled));
585 }594 }
595
596 void test_alarm_identifier()
597 {
598 UCAlarm alarm;
599 QVERIFY(!UCAlarmPrivate::get(&alarm)->identifier().isEmpty());
600 }
601
602 void test_alarm_identifier_differs_on_reset()
603 {
604 UCAlarm alarm;
605 QString id = UCAlarmPrivate::get(&alarm)->identifier();
606 alarm.reset();
607 QVERIFY(!UCAlarmPrivate::get(&alarm)->identifier().isEmpty());
608 QVERIFY(UCAlarmPrivate::get(&alarm)->identifier() != id);
609 }
610
611 void test_find_alarm_by_id()
612 {
613 QStringList ids;
614 for (int i = 0; i < 5; i++) {
615 ids << createOneTime(QString("find_alarm_by_id_%1").arg(i));
616 }
617
618 UCAlarmModel model;
619 for (int i = 0; i < ids.count(); i++) {
620 QVERIFY(model.find(ids[i]));
621 }
622 }
586};623};
587624
588QTEST_MAIN(tst_UCAlarms)625QTEST_MAIN(tst_UCAlarms)

Subscribers

People subscribed via source and target branches