Merge lp:~renatofilho/qtorganizer5-eds/recurrence into lp:~ubuntu-sdk-team/qtorganizer5-eds/trunk

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 25
Merged at revision: 12
Proposed branch: lp:~renatofilho/qtorganizer5-eds/recurrence
Merge into: lp:~ubuntu-sdk-team/qtorganizer5-eds/trunk
Diff against target: 2806 lines (+2033/-178)
17 files modified
qorganizer/CMakeLists.txt (+4/-1)
qorganizer/qorganizer-eds-collection-engineid.cpp (+12/-0)
qorganizer/qorganizer-eds-collection-engineid.h (+3/-0)
qorganizer/qorganizer-eds-engine.cpp (+922/-151)
qorganizer/qorganizer-eds-engine.h (+62/-17)
qorganizer/qorganizer-eds-fetchrequestdata.cpp (+19/-3)
qorganizer/qorganizer-eds-removecollectionrequestdata.cpp (+76/-0)
qorganizer/qorganizer-eds-removecollectionrequestdata.h (+44/-0)
qorganizer/qorganizer-eds-removerequestdata.cpp (+0/-3)
qorganizer/qorganizer-eds-requestdata.cpp (+2/-2)
qorganizer/qorganizer-eds-requestdata.h (+1/-1)
qorganizer/qorganizer-eds-savecollectionrequestdata.cpp (+139/-0)
qorganizer/qorganizer-eds-savecollectionrequestdata.h (+49/-0)
tests/unittest/CMakeLists.txt (+5/-0)
tests/unittest/collections-test.cpp (+191/-0)
tests/unittest/event-test.cpp (+138/-0)
tests/unittest/parseecal-test.cpp (+366/-0)
To merge this branch: bzr merge lp:~renatofilho/qtorganizer5-eds/recurrence
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Gustavo Pichorim Boiko (community) Approve
Review via email: mp+184642@code.launchpad.net

Commit message

- Implemented recurrence support;
- Implemented support for different collection type.
- Implemented Reminder support;

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

Looks good.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'qorganizer/CMakeLists.txt'
--- qorganizer/CMakeLists.txt 2013-08-14 21:23:01 +0000
+++ qorganizer/CMakeLists.txt 2013-09-09 21:01:24 +0000
@@ -7,8 +7,10 @@
7 qorganizer-eds-fetchrequestdata.cpp7 qorganizer-eds-fetchrequestdata.cpp
8 qorganizer-eds-engine.cpp8 qorganizer-eds-engine.cpp
9 qorganizer-eds-engineid.cpp9 qorganizer-eds-engineid.cpp
10 qorganizer-eds-removecollectionrequestdata.cpp
10 qorganizer-eds-removerequestdata.cpp11 qorganizer-eds-removerequestdata.cpp
11 qorganizer-eds-requestdata.cpp12 qorganizer-eds-requestdata.cpp
13 qorganizer-eds-savecollectionrequestdata.cpp
12 qorganizer-eds-saverequestdata.cpp14 qorganizer-eds-saverequestdata.cpp
13)15)
1416
@@ -17,8 +19,10 @@
17 qorganizer-eds-fetchrequestdata.h19 qorganizer-eds-fetchrequestdata.h
18 qorganizer-eds-engine.h20 qorganizer-eds-engine.h
19 qorganizer-eds-engineid.h21 qorganizer-eds-engineid.h
22 qorganizer-eds-removecollectionrequestdata.h
20 qorganizer-eds-removerequestdata.h23 qorganizer-eds-removerequestdata.h
21 qorganizer-eds-requestdata.h24 qorganizer-eds-requestdata.h
25 qorganizer-eds-savecollectionrequestdata.h
22 qorganizer-eds-saverequestdata.h26 qorganizer-eds-saverequestdata.h
23)27)
2428
@@ -53,7 +57,6 @@
53 ${EDATASERVER_LIBRARIES}57 ${EDATASERVER_LIBRARIES}
54)58)
5559
56
57qt5_use_modules(${QORGANIZER_BACKEND}-lib Core Organizer)60qt5_use_modules(${QORGANIZER_BACKEND}-lib Core Organizer)
58qt5_use_modules(${QORGANIZER_BACKEND} Core Organizer)61qt5_use_modules(${QORGANIZER_BACKEND} Core Organizer)
5962
6063
=== modified file 'qorganizer/qorganizer-eds-collection-engineid.cpp'
--- qorganizer/qorganizer-eds-collection-engineid.cpp 2013-08-14 21:23:01 +0000
+++ qorganizer/qorganizer-eds-collection-engineid.cpp 2013-09-09 21:01:24 +0000
@@ -18,12 +18,24 @@
1818
19#include "qorganizer-eds-collection-engineid.h"19#include "qorganizer-eds-collection-engineid.h"
2020
21
22
21QOrganizerEDSCollectionEngineId::QOrganizerEDSCollectionEngineId(ESource *source,23QOrganizerEDSCollectionEngineId::QOrganizerEDSCollectionEngineId(ESource *source,
22 const QString &managerUri)24 const QString &managerUri)
23 : m_managerUri(managerUri), m_esource(source)25 : m_managerUri(managerUri), m_esource(source)
24{26{
25 g_object_ref(m_esource);27 g_object_ref(m_esource);
26 m_collectionId = QString::fromUtf8(e_source_get_uid(m_esource));28 m_collectionId = QString::fromUtf8(e_source_get_uid(m_esource));
29 if (e_source_has_extension(m_esource, E_SOURCE_EXTENSION_CALENDAR)) {
30 m_sourceType = E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
31 } else if (e_source_has_extension(m_esource, E_SOURCE_EXTENSION_TASK_LIST)) {
32 m_sourceType = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
33 } else if (e_source_has_extension(m_esource, E_SOURCE_EXTENSION_MEMO_LIST)) {
34 m_sourceType = E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
35 } else {
36 qWarning() << "Source extension not supported";
37 Q_ASSERT(false);
38 }
27}39}
2840
29QOrganizerEDSCollectionEngineId::QOrganizerEDSCollectionEngineId()41QOrganizerEDSCollectionEngineId::QOrganizerEDSCollectionEngineId()
3042
=== modified file 'qorganizer/qorganizer-eds-collection-engineid.h'
--- qorganizer/qorganizer-eds-collection-engineid.h 2013-08-14 21:23:01 +0000
+++ qorganizer/qorganizer-eds-collection-engineid.h 2013-09-09 21:01:24 +0000
@@ -22,6 +22,7 @@
22#include <QtOrganizer/QOrganizerCollectionEngineId>22#include <QtOrganizer/QOrganizerCollectionEngineId>
2323
24#include <libedataserver/libedataserver.h>24#include <libedataserver/libedataserver.h>
25#include <libecal/libecal.h>
2526
26class QOrganizerEDSCollectionEngineId : public QtOrganizer::QOrganizerCollectionEngineId27class QOrganizerEDSCollectionEngineId : public QtOrganizer::QOrganizerCollectionEngineId
27{28{
@@ -39,6 +40,7 @@
3940
40 QString toString() const;41 QString toString() const;
4142
43
42 uint hash() const;44 uint hash() const;
4345
44#ifndef QT_NO_DEBUG_STREAM46#ifndef QT_NO_DEBUG_STREAM
@@ -49,6 +51,7 @@
49 QString m_collectionId;51 QString m_collectionId;
50 QString m_managerUri;52 QString m_managerUri;
51 ESource *m_esource;53 ESource *m_esource;
54 ECalClientSourceType m_sourceType;
5255
53 QOrganizerEDSCollectionEngineId(ESource *source, const QString &managerUri);56 QOrganizerEDSCollectionEngineId(ESource *source, const QString &managerUri);
5457
5558
=== modified file 'qorganizer/qorganizer-eds-engine.cpp'
--- qorganizer/qorganizer-eds-engine.cpp 2013-08-16 02:22:42 +0000
+++ qorganizer/qorganizer-eds-engine.cpp 2013-09-09 21:01:24 +0000
@@ -23,11 +23,14 @@
23#include "qorganizer-eds-fetchrequestdata.h"23#include "qorganizer-eds-fetchrequestdata.h"
24#include "qorganizer-eds-saverequestdata.h"24#include "qorganizer-eds-saverequestdata.h"
25#include "qorganizer-eds-removerequestdata.h"25#include "qorganizer-eds-removerequestdata.h"
26#include "qorganizer-eds-savecollectionrequestdata.h"
27#include "qorganizer-eds-removecollectionrequestdata.h"
2628
27#include <QtCore/qdebug.h>29#include <QtCore/qdebug.h>
28#include <QtCore/QPointer>30#include <QtCore/QPointer>
29#include <QtCore/qstringbuilder.h>31#include <QtCore/qstringbuilder.h>
30#include <QtCore/quuid.h>32#include <QtCore/quuid.h>
33#include <QtCore/QCoreApplication>
3134
32#include <QtOrganizer/QOrganizerEventAttendee>35#include <QtOrganizer/QOrganizerEventAttendee>
33#include <QtOrganizer/QOrganizerItemLocation>36#include <QtOrganizer/QOrganizerItemLocation>
@@ -36,11 +39,18 @@
36#include <QtOrganizer/QOrganizerItemSaveRequest>39#include <QtOrganizer/QOrganizerItemSaveRequest>
37#include <QtOrganizer/QOrganizerItemRemoveRequest>40#include <QtOrganizer/QOrganizerItemRemoveRequest>
38#include <QtOrganizer/QOrganizerCollectionFetchRequest>41#include <QtOrganizer/QOrganizerCollectionFetchRequest>
42#include <QtOrganizer/QOrganizerCollectionSaveRequest>
43#include <QtOrganizer/QOrganizerCollectionRemoveRequest>
39#include <QtOrganizer/QOrganizerEvent>44#include <QtOrganizer/QOrganizerEvent>
40#include <QtOrganizer/QOrganizerTodo>45#include <QtOrganizer/QOrganizerTodo>
41#include <QtOrganizer/QOrganizerTodoTime>46#include <QtOrganizer/QOrganizerTodoTime>
42#include <QtOrganizer/QOrganizerJournal>47#include <QtOrganizer/QOrganizerJournal>
43#include <QtOrganizer/QOrganizerJournalTime>48#include <QtOrganizer/QOrganizerJournalTime>
49#include <QtOrganizer/QOrganizerItemIdFetchRequest>
50#include <QtOrganizer/QOrganizerItemIdFilter>
51#include <QtOrganizer/QOrganizerItemReminder>
52#include <QtOrganizer/QOrganizerItemAudibleReminder>
53#include <QtOrganizer/QOrganizerItemVisualReminder>
4454
45#include <glib.h>55#include <glib.h>
46#include <libecal/libecal.h>56#include <libecal/libecal.h>
@@ -95,7 +105,7 @@
95 QOrganizerEDSCollectionEngineId *collection = data->nextCollection();105 QOrganizerEDSCollectionEngineId *collection = data->nextCollection();
96 if (collection) {106 if (collection) {
97 e_cal_client_connect(collection->m_esource,107 e_cal_client_connect(collection->m_esource,
98 E_CAL_CLIENT_SOURCE_TYPE_EVENTS,108 collection->m_sourceType,
99 data->cancellable(),109 data->cancellable(),
100 (GAsyncReadyCallback) QOrganizerEDSEngine::itemsAsyncConnected,110 (GAsyncReadyCallback) QOrganizerEDSEngine::itemsAsyncConnected,
101 data);111 data);
@@ -115,7 +125,7 @@
115 EClient *client = e_cal_client_connect_finish(res, &gError);125 EClient *client = e_cal_client_connect_finish(res, &gError);
116126
117 if (gError) {127 if (gError) {
118 qWarning() << "Fail to open calendar" << gError->message;128 qWarning() << "Fail to open calendar:" << gError->message;
119 g_error_free(gError);129 g_error_free(gError);
120 gError = 0;130 gError = 0;
121 data->finish(QOrganizerManager::InvalidCollectionError);131 data->finish(QOrganizerManager::InvalidCollectionError);
@@ -150,26 +160,36 @@
150 delete data;160 delete data;
151 return;161 return;
152 } else {162 } else {
153 qDebug() << "Query size:" << g_slist_length(events);
154 data->appendResults(parseEvents(data->collection(), events));163 data->appendResults(parseEvents(data->collection(), events));
155 }164 }
156 itemsAsyncStart(data);165 itemsAsyncStart(data);
157}166}
158167
159
160
161QList<QOrganizerItem> QOrganizerEDSEngine::items(const QList<QOrganizerItemId> &itemIds,168QList<QOrganizerItem> QOrganizerEDSEngine::items(const QList<QOrganizerItemId> &itemIds,
162 const QOrganizerItemFetchHint &fetchHint,169 const QOrganizerItemFetchHint &fetchHint,
163 QMap<int, QOrganizerManager::Error> *errorMap,170 QMap<int, QOrganizerManager::Error> *errorMap,
164 QOrganizerManager::Error *error)171 QOrganizerManager::Error *error)
165{172{
166 qDebug() << Q_FUNC_INFO;173 qDebug() << Q_FUNC_INFO;
167 Q_UNUSED(fetchHint)174 QOrganizerItemIdFilter filter;
168 Q_UNUSED(itemIds);175 filter.setIds(itemIds);
169 Q_UNUSED(errorMap);176
170177 QOrganizerItemFetchRequest *req = new QOrganizerItemFetchRequest(this);
171 QList<QOrganizerItem> items;178 req->setFilter(filter);
172 return items;179 req->setFetchHint(fetchHint);
180
181 startRequest(req);
182 waitForRequestFinished(req, -1);
183
184 if (error) {
185 *error = req->error();
186 }
187 // TODO implement correct reply for errorMap
188 if (errorMap) {
189 *errorMap = QMap<int, QOrganizerManager::Error>();
190 }
191 req->deleteLater();
192 return req->items();
173}193}
174194
175QList<QOrganizerItem> QOrganizerEDSEngine::items(const QOrganizerItemFilter &filter,195QList<QOrganizerItem> QOrganizerEDSEngine::items(const QOrganizerItemFilter &filter,
@@ -181,12 +201,25 @@
181 QOrganizerManager::Error *error)201 QOrganizerManager::Error *error)
182{202{
183 qDebug() << Q_FUNC_INFO;203 qDebug() << Q_FUNC_INFO;
184 QList<QOrganizerItem> list;204
185 return list;205 QOrganizerItemFetchRequest *req = new QOrganizerItemFetchRequest(this);
206 req->setFilter(filter);
207 req->setStartDate(startDateTime);
208 req->setEndDate(endDateTime);
209 req->setMaxCount(maxCount);
210 req->setSorting(sortOrders);
211 req->setFetchHint(fetchHint);
212
213 startRequest(req);
214 waitForRequestFinished(req, -1);
215
216 if (error) {
217 *error = req->error();
218 }
219 req->deleteLater();
220 return req->items();
186}221}
187222
188
189
190QList<QOrganizerItemId> QOrganizerEDSEngine::itemIds(const QOrganizerItemFilter &filter,223QList<QOrganizerItemId> QOrganizerEDSEngine::itemIds(const QOrganizerItemFilter &filter,
191 const QDateTime &startDateTime,224 const QDateTime &startDateTime,
192 const QDateTime &endDateTime,225 const QDateTime &endDateTime,
@@ -224,6 +257,7 @@
224{257{
225 qDebug() << Q_FUNC_INFO;258 qDebug() << Q_FUNC_INFO;
226 if (req->items().count() == 0) {259 if (req->items().count() == 0) {
260 qWarning() << "Items count is " << req->items().count();
227 QOrganizerManagerEngine::updateItemSaveRequest(req,261 QOrganizerManagerEngine::updateItemSaveRequest(req,
228 QList<QOrganizerItem>(),262 QList<QOrganizerItem>(),
229 QOrganizerManager::NoError,263 QOrganizerManager::NoError,
@@ -248,7 +282,7 @@
248282
249 SaveRequestData *data = new SaveRequestData(this, req, collectionId);283 SaveRequestData *data = new SaveRequestData(this, req, collectionId);
250 e_cal_client_connect(collectionEngineId->m_esource,284 e_cal_client_connect(collectionEngineId->m_esource,
251 E_CAL_CLIENT_SOURCE_TYPE_EVENTS,285 collectionEngineId->m_sourceType,
252 data->cancellable(),286 data->cancellable(),
253 (GAsyncReadyCallback) QOrganizerEDSEngine::saveItemsAsyncConnected,287 (GAsyncReadyCallback) QOrganizerEDSEngine::saveItemsAsyncConnected,
254 data);288 data);
@@ -258,6 +292,7 @@
258 GAsyncResult *res,292 GAsyncResult *res,
259 SaveRequestData *data)293 SaveRequestData *data)
260{294{
295 qDebug() << Q_FUNC_INFO;
261 Q_UNUSED(source_object);296 Q_UNUSED(source_object);
262297
263 GError *gError = 0;298 GError *gError = 0;
@@ -271,7 +306,7 @@
271 } else {306 } else {
272 data->setClient(client);307 data->setClient(client);
273308
274 GSList *comps = parseItems(data->request<QOrganizerItemSaveRequest>()->items());309 GSList *comps = parseItems(data->client(), data->request<QOrganizerItemSaveRequest>()->items());
275 if (comps) {310 if (comps) {
276 if (data->isNew()) {311 if (data->isNew()) {
277 e_cal_client_create_objects(E_CAL_CLIENT(client),312 e_cal_client_create_objects(E_CAL_CLIENT(client),
@@ -300,6 +335,7 @@
300 GAsyncResult *res,335 GAsyncResult *res,
301 SaveRequestData *data)336 SaveRequestData *data)
302{337{
338 qDebug() << Q_FUNC_INFO;
303 Q_UNUSED(source_object);339 Q_UNUSED(source_object);
304340
305 GError *gError = 0;341 GError *gError = 0;
@@ -324,6 +360,7 @@
324 GAsyncResult *res,360 GAsyncResult *res,
325 SaveRequestData *data)361 SaveRequestData *data)
326{362{
363 qDebug() << Q_FUNC_INFO;
327 Q_UNUSED(source_object);364 Q_UNUSED(source_object);
328365
329 GError *gError = 0;366 GError *gError = 0;
@@ -334,7 +371,7 @@
334 &gError);371 &gError);
335372
336 if (gError) {373 if (gError) {
337 qWarning() << "Fail to create items" << gError->message;374 qWarning() << "Fail to create items:" << gError->message;
338 g_error_free(gError);375 g_error_free(gError);
339 gError = 0;376 gError = 0;
340 data->finish(QOrganizerManager::InvalidDetailError);377 data->finish(QOrganizerManager::InvalidDetailError);
@@ -367,7 +404,24 @@
367404
368{405{
369 qDebug() << Q_FUNC_INFO;406 qDebug() << Q_FUNC_INFO;
370 *error = QOrganizerManager::NoError;407
408 QOrganizerItemSaveRequest *req = new QOrganizerItemSaveRequest(this);
409 req->setItems(*items);
410 req->setDetailMask(detailMask);
411
412 startRequest(req);
413 waitForRequestFinished(req, -1);
414
415 *errorMap = req->errorMap();
416 *error = req->error();
417
418 if (*error == QOrganizerManager::NoError) {
419 *items = req->items();
420 return true;
421 } else {
422 return false;
423 }
424
371 return true;425 return true;
372}426}
373427
@@ -392,9 +446,8 @@
392 QOrganizerCollectionId collection = data->begin();446 QOrganizerCollectionId collection = data->begin();
393 if (!collection.isNull()) {447 if (!collection.isNull()) {
394 QOrganizerEDSCollectionEngineId *collectionEngineId = data->parent()->m_collectionsMap[collection.toString()];448 QOrganizerEDSCollectionEngineId *collectionEngineId = data->parent()->m_collectionsMap[collection.toString()];
395 qDebug() << "REmove items from sourcE: " << e_source_get_display_name(collectionEngineId->m_esource);
396 e_cal_client_connect(collectionEngineId->m_esource,449 e_cal_client_connect(collectionEngineId->m_esource,
397 E_CAL_CLIENT_SOURCE_TYPE_EVENTS,450 collectionEngineId->m_sourceType,
398 data->cancellable(),451 data->cancellable(),
399 (GAsyncReadyCallback) QOrganizerEDSEngine::removeItemsAsyncConnected,452 (GAsyncReadyCallback) QOrganizerEDSEngine::removeItemsAsyncConnected,
400 data);453 data);
@@ -447,7 +500,6 @@
447 data->finish(QOrganizerManager::InvalidCollectionError);500 data->finish(QOrganizerManager::InvalidCollectionError);
448 delete data;501 delete data;
449 } else {502 } else {
450 qDebug() << "Item removed";
451 data->commit();503 data->commit();
452 removeItemsAsyncStart(data);504 removeItemsAsyncStart(data);
453 }505 }
@@ -479,23 +531,164 @@
479QList<QOrganizerCollection> QOrganizerEDSEngine::collections(QOrganizerManager::Error* error)531QList<QOrganizerCollection> QOrganizerEDSEngine::collections(QOrganizerManager::Error* error)
480{532{
481 qDebug() << Q_FUNC_INFO;533 qDebug() << Q_FUNC_INFO;
482 *error = QOrganizerManager::NoError;534
483 return m_collections;535 QOrganizerCollectionFetchRequest *req = new QOrganizerCollectionFetchRequest(this);
536
537 startRequest(req);
538 waitForRequestFinished(req, -1);
539
540 *error = req->error();
541
542 if (*error == QOrganizerManager::NoError) {
543 return req->collections();
544 } else {
545 return QList<QOrganizerCollection>();
546 }
484}547}
485548
486bool QOrganizerEDSEngine::saveCollection(QOrganizerCollection* collection, QOrganizerManager::Error* error)549bool QOrganizerEDSEngine::saveCollection(QOrganizerCollection* collection, QOrganizerManager::Error* error)
487{550{
488 qDebug() << Q_FUNC_INFO;551 qDebug() << Q_FUNC_INFO;
489 *error = QOrganizerManager::NoError;552 QOrganizerCollectionSaveRequest *req = new QOrganizerCollectionSaveRequest(this);
490 return true;553 req->setCollection(*collection);
491554
555 startRequest(req);
556 waitForRequestFinished(req, -1);
557
558 *error = req->error();
559 if ((*error == QOrganizerManager::NoError) &&
560 (req->collections().count())) {
561 *collection = req->collections()[0];
562 return true;
563 } else {
564 return false;
565 }
566}
567
568void QOrganizerEDSEngine::saveCollectionAsync(QOrganizerCollectionSaveRequest *req)
569{
570 qDebug() << Q_FUNC_INFO;
571
572 if (req->collections().count() == 0) {
573 QOrganizerManagerEngine::updateCollectionSaveRequest(req,
574 QList<QOrganizerCollection>(),
575 QOrganizerManager::NoError,
576 QMap<int, QOrganizerManager::Error>(),
577 QOrganizerAbstractRequest::FinishedState);
578 return;
579 }
580
581 GError *gError = 0;
582 ESourceRegistry *registry = e_source_registry_new_sync(0, &gError);
583 if (gError) {
584 qWarning() << "Fail to create sourge registry:" << gError->message;
585 g_error_free(gError);
586 QOrganizerManagerEngine::updateCollectionSaveRequest(req,
587 QList<QOrganizerCollection>(),
588 QOrganizerManager::UnspecifiedError,
589 QMap<int, QOrganizerManager::Error>(),
590 QOrganizerAbstractRequest::FinishedState);
591 return;
592 }
593 SaveCollectionRequestData *requestData = new SaveCollectionRequestData(this, req);
594 saveCollectionAsyncStart(registry, requestData);
595}
596
597void QOrganizerEDSEngine::saveCollectionAsyncStart(ESourceRegistry *registry, SaveCollectionRequestData *data)
598{
599 qDebug() << Q_FUNC_INFO;
600
601 ESource *source = data->begin();
602 if (source) {
603 e_source_registry_commit_source(registry,
604 source,
605 data->cancellable(),
606 (GAsyncReadyCallback) QOrganizerEDSEngine::saveCollectionAsyncCommited,
607 data);
608 } else {
609 data->finish();
610 delete data;
611 }
612}
613
614void QOrganizerEDSEngine::saveCollectionAsyncCommited(GObject *source_object,
615 GAsyncResult *res,
616 SaveCollectionRequestData *data)
617{
618 qDebug() << Q_FUNC_INFO;
619 GError *gError = 0;
620 e_source_registry_commit_source_finish(E_SOURCE_REGISTRY(source_object), res, &gError);
621 if (gError) {
622 qWarning() << "Fail to commit source:" << gError->message;
623 g_error_free(gError);
624 data->commit(QOrganizerManager::InvalidCollectionError);
625 } else {
626 data->commit();
627 }
628
629 saveCollectionAsyncStart(E_SOURCE_REGISTRY(source_object), data);
492}630}
493631
494bool QOrganizerEDSEngine::removeCollection(const QOrganizerCollectionId& collectionId, QOrganizerManager::Error* error)632bool QOrganizerEDSEngine::removeCollection(const QOrganizerCollectionId& collectionId, QOrganizerManager::Error* error)
495{633{
496 qDebug() << Q_FUNC_INFO;634 qDebug() << Q_FUNC_INFO;
497 *error = QOrganizerManager::NoError;635
498 return true;636 QOrganizerCollectionRemoveRequest *req = new QOrganizerCollectionRemoveRequest(this);
637 req->setCollectionId(collectionId);
638
639 startRequest(req);
640 waitForRequestFinished(req, -1);
641
642 *error = req->error();
643 return(*error == QOrganizerManager::NoError);
644}
645
646void QOrganizerEDSEngine::removeCollectionAsync(QtOrganizer::QOrganizerCollectionRemoveRequest *req)
647{
648 qDebug() << Q_FUNC_INFO;
649
650 if (req->collectionIds().count() == 0) {
651 QOrganizerManagerEngine::updateCollectionRemoveRequest(req,
652 QOrganizerManager::NoError,
653 QMap<int, QOrganizerManager::Error>(),
654 QOrganizerAbstractRequest::FinishedState);
655 return;
656 }
657
658 RemoveCollectionRequestData *requestData = new RemoveCollectionRequestData(this, req);
659 removeCollectionAsyncStart(0, 0, requestData);
660}
661
662void QOrganizerEDSEngine::removeCollectionAsyncStart(GObject *source_object,
663 GAsyncResult *res,
664 RemoveCollectionRequestData *data)
665{
666 if (source_object && res) {
667 GError *gError = 0;
668 e_source_remove_finish(E_SOURCE(source_object), res, &gError);
669 if (gError) {
670 qWarning() << "Fail to remove collection" << gError->message;
671 g_error_free(gError);
672 data->commit(QOrganizerManager::InvalidCollectionError);
673 } else {
674 data->commit();
675 }
676 }
677
678 ESource *source = data->begin();
679 if (source) {
680 if (e_source_get_removable(source)) {
681 e_source_remove(source, data->cancellable(),
682 (GAsyncReadyCallback) QOrganizerEDSEngine::removeCollectionAsyncStart,
683 data);
684 } else {
685 qWarning() << "Source not removable";
686 data->commit(QOrganizerManager::InvalidCollectionError);
687 }
688 } else {
689 data->finish();
690 delete data;
691 }
499}692}
500693
501void QOrganizerEDSEngine::requestDestroyed(QOrganizerAbstractRequest* req)694void QOrganizerEDSEngine::requestDestroyed(QOrganizerAbstractRequest* req)
@@ -511,7 +704,7 @@
511 if (!req)704 if (!req)
512 return false;705 return false;
513706
514707 updateRequestState(req, QOrganizerAbstractRequest::ActiveState);
515 switch (req->type())708 switch (req->type())
516 {709 {
517 case QOrganizerAbstractRequest::ItemFetchRequest:710 case QOrganizerAbstractRequest::ItemFetchRequest:
@@ -529,7 +722,14 @@
529 case QOrganizerAbstractRequest::ItemRemoveRequest:722 case QOrganizerAbstractRequest::ItemRemoveRequest:
530 removeItemsAsync(qobject_cast<QOrganizerItemRemoveRequest*>(req));723 removeItemsAsync(qobject_cast<QOrganizerItemRemoveRequest*>(req));
531 break;724 break;
725 case QOrganizerAbstractRequest::CollectionSaveRequest:
726 saveCollectionAsync(qobject_cast<QOrganizerCollectionSaveRequest*>(req));
727 break;
728 case QOrganizerAbstractRequest::CollectionRemoveRequest:
729 removeCollectionAsync(qobject_cast<QOrganizerCollectionRemoveRequest*>(req));
730 break;
532 default:731 default:
732 updateRequestState(req, QOrganizerAbstractRequest::FinishedState);
533 qDebug() << "No implemented request" << req->type();733 qDebug() << "No implemented request" << req->type();
534 break;734 break;
535 }735 }
@@ -540,16 +740,20 @@
540bool QOrganizerEDSEngine::cancelRequest(QOrganizerAbstractRequest* req)740bool QOrganizerEDSEngine::cancelRequest(QOrganizerAbstractRequest* req)
541{741{
542 qDebug() << Q_FUNC_INFO;742 qDebug() << Q_FUNC_INFO;
543 Q_UNUSED(req); // we can't cancel since we complete immediately743 Q_UNUSED(req);
744 //TODO
745 Q_ASSERT(false);
544 return false;746 return false;
545}747}
546748
547bool QOrganizerEDSEngine::waitForRequestFinished(QOrganizerAbstractRequest* req, int msecs)749bool QOrganizerEDSEngine::waitForRequestFinished(QOrganizerAbstractRequest* req, int msecs)
548{750{
549 qDebug() << Q_FUNC_INFO;751 qDebug() << Q_FUNC_INFO;
550 // in our implementation, we always complete any operation we start.
551 Q_UNUSED(msecs);752 Q_UNUSED(msecs);
552 Q_UNUSED(req);753
754 while(req->state() == QOrganizerAbstractRequest::ActiveState) {
755 QCoreApplication::processEvents();
756 }
553757
554 return true;758 return true;
555}759}
@@ -641,6 +845,23 @@
641 << QOrganizerItemType::TypeTodoOccurrence;845 << QOrganizerItemType::TypeTodoOccurrence;
642}846}
643847
848void QOrganizerEDSEngine::registerCollection(const QOrganizerCollection &collection, QOrganizerEDSCollectionEngineId *edsId)
849{
850 m_collections << collection;
851 m_collectionsMap.insert(collection.id().toString(), edsId);
852}
853
854void QOrganizerEDSEngine::unregisterCollection(const QOrganizerCollectionId &collectionId)
855{
856 Q_FOREACH(QOrganizerCollection col, m_collections) {
857 if (col.id() == collectionId) {
858 m_collections.removeAll(col);
859 }
860 }
861
862 m_collectionsMap.remove(collectionId.toString());
863}
864
644void QOrganizerEDSEngine::loadCollections()865void QOrganizerEDSEngine::loadCollections()
645{866{
646 m_collections.clear();867 m_collections.clear();
@@ -655,21 +876,24 @@
655 }876 }
656877
657 ESource *defaultSource = e_source_registry_ref_default_address_book(registry);878 ESource *defaultSource = e_source_registry_ref_default_address_book(registry);
658 GList *sources = e_source_registry_list_sources(registry, E_SOURCE_EXTENSION_CALENDAR);879 GList *sources = e_source_registry_list_sources(registry, 0);
659 for(int i=0, iMax=g_list_length(sources); i < iMax; i++) {880 for(int i=0, iMax=g_list_length(sources); i < iMax; i++) {
660 ESource *source = E_SOURCE(g_list_nth_data(sources, i));881 ESource *source = E_SOURCE(g_list_nth_data(sources, i));
661 QOrganizerCollection collection;882
662 QOrganizerEDSCollectionEngineId *edsId = new QOrganizerEDSCollectionEngineId(source, managerUri());883 if (e_source_has_extension(source, E_SOURCE_EXTENSION_CALENDAR) ||
663 QOrganizerCollectionId id(edsId);884 e_source_has_extension(source, E_SOURCE_EXTENSION_TASK_LIST) ||
664 collection.setId(id);885 e_source_has_extension(source, E_SOURCE_EXTENSION_MEMO_LIST))
665 collection.setMetaData(QOrganizerCollection::KeyName,886 {
666 QString::fromUtf8(e_source_get_display_name(source)));887 //TODO get metadata (color, etc..)
667 //TODO get metadata (color, etc..)888 QOrganizerEDSCollectionEngineId *edsId = 0;
668 m_collections << collection;889 QOrganizerCollection collection = parseSource(source, managerUri(), &edsId);
669 m_collectionsMap.insert(id.toString(), edsId);890
670891 registerCollection(collection, edsId);
671 if (e_source_compare_by_display_name(source, defaultSource) == 0) {892
672 m_defaultCollection = collection;893 if (e_source_compare_by_display_name(source, defaultSource) == 0) {
894 qDebug() << "Default Source" << e_source_get_display_name(source);
895 m_defaultCollection = collection;
896 }
673 }897 }
674 }898 }
675899
@@ -681,35 +905,117 @@
681 qDebug() << m_collections.count() << "Collection loaded";905 qDebug() << m_collections.count() << "Collection loaded";
682}906}
683907
908ESource *QOrganizerEDSEngine::findSource(const QtOrganizer::QOrganizerCollectionId &id) const
909{
910 if (!id.isNull() && m_collectionsMap.contains(id.toString())) {
911 QOrganizerEDSCollectionEngineId *edsId = m_collectionsMap[id.toString()];
912 Q_ASSERT(edsId);
913 return edsId->m_esource;
914 } else {
915 return 0;
916 }
917}
918
919QOrganizerCollection QOrganizerEDSEngine::parseSource(ESource *source,
920 const QString &managerUri,
921 QOrganizerEDSCollectionEngineId **edsId)
922{
923 *edsId = new QOrganizerEDSCollectionEngineId(source, managerUri);
924 QOrganizerCollectionId id(*edsId);
925 QOrganizerCollection collection;
926
927 collection.setId(id);
928 collection.setMetaData(QOrganizerCollection::KeyName,
929 QString::fromUtf8(e_source_get_display_name(source)));
930
931 return collection;
932}
933
934QOrganizerCollection QOrganizerEDSEngine::parseSource(ESource *source, const QString &managerUri)
935{
936 QOrganizerEDSCollectionEngineId *edsId = 0;
937 return parseSource(source, managerUri, &edsId);
938}
939
684QDateTime QOrganizerEDSEngine::fromIcalTime(struct icaltimetype value)940QDateTime QOrganizerEDSEngine::fromIcalTime(struct icaltimetype value)
685{941{
686 struct tm tmTime = icaltimetype_to_tm(&value);942 uint tmTime = icaltime_as_timet(value);
687 g_date_time_new_from_unix_local(mktime(&tmTime));943 return QDateTime::fromTime_t(tmTime);
688 return QDateTime::fromTime_t(mktime(&tmTime));
689}944}
690945
691void QOrganizerEDSEngine::parseStartTime(ECalComponent *comp, QOrganizerItem *item)946void QOrganizerEDSEngine::parseStartTime(ECalComponent *comp, QOrganizerItem *item)
692{947{
693 ECalComponentDateTime dt;948 ECalComponentDateTime *dt = g_new0(ECalComponentDateTime, 1);
694 e_cal_component_get_dtstart(comp, &dt);949 e_cal_component_get_dtstart(comp, dt);
695 if (dt.value) {950 if (dt->value) {
696 QOrganizerEventTime etr = item->detail(QOrganizerItemDetail::TypeEventTime);951 QOrganizerEventTime etr = item->detail(QOrganizerItemDetail::TypeEventTime);
697 etr.setStartDateTime(fromIcalTime(*dt.value));952 etr.setStartDateTime(fromIcalTime(*dt->value));
698 item->saveDetail(&etr);953 item->saveDetail(&etr);
699 }954 }
700 e_cal_component_free_datetime(&dt);955 e_cal_component_free_datetime(dt);
701}956}
702957
703void QOrganizerEDSEngine::parseEndTime(ECalComponent *comp, QOrganizerItem *item)958void QOrganizerEDSEngine::parseEndTime(ECalComponent *comp, QOrganizerItem *item)
704{959{
705 ECalComponentDateTime dt;960 ECalComponentDateTime *dt = g_new0(ECalComponentDateTime, 1);
706 e_cal_component_get_dtend(comp, &dt);961 e_cal_component_get_dtend(comp, dt);
707 if (dt.value) {962 if (dt->value) {
708 QOrganizerEventTime etr = item->detail(QOrganizerItemDetail::TypeEventTime);963 QOrganizerEventTime etr = item->detail(QOrganizerItemDetail::TypeEventTime);
709 etr.setEndDateTime(fromIcalTime(*dt.value));964 etr.setEndDateTime(fromIcalTime(*dt->value));
710 item->saveDetail(&etr);965 item->saveDetail(&etr);
711 }966 }
712 e_cal_component_free_datetime(&dt);967 e_cal_component_free_datetime(dt);
968}
969
970void QOrganizerEDSEngine::parseWeekRecurrence(struct icalrecurrencetype *rule, QtOrganizer::QOrganizerRecurrenceRule *qRule)
971{
972 qRule->setFrequency(QOrganizerRecurrenceRule::Weekly);
973
974 QSet<Qt::DayOfWeek> daysOfWeek;
975 for (int d=0; d < Qt::Sunday; d++) {
976 short day = rule->by_day[d];
977 if (day != ICAL_RECURRENCE_ARRAY_MAX) {
978 daysOfWeek.insert(static_cast<Qt::DayOfWeek>(icalrecurrencetype_day_day_of_week(rule->by_day[d]) - 1));
979 }
980 }
981 qRule->setDaysOfWeek(daysOfWeek);
982}
983
984void QOrganizerEDSEngine::parseMonthRecurrence(struct icalrecurrencetype *rule, QtOrganizer::QOrganizerRecurrenceRule *qRule)
985{
986 qRule->setFrequency(QOrganizerRecurrenceRule::Monthly);
987
988 QSet<int> daysOfMonth;
989 for (int d=0; d < ICAL_BY_MONTHDAY_SIZE; d++) {
990 short day = rule->by_month_day[d];
991 if (day != ICAL_RECURRENCE_ARRAY_MAX) {
992 daysOfMonth.insert(day);
993 }
994 }
995 qRule->setDaysOfMonth(daysOfMonth);
996}
997
998void QOrganizerEDSEngine::parseYearRecurrence(struct icalrecurrencetype *rule, QtOrganizer::QOrganizerRecurrenceRule *qRule)
999{
1000 qRule->setFrequency(QOrganizerRecurrenceRule::Yearly);
1001
1002 QSet<int> daysOfYear;
1003 for (int d=0; d < ICAL_BY_YEARDAY_SIZE; d++) {
1004 short day = rule->by_year_day[d];
1005 if (day != ICAL_RECURRENCE_ARRAY_MAX) {
1006 daysOfYear.insert(day);
1007 }
1008 }
1009 qRule->setDaysOfYear(daysOfYear);
1010
1011 QSet<QOrganizerRecurrenceRule::Month> monthOfYear;
1012 for (int d=0; d < ICAL_BY_MONTH_SIZE; d++) {
1013 short month = rule->by_month[d];
1014 if (month != ICAL_RECURRENCE_ARRAY_MAX) {
1015 monthOfYear.insert(static_cast<QOrganizerRecurrenceRule::Month>(month));
1016 }
1017 }
1018 qRule->setMonthsOfYear(monthOfYear);
713}1019}
7141020
715void QOrganizerEDSEngine::parseRecurrence(ECalComponent *comp, QOrganizerItem *item)1021void QOrganizerEDSEngine::parseRecurrence(ECalComponent *comp, QOrganizerItem *item)
@@ -735,6 +1041,7 @@
735 if (e_cal_component_has_exdates(comp)) {1041 if (e_cal_component_has_exdates(comp)) {
736 QSet<QDate> dates;1042 QSet<QDate> dates;
737 GSList *exdateList = 0;1043 GSList *exdateList = 0;
1044
738 e_cal_component_get_exdate_list(comp, &exdateList);1045 e_cal_component_get_exdate_list(comp, &exdateList);
739 for(GSList *i = exdateList; i != 0; i = i->next) {1046 for(GSList *i = exdateList; i != 0; i = i->next) {
740 ECalComponentDateTime* dateTime = (ECalComponentDateTime*) i->data;1047 ECalComponentDateTime* dateTime = (ECalComponentDateTime*) i->data;
@@ -748,6 +1055,69 @@
748 item->saveDetail(&irec);1055 item->saveDetail(&irec);
749 }1056 }
7501057
1058 // rules
1059 GSList *ruleList = 0;
1060 e_cal_component_get_rrule_list(comp, &ruleList);
1061 if (ruleList) {
1062 QSet<QOrganizerRecurrenceRule> qRules;
1063
1064 for(GSList *i = ruleList; i != 0; i = i->next) {
1065 struct icalrecurrencetype *rule = (struct icalrecurrencetype*) i->data;
1066 QOrganizerRecurrenceRule qRule;
1067 switch (rule->freq) {
1068 case ICAL_SECONDLY_RECURRENCE:
1069 case ICAL_MINUTELY_RECURRENCE:
1070 case ICAL_HOURLY_RECURRENCE:
1071 qWarning() << "Recurrence frequency not supported";
1072 break;
1073 case ICAL_DAILY_RECURRENCE:
1074 qRule.setFrequency(QOrganizerRecurrenceRule::Daily);
1075 break;
1076 case ICAL_WEEKLY_RECURRENCE:
1077 parseWeekRecurrence(rule, &qRule);
1078 break;
1079 case ICAL_MONTHLY_RECURRENCE:
1080 parseMonthRecurrence(rule, &qRule);
1081 break;
1082 case ICAL_YEARLY_RECURRENCE:
1083 parseYearRecurrence(rule, &qRule);
1084 break;
1085 case ICAL_NO_RECURRENCE:
1086 break;
1087 }
1088
1089
1090 if (rule->count > 0) {
1091 qRule.setLimit(rule->count);
1092 } else {
1093 QDateTime dt = fromIcalTime(rule->until);
1094 if (dt.isValid()) {
1095 qRule.setLimit(dt.date());
1096 } else {
1097 qRule.clearLimit();
1098 }
1099 }
1100 qRule.setInterval(rule->interval);
1101
1102 QSet<int> positions;
1103 for (int d=0; d < ICAL_BY_SETPOS_SIZE; d++) {
1104 short day = rule->by_set_pos[d];
1105 if (day != ICAL_RECURRENCE_ARRAY_MAX) {
1106 positions.insert(day);
1107 }
1108 }
1109 qRule.setPositions(positions);
1110
1111 qRules << qRule;
1112 }
1113
1114 if (!qRules.isEmpty()) {
1115 QOrganizerItemRecurrence irec = item->detail(QOrganizerItemDetail::TypeRecurrence);
1116 irec.setRecurrenceRules(qRules);
1117 item->saveDetail(&irec);
1118 }
1119 }
1120 // TODO: free ruleList;
751 // TODO: exeptions rules1121 // TODO: exeptions rules
752}1122}
7531123
@@ -866,6 +1236,143 @@
866 return journal;1236 return journal;
867}1237}
8681238
1239void QOrganizerEDSEngine::parseSummary(ECalComponent *comp, QtOrganizer::QOrganizerItem *item)
1240{
1241 ECalComponentText summary;
1242 e_cal_component_get_summary(comp, &summary);
1243 if (summary.value) {
1244 item->setDisplayLabel(QString::fromUtf8(summary.value));
1245 }
1246}
1247
1248void QOrganizerEDSEngine::parseDescription(ECalComponent *comp, QtOrganizer::QOrganizerItem *item)
1249{
1250
1251 GSList *descriptions = 0;
1252 e_cal_component_get_description_list(comp, &descriptions);
1253
1254 QStringList itemDescription;
1255
1256 for(GSList *descList = descriptions; descList != 0; descList = descList->next) {
1257 ECalComponentText *description = static_cast<ECalComponentText*>(descList->data);
1258 if (description) {
1259 itemDescription.append(QString::fromUtf8(description->value));
1260 }
1261 }
1262
1263 item->setDescription(itemDescription.join("\n"));
1264}
1265
1266void QOrganizerEDSEngine::parseComments(ECalComponent *comp, QtOrganizer::QOrganizerItem *item)
1267{
1268 GSList *comments = 0;
1269 e_cal_component_get_comment_list(comp, &comments);
1270 for(int ci=0, ciMax=g_slist_length(comments); ci < ciMax; ci++) {
1271 ECalComponentText *txt = static_cast<ECalComponentText*>(g_slist_nth_data(comments, ci));
1272 item->addComment(QString::fromUtf8(txt->value));
1273 }
1274 e_cal_component_free_text_list(comments);
1275}
1276
1277void QOrganizerEDSEngine::parseTags(ECalComponent *comp, QtOrganizer::QOrganizerItem *item)
1278{
1279 GSList *categories = 0;
1280 e_cal_component_get_categories_list(comp, &categories);
1281 for(GSList *tag=categories; tag != 0; tag = tag->next) {
1282 item->addTag(QString::fromUtf8(static_cast<gchar*>(tag->data)));
1283 }
1284 e_cal_component_free_categories_list(categories);
1285}
1286
1287QByteArray QOrganizerEDSEngine::dencodeAttachment(ECalComponentAlarm *alarm)
1288{
1289 QByteArray attachment;
1290
1291 icalattach *attach = 0;
1292 e_cal_component_alarm_get_attach(alarm, &attach);
1293 if (attach) {
1294 attachment = QByteArray::fromBase64(icalattach_get_url(attach));
1295 icalattach_unref(attach);
1296 }
1297
1298 return attachment;
1299}
1300
1301
1302void QOrganizerEDSEngine::parseVisualReminderAttachment(ECalComponentAlarm *alarm, QOrganizerItemReminder *aDetail)
1303{
1304 QByteArray attach = dencodeAttachment(alarm);
1305 if (!attach.isEmpty()) {
1306 QUrl url;
1307 QString txt;
1308
1309 QDataStream attachStream(&attach, QIODevice::ReadOnly);
1310
1311 attachStream >> url;
1312 attachStream >> txt;
1313
1314 aDetail->setValue(QOrganizerItemVisualReminder::FieldDataUrl, QVariant(url));
1315 aDetail->setValue(QOrganizerItemVisualReminder::FieldMessage, QVariant(txt));
1316 }
1317}
1318
1319
1320void QOrganizerEDSEngine::parseAudibleReminderAttachment(ECalComponentAlarm *alarm, QOrganizerItemReminder *aDetail)
1321{
1322 QByteArray attach = dencodeAttachment(alarm);
1323 if (!attach.isEmpty()) {
1324 QUrl url;
1325
1326 QDataStream attachStream(&attach, QIODevice::ReadOnly);
1327
1328 attachStream >> url;
1329
1330 aDetail->setValue(QOrganizerItemAudibleReminder::FieldDataUrl, QVariant(url));
1331 }
1332}
1333
1334void QOrganizerEDSEngine::parseReminders(ECalComponent *comp, QtOrganizer::QOrganizerItem *item)
1335{
1336 GList *alarms = e_cal_component_get_alarm_uids(comp);
1337 for(GList *a = alarms; a != 0; a = a->next) {
1338 QOrganizerItemReminder *aDetail = 0;
1339
1340 ECalComponentAlarm *alarm = e_cal_component_get_alarm(comp, static_cast<const gchar*>(a->data));
1341 if (!alarm) {
1342 continue;
1343 }
1344 ECalComponentAlarmAction aAction;
1345
1346 e_cal_component_alarm_get_action(alarm, &aAction);
1347 switch(aAction)
1348 {
1349 case E_CAL_COMPONENT_ALARM_DISPLAY:
1350 aDetail = new QOrganizerItemVisualReminder();
1351 parseVisualReminderAttachment(alarm, aDetail);
1352 break;
1353 case E_CAL_COMPONENT_ALARM_AUDIO:
1354 // use audio as fallback
1355 default:
1356 aDetail = new QOrganizerItemAudibleReminder();
1357 parseAudibleReminderAttachment(alarm, aDetail);
1358 break;
1359 }
1360
1361 ECalComponentAlarmTrigger trigger;
1362 e_cal_component_alarm_get_trigger(alarm, &trigger);
1363 if (trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START) {
1364 aDetail->setSecondsBeforeStart(icaldurationtype_as_int(trigger.u.rel_duration) * -1);
1365 }
1366
1367 ECalComponentAlarmRepeat aRepeat;
1368 e_cal_component_alarm_get_repeat(alarm, &aRepeat);
1369 aDetail->setRepetition(aRepeat.repetitions, icaldurationtype_as_int(aRepeat.duration));
1370
1371 item->saveDetail(aDetail);
1372 delete aDetail;
1373 }
1374}
1375
869QList<QOrganizerItem> QOrganizerEDSEngine::parseEvents(QOrganizerEDSCollectionEngineId *collection, GSList *events)1376QList<QOrganizerItem> QOrganizerEDSEngine::parseEvents(QOrganizerEDSCollectionEngineId *collection, GSList *events)
870{1377{
871 QList<QOrganizerItem> items;1378 QList<QOrganizerItem> items;
@@ -905,32 +1412,11 @@
905 collection->managerUri());1412 collection->managerUri());
906 item->setId(QOrganizerItemId(eid));1413 item->setId(QOrganizerItemId(eid));
907 item->setCollectionId(cId);1414 item->setCollectionId(cId);
908 qDebug() << ">>>>>>>>>>>>>>>>>>Loaded item id: " << item->id().toString();1415 parseDescription(comp, item);
9091416 parseSummary(comp, item);
910 //summary1417 parseComments(comp, item);
911 ECalComponentText summary;1418 parseTags(comp, item);
912 e_cal_component_get_summary(comp, &summary);1419 parseReminders(comp, item);
913 if (summary.value) {
914 item->setDisplayLabel(QString::fromUtf8(summary.value));
915 }
916
917 //comments
918 GSList *comments = 0;
919 e_cal_component_get_comment_list(comp, &comments);
920 for(int ci=0, ciMax=g_slist_length(comments); ci < ciMax; ci++) {
921 ECalComponentText *txt = static_cast<ECalComponentText*>(g_slist_nth_data(comments, ci));
922 item->addComment(QString::fromUtf8(txt->value));
923 }
924 e_cal_component_free_text_list(comments);
925
926 //tags
927 GSList *categories = 0;
928 e_cal_component_get_categories_list(comp, &categories);
929 for(int ci=0, ciMax=g_slist_length(comments); ci < ciMax; ci++) {
930 item->addTag(QString::fromUtf8(static_cast<gchar*>(g_slist_nth_data(categories, ci))));
931 }
932 e_cal_component_free_categories_list(categories);
933
9341420
935// //Attendee1421// //Attendee
936// GList *attendeeList = 0;1422// GList *attendeeList = 0;
@@ -958,10 +1444,12 @@
958{1444{
959 QOrganizerEventTime etr = item.detail(QOrganizerItemDetail::TypeEventTime);1445 QOrganizerEventTime etr = item.detail(QOrganizerItemDetail::TypeEventTime);
960 if (!etr.isEmpty()) {1446 if (!etr.isEmpty()) {
961 ECalComponentDateTime dt;1447 ECalComponentDateTime *dt = g_new0(ECalComponentDateTime, 1);
962 struct icaltimetype itt = icaltime_from_timet(etr.startDateTime().toTime_t(), FALSE);1448 dt->value = g_new0(struct icaltimetype, 1);
963 dt.value = &itt;1449 *dt->value = icaltime_from_timet(etr.startDateTime().toTime_t(), FALSE);
964 e_cal_component_set_dtstart(comp, &dt);1450
1451 e_cal_component_set_dtstart(comp, dt);
1452 e_cal_component_free_datetime(dt);
965 }1453 }
966}1454}
9671455
@@ -969,12 +1457,98 @@
969{1457{
970 QOrganizerEventTime etr = item.detail(QOrganizerItemDetail::TypeEventTime);1458 QOrganizerEventTime etr = item.detail(QOrganizerItemDetail::TypeEventTime);
971 if (!etr.isEmpty()) {1459 if (!etr.isEmpty()) {
972 ECalComponentDateTime dt;1460 ECalComponentDateTime *dt = g_new0(ECalComponentDateTime, 1);
973 struct icaltimetype itt = icaltime_from_timet(etr.endDateTime().toTime_t(), FALSE);1461 dt->value = g_new0(struct icaltimetype, 1);
974 dt.value = &itt;1462 *dt->value = icaltime_from_timet(etr.endDateTime().toTime_t(), FALSE);
975 e_cal_component_set_dtend(comp, &dt);;1463 e_cal_component_set_dtend(comp, dt);
976 }1464 e_cal_component_free_datetime(dt);
977}1465 }
1466}
1467
1468void QOrganizerEDSEngine::parseTodoStartTime(const QOrganizerItem &item, ECalComponent *comp)
1469{
1470 QOrganizerTodoTime etr = item.detail(QOrganizerItemDetail::TypeTodoTime);
1471 if (!etr.isEmpty()) {
1472 ECalComponentDateTime *dt = g_new0(ECalComponentDateTime, 1);
1473 dt->value = g_new0(struct icaltimetype, 1);
1474 *dt->value = icaltime_from_timet(etr.startDateTime().toTime_t(), FALSE);
1475
1476 e_cal_component_set_dtstart(comp, dt);
1477 e_cal_component_free_datetime(dt);
1478 }
1479}
1480
1481void QOrganizerEDSEngine::parseWeekRecurrence(const QOrganizerRecurrenceRule &qRule, struct icalrecurrencetype *rule)
1482{
1483 static QMap<Qt::DayOfWeek, icalrecurrencetype_weekday> daysOfWeekMap;
1484 if (daysOfWeekMap.isEmpty()) {
1485 daysOfWeekMap.insert(Qt::Monday, ICAL_MONDAY_WEEKDAY);
1486 daysOfWeekMap.insert(Qt::Thursday, ICAL_THURSDAY_WEEKDAY);
1487 daysOfWeekMap.insert(Qt::Wednesday, ICAL_WEDNESDAY_WEEKDAY);
1488 daysOfWeekMap.insert(Qt::Tuesday, ICAL_TUESDAY_WEEKDAY);
1489 daysOfWeekMap.insert(Qt::Friday, ICAL_FRIDAY_WEEKDAY);
1490 daysOfWeekMap.insert(Qt::Saturday, ICAL_SATURDAY_WEEKDAY);
1491 daysOfWeekMap.insert(Qt::Sunday, ICAL_SUNDAY_WEEKDAY);
1492 }
1493
1494 QList<Qt::DayOfWeek> daysOfWeek = qRule.daysOfWeek().toList();
1495 int c = 0;
1496
1497 rule->freq = ICAL_WEEKLY_RECURRENCE;
1498 for(int d=Qt::Monday; d <= Qt::Sunday; d++) {
1499 if (daysOfWeek.contains(static_cast<Qt::DayOfWeek>(d))) {
1500 rule->by_day[c++] = daysOfWeekMap[static_cast<Qt::DayOfWeek>(d)];
1501 }
1502 }
1503 for (int d = c; d < ICAL_BY_DAY_SIZE; d++) {
1504 rule->by_day[d] = ICAL_RECURRENCE_ARRAY_MAX;
1505 }
1506}
1507
1508void QOrganizerEDSEngine::parseMonthRecurrence(const QOrganizerRecurrenceRule &qRule, struct icalrecurrencetype *rule)
1509{
1510 rule->freq = ICAL_MONTHLY_RECURRENCE;
1511
1512 QList<int> daysOfMonth = qRule.daysOfMonth().toList();
1513 int c = 0;
1514 for (int d=1; d < ICAL_BY_MONTHDAY_SIZE; d++) {
1515 if (daysOfMonth.contains(d)) {
1516 rule->by_month_day[c++] = d;
1517 }
1518 }
1519 for (int d = c; d < ICAL_BY_MONTHDAY_SIZE; d++) {
1520 rule->by_month_day[d] = ICAL_RECURRENCE_ARRAY_MAX;
1521 }
1522}
1523
1524void QOrganizerEDSEngine::parseYearRecurrence(const QOrganizerRecurrenceRule &qRule, struct icalrecurrencetype *rule)
1525{
1526 rule->freq = ICAL_YEARLY_RECURRENCE;
1527
1528 QList<int> daysOfYear = qRule.daysOfYear().toList();
1529 int c = 0;
1530 for (int d=1; d < ICAL_BY_YEARDAY_SIZE; d++) {
1531 if (daysOfYear.contains(d)) {
1532 rule->by_year_day[c++] = d;
1533 }
1534 }
1535 for (int d = c; d < ICAL_BY_YEARDAY_SIZE; d++) {
1536 rule->by_year_day[d] = ICAL_RECURRENCE_ARRAY_MAX;
1537 }
1538
1539 c = 0;
1540 QList<QOrganizerRecurrenceRule::Month> monthOfYear = qRule.monthsOfYear().toList();
1541 for (int d=1; d < ICAL_BY_MONTH_SIZE; d++) {
1542 if (monthOfYear.contains(static_cast<QOrganizerRecurrenceRule::Month>(d))) {
1543 rule->by_month[c++] = d;
1544 }
1545 }
1546 for (int d = c; d < ICAL_BY_YEARDAY_SIZE; d++) {
1547 rule->by_month[d] = ICAL_RECURRENCE_ARRAY_MAX;
1548 }
1549}
1550
1551
9781552
979void QOrganizerEDSEngine::parseRecurrence(const QOrganizerItem &item, ECalComponent *comp)1553void QOrganizerEDSEngine::parseRecurrence(const QOrganizerItem &item, ECalComponent *comp)
980{1554{
@@ -983,7 +1557,7 @@
983 GSList *periodList = 0;1557 GSList *periodList = 0;
984 Q_FOREACH(QDate dt, rec.recurrenceDates()) {1558 Q_FOREACH(QDate dt, rec.recurrenceDates()) {
985 ECalComponentPeriod *period = g_new0(ECalComponentPeriod, 1);1559 ECalComponentPeriod *period = g_new0(ECalComponentPeriod, 1);
986 period->start = icaltime_from_timet(QDateTime(dt).toTime_t(), TRUE);1560 period->start = icaltime_from_timet(QDateTime(dt).toTime_t(), FALSE);
987 periodList = g_slist_append(periodList, period);1561 periodList = g_slist_append(periodList, period);
988 //TODO: period.end, period.duration1562 //TODO: period.end, period.duration
989 }1563 }
@@ -992,15 +1566,58 @@
9921566
993 GSList *exdateList = 0;1567 GSList *exdateList = 0;
994 Q_FOREACH(QDate dt, rec.exceptionDates()) {1568 Q_FOREACH(QDate dt, rec.exceptionDates()) {
995 ECalComponentDateTime dateTime;1569 ECalComponentDateTime *dateTime = g_new0(ECalComponentDateTime, 1);
996 struct icaltimetype itt = icaltime_from_timet(QDateTime(dt).toTime_t(), TRUE);1570 struct icaltimetype *itt = g_new0(struct icaltimetype, 1);
997 dateTime.value = &itt;1571 *itt = icaltime_from_timet(QDateTime(dt).toTime_t(), FALSE);
998 exdateList = g_slist_append(exdateList, &dateTime);1572 dateTime->value = itt;
1573 exdateList = g_slist_append(exdateList, dateTime);
999 }1574 }
1000 e_cal_component_set_exdate_list(comp, exdateList);1575 e_cal_component_set_exdate_list(comp, exdateList);
1001 e_cal_component_free_exdate_list(exdateList);1576 e_cal_component_free_exdate_list(exdateList);
1577
1578 GSList *ruleList = 0;
1579 Q_FOREACH(QOrganizerRecurrenceRule qRule, rec.recurrenceRules()) {
1580 struct icalrecurrencetype *rule = g_new0(struct icalrecurrencetype, 1);
1581 switch(qRule.frequency()) {
1582 case QOrganizerRecurrenceRule::Daily:
1583 rule->freq = ICAL_DAILY_RECURRENCE;
1584 break;
1585 case QOrganizerRecurrenceRule::Weekly:
1586 parseWeekRecurrence(qRule, rule);
1587 break;
1588 case QOrganizerRecurrenceRule::Monthly:
1589 parseMonthRecurrence(qRule, rule);
1590 break;
1591 case QOrganizerRecurrenceRule::Yearly:
1592 parseYearRecurrence(qRule, rule);
1593 break;
1594 case QOrganizerRecurrenceRule::Invalid:
1595 rule->freq = ICAL_NO_RECURRENCE;
1596 break;
1597 }
1598
1599 if (qRule.limitDate().isValid()) {
1600 rule->until = icaltime_from_timet(QDateTime(qRule.limitDate()).toTime_t(), TRUE);
1601 rule->count = ICAL_RECURRENCE_ARRAY_MAX;
1602 } else {
1603 rule->count = qRule.limitCount();
1604 }
1605
1606 QSet<int> positions = qRule.positions();
1607 for (int d=1; d < ICAL_BY_SETPOS_SIZE; d++) {
1608 if (positions.contains(d)) {
1609 rule->by_set_pos[d] = d;
1610 } else {
1611 rule->by_set_pos[d] = ICAL_RECURRENCE_ARRAY_MAX;
1612 }
1613 }
1614
1615 rule->interval = qRule.interval();
1616 ruleList = g_slist_append(ruleList, rule);
1617 }
1618 e_cal_component_set_rrule_list(comp, ruleList);
1619 //TODO: free ruleList
1002 }1620 }
1003 // TODO: exeptions rules
1004}1621}
10051622
1006void QOrganizerEDSEngine::parsePriority(const QOrganizerItem &item, ECalComponent *comp)1623void QOrganizerEDSEngine::parsePriority(const QOrganizerItem &item, ECalComponent *comp)
@@ -1008,6 +1625,7 @@
1008 QOrganizerItemPriority priority = item.detail(QOrganizerItemDetail::TypePriority);1625 QOrganizerItemPriority priority = item.detail(QOrganizerItemDetail::TypePriority);
1009 if (!priority.isEmpty()) {1626 if (!priority.isEmpty()) {
1010 gint iPriority = (gint) priority.priority();1627 gint iPriority = (gint) priority.priority();
1628 qDebug() << "Priority" << iPriority;
1011 e_cal_component_set_priority(comp, &iPriority);1629 e_cal_component_set_priority(comp, &iPriority);
1012 }1630 }
1013}1631}
@@ -1024,10 +1642,14 @@
1024{1642{
1025 QOrganizerTodoTime ttr = item.detail(QOrganizerItemDetail::TypeTodoTime);1643 QOrganizerTodoTime ttr = item.detail(QOrganizerItemDetail::TypeTodoTime);
1026 if (!ttr.isEmpty()) {1644 if (!ttr.isEmpty()) {
1027 ECalComponentDateTime due;1645 qDebug() << "Due date" << ttr.dueDateTime();
1646 ECalComponentDateTime *due = g_new0(ECalComponentDateTime, 1);
1647 due->value = g_new0(struct icaltimetype, 1);
1648
1028 struct icaltimetype itt = icaltime_from_timet(ttr.dueDateTime().toTime_t(), FALSE);1649 struct icaltimetype itt = icaltime_from_timet(ttr.dueDateTime().toTime_t(), FALSE);
1029 due.value = &itt;1650 *due->value = itt;
1030 e_cal_component_set_due(comp, &due);1651 e_cal_component_set_due(comp, due);
1652 e_cal_component_free_datetime(due);
1031 }1653 }
1032}1654}
10331655
@@ -1035,6 +1657,7 @@
1035{1657{
1036 QOrganizerTodoProgress tp = item.detail(QOrganizerItemDetail::TypeTodoProgress);1658 QOrganizerTodoProgress tp = item.detail(QOrganizerItemDetail::TypeTodoProgress);
1037 if (!tp.isEmpty()) {1659 if (!tp.isEmpty()) {
1660 qDebug() << "Progress" << tp.percentageComplete();
1038 e_cal_component_set_percent_as_int(comp, tp.percentageComplete());1661 e_cal_component_set_percent_as_int(comp, tp.percentageComplete());
1039 }1662 }
1040}1663}
@@ -1048,22 +1671,45 @@
1048 e_cal_component_set_status(comp, ICAL_STATUS_NONE);1671 e_cal_component_set_status(comp, ICAL_STATUS_NONE);
1049 break;1672 break;
1050 case QOrganizerTodoProgress::StatusInProgress:1673 case QOrganizerTodoProgress::StatusInProgress:
1674 qDebug() << "Set status in progress";
1051 e_cal_component_set_status(comp, ICAL_STATUS_INPROCESS);1675 e_cal_component_set_status(comp, ICAL_STATUS_INPROCESS);
1052 break;1676 break;
1053 case QOrganizerTodoProgress::StatusComplete:1677 case QOrganizerTodoProgress::StatusComplete:
1054 e_cal_component_set_status(comp, ICAL_STATUS_COMPLETED);1678 e_cal_component_set_status(comp, ICAL_STATUS_COMPLETED);
1055 break;1679 break;
1056 default:1680 default:
1681 qDebug() << "Set status cancelled";
1057 e_cal_component_set_status(comp, ICAL_STATUS_CANCELLED);1682 e_cal_component_set_status(comp, ICAL_STATUS_CANCELLED);
1058 break;1683 break;
1059 }1684 }
1060 }1685 }
1061}1686}
10621687
1063ECalComponent *QOrganizerEDSEngine::parseEventItem(const QOrganizerItem &item)1688ECalComponent *QOrganizerEDSEngine::createDefaultComponent(ECalClient *client,
1064{1689 icalcomponent_kind iKind,
1065 ECalComponent *comp = e_cal_component_new();1690 ECalComponentVType eType)
1066 e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT);1691{
1692 ECalComponent *comp;
1693 icalcomponent *icalcomp = 0;
1694
1695 if (client && !e_cal_client_get_default_object_sync(client, &icalcomp, NULL, NULL)) {
1696 icalcomp = icalcomponent_new(iKind);
1697 }
1698
1699 comp = e_cal_component_new();
1700 if (icalcomp && !e_cal_component_set_icalcomponent(comp, icalcomp)) {
1701 icalcomponent_free(icalcomp);
1702 }
1703
1704 e_cal_component_set_new_vtype(comp, eType);
1705
1706 return comp;
1707}
1708
1709ECalComponent *QOrganizerEDSEngine::parseEventItem(ECalClient *client, const QOrganizerItem &item)
1710{
1711 qDebug() << Q_FUNC_INFO;
1712 ECalComponent *comp = createDefaultComponent(client, ICAL_VEVENT_COMPONENT, E_CAL_COMPONENT_EVENT);
10671713
1068 parseStartTime(item, comp);1714 parseStartTime(item, comp);
1069 parseEndTime(item, comp);1715 parseEndTime(item, comp);
@@ -1074,12 +1720,12 @@
10741720
1075}1721}
10761722
1077ECalComponent *QOrganizerEDSEngine::parseTodoItem(const QOrganizerItem &item)1723ECalComponent *QOrganizerEDSEngine::parseTodoItem(ECalClient *client, const QOrganizerItem &item)
1078{1724{
1079 ECalComponent *comp = e_cal_component_new();1725 qDebug() << Q_FUNC_INFO;
1080 e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_TODO);1726 ECalComponent *comp = createDefaultComponent(client, ICAL_VTODO_COMPONENT, E_CAL_COMPONENT_TODO);
10811727
1082 parseStartTime(item, comp);1728 parseTodoStartTime(item, comp);
1083 parseDueDate(item, comp);1729 parseDueDate(item, comp);
1084 parseRecurrence(item, comp);1730 parseRecurrence(item, comp);
1085 parsePriority(item, comp);1731 parsePriority(item, comp);
@@ -1089,10 +1735,10 @@
1089 return comp;1735 return comp;
1090}1736}
10911737
1092ECalComponent *QOrganizerEDSEngine::parseJournalItem(const QOrganizerItem &item)1738ECalComponent *QOrganizerEDSEngine::parseJournalItem(ECalClient *client, const QOrganizerItem &item)
1093{1739{
1094 ECalComponent *comp = e_cal_component_new();1740 qDebug() << Q_FUNC_INFO;
1095 e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_JOURNAL);1741 ECalComponent *comp = createDefaultComponent(client, ICAL_VJOURNAL_COMPONENT, E_CAL_COMPONENT_JOURNAL);
10961742
1097 QOrganizerJournalTime jtime = item.detail(QOrganizerItemDetail::TypeJournalTime);1743 QOrganizerJournalTime jtime = item.detail(QOrganizerItemDetail::TypeJournalTime);
1098 if (!jtime.isEmpty()) {1744 if (!jtime.isEmpty()) {
@@ -1105,7 +1751,147 @@
1105 return comp;1751 return comp;
1106}1752}
11071753
1108GSList *QOrganizerEDSEngine::parseItems(QList<QOrganizerItem> items)1754void QOrganizerEDSEngine::parseSummary(const QOrganizerItem &item, ECalComponent *comp)
1755{
1756 //summary
1757 if (!item.displayLabel().isEmpty()) {
1758 ECalComponentText txt;
1759 QByteArray str = item.displayLabel().toUtf8();
1760 txt.altrep = 0;
1761 txt.value = str.constData();
1762 e_cal_component_set_summary(comp, &txt);
1763 }
1764}
1765
1766void QOrganizerEDSEngine::parseDescription(const QOrganizerItem &item, ECalComponent *comp)
1767{
1768 //description
1769 if (item.description().isEmpty()) {
1770 GSList *descriptions = 0;
1771 QByteArray str = item.description().toUtf8();
1772 ECalComponentText *txt = g_new0(ECalComponentText, 1);
1773
1774 txt->value = str.constData();
1775 descriptions = g_slist_append(descriptions, txt);
1776
1777 e_cal_component_set_description_list(comp, descriptions);
1778 e_cal_component_free_text_list(descriptions);
1779 }
1780}
1781
1782void QOrganizerEDSEngine::parseComments(const QOrganizerItem &item, ECalComponent *comp)
1783{
1784 //comments
1785 GSList *comments = 0;
1786 Q_FOREACH(QString comment, item.comments()) {
1787 QByteArray str = comment.toUtf8();
1788 ECalComponentText *txt = g_new0(ECalComponentText, 1);
1789 txt->value = str.constData();
1790 comments = g_slist_append(comments, txt);
1791 }
1792
1793 if (comments) {
1794 e_cal_component_set_comment_list(comp, comments);
1795 e_cal_component_free_text_list(comments);
1796 }
1797}
1798
1799void QOrganizerEDSEngine::parseTags(const QOrganizerItem &item, ECalComponent *comp)
1800{
1801 //tags
1802 GSList *categories = 0;
1803 Q_FOREACH(QString tag, item.tags()) {
1804 QByteArray str = tag.toUtf8();
1805 ECalComponentText *txt = g_new0(ECalComponentText, 1);
1806 txt->value = str.constData();
1807 categories = g_slist_append(categories, txt);
1808 }
1809
1810 if (categories) {
1811 e_cal_component_set_categories_list(comp, categories);
1812 e_cal_component_free_text_list(categories);
1813 }
1814}
1815
1816void QOrganizerEDSEngine::encodeAttachment(QByteArray data, ECalComponentAlarm *alarm)
1817{
1818 gchar *b64Bytes = strdup(data.toBase64());
1819 icalattach *attach = icalattach_new_from_url(b64Bytes);
1820
1821 e_cal_component_alarm_set_attach(alarm, attach);
1822
1823 icalattach_unref(attach);
1824}
1825
1826void QOrganizerEDSEngine::parseVisualReminderAttachment(const QOrganizerItemDetail &detail, ECalComponentAlarm *alarm)
1827{
1828 QByteArray attachBytes;
1829
1830 {
1831 QDataStream attachData(&attachBytes, QIODevice::WriteOnly);
1832
1833 attachData << detail.value(QOrganizerItemVisualReminder::FieldDataUrl).toUrl();
1834 attachData << detail.value(QOrganizerItemVisualReminder::FieldMessage).toString();
1835 }
1836
1837 encodeAttachment(attachBytes, alarm);
1838}
1839
1840void QOrganizerEDSEngine::parseAudibleReminderAttachment(const QOrganizerItemDetail &detail, ECalComponentAlarm *alarm)
1841{
1842 QByteArray attachBytes;
1843
1844 {
1845 QDataStream attachData(&attachBytes, QIODevice::WriteOnly);
1846 attachData << detail.value(QOrganizerItemAudibleReminder::FieldDataUrl).toUrl();
1847 }
1848
1849 encodeAttachment(attachBytes, alarm);
1850}
1851
1852void QOrganizerEDSEngine::parseReminders(const QOrganizerItem &item, ECalComponent *comp)
1853{
1854 //reminders
1855 QList<QOrganizerItemDetail> reminders = item.details(QOrganizerItemDetail::TypeAudibleReminder);
1856 reminders += item.details(QOrganizerItemDetail::TypeVisualReminder);
1857
1858 Q_FOREACH(const QOrganizerItemDetail &detail, reminders) {
1859 const QOrganizerItemReminder *reminder = static_cast<const QOrganizerItemReminder*>(&detail);
1860
1861 ECalComponentAlarm *alarm = e_cal_component_alarm_new();
1862 switch(reminder->type())
1863 {
1864 case QOrganizerItemReminder::TypeVisualReminder:
1865 e_cal_component_alarm_set_action(alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
1866 parseVisualReminderAttachment(detail, alarm);
1867 break;
1868 case QOrganizerItemReminder::TypeAudibleReminder:
1869 default:
1870 // use audio as fallback
1871 e_cal_component_alarm_set_action(alarm, E_CAL_COMPONENT_ALARM_AUDIO);
1872 parseAudibleReminderAttachment(detail, alarm);
1873 break;
1874 }
1875
1876 if (reminder->secondsBeforeStart() > 0) {
1877 ECalComponentAlarmTrigger trigger;
1878 trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
1879 trigger.u.rel_duration = icaldurationtype_from_int(- reminder->secondsBeforeStart());
1880 e_cal_component_alarm_set_trigger(alarm, trigger);
1881 }
1882
1883 ECalComponentAlarmRepeat aRepeat;
1884 // TODO: check if this is really necessary
1885 aRepeat.repetitions = reminder->repetitionCount(); //qMax(reminder->repetitionCount(), 1);
1886 aRepeat.duration = icaldurationtype_from_int(reminder->repetitionDelay());
1887 e_cal_component_alarm_set_repeat(alarm, aRepeat);
1888
1889 e_cal_component_add_alarm(comp, alarm);
1890 e_cal_component_alarm_free(alarm);
1891 }
1892}
1893
1894GSList *QOrganizerEDSEngine::parseItems(ECalClient *client, QList<QOrganizerItem> items)
1109{1895{
1110 GSList *comps = 0;1896 GSList *comps = 0;
11111897
@@ -1114,13 +1900,13 @@
11141900
1115 switch(item.type()) {1901 switch(item.type()) {
1116 case QOrganizerItemType::TypeEvent:1902 case QOrganizerItemType::TypeEvent:
1117 comp = parseEventItem(item);1903 comp = parseEventItem(client, item);
1118 break;1904 break;
1119 case QOrganizerItemType::TypeTodo:1905 case QOrganizerItemType::TypeTodo:
1120 comp = parseTodoItem(item);1906 comp = parseTodoItem(client, item);
1121 break;1907 break;
1122 case QOrganizerItemType::TypeJournal:1908 case QOrganizerItemType::TypeJournal:
1123 comp = parseJournalItem(item);1909 comp = parseJournalItem(client, item);
1124 break;1910 break;
1125 case QOrganizerItemType::TypeEventOccurrence:1911 case QOrganizerItemType::TypeEventOccurrence:
1126 qWarning() << "Component TypeEventOccurrence not supported;";1912 qWarning() << "Component TypeEventOccurrence not supported;";
@@ -1136,41 +1922,26 @@
11361922
1137 // id1923 // id
1138 if (!item.id().isNull()) {1924 if (!item.id().isNull()) {
1139 QOrganizerItemId id = item.id();1925 QOrganizerItemId id = item.id();
1140 QString cId = QOrganizerEDSEngineId::toComponentId(id);1926 QString cId = QOrganizerEDSEngineId::toComponentId(id);
1141 e_cal_component_set_uid(comp, cId.toUtf8().data());1927 e_cal_component_set_uid(comp, cId.toUtf8().data());
1142 }1928 }
11431929
1144 //summary1930 parseSummary(item, comp);
1145 if (!item.displayLabel().isEmpty()) {1931 parseDescription(item, comp);
1146 ECalComponentText txt;1932 parseComments(item, comp);
1147 txt.altrep = "";1933 parseTags(item, comp);
1148 txt.value = item.displayLabel().toUtf8().data();1934 parseReminders(item, comp);
1149 e_cal_component_set_summary(comp, &txt);1935
1150 }1936 if (!item.id().isNull()) {
11511937 e_cal_component_commit_sequence(comp);
1152 //comments1938 } else {
1153 GSList *comments = 0;1939 e_cal_component_abort_sequence(comp);
1154 Q_FOREACH(QString comment, item.comments()) {1940 }
1155 ECalComponentText *txt = g_new0(ECalComponentText, 1);
1156 txt->value = comment.toUtf8().data();
1157 comments = g_slist_append(comments, txt);
1158 }
1159 e_cal_component_set_comment_list(comp, comments);
1160 e_cal_component_free_text_list(comments);
1161
1162 //tags
1163 GSList *categories = 0;
1164 Q_FOREACH(QString tag, item.tags()) {
1165 ECalComponentText *txt = g_new0(ECalComponentText, 1);
1166 txt->value = tag.toUtf8().data();
1167 categories = g_slist_append(categories, txt);
1168 }
1169 e_cal_component_set_categories_list(comp, categories);
1170 e_cal_component_free_text_list(categories);
11711941
1172 comps = g_slist_append(comps,1942 comps = g_slist_append(comps,
1173 icalcomponent_new_clone(e_cal_component_get_icalcomponent(comp)));1943 icalcomponent_new_clone(e_cal_component_get_icalcomponent(comp)));
1944
1174 g_object_unref(comp);1945 g_object_unref(comp);
1175 }1946 }
11761947
11771948
=== modified file 'qorganizer/qorganizer-eds-engine.h'
--- qorganizer/qorganizer-eds-engine.h 2013-08-16 02:22:42 +0000
+++ qorganizer/qorganizer-eds-engine.h 2013-09-09 21:01:24 +0000
@@ -29,11 +29,15 @@
29#include <QtOrganizer/QOrganizerItemFilter>29#include <QtOrganizer/QOrganizerItemFilter>
30#include <QtOrganizer/QOrganizerItemChangeSet>30#include <QtOrganizer/QOrganizerItemChangeSet>
31#include <QtOrganizer/QOrganizerCollectionId>31#include <QtOrganizer/QOrganizerCollectionId>
32#include <QtOrganizer/QOrganizerItemReminder>
3233
33#include <libecal/libecal.h>34#include <libecal/libecal.h>
35
34class FetchRequestData;36class FetchRequestData;
35class SaveRequestData;37class SaveRequestData;
36class RemoveRequestData;38class RemoveRequestData;
39class SaveCollectionRequestData;
40class RemoveCollectionRequestData;
3741
38class QOrganizerEDSEngine : public QtOrganizer::QOrganizerManagerEngine42class QOrganizerEDSEngine : public QtOrganizer::QOrganizerManagerEngine
39{43{
@@ -135,36 +139,68 @@
135 QList<FetchRequestData*> m_pendingFetchRequest;139 QList<FetchRequestData*> m_pendingFetchRequest;
136140
137 void loadCollections();141 void loadCollections();
142 void registerCollection(const QtOrganizer::QOrganizerCollection &collection, QOrganizerEDSCollectionEngineId *edsId);
143 void unregisterCollection(const QtOrganizer::QOrganizerCollectionId &collectionId);
144
145 ESource *findSource(const QtOrganizer::QOrganizerCollectionId &id) const;
146
147 static QtOrganizer::QOrganizerCollection parseSource(ESource *source, const QString &managerUri);
148 static QtOrganizer::QOrganizerCollection parseSource(ESource *source, const QString &managerUri, QOrganizerEDSCollectionEngineId **edsId);
138 static QList<QtOrganizer::QOrganizerItem> parseEvents(QOrganizerEDSCollectionEngineId *collection, GSList *events);149 static QList<QtOrganizer::QOrganizerItem> parseEvents(QOrganizerEDSCollectionEngineId *collection, GSList *events);
139 static GSList *parseItems(QList<QtOrganizer::QOrganizerItem> items);150 static GSList *parseItems(ECalClient *client, QList<QtOrganizer::QOrganizerItem> items);
140151
141 static QDateTime fromIcalTime(struct icaltimetype value);152 // QOrganizerItem -> ECalComponent
153 static void parseSummary(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
154 static void parseDescription(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
155 static void parseComments(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
156 static void parseTags(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
157 static void parseReminders(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
158 static void encodeAttachment(QByteArray data, ECalComponentAlarm *alarm);
159 static void parseVisualReminderAttachment(const QtOrganizer::QOrganizerItemDetail &detail, ECalComponentAlarm *alarm);
160 static void parseAudibleReminderAttachment(const QtOrganizer::QOrganizerItemDetail &detail, ECalComponentAlarm *alarm);
161 static void parseStartTime(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
162 static void parseEndTime(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
163 static void parseTodoStartTime(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
164 static void parseRecurrence(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
165 static void parseWeekRecurrence(const QtOrganizer::QOrganizerRecurrenceRule &qRule, struct icalrecurrencetype *rule);
166 static void parseMonthRecurrence(const QtOrganizer::QOrganizerRecurrenceRule &qRule, struct icalrecurrencetype *rule);
167 static void parseYearRecurrence(const QtOrganizer::QOrganizerRecurrenceRule &qRule, struct icalrecurrencetype *rule);
168 static void parsePriority(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
169 static void parseLocation(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
170 static void parseDueDate(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
171 static void parseProgress(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
172 static void parseStatus(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
173
174 // ECalComponent -> QOrganizerItem
175 static void parseSummary(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
176 static void parseDescription(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
177 static void parseComments(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
178 static void parseTags(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
179 static void parseReminders(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
180 static QByteArray dencodeAttachment(ECalComponentAlarm *alarm);
181 static void parseAudibleReminderAttachment(ECalComponentAlarm *alarm, QtOrganizer::QOrganizerItemReminder *aDetail);
182 static void parseVisualReminderAttachment(ECalComponentAlarm *alarm, QtOrganizer::QOrganizerItemReminder *aDetail);
142 static void parseStartTime(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);183 static void parseStartTime(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
143 static void parseEndTime(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);184 static void parseEndTime(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
144 static void parseRecurrence(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);185 static void parseRecurrence(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
186 static void parseWeekRecurrence(struct icalrecurrencetype *rule, QtOrganizer::QOrganizerRecurrenceRule *qRule);
187 static void parseMonthRecurrence(struct icalrecurrencetype *rule, QtOrganizer::QOrganizerRecurrenceRule *qRule);
188 static void parseYearRecurrence(struct icalrecurrencetype *rule, QtOrganizer::QOrganizerRecurrenceRule *qRule);
145 static void parsePriority(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);189 static void parsePriority(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
146 static void parseLocation(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);190 static void parseLocation(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
147 static void parseDueDate(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);191 static void parseDueDate(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
148 static void parseProgress(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);192 static void parseProgress(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
149 static void parseStatus(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);193 static void parseStatus(ECalComponent *comp, QtOrganizer::QOrganizerItem *item);
150194
195 static QDateTime fromIcalTime(struct icaltimetype value);
151 static QtOrganizer::QOrganizerItem *parseEvent(ECalComponent *comp);196 static QtOrganizer::QOrganizerItem *parseEvent(ECalComponent *comp);
152 static QtOrganizer::QOrganizerItem *parseToDo(ECalComponent *comp);197 static QtOrganizer::QOrganizerItem *parseToDo(ECalComponent *comp);
153 static QtOrganizer::QOrganizerItem *parseJournal(ECalComponent *comp);198 static QtOrganizer::QOrganizerItem *parseJournal(ECalComponent *comp);
154199
155200 static ECalComponent *createDefaultComponent(ECalClient *client, icalcomponent_kind iKind, ECalComponentVType eType);
156 static void parseStartTime(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);201 static ECalComponent *parseEventItem(ECalClient *client, const QtOrganizer::QOrganizerItem &item);
157 static void parseEndTime(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);202 static ECalComponent *parseTodoItem(ECalClient *client, const QtOrganizer::QOrganizerItem &item);
158 static void parseRecurrence(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);203 static ECalComponent *parseJournalItem(ECalClient *client, const QtOrganizer::QOrganizerItem &item);
159 static void parsePriority(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
160 static void parseLocation(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
161 static void parseDueDate(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
162 static void parseProgress(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
163 static void parseStatus(const QtOrganizer::QOrganizerItem &item, ECalComponent *comp);
164
165 static ECalComponent *parseEventItem(const QtOrganizer::QOrganizerItem &item);
166 static ECalComponent *parseTodoItem(const QtOrganizer::QOrganizerItem &item);
167 static ECalComponent *parseJournalItem(const QtOrganizer::QOrganizerItem &item);
168204
169 // glib callback205 // glib callback
170 void itemsAsync(QtOrganizer::QOrganizerItemFetchRequest *req);206 void itemsAsync(QtOrganizer::QOrganizerItemFetchRequest *req);
@@ -181,6 +217,13 @@
181 static void removeItemsAsyncStart(RemoveRequestData *data);217 static void removeItemsAsyncStart(RemoveRequestData *data);
182 static void removeItemsAsyncConnected(GObject *source_object, GAsyncResult *res, RemoveRequestData *data);218 static void removeItemsAsyncConnected(GObject *source_object, GAsyncResult *res, RemoveRequestData *data);
183 static void removeItemsAsyncRemoved(GObject *source_object, GAsyncResult *res, RemoveRequestData *data);219 static void removeItemsAsyncRemoved(GObject *source_object, GAsyncResult *res, RemoveRequestData *data);
220
221 void saveCollectionAsync(QtOrganizer::QOrganizerCollectionSaveRequest *req);
222 static void saveCollectionAsyncStart(ESourceRegistry *registry, SaveCollectionRequestData *data);
223 static void saveCollectionAsyncCommited(GObject *source_object, GAsyncResult *res, SaveCollectionRequestData *data);
224
225 void removeCollectionAsync(QtOrganizer::QOrganizerCollectionRemoveRequest *req);
226 static void removeCollectionAsyncStart(GObject *source_object, GAsyncResult *res, RemoveCollectionRequestData *data);
184/*227/*
185 QList<QtOrganizer::QOrganizerItem> internalItemOccurrences(const QtOrganizer::QOrganizerItem& parentItem,228 QList<QtOrganizer::QOrganizerItem> internalItemOccurrences(const QtOrganizer::QOrganizerItem& parentItem,
186 const QDateTime& periodStart,229 const QDateTime& periodStart,
@@ -200,7 +243,9 @@
200 bool forExport) const;243 bool forExport) const;
201 QtOrganizer::QOrganizerItem item(const QtOrganizer::QOrganizerItemId& organizeritemId) const;244 QtOrganizer::QOrganizerItem item(const QtOrganizer::QOrganizerItemId& organizeritemId) const;
202 */245 */
203 friend class FetchRequestData;246 friend class FetchRequestData;
247 friend class SaveCollectionRequestData;
248 friend class RemoveCollectionRequestData;
204};249};
205250
206#endif251#endif
207252
=== modified file 'qorganizer/qorganizer-eds-fetchrequestdata.cpp'
--- qorganizer/qorganizer-eds-fetchrequestdata.cpp 2013-08-14 21:23:01 +0000
+++ qorganizer/qorganizer-eds-fetchrequestdata.cpp 2013-09-09 21:01:24 +0000
@@ -60,14 +60,30 @@
6060
61void FetchRequestData::appendResults(QList<QOrganizerItem> results)61void FetchRequestData::appendResults(QList<QOrganizerItem> results)
62{62{
63 m_results += results;63 QOrganizerItemFetchRequest *req = request<QOrganizerItemFetchRequest>();
64 Q_FOREACH(QOrganizerItem item, results) {
65 if (QOrganizerManagerEngine::testFilter(req->filter(), item)) {
66 m_results << item;
67 }
68 }
64}69}
6570
66QString FetchRequestData::dateFilter()71QString FetchRequestData::dateFilter()
67{72{
73 QDateTime startDate = request<QOrganizerItemFetchRequest>()->startDate();
74 QDateTime endDate = request<QOrganizerItemFetchRequest>()->endDate();
75
76 if (!startDate.isValid()) {
77 startDate.setMSecsSinceEpoch(0);
78 }
79
80 if (!endDate.isValid()) {
81 endDate.setMSecsSinceEpoch(std::numeric_limits<qint64>::max());
82 }
83
68 QString query = QString("(occur-in-time-range? "84 QString query = QString("(occur-in-time-range? "
69 "(make-time \"%1\") (make-time \"%2\"))")85 "(make-time \"%1\") (make-time \"%2\"))")
70 .arg(isodate_from_time_t(request<QOrganizerItemFetchRequest>()->startDate().toTime_t()))86 .arg(isodate_from_time_t(startDate.toTime_t()))
71 .arg(isodate_from_time_t(request<QOrganizerItemFetchRequest>()->endDate().toTime_t()));87 .arg(isodate_from_time_t(endDate.toTime_t()));
72 return query;88 return query;
73}89}
7490
=== added file 'qorganizer/qorganizer-eds-removecollectionrequestdata.cpp'
--- qorganizer/qorganizer-eds-removecollectionrequestdata.cpp 1970-01-01 00:00:00 +0000
+++ qorganizer/qorganizer-eds-removecollectionrequestdata.cpp 2013-09-09 21:01:24 +0000
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of ubuntu-pim-service.
5 *
6 * contact-service-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * contact-service-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "qorganizer-eds-removecollectionrequestdata.h"
20#include "qorganizer-eds-engineid.h"
21
22#include <QtOrganizer/QOrganizerManagerEngine>
23#include <QtOrganizer/QOrganizerCollectionRemoveRequest>
24
25using namespace QtOrganizer;
26
27RemoveCollectionRequestData::RemoveCollectionRequestData(QOrganizerEDSEngine *engine, QtOrganizer::QOrganizerAbstractRequest *req)
28 : RequestData(engine, req),
29 m_currentCollection(0)
30{
31 m_pendingCollections = request<QOrganizerCollectionRemoveRequest>()->collectionIds();
32}
33
34RemoveCollectionRequestData::~RemoveCollectionRequestData()
35{
36}
37
38void RemoveCollectionRequestData::finish(QtOrganizer::QOrganizerManager::Error error)
39{
40 QOrganizerManagerEngine::updateCollectionRemoveRequest(request<QOrganizerCollectionRemoveRequest>(),
41 error,
42 m_errorMap,
43 QOrganizerAbstractRequest::FinishedState);
44
45 // emit collection removed signal
46 QList<QOrganizerCollectionId> removedIds = m_pendingCollections;
47 Q_FOREACH(int index, m_errorMap.keys()) {
48 removedIds.removeAt(index);
49 }
50
51 // remove source from engine
52 Q_FOREACH(QOrganizerCollectionId id, removedIds) {
53 parent()->unregisterCollection(id);
54 }
55
56 Q_EMIT parent()->collectionsRemoved(removedIds);
57}
58
59void RemoveCollectionRequestData::commit(QtOrganizer::QOrganizerManager::Error error)
60{
61 if (error != QOrganizerManager::NoError) {
62 m_errorMap.insert(m_currentCollection, error);
63 }
64
65 m_currentCollection++;
66}
67
68ESource *RemoveCollectionRequestData::begin()
69{
70 if (m_pendingCollections.count() > m_currentCollection) {
71 QOrganizerCollectionId cId = m_pendingCollections.at(m_currentCollection);
72 return parent()->findSource(cId);
73 } else {
74 return 0;
75 }
76}
077
=== added file 'qorganizer/qorganizer-eds-removecollectionrequestdata.h'
--- qorganizer/qorganizer-eds-removecollectionrequestdata.h 1970-01-01 00:00:00 +0000
+++ qorganizer/qorganizer-eds-removecollectionrequestdata.h 2013-09-09 21:01:24 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of ubuntu-pim-service.
5 *
6 * contact-service-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * contact-service-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __QORGANIZER_EDS_REMOVECOLLECTIONQUESTDATA_H__
20#define __QORGANIZER_EDS_REMOVECOLLECTIONQUESTDATA_H__
21
22#include "qorganizer-eds-requestdata.h"
23
24#include <glib.h>
25
26class RemoveCollectionRequestData : public RequestData
27{
28public:
29 RemoveCollectionRequestData(QOrganizerEDSEngine *engine, QtOrganizer::QOrganizerAbstractRequest *req);
30 ~RemoveCollectionRequestData();
31
32 void finish(QtOrganizer::QOrganizerManager::Error error = QtOrganizer::QOrganizerManager::NoError);
33
34 ESource* begin();
35 void commit(QtOrganizer::QOrganizerManager::Error error = QtOrganizer::QOrganizerManager::NoError);
36
37private:
38 QList<QtOrganizer::QOrganizerCollectionId> m_pendingCollections;
39 QMap<int, QtOrganizer::QOrganizerManager::Error> m_errorMap;
40 int m_currentCollection;
41
42};
43
44#endif
045
=== modified file 'qorganizer/qorganizer-eds-removerequestdata.cpp'
--- qorganizer/qorganizer-eds-removerequestdata.cpp 2013-08-14 21:23:01 +0000
+++ qorganizer/qorganizer-eds-removerequestdata.cpp 2013-09-09 21:01:24 +0000
@@ -56,7 +56,6 @@
56 ECalComponentId *id = g_new0(ECalComponentId, 1);56 ECalComponentId *id = g_new0(ECalComponentId, 1);
5757
58 id->uid = g_strdup(QOrganizerEDSEngineId::toComponentId(item.id()).toUtf8().data());58 id->uid = g_strdup(QOrganizerEDSEngineId::toComponentId(item.id()).toUtf8().data());
59 qDebug() << "Remove item:" << id->uid;
60 ids = g_slist_append(ids, id);59 ids = g_slist_append(ids, id);
6160
62 m_pendingItems.removeAll(item);61 m_pendingItems.removeAll(item);
@@ -102,9 +101,7 @@
102 QSet<QtOrganizer::QOrganizerCollectionId>::const_iterator i = m_pendingCollections.constBegin();101 QSet<QtOrganizer::QOrganizerCollectionId>::const_iterator i = m_pendingCollections.constBegin();
103 m_pendingCollections.remove(*i);102 m_pendingCollections.remove(*i);
104 m_currentCollectionId = *i;103 m_currentCollectionId = *i;
105 qDebug() << "Will get item for sourcE:" << m_currentCollectionId.isNull() << m_currentCollectionId;
106 m_currentCompIds = takeItemsIds(m_currentCollectionId);104 m_currentCompIds = takeItemsIds(m_currentCollectionId);
107 qDebug() << "DONE Will get item for sourcE:" << m_currentCollectionId.isNull() << m_currentCollectionId;
108 return m_currentCollectionId;105 return m_currentCollectionId;
109 }106 }
110 return QOrganizerCollectionId();107 return QOrganizerCollectionId();
111108
=== modified file 'qorganizer/qorganizer-eds-requestdata.cpp'
--- qorganizer/qorganizer-eds-requestdata.cpp 2013-08-14 21:23:01 +0000
+++ qorganizer/qorganizer-eds-requestdata.cpp 2013-09-09 21:01:24 +0000
@@ -51,9 +51,9 @@
51 return !m_req.isNull();51 return !m_req.isNull();
52}52}
5353
54EClient *RequestData::client() const54ECalClient *RequestData::client() const
55{55{
56 return m_client;56 return E_CAL_CLIENT(m_client);
57}57}
5858
59QOrganizerEDSEngine *RequestData::parent() const59QOrganizerEDSEngine *RequestData::parent() const
6060
=== modified file 'qorganizer/qorganizer-eds-requestdata.h'
--- qorganizer/qorganizer-eds-requestdata.h 2013-08-14 21:23:01 +0000
+++ qorganizer/qorganizer-eds-requestdata.h 2013-09-09 21:01:24 +0000
@@ -35,7 +35,7 @@
35 GCancellable* cancellable() const;35 GCancellable* cancellable() const;
36 bool isLive() const;36 bool isLive() const;
37 void setClient(EClient *client);37 void setClient(EClient *client);
38 EClient *client() const;38 ECalClient *client() const;
39 virtual void finish(QtOrganizer::QOrganizerManager::Error error = QtOrganizer::QOrganizerManager::NoError) = 0;39 virtual void finish(QtOrganizer::QOrganizerManager::Error error = QtOrganizer::QOrganizerManager::NoError) = 0;
40 QOrganizerEDSEngine *parent() const;40 QOrganizerEDSEngine *parent() const;
41 virtual void cancel();41 virtual void cancel();
4242
=== added file 'qorganizer/qorganizer-eds-savecollectionrequestdata.cpp'
--- qorganizer/qorganizer-eds-savecollectionrequestdata.cpp 1970-01-01 00:00:00 +0000
+++ qorganizer/qorganizer-eds-savecollectionrequestdata.cpp 2013-09-09 21:01:24 +0000
@@ -0,0 +1,139 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of ubuntu-pim-service.
5 *
6 * contact-service-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * contact-service-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "qorganizer-eds-savecollectionrequestdata.h"
20
21#include <QtOrganizer/QOrganizerManagerEngine>
22#include <QtOrganizer/QOrganizerCollectionSaveRequest>
23
24using namespace QtOrganizer;
25
26#define COLLECTION_CALLENDAR_TYPE_METADATA "collection-type"
27
28SaveCollectionRequestData::SaveCollectionRequestData(QOrganizerEDSEngine *engine,
29 QtOrganizer::QOrganizerAbstractRequest *req)
30 : RequestData(engine, req),
31 m_sources(0),
32 m_currentSource(0)
33{
34 parseCollections();
35}
36
37SaveCollectionRequestData::~SaveCollectionRequestData()
38{
39}
40
41
42void SaveCollectionRequestData::finish(QtOrganizer::QOrganizerManager::Error error)
43{
44 qDebug() << "update request collections" << m_results;
45
46 QOrganizerManagerEngine::updateCollectionSaveRequest(request<QOrganizerCollectionSaveRequest>(),
47 m_results,
48 error,
49 m_errorMap,
50 QOrganizerAbstractRequest::FinishedState);
51
52 QList<QOrganizerCollectionId> added;
53 Q_FOREACH(QOrganizerCollection col, m_results) {
54 added.append(col.id());
55 }
56 Q_EMIT parent()->collectionsAdded(added);
57}
58
59void SaveCollectionRequestData::commit(QtOrganizer::QOrganizerManager::Error error)
60{
61 if (error != QOrganizerManager::NoError) {
62 m_errorMap.insert(m_currentSource, error);
63 } else {
64 ESource *source = E_SOURCE(g_list_nth_data(m_sources, m_currentSource));
65 QOrganizerEDSCollectionEngineId *edsId = 0;
66
67 QOrganizerCollection collection = QOrganizerEDSEngine::parseSource(source, parent()->managerUri(), &edsId);
68 parent()->registerCollection(collection, edsId);
69
70 m_results.append(collection);
71 }
72 m_currentSource++;
73}
74
75GList *SaveCollectionRequestData::sources() const
76{
77 return m_sources;
78}
79
80QList<QOrganizerCollection> SaveCollectionRequestData::results() const
81{
82 return m_results;
83}
84
85void SaveCollectionRequestData::parseCollections()
86{
87 if (m_sources) {
88 g_list_free_full(m_sources, g_object_unref);
89 m_sources = 0;
90 }
91
92 m_errorMap.clear();
93 int index = 0;
94 Q_FOREACH(QOrganizerCollection collection, request<QOrganizerCollectionSaveRequest>()->collections()) {
95 ESource *source = 0;
96 if (collection.id().isNull()) {
97 GError *gError = 0;
98 source = e_source_new(0, 0, &gError);
99 if (gError) {
100 m_errorMap.insert(index, QOrganizerManager::UnspecifiedError);
101 qWarning() << "Fail to create source:" << gError->message;
102 g_error_free(gError);
103 }
104 } else {
105 qDebug() << "Collection update not implemented";
106 Q_ASSERT(FALSE);
107 }
108
109 QString name = collection.metaData(QOrganizerCollection::KeyName).toString();
110 e_source_set_display_name(source, name.toUtf8().data());
111 e_source_set_parent(source, "local-stub");
112
113 QVariant callendarType = collection.extendedMetaData(COLLECTION_CALLENDAR_TYPE_METADATA);
114 ESourceBackend *extCalendar = 0;
115
116 if (callendarType.toString() == E_SOURCE_EXTENSION_TASK_LIST) {
117 extCalendar = E_SOURCE_BACKEND(e_source_get_extension(source, E_SOURCE_EXTENSION_TASK_LIST));
118 } else if (callendarType.toString() == E_SOURCE_EXTENSION_MEMO_LIST) {
119 extCalendar = E_SOURCE_BACKEND(e_source_get_extension(source, E_SOURCE_EXTENSION_MEMO_LIST));
120 } else {
121 extCalendar = E_SOURCE_BACKEND(e_source_get_extension(source, E_SOURCE_EXTENSION_CALENDAR));
122 }
123
124 if (extCalendar) {
125 e_source_backend_set_backend_name(extCalendar, "local");
126 } else {
127 qWarning() << "Fail to get source callendar";
128 }
129 m_sources = g_list_append(m_sources, source);
130 index++;
131 }
132
133 qDebug() << "Request with" << g_list_length(m_sources) << "sources";
134}
135
136ESource *SaveCollectionRequestData::begin() const
137{
138 return E_SOURCE(g_list_nth_data(m_sources, m_currentSource));
139}
0140
=== added file 'qorganizer/qorganizer-eds-savecollectionrequestdata.h'
--- qorganizer/qorganizer-eds-savecollectionrequestdata.h 1970-01-01 00:00:00 +0000
+++ qorganizer/qorganizer-eds-savecollectionrequestdata.h 2013-09-09 21:01:24 +0000
@@ -0,0 +1,49 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of ubuntu-pim-service.
5 *
6 * contact-service-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * contact-service-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __QORGANIZER_EDS_SAVECOLLECTIONREQUESTDATA_H__
20#define __QORGANIZER_EDS_SAVECOLLECTIONREQUESTDATA_H__
21
22#include "qorganizer-eds-requestdata.h"
23
24class SaveCollectionRequestData : public RequestData
25{
26public:
27 SaveCollectionRequestData(QOrganizerEDSEngine *engine,
28 QtOrganizer::QOrganizerAbstractRequest *req);
29 ~SaveCollectionRequestData();
30
31 void finish(QtOrganizer::QOrganizerManager::Error error = QtOrganizer::QOrganizerManager::NoError);
32 bool isNew(int index) const;
33
34 GList *sources() const;
35 QList<QtOrganizer::QOrganizerCollection> results() const;
36 ESource *begin() const;
37 void commit(QtOrganizer::QOrganizerManager::Error error = QtOrganizer::QOrganizerManager::NoError);
38
39private:
40 QMap<int, QtOrganizer::QOrganizerManager::Error> m_errorMap;
41 QList<QtOrganizer::QOrganizerCollection> m_results;
42 GList *m_sources;
43 int m_currentSource;
44
45 void parseCollections();
46
47};
48
49#endif
050
=== modified file 'tests/unittest/CMakeLists.txt'
--- tests/unittest/CMakeLists.txt 2013-08-14 21:23:01 +0000
+++ tests/unittest/CMakeLists.txt 2013-09-09 21:01:24 +0000
@@ -39,3 +39,8 @@
39endif()39endif()
4040
41declare_test(itemid-test)41declare_test(itemid-test)
42declare_test(parseecal-test)
43# Jenkins will not be able to run these tests because they need EDS running
44# FIXME: Mock EDS to run the tests bellow
45#declare_test(collections-test)
46#declare_test(event-test)
4247
=== added file 'tests/unittest/collections-test.cpp'
--- tests/unittest/collections-test.cpp 1970-01-01 00:00:00 +0000
+++ tests/unittest/collections-test.cpp 2013-09-09 21:01:24 +0000
@@ -0,0 +1,191 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of qtorganizer5-eds.
5 *
6 * contact-service-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * contact-service-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20#include <QObject>
21#include <QtTest>
22#include <QDebug>
23
24#include <QtOrganizer>
25
26#include "qorganizer-eds-engine.h"
27
28
29using namespace QtOrganizer;
30
31class CollectionTest : public QObject
32{
33 Q_OBJECT
34private:
35 static const QString defaultCollectionName;
36 static const QString defaultTaskCollectionName;
37 static const QString collectionTypePropertyName;
38 static const QString taskListTypeName;
39private Q_SLOTS:
40 void testCreateCollection()
41 {
42 QOrganizerEDSEngine *engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
43
44 QOrganizerCollection collection;
45 QtOrganizer::QOrganizerManager::Error error;
46 collection.setMetaData(QOrganizerCollection::KeyName, defaultCollectionName);
47
48 QVERIFY(engine->saveCollection(&collection, &error));
49 QCOMPARE(error, QOrganizerManager::NoError);
50 QVERIFY(!collection.id().isNull());
51 }
52
53 void testCreateTaskList()
54 {
55 QOrganizerEDSEngine *engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
56
57 QOrganizerCollection collection;
58 QtOrganizer::QOrganizerManager::Error error;
59 collection.setMetaData(QOrganizerCollection::KeyName, defaultTaskCollectionName);
60 collection.setExtendedMetaData(collectionTypePropertyName, taskListTypeName);
61
62 QSignalSpy createdCollection(engine, SIGNAL(collectionsAdded(QList<QOrganizerCollectionId>)));
63 QVERIFY(engine->saveCollection(&collection, &error));
64 QCOMPARE(error, QOrganizerManager::NoError);
65 QVERIFY(!collection.id().isNull());
66
67 //verify signal
68 QCOMPARE(createdCollection.count(), 1);
69 QList<QVariant> args = createdCollection.takeFirst();
70 QCOMPARE(args.count(), 1);
71
72 QVERIFY(engine->collections(&error).contains(collection));
73 delete engine;
74
75 // recreate and check if the new collection is listed
76 engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
77 QVERIFY(engine->collections(&error).contains(collection));
78 }
79
80 void testCreateTask()
81 {
82 static QString displayLabelValue = QStringLiteral("Todo test");
83 static QString descriptionValue = QStringLiteral("Todo description");
84
85 QOrganizerEDSEngine *engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
86
87 QOrganizerCollection collection;
88 QtOrganizer::QOrganizerManager::Error error;
89 collection.setMetaData(QOrganizerCollection::KeyName, defaultTaskCollectionName + "2");
90 collection.setExtendedMetaData(collectionTypePropertyName, taskListTypeName);
91 QVERIFY(engine->saveCollection(&collection, &error));
92
93 QOrganizerTodo todo;
94 todo.setCollectionId(collection.id());
95 todo.setStartDateTime(QDateTime(QDate(2013, 9, 3), QTime(0,30,0)));
96 todo.setDisplayLabel(displayLabelValue);
97 todo.setDescription(descriptionValue);
98
99 QMap<int, QtOrganizer::QOrganizerManager::Error> errorMap;
100 QList<QOrganizerItem> items;
101 QSignalSpy createdItem(engine, SIGNAL(itemsAdded(QList<QOrganizerItemId>)));
102 items << todo;
103 bool saveResult = engine->saveItems(&items,
104 QList<QtOrganizer::QOrganizerItemDetail::DetailType>(),
105 &errorMap,
106 &error);
107 QVERIFY(saveResult);
108 QCOMPARE(error, QOrganizerManager::NoError);
109 QVERIFY(errorMap.isEmpty());
110 QVERIFY(!items[0].id().isNull());
111
112 //verify signal
113 QCOMPARE(createdItem.count(), 1);
114 QList<QVariant> args = createdItem.takeFirst();
115 QCOMPARE(args.count(), 1);
116
117 // check if the item is listead inside the correct collection
118 QOrganizerItemSortOrder sort;
119 QOrganizerItemFetchHint hint;
120 QOrganizerItemCollectionFilter filter;
121
122 filter.setCollectionId(collection.id());
123
124 items = engine->items(filter,
125 QDateTime(),
126 QDateTime(),
127 10,
128 sort,
129 hint,
130 &error);
131
132 QCOMPARE(items.count(), 1);
133 QOrganizerTodo result = static_cast<QOrganizerTodo>(items[0]);
134 todo = items[0];
135 QCOMPARE(result.id(), todo.id());
136 QCOMPARE(result.startDateTime(), todo.startDateTime());
137 QCOMPARE(result.displayLabel(), todo.displayLabel());
138 QCOMPARE(result.description(), todo.description());
139
140
141 // check if the item is listead by id
142 QList<QOrganizerItemId> ids;
143 ids << todo.id();
144
145 items = engine->items(ids, hint, &errorMap, &error);
146 QCOMPARE(items.count(), 1);
147 result = static_cast<QOrganizerTodo>(items[0]);
148 todo = items[0];
149 QCOMPARE(result.id(), todo.id());
150 QCOMPARE(result.startDateTime(), todo.startDateTime());
151 QCOMPARE(result.displayLabel(), todo.displayLabel());
152 QCOMPARE(result.description(), todo.description());
153
154 delete engine;
155 }
156
157 void testRemoveCollection()
158 {
159 static QString removableCollectionName = defaultTaskCollectionName + QStringLiteral("_REMOVABLE");
160
161 QOrganizerEDSEngine *engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
162
163 // Create a collection
164 QOrganizerCollection collection;
165 QtOrganizer::QOrganizerManager::Error error;
166 collection.setMetaData(QOrganizerCollection::KeyName, removableCollectionName);
167 QVERIFY(engine->saveCollection(&collection, &error));
168 delete engine;
169
170 QTest::qSleep(1000);
171
172 engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
173 // remove recent created collection
174 QVERIFY(engine->removeCollection(collection.id(), &error));
175
176 // Check if collection is not listed anymore
177 QTest::qSleep(1000);
178 QList<QOrganizerCollection> collections = engine->collections(&error);
179 QVERIFY(!collections.contains(collection));
180 }
181};
182
183const QString CollectionTest::defaultCollectionName = QStringLiteral("TEST COLLECTION");
184const QString CollectionTest::defaultTaskCollectionName = QStringLiteral("TEST COLLECTION TASK LIST");
185const QString CollectionTest::collectionTypePropertyName = QStringLiteral("collection-type");
186const QString CollectionTest::taskListTypeName = QStringLiteral("Task List");
187
188
189QTEST_MAIN(CollectionTest)
190
191#include "collections-test.moc"
0192
=== added file 'tests/unittest/event-test.cpp'
--- tests/unittest/event-test.cpp 1970-01-01 00:00:00 +0000
+++ tests/unittest/event-test.cpp 2013-09-09 21:01:24 +0000
@@ -0,0 +1,138 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of qtorganizer5-eds.
5 *
6 * contact-service-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * contact-service-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20#include <QObject>
21#include <QtTest>
22#include <QDebug>
23
24#include <QtOrganizer>
25
26#include "qorganizer-eds-engine.h"
27
28
29using namespace QtOrganizer;
30
31class EventTest : public QObject
32{
33 Q_OBJECT
34private:
35 static const QString defaultCollectionName;
36 static const QString defaultTaskCollectionName;
37 static const QString collectionTypePropertyName;
38 static const QString taskListTypeName;
39
40private Q_SLOTS:
41 void testCreateEventWithReminder()
42 {
43 static QString displayLabelValue = QStringLiteral("Todo test");
44 static QString descriptionValue = QStringLiteral("Todo description");
45
46 QOrganizerEDSEngine *engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
47
48 QOrganizerCollection collection;
49 QtOrganizer::QOrganizerManager::Error error;
50 collection.setMetaData(QOrganizerCollection::KeyName, defaultCollectionName);
51 collection.setExtendedMetaData(collectionTypePropertyName, taskListTypeName);
52
53 engine->saveCollection(&collection, &error);
54
55 QOrganizerTodo todo;
56 todo.setCollectionId(collection.id());
57 todo.setStartDateTime(QDateTime(QDate(2013, 9, 3), QTime(0,30,0)));
58 todo.setDisplayLabel(displayLabelValue);
59 todo.setDescription(descriptionValue);
60
61 QOrganizerItemVisualReminder vReminder;
62 vReminder.setDataUrl(QUrl("http://www.alarms.com"));
63 vReminder.setMessage("Test visual reminder");
64
65 QOrganizerItemAudibleReminder aReminder;
66 aReminder.setSecondsBeforeStart(10);
67 aReminder.setRepetition(10, 20);
68 aReminder.setDataUrl(QUrl("file://home/user/My Musics/play as alarm.wav"));
69
70
71 todo.saveDetail(&aReminder);
72 todo.saveDetail(&vReminder);
73
74 QMap<int, QtOrganizer::QOrganizerManager::Error> errorMap;
75 QList<QOrganizerItem> items;
76 items << todo;
77 bool saveResult = engine->saveItems(&items,
78 QList<QtOrganizer::QOrganizerItemDetail::DetailType>(),
79 &errorMap,
80 &error);
81 QVERIFY(saveResult);
82
83 // delete engine to make sure the new engine will be loaded from scratch
84 delete engine;
85
86 engine = QOrganizerEDSEngine::createEDSEngine(QMap<QString, QString>());
87
88 QOrganizerItemSortOrder sort;
89 QOrganizerItemFetchHint hint;
90 QOrganizerItemIdFilter filter;
91
92 QList<QOrganizerItemId> ids;
93 ids << items[0].id();
94 filter.setIds(ids);
95
96 items = engine->items(filter,
97 QDateTime(),
98 QDateTime(),
99 10,
100 sort,
101 hint,
102 &error);
103 QCOMPARE(items.count(), 1);
104
105 // audible
106 QList<QOrganizerItemDetail> reminders = items[0].details(QOrganizerItemDetail::TypeAudibleReminder);
107 QCOMPARE(reminders.size(), 1);
108
109 QOrganizerItemAudibleReminder aReminder2 = reminders[0];
110 QCOMPARE(aReminder2.secondsBeforeStart(), aReminder.secondsBeforeStart());
111 QCOMPARE(aReminder2.repetitionCount(), aReminder.repetitionCount());
112 QCOMPARE(aReminder2.repetitionDelay(), aReminder.repetitionDelay());
113 QCOMPARE(aReminder2.dataUrl(), aReminder.dataUrl());
114 //QCOMPARE(aReminder2, aReminder);
115
116 // visual
117 reminders = items[0].details(QOrganizerItemDetail::TypeVisualReminder);
118 QCOMPARE(reminders.size(), 1);
119
120 QOrganizerItemVisualReminder vReminder2 = reminders[0];
121 //vReminder.setRepetition(1, 0);
122 QCOMPARE(vReminder2.secondsBeforeStart(), vReminder.secondsBeforeStart());
123 QCOMPARE(vReminder2.repetitionCount(), vReminder.repetitionCount());
124 QCOMPARE(vReminder2.repetitionDelay(), vReminder.repetitionDelay());
125 QCOMPARE(vReminder2.dataUrl(), vReminder.dataUrl());
126 QCOMPARE(vReminder2.message(), vReminder.message());
127 }
128};
129
130const QString EventTest::defaultCollectionName = QStringLiteral("TEST_EVENT_COLLECTION");
131const QString EventTest::defaultTaskCollectionName = QStringLiteral("TEST_EVENT_COLLECTION TASK LIST");
132const QString EventTest::collectionTypePropertyName = QStringLiteral("collection-type");
133const QString EventTest::taskListTypeName = QStringLiteral("Task List");
134
135
136QTEST_MAIN(EventTest)
137
138#include "event-test.moc"
0139
=== added file 'tests/unittest/parseecal-test.cpp'
--- tests/unittest/parseecal-test.cpp 1970-01-01 00:00:00 +0000
+++ tests/unittest/parseecal-test.cpp 2013-09-09 21:01:24 +0000
@@ -0,0 +1,366 @@
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This file is part of qtorganizer5-eds.
5 *
6 * contact-service-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * contact-service-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19//ugly hack but this allow us to test the engine without mock EDS
20#define private public
21#include "qorganizer-eds-engine.h"
22#undef private
23
24#include <QObject>
25#include <QtTest>
26#include <QDebug>
27
28#include <QtOrganizer>
29
30#include <libecal/libecal.h>
31
32using namespace QtOrganizer;
33
34class ParseEcalTest : public QObject
35{
36 Q_OBJECT
37
38private Q_SLOTS:
39 void testParseStartTime()
40 {
41 QDateTime startTime = QDateTime::currentDateTime();
42 QDateTime endTime(startTime);
43 endTime = endTime.addDays(2);
44
45 ECalComponent *comp = e_cal_component_new();
46 e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT);
47
48 ECalComponentDateTime dt;
49
50 struct icaltimetype itt = icaltime_from_timet(startTime.toTime_t(), FALSE);
51 dt.value = &itt;
52 dt.tzid = "";
53 e_cal_component_set_dtstart(comp, &dt);
54
55 QOrganizerEvent item;
56 QOrganizerEDSEngine::parseStartTime(comp, &item);
57 QCOMPARE(item.startDateTime().toTime_t(), startTime.toTime_t());
58
59 itt = icaltime_from_timet(endTime.toTime_t(), FALSE);
60 dt.value = &itt;
61 e_cal_component_set_dtend(comp, &dt);
62
63 QOrganizerEDSEngine::parseEndTime(comp, &item);
64 QCOMPARE(item.endDateTime().toTime_t(), endTime.toTime_t());
65 }
66
67 void testParseRemindersQOrganizerEvent2ECalComponent()
68 {
69 QOrganizerEvent event;
70 QOrganizerItemAudibleReminder aReminder;
71
72 // Check audible reminder
73 aReminder.setRepetition(10, 30);
74 aReminder.setSecondsBeforeStart(10);
75 QCOMPARE(aReminder.secondsBeforeStart(), 10);
76 event.saveDetail(&aReminder);
77
78 ECalComponent *comp = e_cal_component_new();
79 e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT);
80
81 QOrganizerEDSEngine::parseReminders(event, comp);
82
83 GList *aIds = e_cal_component_get_alarm_uids(comp);
84 QCOMPARE(g_list_length(aIds), (guint) 1);
85
86 ECalComponentAlarm *alarm = e_cal_component_get_alarm(comp, (const gchar*)aIds->data);
87 QVERIFY(alarm);
88
89 ECalComponentAlarmAction aAction;
90 e_cal_component_alarm_get_action(alarm, &aAction);
91 QCOMPARE(aAction, E_CAL_COMPONENT_ALARM_AUDIO);
92
93 ECalComponentAlarmTrigger trigger;
94 e_cal_component_alarm_get_trigger(alarm, &trigger);
95 QCOMPARE(trigger.type, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START);
96 QCOMPARE(icaldurationtype_as_int(trigger.u.rel_duration) * -1, aReminder.secondsBeforeStart());
97
98 ECalComponentAlarmRepeat aRepeat;
99 e_cal_component_alarm_get_repeat(alarm, &aRepeat);
100 QCOMPARE(aRepeat.repetitions, aReminder.repetitionCount());
101 QCOMPARE(icaldurationtype_as_int(aRepeat.duration), aReminder.repetitionDelay());
102
103 g_object_unref(comp);
104 }
105
106 void testParseRemindersECalComponent2QOrganizerEvent()
107 {
108 ECalComponent *comp = e_cal_component_new();
109 e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT);
110
111 ECalComponentAlarm *alarm = e_cal_component_alarm_new();
112 e_cal_component_alarm_set_action(alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
113
114 ECalComponentAlarmTrigger trigger;
115 trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
116 trigger.u.rel_duration = icaldurationtype_from_int(-10);
117 e_cal_component_alarm_set_trigger(alarm, trigger);
118
119 ECalComponentAlarmRepeat aRepeat;
120 aRepeat.repetitions = 5;
121 aRepeat.duration = icaldurationtype_from_int(100);
122 e_cal_component_alarm_set_repeat(alarm, aRepeat);
123
124 e_cal_component_add_alarm(comp, alarm);
125 e_cal_component_alarm_free(alarm);
126
127 QOrganizerItem alarmItem;
128 QOrganizerEDSEngine::parseReminders(comp, &alarmItem);
129
130 QOrganizerItemVisualReminder vReminder = alarmItem.detail(QOrganizerItemDetail::TypeVisualReminder);
131 QCOMPARE(vReminder.repetitionCount(), 5);
132 QCOMPARE(vReminder.repetitionDelay(), 100);
133 QCOMPARE(vReminder.secondsBeforeStart(), 10);
134
135 g_object_unref(comp);
136 }
137
138 void testParseRecurenceQOrganizerEvent2ECalComponent()
139 {
140 // by date
141 QOrganizerEvent event;
142 QOrganizerItemRecurrence rec;
143
144 QList<QDate> rDates;
145 rDates << QDate(2010, 1, 20)
146 << QDate(2011, 2, 21)
147 << QDate(2012, 3, 22);
148
149 rec.setRecurrenceDates(rDates.toSet());
150
151 QList<QDate> rExeptDates;
152 rExeptDates << QDate(2013, 4, 23)
153 << QDate(2014, 5, 24)
154 << QDate(2015, 6, 25);
155 rec.setExceptionDates(rExeptDates.toSet());
156
157 QOrganizerRecurrenceRule dailyRule;
158 QList<QOrganizerRecurrenceRule> rrules;
159
160 dailyRule.setFrequency(QOrganizerRecurrenceRule::Daily);
161 dailyRule.setLimit(1000);
162 rrules << dailyRule;
163
164 QOrganizerRecurrenceRule weeklyRule;
165 weeklyRule.setFrequency(QOrganizerRecurrenceRule::Weekly);
166 weeklyRule.setLimit(1001);
167 QList<Qt::DayOfWeek> daysOfWeek;
168 daysOfWeek << Qt::Monday
169 << Qt::Tuesday
170 << Qt::Wednesday
171 << Qt::Thursday
172 << Qt::Friday;
173 weeklyRule.setDaysOfWeek(daysOfWeek.toSet());
174 weeklyRule.setFirstDayOfWeek(Qt::Sunday);
175 rrules << weeklyRule;
176
177 QOrganizerRecurrenceRule monthlyRule;
178 monthlyRule.setFrequency(QOrganizerRecurrenceRule::Monthly);
179 monthlyRule.setLimit(1002);
180
181 QList<int> daysOfMonth;
182 daysOfMonth << 1
183 << 15
184 << 30;
185 monthlyRule.setDaysOfMonth(daysOfMonth.toSet());
186 rrules << monthlyRule;
187
188 QOrganizerRecurrenceRule yearlyRule;
189 yearlyRule.setFrequency(QOrganizerRecurrenceRule::Yearly);
190 yearlyRule.setLimit(1003);
191 QList<int> daysOfYear;
192 daysOfYear << 1
193 << 10
194 << 20
195 << 50
196 << 300;
197 yearlyRule.setDaysOfYear(daysOfYear.toSet());
198
199
200 QList<QOrganizerRecurrenceRule::Month> monthsOfYear;
201 monthsOfYear << QOrganizerRecurrenceRule::January
202 << QOrganizerRecurrenceRule::March
203 << QOrganizerRecurrenceRule::December;
204 yearlyRule.setMonthsOfYear(monthsOfYear.toSet());
205 rrules << yearlyRule;
206
207 rec.setRecurrenceRules(rrules.toSet());
208
209 // save recurrence
210 event.saveDetail(&rec);
211
212 ECalComponent *comp = e_cal_component_new();
213 e_cal_component_set_new_vtype(comp, E_CAL_COMPONENT_EVENT);
214 QOrganizerEDSEngine::parseRecurrence(event, comp);
215
216 // recurrence dates
217 GSList *periodList = 0;
218 e_cal_component_get_rdate_list(comp, &periodList);
219
220 QCOMPARE(g_slist_length(periodList), (guint)3);
221
222 for(GSList *pIter = periodList; pIter != 0; pIter = pIter->next) {
223 ECalComponentPeriod *period = static_cast<ECalComponentPeriod*>(pIter->data);
224 QDate periodDate = QDateTime::fromTime_t(icaltime_as_timet(period->start)).date();
225
226 QVERIFY(rDates.contains(periodDate));
227 }
228 e_cal_component_free_period_list(periodList);
229
230 // exception dates
231 GSList *exDateList = 0;
232 e_cal_component_get_exdate_list(comp, &exDateList);
233 for(GSList *pIter = exDateList; pIter != 0; pIter = pIter->next) {
234 ECalComponentDateTime *exDate = static_cast<ECalComponentDateTime*>(pIter->data);
235 QDate exDateValue = QDateTime::fromTime_t(icaltime_as_timet(*exDate->value)).date();
236 QVERIFY(rExeptDates.contains(exDateValue));
237 }
238 e_cal_component_free_exdate_list(exDateList);
239
240
241 // rules
242 GSList *recurList = 0;
243 e_cal_component_get_rrule_list(comp, &recurList);
244 QCOMPARE(g_slist_length(recurList), (guint) rrules.count());
245
246 for(GSList *recurListIter = recurList; recurListIter != 0; recurListIter = recurListIter->next) {
247 struct icalrecurrencetype *rule = static_cast<struct icalrecurrencetype*>(recurListIter->data);
248
249 switch(rule->freq)
250 {
251 case ICAL_DAILY_RECURRENCE:
252 QCOMPARE(rule->count, dailyRule.limitCount());
253 break;
254 case ICAL_WEEKLY_RECURRENCE:
255 QCOMPARE(rule->count, weeklyRule.limitCount());
256 for (int d = Qt::Monday; d <= Qt::Sunday; d++) {
257 if (daysOfWeek.contains(static_cast<Qt::DayOfWeek>(d))) {
258 QVERIFY(rule->by_day[(d-1)] != ICAL_RECURRENCE_ARRAY_MAX);
259 } else {
260 QVERIFY(rule->by_day[d-1] == ICAL_RECURRENCE_ARRAY_MAX);
261 }
262 }
263 break;
264 case ICAL_MONTHLY_RECURRENCE:
265 {
266 QCOMPARE(rule->count, monthlyRule.limitCount());
267
268 QList<int> ruleDays;
269 for (int d=0; d < ICAL_BY_MONTHDAY_SIZE; d++) {
270 if (rule->by_month_day[d] != ICAL_RECURRENCE_ARRAY_MAX) {
271 ruleDays << rule->by_month_day[d];
272 }
273 }
274 QCOMPARE(ruleDays.count(), daysOfMonth.count());
275 Q_FOREACH(int day, ruleDays) {
276 QVERIFY(daysOfMonth.contains(day));
277 }
278 break;
279 }
280 case ICAL_YEARLY_RECURRENCE:
281 {
282 QCOMPARE(rule->count, yearlyRule.limitCount());
283 QList<int> ruleDays;
284
285 for (int d=0; d < ICAL_BY_YEARDAY_SIZE; d++) {
286 if (rule->by_year_day[d] != ICAL_RECURRENCE_ARRAY_MAX) {
287
288 ruleDays << rule->by_year_day[d];
289 }
290 }
291 QCOMPARE(ruleDays.count(), daysOfYear.count());
292 Q_FOREACH(int day, ruleDays) {
293 QVERIFY(daysOfYear.contains(day));
294 }
295
296 QList<int> ruleMonths;
297 for (int d=0; d < ICAL_BY_MONTH_SIZE; d++) {
298 if (rule->by_month[d] != ICAL_RECURRENCE_ARRAY_MAX) {
299 ruleMonths << rule->by_month[d];
300 }
301 }
302 QCOMPARE(ruleMonths.count(), monthsOfYear.count());
303 Q_FOREACH(int month, ruleMonths) {
304 QVERIFY(monthsOfYear.contains(static_cast<QOrganizerRecurrenceRule::Month>(month)));
305 }
306 }
307 default:
308 break;
309 }
310 }
311
312 // invert
313 QOrganizerEvent event2;
314 QOrganizerEDSEngine::parseRecurrence(comp, &event2);
315
316 QCOMPARE(event2.recurrenceDates(), event.recurrenceDates());
317 QCOMPARE(event2.exceptionDates(), event.exceptionDates());
318
319 QList<QOrganizerRecurrenceRule> rrules2 = event2.recurrenceRules().toList();
320 QCOMPARE(rrules2.count(), rrules.count());
321
322 Q_FOREACH(QOrganizerRecurrenceRule rule2, rrules2) {
323 switch(rule2.frequency()) {
324 case QOrganizerRecurrenceRule::Daily:
325 QCOMPARE(rule2.limitCount(), dailyRule.limitCount());
326 break;
327 case QOrganizerRecurrenceRule::Weekly:
328 {
329 QCOMPARE(rule2.limitCount(), weeklyRule.limitCount());
330 QList<Qt::DayOfWeek> daysOfWeek2 = rule2.daysOfWeek().toList();
331 qSort(daysOfWeek2);
332 QCOMPARE(daysOfWeek2, daysOfWeek);
333 break;
334 }
335 case QOrganizerRecurrenceRule::Monthly:
336 {
337 QCOMPARE(rule2.limitCount(), monthlyRule.limitCount());
338 QList<int> daysOfMonth2 = rule2.daysOfMonth().toList();
339 qSort(daysOfMonth2);
340 QCOMPARE(daysOfMonth2, daysOfMonth);
341 break;
342 }
343 case QOrganizerRecurrenceRule::Yearly:
344 {
345 QCOMPARE(rule2.limitCount(), yearlyRule.limitCount());
346 QList<int> daysOfYear2 = rule2.daysOfYear().toList();
347 qSort(daysOfYear2);
348 QCOMPARE(daysOfYear2, daysOfYear);
349
350 QList<QOrganizerRecurrenceRule::Month> monthsOfYear2 = rule2.monthsOfYear().toList();
351 qSort(monthsOfYear2);
352 QCOMPARE(monthsOfYear2, monthsOfYear);
353 break;
354 }
355 default:
356 QVERIFY(false);
357 }
358 }
359
360 g_object_unref(comp);
361 }
362};
363
364QTEST_MAIN(ParseEcalTest)
365
366#include "parseecal-test.moc"
0367
=== added file 'tests/unittest/parseitem-test.cpp'

Subscribers

People subscribed via source and target branches