Merge lp:~renatofilho/qtorganizer5-eds/calendar-with-account-id into lp:qtorganizer5-eds
- calendar-with-account-id
- Merge into trunk
| Status: | Merged |
|---|---|
| Approved by: | Bill Filler |
| Approved revision: | 117 |
| Merged at revision: | 106 |
| Proposed branch: | lp:~renatofilho/qtorganizer5-eds/calendar-with-account-id |
| Merge into: | lp:qtorganizer5-eds |
| Diff against target: |
999 lines (+394/-90) 20 files modified
CMakeLists.txt (+1/-0) debian/control (+2/-1) organizer/CMakeLists.txt (+3/-0) organizer/qorganizer-eds-engine.cpp (+67/-20) organizer/qorganizer-eds-enginedata.cpp (+1/-1) organizer/qorganizer-eds-fetchrequestdata.cpp (+3/-0) organizer/qorganizer-eds-parseeventthread.cpp (+12/-0) organizer/qorganizer-eds-parseeventthread.h (+2/-0) organizer/qorganizer-eds-requestdata.h (+5/-1) organizer/qorganizer-eds-savecollectionrequestdata.cpp (+20/-14) organizer/qorganizer-eds-source-registry.cpp (+38/-0) organizer/qorganizer-eds-source-registry.h (+4/-0) organizer/qorganizer-eds-viewwatcher.cpp (+25/-13) organizer/qorganizer-eds-viewwatcher.h (+8/-0) tests/unittest/CMakeLists.txt (+1/-0) tests/unittest/collections-test.cpp (+113/-0) tests/unittest/eds-base-test.cpp (+19/-19) tests/unittest/eds-base-test.h (+2/-0) tests/unittest/gscopedpointer.h (+43/-0) tests/unittest/parseecal-test.cpp (+25/-21) |
| To merge this branch: | bzr merge lp:~renatofilho/qtorganizer5-eds/calendar-with-account-id |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| system-apps-ci-bot | continuous-integration | Needs Fixing | |
| PS Jenkins bot | continuous-integration | Approve | |
| Ubuntu Phablet Team | Pending | ||
|
Review via email:
|
|||
Commit message
Create a "collection-
Description of the change
| PS Jenkins bot (ps-jenkins) wrote : | # |
- 102. By Renato Araujo Oliveira Filho
-
Does not use source name as part of collection id.
- 103. By Renato Araujo Oliveira Filho
-
Use ubuntu eds extensions for calendar sources.
- 104. By Renato Araujo Oliveira Filho
-
Add "evolution-
data-server- ubuntu- dev" as build dep. - 105. By Renato Araujo Oliveira Filho
-
Print a warning message if it fails to create ubuntu extension.
- 106. By Renato Araujo Oliveira Filho
-
Implemented support for extra medata in the collections.
Will be used by syncMonitor to store sync url.
- 107. By Renato Araujo Oliveira Filho
-
Fixed sync writable property.
- 108. By Renato Araujo Oliveira Filho
-
check if the source has a ubuntu extension.
- 109. By Renato Araujo Oliveira Filho
-
Make a copy of calendar items on parse thread to avoid it to be destroyed outside of the thread.
- 110. By Renato Araujo Oliveira Filho
-
Trunk merged.
- 111. By Renato Araujo Oliveira Filho
-
Print warning message on trigger parse only once.
- 112. By Renato Araujo Oliveira Filho
-
Avoid crash during the engine destruction.
- 113. By Renato Araujo Oliveira Filho
-
Avoid crash if request is cancelled during the query.
| system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:113
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 114. By Renato Araujo Oliveira Filho
-
Emit 'collectionsMod
ified' when necessary.
| system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:114
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 115. By Renato Araujo Oliveira Filho
-
Use a batch operation to send event changes signal.
| system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:115
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 116. By Renato Araujo Oliveira Filho
-
Fixed memory leaks.
| system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:116
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 117. By Renato Araujo Oliveira Filho
-
Trunk merged.
| system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:117
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
| 1 | === modified file 'CMakeLists.txt' |
| 2 | --- CMakeLists.txt 2016-01-11 21:15:32 +0000 |
| 3 | +++ CMakeLists.txt 2016-07-11 14:47:56 +0000 |
| 4 | @@ -15,6 +15,7 @@ |
| 5 | pkg_check_modules(GIO REQUIRED gio-2.0>=2.32) |
| 6 | pkg_check_modules(EDATASERVER REQUIRED libedataserver-1.2>=3.8) |
| 7 | pkg_check_modules(ECAL REQUIRED REQUIRED libecal-1.2>=3.8) |
| 8 | +pkg_check_modules(UEDS REQUIRED REQUIRED evolution-data-server-ubuntu) |
| 9 | |
| 10 | set(CMAKE_INCLUDE_CURRENT_DIR ON) |
| 11 | set(CMAKE_AUTOMOC ON) |
| 12 | |
| 13 | === modified file 'debian/control' |
| 14 | --- debian/control 2015-07-23 13:48:21 +0000 |
| 15 | +++ debian/control 2016-07-11 14:47:56 +0000 |
| 16 | @@ -12,7 +12,8 @@ |
| 17 | qtpim5-dev, |
| 18 | evolution-data-server, |
| 19 | dbus-test-runner, |
| 20 | - gvfs-daemons |
| 21 | + gvfs-daemons, |
| 22 | + evolution-data-server-ubuntu-dev |
| 23 | Standards-Version: 3.9.4 |
| 24 | Homepage: https://launchpad.net/qtorganizer5-eds |
| 25 | # If you aren't a member of ~phablet-team but need to upload packaging changes, |
| 26 | |
| 27 | === modified file 'organizer/CMakeLists.txt' |
| 28 | --- organizer/CMakeLists.txt 2016-01-11 20:54:42 +0000 |
| 29 | +++ organizer/CMakeLists.txt 2016-07-11 14:47:56 +0000 |
| 30 | @@ -56,12 +56,14 @@ |
| 31 | ${GIO_INCLUDE_DIRS} |
| 32 | ${ECAL_INCLUDE_DIRS} |
| 33 | ${EDATASERVER_INCLUDE_DIRS} |
| 34 | + ${UEDS_INCLIDE_DIRS} |
| 35 | ) |
| 36 | |
| 37 | target_link_libraries(${QORGANIZER_BACKEND}-lib |
| 38 | ${GLIB_LIBRARIES} |
| 39 | ${ECAL_LIBRARIES} |
| 40 | ${EDATASERVER_LIBRARIES} |
| 41 | + ${UEDS_LIBRARIES} |
| 42 | ) |
| 43 | |
| 44 | target_link_libraries(${QORGANIZER_BACKEND} |
| 45 | @@ -69,6 +71,7 @@ |
| 46 | ${GLIB_LIBRARIES} |
| 47 | ${ECAL_LIBRARIES} |
| 48 | ${EDATASERVER_LIBRARIES} |
| 49 | + ${UEDS_LIBRARIES} |
| 50 | ) |
| 51 | |
| 52 | qt5_use_modules(${QORGANIZER_BACKEND}-lib Core Organizer) |
| 53 | |
| 54 | === modified file 'organizer/qorganizer-eds-engine.cpp' |
| 55 | --- organizer/qorganizer-eds-engine.cpp 2016-05-05 22:13:05 +0000 |
| 56 | +++ organizer/qorganizer-eds-engine.cpp 2016-07-11 14:47:56 +0000 |
| 57 | @@ -271,10 +271,12 @@ |
| 58 | // check if request was destroyed by the caller |
| 59 | if (data->isLive()) { |
| 60 | QOrganizerItemFetchRequest *req = data->request<QOrganizerItemFetchRequest>(); |
| 61 | - data->appendResults(data->parent()->parseEvents(data->collection(), |
| 62 | - events, |
| 63 | - false, |
| 64 | - req->fetchHint().detailTypesHint())); |
| 65 | + if (req) { |
| 66 | + data->appendResults(data->parent()->parseEvents(data->collection(), |
| 67 | + events, |
| 68 | + false, |
| 69 | + req->fetchHint().detailTypesHint())); |
| 70 | + } |
| 71 | itemsAsyncStart(data); |
| 72 | } else { |
| 73 | releaseRequestData(data); |
| 74 | @@ -814,6 +816,7 @@ |
| 75 | QOrganizerCollectionId collection = data->next(); |
| 76 | for(; !collection.isNull(); collection = data->next()) { |
| 77 | EClient *client = data->parent()->d->m_sourceRegistry->client(collection.toString()); |
| 78 | + Q_ASSERT(client); |
| 79 | data->setClient(client); |
| 80 | g_object_unref(client); |
| 81 | GSList *ids = data->compIds(); |
| 82 | @@ -1270,18 +1273,35 @@ |
| 83 | void QOrganizerEDSEngine::onSourceAdded(const QString &collectionId) |
| 84 | { |
| 85 | d->watch(collectionId); |
| 86 | - Q_EMIT collectionsAdded(QList<QOrganizerCollectionId>() << QOrganizerCollectionId::fromString(collectionId)); |
| 87 | + QOrganizerCollectionId id = QOrganizerCollectionId::fromString(collectionId); |
| 88 | + |
| 89 | + Q_EMIT collectionsAdded(QList<QOrganizerCollectionId>() << id); |
| 90 | + |
| 91 | + QList<QPair<QOrganizerCollectionId, QOrganizerManager::Operation> > ops; |
| 92 | + ops << qMakePair(id, QOrganizerManager::Add); |
| 93 | + Q_EMIT collectionsModified(ops); |
| 94 | } |
| 95 | |
| 96 | void QOrganizerEDSEngine::onSourceRemoved(const QString &collectionId) |
| 97 | { |
| 98 | d->unWatch(collectionId); |
| 99 | - Q_EMIT collectionsRemoved(QList<QOrganizerCollectionId>() << QOrganizerCollectionId::fromString(collectionId)); |
| 100 | + QOrganizerCollectionId id = QOrganizerCollectionId::fromString(collectionId); |
| 101 | + |
| 102 | + Q_EMIT collectionsRemoved(QList<QOrganizerCollectionId>() << id); |
| 103 | + |
| 104 | + QList<QPair<QOrganizerCollectionId, QOrganizerManager::Operation> > ops; |
| 105 | + ops << qMakePair(id, QOrganizerManager::Remove); |
| 106 | + Q_EMIT collectionsModified(ops); |
| 107 | } |
| 108 | |
| 109 | void QOrganizerEDSEngine::onSourceUpdated(const QString &collectionId) |
| 110 | { |
| 111 | - Q_EMIT collectionsChanged(QList<QOrganizerCollectionId>() << QOrganizerCollectionId::fromString(collectionId)); |
| 112 | + QOrganizerCollectionId id = QOrganizerCollectionId::fromString(collectionId); |
| 113 | + Q_EMIT collectionsChanged(QList<QOrganizerCollectionId>() << id); |
| 114 | + |
| 115 | + QList<QPair<QOrganizerCollectionId, QOrganizerManager::Operation> > ops; |
| 116 | + ops << qMakePair(id, QOrganizerManager::Change); |
| 117 | + Q_EMIT collectionsModified(ops); |
| 118 | } |
| 119 | |
| 120 | void QOrganizerEDSEngine::onViewChanged(QOrganizerItemChangeSet *change) |
| 121 | @@ -1383,6 +1403,7 @@ |
| 122 | item->saveDetail(&etr); |
| 123 | } |
| 124 | e_cal_component_free_datetime(dt); |
| 125 | + g_free(dt); |
| 126 | } |
| 127 | |
| 128 | void QOrganizerEDSEngine::parseTodoStartTime(ECalComponent *comp, QOrganizerItem *item) |
| 129 | @@ -1398,6 +1419,7 @@ |
| 130 | item->saveDetail(&etr); |
| 131 | } |
| 132 | e_cal_component_free_datetime(dt); |
| 133 | + g_free(dt); |
| 134 | } |
| 135 | |
| 136 | void QOrganizerEDSEngine::parseEndTime(ECalComponent *comp, QOrganizerItem *item) |
| 137 | @@ -1413,6 +1435,7 @@ |
| 138 | item->saveDetail(&etr); |
| 139 | } |
| 140 | e_cal_component_free_datetime(dt); |
| 141 | + g_free(dt); |
| 142 | } |
| 143 | |
| 144 | void QOrganizerEDSEngine::parseWeekRecurrence(struct icalrecurrencetype *rule, QtOrganizer::QOrganizerRecurrenceRule *qRule) |
| 145 | @@ -1951,24 +1974,40 @@ |
| 146 | ECalComponentAlarmTrigger trigger; |
| 147 | e_cal_component_alarm_get_trigger(alarm.data(), &trigger); |
| 148 | int relSecs = 0; |
| 149 | + bool fail = false; |
| 150 | if (trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) { |
| 151 | + |
| 152 | relSecs = - icaldurationtype_as_int(trigger.u.rel_duration); |
| 153 | if (relSecs < 0) { |
| 154 | + //WORKAROUND: Print warning only once, avoid flood application output |
| 155 | + static bool relativeStartwarningPrinted = false; |
| 156 | relSecs = 0; |
| 157 | - qWarning() << "QOrganizer does not support triggers after event start"; |
| 158 | + if (!relativeStartwarningPrinted) { |
| 159 | + fail = true; |
| 160 | + relativeStartwarningPrinted = true; |
| 161 | + qWarning() << "QOrganizer does not support triggers after event start"; |
| 162 | + } |
| 163 | } |
| 164 | } else if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_NONE) { |
| 165 | - qWarning() << "QOrganizer only supports triggers relative to event start."; |
| 166 | - } |
| 167 | - aDetail->setSecondsBeforeStart(relSecs); |
| 168 | - |
| 169 | - ECalComponentAlarmRepeat aRepeat; |
| 170 | - e_cal_component_alarm_get_repeat(alarm.data(), &aRepeat); |
| 171 | - aDetail->setRepetition(aRepeat.repetitions, icaldurationtype_as_int(aRepeat.duration)); |
| 172 | - |
| 173 | - item->saveDetail(aDetail); |
| 174 | + fail = true; |
| 175 | + //WORKAROUND: Print warning only once, avoid flood application output |
| 176 | + static bool warningPrinted = false; |
| 177 | + if (!warningPrinted) { |
| 178 | + qWarning() << "QOrganizer only supports triggers relative to event start.:" << trigger.type; |
| 179 | + warningPrinted = true; |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + if (!fail) { |
| 184 | + aDetail->setSecondsBeforeStart(relSecs); |
| 185 | + ECalComponentAlarmRepeat aRepeat; |
| 186 | + e_cal_component_alarm_get_repeat(alarm.data(), &aRepeat); |
| 187 | + aDetail->setRepetition(aRepeat.repetitions, icaldurationtype_as_int(aRepeat.duration)); |
| 188 | + item->saveDetail(aDetail); |
| 189 | + } |
| 190 | delete aDetail; |
| 191 | } |
| 192 | + cal_obj_uid_list_free(alarms); |
| 193 | } |
| 194 | |
| 195 | void QOrganizerEDSEngine::parseEventsAsync(const QMap<QString, GSList *> &events, |
| 196 | @@ -1980,7 +2019,15 @@ |
| 197 | QMap<QOrganizerEDSCollectionEngineId*, GSList*> request; |
| 198 | Q_FOREACH(const QString &collectionId, events.keys()) { |
| 199 | QOrganizerEDSCollectionEngineId *collection = d->m_sourceRegistry->collectionEngineId(collectionId); |
| 200 | - request.insert(collection, events.value(collectionId)); |
| 201 | + if (isIcalEvents) { |
| 202 | + request.insert(collection, |
| 203 | + g_slist_copy_deep(events.value(collectionId), |
| 204 | + (GCopyFunc) icalcomponent_new_clone, NULL)); |
| 205 | + } else { |
| 206 | + request.insert(collection, |
| 207 | + g_slist_copy_deep(events.value(collectionId), |
| 208 | + (GCopyFunc) g_object_ref, NULL)); |
| 209 | + } |
| 210 | } |
| 211 | |
| 212 | // the thread will destroy itself when done |
| 213 | @@ -2208,7 +2255,7 @@ |
| 214 | { |
| 215 | QOrganizerItemRecurrence rec = item.detail(QOrganizerItemDetail::TypeRecurrence); |
| 216 | if (!rec.isEmpty()) { |
| 217 | - GSList *periodList = 0; |
| 218 | + GSList *periodList = NULL; |
| 219 | Q_FOREACH(const QDate &dt, rec.recurrenceDates()) { |
| 220 | ECalComponentPeriod *period = g_new0(ECalComponentPeriod, 1); |
| 221 | period->start = icaltime_from_timet(QDateTime(dt).toTime_t(), FALSE); |
| 222 | @@ -2741,7 +2788,7 @@ |
| 223 | // use component tz on recurrence id |
| 224 | ECalComponentDateTime dt; |
| 225 | e_cal_component_get_dtstart(comp, &dt); |
| 226 | - dt.value = g_new(icaltimetype, 1); |
| 227 | + dt.value = g_new0(icaltimetype, 1); |
| 228 | *dt.value = icaltime_from_string(rId.toUtf8().data()); |
| 229 | |
| 230 | recur_id.type = E_CAL_COMPONENT_RANGE_SINGLE; |
| 231 | |
| 232 | === modified file 'organizer/qorganizer-eds-enginedata.cpp' |
| 233 | --- organizer/qorganizer-eds-enginedata.cpp 2013-12-04 23:07:24 +0000 |
| 234 | +++ organizer/qorganizer-eds-enginedata.cpp 2016-07-11 14:47:56 +0000 |
| 235 | @@ -37,7 +37,7 @@ |
| 236 | m_viewWatchers.clear(); |
| 237 | |
| 238 | if (m_sourceRegistry) { |
| 239 | - delete m_sourceRegistry; |
| 240 | + m_sourceRegistry->deleteLater(); |
| 241 | m_sourceRegistry = 0; |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | === modified file 'organizer/qorganizer-eds-fetchrequestdata.cpp' |
| 246 | --- organizer/qorganizer-eds-fetchrequestdata.cpp 2016-03-07 17:40:10 +0000 |
| 247 | +++ organizer/qorganizer-eds-fetchrequestdata.cpp 2016-07-11 14:47:56 +0000 |
| 248 | @@ -221,6 +221,9 @@ |
| 249 | { |
| 250 | int count = 0; |
| 251 | QOrganizerItemFetchRequest *req = request<QOrganizerItemFetchRequest>(); |
| 252 | + if (!req) { |
| 253 | + return 0; |
| 254 | + } |
| 255 | QOrganizerItemFilter filter = req->filter(); |
| 256 | QList<QOrganizerItemSortOrder> sorting = req->sorting(); |
| 257 | |
| 258 | |
| 259 | === modified file 'organizer/qorganizer-eds-parseeventthread.cpp' |
| 260 | --- organizer/qorganizer-eds-parseeventthread.cpp 2015-04-11 00:00:05 +0000 |
| 261 | +++ organizer/qorganizer-eds-parseeventthread.cpp 2016-07-11 14:47:56 +0000 |
| 262 | @@ -21,6 +21,18 @@ |
| 263 | connect(this, SIGNAL(finished()), SLOT(deleteLater())); |
| 264 | } |
| 265 | |
| 266 | +QOrganizerParseEventThread::~QOrganizerParseEventThread() |
| 267 | +{ |
| 268 | + Q_FOREACH(GSList *components ,m_events.values()) { |
| 269 | + if (m_isIcalEvents) { |
| 270 | + g_slist_free_full(components, (GDestroyNotify)icalcomponent_free); |
| 271 | + } else { |
| 272 | + g_slist_free_full(components, (GDestroyNotify)g_object_unref); |
| 273 | + } |
| 274 | + } |
| 275 | + m_events.clear(); |
| 276 | +} |
| 277 | + |
| 278 | void QOrganizerParseEventThread::start(QMap<QOrganizerEDSCollectionEngineId *, GSList *> events, |
| 279 | bool isIcalEvents, |
| 280 | QList<QOrganizerItemDetail::DetailType> detailsHint) |
| 281 | |
| 282 | === modified file 'organizer/qorganizer-eds-parseeventthread.h' |
| 283 | --- organizer/qorganizer-eds-parseeventthread.h 2015-04-10 19:52:26 +0000 |
| 284 | +++ organizer/qorganizer-eds-parseeventthread.h 2016-07-11 14:47:56 +0000 |
| 285 | @@ -40,6 +40,7 @@ |
| 286 | QOrganizerParseEventThread(QObject *source, |
| 287 | const QByteArray &slot, |
| 288 | QObject *parent = 0); |
| 289 | + ~QOrganizerParseEventThread(); |
| 290 | |
| 291 | void start(QMap<QOrganizerEDSCollectionEngineId *, GSList *> events, |
| 292 | bool isIcalEvents, |
| 293 | @@ -48,6 +49,7 @@ |
| 294 | private: |
| 295 | QPointer<QObject> m_source; |
| 296 | QMetaMethod m_slot; |
| 297 | + bool m_abort; |
| 298 | |
| 299 | // parse data |
| 300 | QMap<QOrganizerEDSCollectionEngineId *, GSList *> m_events; |
| 301 | |
| 302 | === modified file 'organizer/qorganizer-eds-requestdata.h' |
| 303 | --- organizer/qorganizer-eds-requestdata.h 2016-01-12 13:10:01 +0000 |
| 304 | +++ organizer/qorganizer-eds-requestdata.h 2016-07-11 14:47:56 +0000 |
| 305 | @@ -47,7 +47,11 @@ |
| 306 | |
| 307 | template<class T> |
| 308 | T* request() const { |
| 309 | - return qobject_cast<T*>(m_req.data()); |
| 310 | + if (m_req) { |
| 311 | + return qobject_cast<T*>(m_req.data()); |
| 312 | + } else { |
| 313 | + return 0; |
| 314 | + } |
| 315 | } |
| 316 | |
| 317 | template<class T> |
| 318 | |
| 319 | === modified file 'organizer/qorganizer-eds-savecollectionrequestdata.cpp' |
| 320 | --- organizer/qorganizer-eds-savecollectionrequestdata.cpp 2016-03-15 13:05:04 +0000 |
| 321 | +++ organizer/qorganizer-eds-savecollectionrequestdata.cpp 2016-07-11 14:47:56 +0000 |
| 322 | @@ -26,6 +26,8 @@ |
| 323 | #include <QtOrganizer/QOrganizerCollectionSaveRequest> |
| 324 | #include <QtOrganizer/QOrganizerCollectionChangeSet> |
| 325 | |
| 326 | +#include <evolution-data-server-ubuntu/e-source-ubuntu.h> |
| 327 | + |
| 328 | using namespace QtOrganizer; |
| 329 | |
| 330 | SaveCollectionRequestData::SaveCollectionRequestData(QOrganizerEDSEngine *engine, |
| 331 | @@ -160,20 +162,11 @@ |
| 332 | int index = 0; |
| 333 | Q_FOREACH(const QOrganizerCollection &collection, request<QOrganizerCollectionSaveRequest>()->collections()) { |
| 334 | ESource *source = 0; |
| 335 | - bool isNew = true; |
| 336 | - if (collection.id().isNull()) { |
| 337 | - GError *gError = 0; |
| 338 | - source = e_source_new(0, 0, &gError); |
| 339 | - if (gError) { |
| 340 | - m_errorMap.insert(index, QOrganizerManager::UnspecifiedError); |
| 341 | - qWarning() << "Fail to create source:" << gError->message; |
| 342 | - g_error_free(gError); |
| 343 | - Q_ASSERT(false); |
| 344 | - } |
| 345 | - e_source_set_parent(source, "local-stub"); |
| 346 | + bool isNew = collection.id().isNull(); |
| 347 | + if (isNew) { |
| 348 | + source = SourceRegistry::newSourceFromCollection(collection); |
| 349 | } else { |
| 350 | source = m_parent->d->m_sourceRegistry->source(collection.id().toString()); |
| 351 | - isNew = false; |
| 352 | } |
| 353 | |
| 354 | QVariant callendarType = collection.extendedMetaData(COLLECTION_CALLENDAR_TYPE_METADATA); |
| 355 | @@ -187,7 +180,6 @@ |
| 356 | extCalendar = E_SOURCE_BACKEND(e_source_get_extension(source, E_SOURCE_EXTENSION_CALENDAR)); |
| 357 | } |
| 358 | |
| 359 | - |
| 360 | if (source) { |
| 361 | if (isNew) { |
| 362 | if (extCalendar) { |
| 363 | @@ -213,6 +205,21 @@ |
| 364 | bool isDefault = collection.extendedMetaData(COLLECTION_DEFAULT_METADATA).toBool(); |
| 365 | g_object_set_data(G_OBJECT(source), "is-default", GINT_TO_POINTER(isDefault)); |
| 366 | |
| 367 | + // Ubuntu extension |
| 368 | + QVariant accountId = collection.extendedMetaData(COLLECTION_ACCOUNT_ID_METADATA); |
| 369 | + QVariant readOnly = collection.extendedMetaData(COLLECTION_SYNC_READONLY_METADATA); |
| 370 | + QVariant metadata = collection.extendedMetaData(COLLECTION_DATA_METADATA); |
| 371 | + if (accountId.isValid() || |
| 372 | + readOnly.isValid() || |
| 373 | + metadata.isValid()) { |
| 374 | + |
| 375 | + ESourceUbuntu *extUbuntu = E_SOURCE_UBUNTU(e_source_get_extension(source, E_SOURCE_EXTENSION_UBUNTU)); |
| 376 | + e_source_ubuntu_set_writable(extUbuntu, readOnly.isValid() ? !readOnly.toBool() : true); |
| 377 | + e_source_ubuntu_set_account_id(extUbuntu, accountId.toUInt()); |
| 378 | + e_source_ubuntu_set_metadata(extUbuntu, metadata.toString().toUtf8().constData()); |
| 379 | + e_source_ubuntu_set_autoremove(extUbuntu, TRUE); |
| 380 | + } |
| 381 | + |
| 382 | m_sources.insert(index, source); |
| 383 | if (isNew) { |
| 384 | m_sourcesToCreate.insert(index, source); |
| 385 | @@ -223,4 +230,3 @@ |
| 386 | } |
| 387 | } |
| 388 | } |
| 389 | - |
| 390 | |
| 391 | === modified file 'organizer/qorganizer-eds-source-registry.cpp' |
| 392 | --- organizer/qorganizer-eds-source-registry.cpp 2016-03-17 17:01:35 +0000 |
| 393 | +++ organizer/qorganizer-eds-source-registry.cpp 2016-07-11 14:47:56 +0000 |
| 394 | @@ -2,6 +2,7 @@ |
| 395 | #include "config.h" |
| 396 | |
| 397 | #include <QtCore/QDebug> |
| 398 | +#include <evolution-data-server-ubuntu/e-source-ubuntu.h> |
| 399 | |
| 400 | using namespace QtOrganizer; |
| 401 | |
| 402 | @@ -310,11 +311,33 @@ |
| 403 | QOrganizerCollectionId id(*edsId); |
| 404 | QOrganizerCollection collection; |
| 405 | |
| 406 | + // id |
| 407 | collection.setId(id); |
| 408 | + |
| 409 | updateCollection(&collection, isDefault, source); |
| 410 | return collection; |
| 411 | } |
| 412 | |
| 413 | +ESource *SourceRegistry::newSourceFromCollection(const QtOrganizer::QOrganizerCollection &collection) |
| 414 | +{ |
| 415 | + if (!collection.id().isNull()) { |
| 416 | + qWarning() << "Fail to create source from collection: Collection already has id."; |
| 417 | + return NULL; |
| 418 | + } |
| 419 | + |
| 420 | + GError *gError = 0; |
| 421 | + ESource *source = e_source_new(NULL, NULL, &gError); |
| 422 | + |
| 423 | + if (gError) { |
| 424 | + qWarning() << "Fail to create source:" << gError->message; |
| 425 | + g_error_free(gError); |
| 426 | + return NULL; |
| 427 | + } |
| 428 | + |
| 429 | + e_source_set_parent(source, "local-stub"); |
| 430 | + return source; |
| 431 | +} |
| 432 | + |
| 433 | QByteArray SourceRegistry::defaultCollectionId() const |
| 434 | { |
| 435 | QVariant id = m_settings.value(DEFAULT_COLLECTION_SETTINGS); |
| 436 | @@ -426,4 +449,19 @@ |
| 437 | |
| 438 | // default |
| 439 | collection->setExtendedMetaData(COLLECTION_DEFAULT_METADATA, isDefault); |
| 440 | + |
| 441 | + // Ubuntu Extension |
| 442 | + ESourceUbuntu *extUbuntu = E_SOURCE_UBUNTU(e_source_get_extension(source, E_SOURCE_EXTENSION_UBUNTU)); |
| 443 | + if (extUbuntu) { |
| 444 | + collection->setExtendedMetaData(COLLECTION_ACCOUNT_ID_METADATA, e_source_ubuntu_get_account_id(extUbuntu)); |
| 445 | + writable = e_source_ubuntu_get_writable(extUbuntu) == TRUE; |
| 446 | + collection->setExtendedMetaData(COLLECTION_SYNC_READONLY_METADATA, !writable); |
| 447 | + if (!writable) { |
| 448 | + // Set account as read-only if not writable |
| 449 | + collection->setExtendedMetaData(COLLECTION_READONLY_METADATA, true); |
| 450 | + } |
| 451 | + const gchar *data = e_source_ubuntu_get_metadata(extUbuntu); |
| 452 | + collection->setExtendedMetaData(COLLECTION_DATA_METADATA, data ? QString::fromUtf8(data) : QString()); |
| 453 | + } |
| 454 | + |
| 455 | } |
| 456 | |
| 457 | === modified file 'organizer/qorganizer-eds-source-registry.h' |
| 458 | --- organizer/qorganizer-eds-source-registry.h 2016-03-17 17:01:35 +0000 |
| 459 | +++ organizer/qorganizer-eds-source-registry.h 2016-07-11 14:47:56 +0000 |
| 460 | @@ -33,6 +33,9 @@ |
| 461 | #define COLLECTION_SELECTED_METADATA "collection-selected" |
| 462 | #define COLLECTION_READONLY_METADATA "collection-readonly" |
| 463 | #define COLLECTION_DEFAULT_METADATA "collection-default" |
| 464 | +#define COLLECTION_SYNC_READONLY_METADATA "collection-sync-readonly" |
| 465 | +#define COLLECTION_ACCOUNT_ID_METADATA "collection-account-id" |
| 466 | +#define COLLECTION_DATA_METADATA "collection-metadata" |
| 467 | |
| 468 | class SourceRegistry : public QObject |
| 469 | { |
| 470 | @@ -61,6 +64,7 @@ |
| 471 | static QtOrganizer::QOrganizerCollection parseSource(ESource *source, |
| 472 | bool isDefault, |
| 473 | QOrganizerEDSCollectionEngineId **edsId); |
| 474 | + static ESource *newSourceFromCollection(const QtOrganizer::QOrganizerCollection &collection); |
| 475 | |
| 476 | Q_SIGNALS: |
| 477 | void sourceAdded(const QString &collectionId); |
| 478 | |
| 479 | === modified file 'organizer/qorganizer-eds-viewwatcher.cpp' |
| 480 | --- organizer/qorganizer-eds-viewwatcher.cpp 2014-10-09 02:55:01 +0000 |
| 481 | +++ organizer/qorganizer-eds-viewwatcher.cpp 2016-07-11 14:47:56 +0000 |
| 482 | @@ -47,6 +47,8 @@ |
| 483 | (GAsyncReadyCallback) ViewWatcher::viewReady, |
| 484 | this); |
| 485 | wait(); |
| 486 | + m_dirty.setSingleShot(true); |
| 487 | + connect(&m_dirty, SIGNAL(timeout()), SLOT(flush())); |
| 488 | } |
| 489 | |
| 490 | ViewWatcher::~ViewWatcher() |
| 491 | @@ -108,7 +110,12 @@ |
| 492 | } |
| 493 | |
| 494 | if (m_eView) { |
| 495 | - e_cal_client_view_stop(m_eView, 0); |
| 496 | + GError *gErr = 0; |
| 497 | + e_cal_client_view_stop(m_eView, &gErr); |
| 498 | + if (gErr) { |
| 499 | + qWarning() << "Fail to stop view" << gErr->message; |
| 500 | + g_error_free(gErr); |
| 501 | + } |
| 502 | g_clear_object(&m_eView); |
| 503 | } |
| 504 | |
| 505 | @@ -148,15 +155,24 @@ |
| 506 | return result; |
| 507 | } |
| 508 | |
| 509 | +void ViewWatcher::notify() |
| 510 | +{ |
| 511 | + m_dirty.start(500); |
| 512 | +} |
| 513 | + |
| 514 | +void ViewWatcher::flush() |
| 515 | +{ |
| 516 | + m_engineData->emitSharedSignals(&m_changeSet); |
| 517 | + m_changeSet.clearAll(); |
| 518 | +} |
| 519 | + |
| 520 | void ViewWatcher::onObjectsAdded(ECalClientView *view, |
| 521 | GSList *objects, |
| 522 | ViewWatcher *self) |
| 523 | { |
| 524 | Q_UNUSED(view); |
| 525 | - |
| 526 | - QOrganizerItemChangeSet changeSet; |
| 527 | - changeSet.insertAddedItems(self->parseItemIds(objects)); |
| 528 | - self->m_engineData->emitSharedSignals(&changeSet); |
| 529 | + self->m_changeSet.insertAddedItems(self->parseItemIds(objects)); |
| 530 | + self->notify(); |
| 531 | } |
| 532 | |
| 533 | void ViewWatcher::onObjectsRemoved(ECalClientView *view, |
| 534 | @@ -164,16 +180,14 @@ |
| 535 | ViewWatcher *self) |
| 536 | { |
| 537 | Q_UNUSED(view); |
| 538 | - QOrganizerItemChangeSet changeSet; |
| 539 | |
| 540 | for (GSList *l = objects; l; l = l->next) { |
| 541 | ECalComponentId *id = static_cast<ECalComponentId*>(l->data); |
| 542 | QOrganizerEDSEngineId *itemId = new QOrganizerEDSEngineId(self->m_collectionId, |
| 543 | QString::fromUtf8(id->uid)); |
| 544 | - changeSet.insertRemovedItem(QOrganizerItemId(itemId)); |
| 545 | + self->m_changeSet.insertRemovedItem(QOrganizerItemId(itemId)); |
| 546 | } |
| 547 | - |
| 548 | - self->m_engineData->emitSharedSignals(&changeSet); |
| 549 | + self->notify(); |
| 550 | } |
| 551 | |
| 552 | void ViewWatcher::onObjectsModified(ECalClientView *view, |
| 553 | @@ -182,8 +196,6 @@ |
| 554 | { |
| 555 | Q_UNUSED(view); |
| 556 | |
| 557 | - QOrganizerItemChangeSet changeSet; |
| 558 | - changeSet.insertChangedItems(self->parseItemIds(objects)); |
| 559 | - |
| 560 | - self->m_engineData->emitSharedSignals(&changeSet); |
| 561 | + self->m_changeSet.insertChangedItems(self->parseItemIds(objects)); |
| 562 | + self->notify(); |
| 563 | } |
| 564 | |
| 565 | === modified file 'organizer/qorganizer-eds-viewwatcher.h' |
| 566 | --- organizer/qorganizer-eds-viewwatcher.h 2013-12-03 01:23:34 +0000 |
| 567 | +++ organizer/qorganizer-eds-viewwatcher.h 2016-07-11 14:47:56 +0000 |
| 568 | @@ -24,6 +24,7 @@ |
| 569 | #include <QtCore/QList> |
| 570 | #include <QtCore/QObject> |
| 571 | #include <QtCore/QEventLoop> |
| 572 | +#include <QtCore/QTimer> |
| 573 | |
| 574 | #include <libecal/libecal.h> |
| 575 | |
| 576 | @@ -40,6 +41,9 @@ |
| 577 | void clear(); |
| 578 | void wait(); |
| 579 | |
| 580 | +private Q_SLOTS: |
| 581 | + void flush(); |
| 582 | + |
| 583 | private: |
| 584 | QString m_collectionId; |
| 585 | QOrganizerEDSEngineData *m_engineData; |
| 586 | @@ -47,8 +51,12 @@ |
| 587 | ECalClient *m_eClient; |
| 588 | ECalClientView *m_eView; |
| 589 | QEventLoop *m_eventLoop; |
| 590 | + QOrganizerItemChangeSet m_changeSet; |
| 591 | + QTimer m_dirty; |
| 592 | |
| 593 | QList<QtOrganizer::QOrganizerItemId> parseItemIds(GSList *objects); |
| 594 | + void notify(); |
| 595 | + |
| 596 | |
| 597 | static void clientConnected(GObject *sourceObject, GAsyncResult *res, ViewWatcher *self); |
| 598 | static void viewReady(GObject *sourceObject, GAsyncResult *res, ViewWatcher *self); |
| 599 | |
| 600 | === modified file 'tests/unittest/CMakeLists.txt' |
| 601 | --- tests/unittest/CMakeLists.txt 2016-01-12 13:10:01 +0000 |
| 602 | +++ tests/unittest/CMakeLists.txt 2016-07-11 14:47:56 +0000 |
| 603 | @@ -3,6 +3,7 @@ |
| 604 | ${TESTNAME}.cpp |
| 605 | eds-base-test.cpp |
| 606 | eds-base-test.h |
| 607 | + gscopedpointer.h |
| 608 | ) |
| 609 | qt5_use_modules(${TESTNAME} Core Organizer Test) |
| 610 | |
| 611 | |
| 612 | === modified file 'tests/unittest/collections-test.cpp' |
| 613 | --- tests/unittest/collections-test.cpp 2016-03-14 20:19:46 +0000 |
| 614 | +++ tests/unittest/collections-test.cpp 2016-07-11 14:47:56 +0000 |
| 615 | @@ -218,6 +218,7 @@ |
| 616 | QTRY_VERIFY(updateCollection.count() > 0); |
| 617 | QList<QVariant> args = updateCollection.takeFirst(); |
| 618 | QCOMPARE(args.count(), 1); |
| 619 | + QCOMPARE(args[0].value<QList<QOrganizerCollectionId> >().count(), 1); |
| 620 | QCOMPARE(args[0].value<QList<QOrganizerCollectionId> >().at(0).toString(), collection.id().toString()); |
| 621 | |
| 622 | |
| 623 | @@ -351,6 +352,118 @@ |
| 624 | // wait collection to became the default one |
| 625 | QTRY_COMPARE_WITH_TIMEOUT(m_engineRead->defaultCollection(0).id(), newCollection.id(), 5000); |
| 626 | } |
| 627 | + |
| 628 | + void testSaveCollectionWithAccountId() |
| 629 | + { |
| 630 | + static QString newCollectionId = uniqueCollectionName(); |
| 631 | + |
| 632 | + // Create a collection |
| 633 | + QOrganizerCollection collection; |
| 634 | + QtOrganizer::QOrganizerManager::Error error; |
| 635 | + collection.setMetaData(QOrganizerCollection::KeyName, newCollectionId); |
| 636 | + collection.setExtendedMetaData(COLLECTION_ACCOUNT_ID_METADATA, 99); |
| 637 | + |
| 638 | + QSignalSpy createCollection(m_engineRead, SIGNAL(collectionsAdded(QList<QOrganizerCollectionId>))); |
| 639 | + QVERIFY(m_engineWrite->saveCollection(&collection, &error)); |
| 640 | + QTRY_COMPARE(createCollection.count(), 1); |
| 641 | + |
| 642 | + // check if collection contains the account id in the id |
| 643 | + QCOMPARE(collection.extendedMetaData(COLLECTION_ACCOUNT_ID_METADATA).toInt(), 99); |
| 644 | + |
| 645 | + // Query for collection |
| 646 | + QOrganizerCollection newCollection = m_engineRead->collection(collection.id(), 0); |
| 647 | + |
| 648 | + // check account field |
| 649 | + QCOMPARE(newCollection.extendedMetaData(COLLECTION_ACCOUNT_ID_METADATA).toInt(), 99); |
| 650 | + } |
| 651 | + |
| 652 | + void testSaveCollectionWithMetadata() |
| 653 | + { |
| 654 | + static QString newCollectionId = uniqueCollectionName(); |
| 655 | + |
| 656 | + // Create a collection |
| 657 | + QOrganizerCollection collection; |
| 658 | + QtOrganizer::QOrganizerManager::Error error; |
| 659 | + collection.setMetaData(QOrganizerCollection::KeyName, newCollectionId); |
| 660 | + collection.setExtendedMetaData(COLLECTION_DATA_METADATA, QStringLiteral("string metadata")); |
| 661 | + |
| 662 | + QSignalSpy createCollection(m_engineRead, SIGNAL(collectionsAdded(QList<QOrganizerCollectionId>))); |
| 663 | + QVERIFY(m_engineWrite->saveCollection(&collection, &error)); |
| 664 | + QTRY_COMPARE(createCollection.count(), 1); |
| 665 | + |
| 666 | + // check if collection contains the metadata |
| 667 | + QCOMPARE(collection.extendedMetaData(COLLECTION_DATA_METADATA).toString(), QStringLiteral("string metadata")); |
| 668 | + |
| 669 | + // Query for collection |
| 670 | + QOrganizerCollection newCollection = m_engineRead->collection(collection.id(), 0); |
| 671 | + |
| 672 | + // check account field |
| 673 | + QCOMPARE(newCollection.extendedMetaData(COLLECTION_DATA_METADATA).toString(), QStringLiteral("string metadata")); |
| 674 | + } |
| 675 | + |
| 676 | + void testSaveCollectionWithSyncWritable() |
| 677 | + { |
| 678 | + static QString newCollectionId = uniqueCollectionName(); |
| 679 | + |
| 680 | + // Create a collection |
| 681 | + QOrganizerCollection collection; |
| 682 | + QtOrganizer::QOrganizerManager::Error error; |
| 683 | + collection.setMetaData(QOrganizerCollection::KeyName, newCollectionId); |
| 684 | + collection.setExtendedMetaData(COLLECTION_SYNC_READONLY_METADATA, true); |
| 685 | + QCOMPARE(collection.extendedMetaData(COLLECTION_SYNC_READONLY_METADATA).toBool(), true); |
| 686 | + |
| 687 | + QSignalSpy createCollection(m_engineRead, SIGNAL(collectionsAdded(QList<QOrganizerCollectionId>))); |
| 688 | + QVERIFY(m_engineWrite->saveCollection(&collection, &error)); |
| 689 | + QTRY_COMPARE(createCollection.count(), 1); |
| 690 | + |
| 691 | + // check if collection was marked as read-only |
| 692 | + QCOMPARE(collection.extendedMetaData(COLLECTION_SYNC_READONLY_METADATA).toBool(), true); |
| 693 | + QCOMPARE(collection.extendedMetaData(COLLECTION_READONLY_METADATA).toBool(), true); |
| 694 | + |
| 695 | + // Query for collection |
| 696 | + QOrganizerCollection newCollection = m_engineRead->collection(collection.id(), 0); |
| 697 | + |
| 698 | + // check if collection was marked as read-only |
| 699 | + QCOMPARE(newCollection.extendedMetaData(COLLECTION_SYNC_READONLY_METADATA).toBool(), true); |
| 700 | + QCOMPARE(newCollection.extendedMetaData(COLLECTION_READONLY_METADATA).toBool(), true); |
| 701 | + } |
| 702 | + |
| 703 | + void testModifyMetaDataUpdateCollection() |
| 704 | + { |
| 705 | + static QString newCollectionId = uniqueCollectionName(); |
| 706 | + |
| 707 | + // Create a collection |
| 708 | + QOrganizerCollection collection; |
| 709 | + QtOrganizer::QOrganizerManager::Error error; |
| 710 | + collection.setMetaData(QOrganizerCollection::KeyName, newCollectionId); |
| 711 | + collection.setExtendedMetaData(COLLECTION_SYNC_READONLY_METADATA, true); |
| 712 | + QCOMPARE(collection.extendedMetaData(COLLECTION_SYNC_READONLY_METADATA).toBool(), true); |
| 713 | + |
| 714 | + QSignalSpy createCollection(m_engineRead, &QOrganizerManagerEngine::collectionsAdded); |
| 715 | + QVERIFY(m_engineWrite->saveCollection(&collection, &error)); |
| 716 | + QTRY_COMPARE(createCollection.count(), 1); |
| 717 | + QTest::qWait(1000); |
| 718 | + |
| 719 | + // check if collection update signal is fired |
| 720 | + QSignalSpy collectionsModified(m_engineRead, &QOrganizerManagerEngine::collectionsModified); |
| 721 | + QSignalSpy collectionsChanged(m_engineRead, &QOrganizerManagerEngine::collectionsChanged); |
| 722 | + |
| 723 | + // Modify collection on EDS |
| 724 | + const QString metadataValue = QStringLiteral("new metadata"); |
| 725 | + QTRY_COMPARE(collectionsChanged.count(), 0); |
| 726 | + qDebug() << "WIll update metadata"; |
| 727 | + setCollectionMetadata(collection.id(), metadataValue); |
| 728 | + |
| 729 | + // it will fire two signals |
| 730 | + // 1- Property change |
| 731 | + // 2- Source write |
| 732 | + QTRY_COMPARE(collectionsChanged.count(), 2); |
| 733 | + QTRY_COMPARE(collectionsModified.count(), 2); |
| 734 | + |
| 735 | + // check if the metadata was changed |
| 736 | + QOrganizerCollection newCollection = m_engineRead->collection(collection.id(), 0); |
| 737 | + QCOMPARE(newCollection.extendedMetaData(COLLECTION_DATA_METADATA).toString(), metadataValue); |
| 738 | + } |
| 739 | }; |
| 740 | |
| 741 | const QString CollectionTest::collectionTypePropertyName = QStringLiteral("collection-type"); |
| 742 | |
| 743 | === modified file 'tests/unittest/eds-base-test.cpp' |
| 744 | --- tests/unittest/eds-base-test.cpp 2016-05-06 14:31:43 +0000 |
| 745 | +++ tests/unittest/eds-base-test.cpp 2016-07-11 14:47:56 +0000 |
| 746 | @@ -19,33 +19,17 @@ |
| 747 | #include "config.h" |
| 748 | #include "eds-base-test.h" |
| 749 | #include "qorganizer-eds-engine.h" |
| 750 | +#include "gscopedpointer.h" |
| 751 | |
| 752 | #include <QtCore> |
| 753 | #include <QtTest> |
| 754 | |
| 755 | #include <libecal/libecal.h> |
| 756 | |
| 757 | +#include <evolution-data-server-ubuntu/e-source-ubuntu.h> |
| 758 | + |
| 759 | using namespace QtOrganizer; |
| 760 | |
| 761 | -class GScopedPointerUnref |
| 762 | -{ |
| 763 | -public: |
| 764 | - static inline void cleanup(void *pointer) |
| 765 | - { |
| 766 | - if (pointer) { |
| 767 | - g_clear_object(&pointer); |
| 768 | - } |
| 769 | - } |
| 770 | -}; |
| 771 | - |
| 772 | -template<class KLASS> |
| 773 | -class GScopedPointer : public QScopedPointer<KLASS, GScopedPointerUnref> |
| 774 | -{ |
| 775 | -public: |
| 776 | - GScopedPointer(KLASS* obj = 0) |
| 777 | - : QScopedPointer<KLASS, GScopedPointerUnref>(obj) |
| 778 | - {} |
| 779 | -}; |
| 780 | |
| 781 | EDSBaseTest::EDSBaseTest() |
| 782 | { |
| 783 | @@ -74,6 +58,22 @@ |
| 784 | QTest::qWait(1000); |
| 785 | } |
| 786 | |
| 787 | +void EDSBaseTest::setCollectionMetadata(const QOrganizerCollectionId &collectionId, const QString &metaData) |
| 788 | +{ |
| 789 | + GError *error = NULL; |
| 790 | + GScopedPointer<ESourceRegistry> sourceRegistry(e_source_registry_new_sync(NULL, &error)); |
| 791 | + if (error) { |
| 792 | + qWarning() << "Fail to create source registry" << error->message; |
| 793 | + g_error_free(error); |
| 794 | + return; |
| 795 | + } |
| 796 | + GScopedPointer<ESource> calendar(e_source_registry_ref_source(sourceRegistry.data(), |
| 797 | + collectionId.toString().split(":").last().toUtf8().data())); |
| 798 | + ESourceUbuntu *ubuntu = E_SOURCE_UBUNTU(e_source_get_extension(calendar.data(), E_SOURCE_EXTENSION_UBUNTU)); |
| 799 | + e_source_ubuntu_set_metadata(ubuntu, metaData.toUtf8().constData()); |
| 800 | + e_source_write_sync(calendar.data(), NULL, NULL); |
| 801 | +} |
| 802 | + |
| 803 | QString EDSBaseTest::getEventFromEvolution(const QOrganizerItemId &id, |
| 804 | const QOrganizerCollectionId &collectionId) |
| 805 | { |
| 806 | |
| 807 | === modified file 'tests/unittest/eds-base-test.h' |
| 808 | --- tests/unittest/eds-base-test.h 2015-04-09 00:03:01 +0000 |
| 809 | +++ tests/unittest/eds-base-test.h 2016-07-11 14:47:56 +0000 |
| 810 | @@ -37,6 +37,8 @@ |
| 811 | virtual void cleanup(); |
| 812 | |
| 813 | |
| 814 | + void setCollectionMetadata(const QtOrganizer::QOrganizerCollectionId &collectionId, |
| 815 | + const QString &metaData); |
| 816 | QString getEventFromEvolution(const QtOrganizer::QOrganizerItemId &id, |
| 817 | const QtOrganizer::QOrganizerCollectionId &collectionId = QtOrganizer::QOrganizerCollectionId()); |
| 818 | QString uniqueCollectionName() const; |
| 819 | |
| 820 | === added file 'tests/unittest/gscopedpointer.h' |
| 821 | --- tests/unittest/gscopedpointer.h 1970-01-01 00:00:00 +0000 |
| 822 | +++ tests/unittest/gscopedpointer.h 2016-07-11 14:47:56 +0000 |
| 823 | @@ -0,0 +1,43 @@ |
| 824 | +/* |
| 825 | + * Copyright 2016 Canonical Ltd. |
| 826 | + * |
| 827 | + * This file is part of qtorganizer5-eds. |
| 828 | + * |
| 829 | + * contact-service-app is free software; you can redistribute it and/or modify |
| 830 | + * it under the terms of the GNU General Public License as published by |
| 831 | + * the Free Software Foundation; version 3. |
| 832 | + * |
| 833 | + * contact-service-app is distributed in the hope that it will be useful, |
| 834 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 835 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 836 | + * GNU General Public License for more details. |
| 837 | + * |
| 838 | + * You should have received a copy of the GNU General Public License |
| 839 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 840 | + */ |
| 841 | + |
| 842 | +#ifndef __GSCOPEDPOINTER__ |
| 843 | +#define __GSCOPEDPOINTER__ |
| 844 | + |
| 845 | + |
| 846 | +class GScopedPointerUnref |
| 847 | +{ |
| 848 | +public: |
| 849 | + static inline void cleanup(void *pointer) |
| 850 | + { |
| 851 | + if (pointer) { |
| 852 | + g_clear_object(&pointer); |
| 853 | + } |
| 854 | + } |
| 855 | +}; |
| 856 | + |
| 857 | +template<class KLASS> |
| 858 | +class GScopedPointer : public QScopedPointer<KLASS, GScopedPointerUnref> |
| 859 | +{ |
| 860 | +public: |
| 861 | + GScopedPointer(KLASS* obj = 0) |
| 862 | + : QScopedPointer<KLASS, GScopedPointerUnref>(obj) |
| 863 | + {} |
| 864 | +}; |
| 865 | + |
| 866 | +#endif |
| 867 | |
| 868 | === modified file 'tests/unittest/parseecal-test.cpp' |
| 869 | --- tests/unittest/parseecal-test.cpp 2015-04-10 18:20:07 +0000 |
| 870 | +++ tests/unittest/parseecal-test.cpp 2016-07-11 14:47:56 +0000 |
| 871 | @@ -21,6 +21,8 @@ |
| 872 | #include "qorganizer-eds-engine.h" |
| 873 | #undef private |
| 874 | |
| 875 | +#include "gscopedpointer.h" |
| 876 | + |
| 877 | #include <QObject> |
| 878 | #include <QtTest> |
| 879 | #include <QDebug> |
| 880 | @@ -56,25 +58,25 @@ |
| 881 | QDateTime endTime(startTime); |
| 882 | endTime = endTime.addDays(2); |
| 883 | |
| 884 | - ECalComponent *comp = e_cal_component_new(); |
| 885 | - e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT); |
| 886 | + GScopedPointer<ECalComponent> comp(e_cal_component_new()); |
| 887 | + e_cal_component_set_new_vtype(comp.data(), E_CAL_COMPONENT_EVENT); |
| 888 | |
| 889 | ECalComponentDateTime dt; |
| 890 | |
| 891 | struct icaltimetype itt = icaltime_from_timet(startTime.toTime_t(), FALSE); |
| 892 | dt.value = &itt; |
| 893 | dt.tzid = ""; |
| 894 | - e_cal_component_set_dtstart(comp, &dt); |
| 895 | + e_cal_component_set_dtstart(comp.data(), &dt); |
| 896 | |
| 897 | QOrganizerEvent item; |
| 898 | - QOrganizerEDSEngine::parseStartTime(comp, &item); |
| 899 | + QOrganizerEDSEngine::parseStartTime(comp.data(), &item); |
| 900 | QCOMPARE(item.startDateTime().toTime_t(), startTime.toTime_t()); |
| 901 | |
| 902 | itt = icaltime_from_timet(endTime.toTime_t(), FALSE); |
| 903 | dt.value = &itt; |
| 904 | - e_cal_component_set_dtend(comp, &dt); |
| 905 | + e_cal_component_set_dtend(comp.data(), &dt); |
| 906 | |
| 907 | - QOrganizerEDSEngine::parseEndTime(comp, &item); |
| 908 | + QOrganizerEDSEngine::parseEndTime(comp.data(), &item); |
| 909 | QCOMPARE(item.endDateTime().toTime_t(), endTime.toTime_t()); |
| 910 | } |
| 911 | |
| 912 | @@ -89,15 +91,15 @@ |
| 913 | QCOMPARE(aReminder.secondsBeforeStart(), 10); |
| 914 | event.saveDetail(&aReminder); |
| 915 | |
| 916 | - ECalComponent *comp = e_cal_component_new(); |
| 917 | - e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT); |
| 918 | - |
| 919 | - QOrganizerEDSEngine::parseReminders(event, comp); |
| 920 | - |
| 921 | - GList *aIds = e_cal_component_get_alarm_uids(comp); |
| 922 | + GScopedPointer<ECalComponent> comp(e_cal_component_new()); |
| 923 | + e_cal_component_set_new_vtype(comp.data(), E_CAL_COMPONENT_EVENT); |
| 924 | + |
| 925 | + QOrganizerEDSEngine::parseReminders(event, comp.data()); |
| 926 | + |
| 927 | + GList *aIds = e_cal_component_get_alarm_uids(comp.data()); |
| 928 | QCOMPARE(g_list_length(aIds), (guint) 1); |
| 929 | |
| 930 | - ECalComponentAlarm *alarm = e_cal_component_get_alarm(comp, (const gchar*)aIds->data); |
| 931 | + ECalComponentAlarm *alarm = e_cal_component_get_alarm(comp.data(), (const gchar*)aIds->data); |
| 932 | QVERIFY(alarm); |
| 933 | |
| 934 | ECalComponentAlarmAction aAction; |
| 935 | @@ -114,13 +116,14 @@ |
| 936 | QCOMPARE(aRepeat.repetitions, aReminder.repetitionCount()); |
| 937 | QCOMPARE(icaldurationtype_as_int(aRepeat.duration), aReminder.repetitionDelay()); |
| 938 | |
| 939 | - g_object_unref(comp); |
| 940 | + e_cal_component_alarm_free(alarm); |
| 941 | + cal_obj_uid_list_free(aIds); |
| 942 | } |
| 943 | |
| 944 | void testParseRemindersECalComponent2QOrganizerEvent() |
| 945 | { |
| 946 | - ECalComponent *comp = e_cal_component_new(); |
| 947 | - e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT); |
| 948 | + GScopedPointer<ECalComponent> comp(e_cal_component_new()); |
| 949 | + e_cal_component_set_new_vtype(comp.data(), E_CAL_COMPONENT_EVENT); |
| 950 | |
| 951 | ECalComponentAlarm *alarm = e_cal_component_alarm_new(); |
| 952 | e_cal_component_alarm_set_action(alarm, E_CAL_COMPONENT_ALARM_DISPLAY); |
| 953 | @@ -135,18 +138,16 @@ |
| 954 | aRepeat.duration = icaldurationtype_from_int(100); |
| 955 | e_cal_component_alarm_set_repeat(alarm, aRepeat); |
| 956 | |
| 957 | - e_cal_component_add_alarm(comp, alarm); |
| 958 | + e_cal_component_add_alarm(comp.data(), alarm); |
| 959 | e_cal_component_alarm_free(alarm); |
| 960 | |
| 961 | QOrganizerItem alarmItem; |
| 962 | - QOrganizerEDSEngine::parseReminders(comp, &alarmItem); |
| 963 | + QOrganizerEDSEngine::parseReminders(comp.data(), &alarmItem); |
| 964 | |
| 965 | QOrganizerItemVisualReminder vReminder = alarmItem.detail(QOrganizerItemDetail::TypeVisualReminder); |
| 966 | QCOMPARE(vReminder.repetitionCount(), 5); |
| 967 | QCOMPARE(vReminder.repetitionDelay(), 100); |
| 968 | QCOMPARE(vReminder.secondsBeforeStart(), 10); |
| 969 | - |
| 970 | - g_object_unref(comp); |
| 971 | } |
| 972 | |
| 973 | void testParseRecurenceQOrganizerEvent2ECalComponent() |
| 974 | @@ -323,6 +324,8 @@ |
| 975 | } |
| 976 | } |
| 977 | |
| 978 | + e_cal_component_free_recur_list(recurList); |
| 979 | + |
| 980 | // invert |
| 981 | QOrganizerEvent event2; |
| 982 | QOrganizerEDSEngine::parseRecurrence(comp, &event2); |
| 983 | @@ -384,7 +387,7 @@ |
| 984 | QVERIFY(icalcomponent_is_valid(ical)); |
| 985 | |
| 986 | QList<QOrganizerItemDetail::DetailType> detailsHint; |
| 987 | - GSList *events = g_slist_append(0, ical); |
| 988 | + GSList *events = g_slist_append(events, ical); |
| 989 | QMap<QString, GSList*> eventMap; |
| 990 | eventMap.insert(engine->defaultCollection(0).id().toString(), events); |
| 991 | engine->parseEventsAsync(eventMap, true, detailsHint, this, SLOT(onEventAsyncParsed(QList<QOrganizerItem>))); |
| 992 | @@ -412,6 +415,7 @@ |
| 993 | QCOMPARE(vreminder.message(), QStringLiteral("alarm to parse")); |
| 994 | |
| 995 | g_slist_free_full(events, (GDestroyNotify)icalcomponent_free); |
| 996 | + icalcomponent_free(ical); |
| 997 | delete engine; |
| 998 | } |
| 999 | }; |
PASSED: Continuous integration, rev:101 jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-ci/ 256/ jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-vivid- amd64-ci/ 63 jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-vivid- armhf-ci/ 63 jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-vivid- armhf-ci/ 63/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ qtorganizer5- eds-vivid- i386-ci/ 63
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/qtorganizer 5-eds-ci/ 256/rebuild
http://