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: mp+294981@code.launchpad.net |
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://