125 QContactLocalId id = d->hash->append(uid); |
126 QContactLocalId id = d->hash->append(uid); |
126 |
127 |
127 if (id) |
128 if (id) |
128 contactIds << id; |
129 contactIds << id; |
129 } |
130 } |
130 d->that->_contactsAdded(contactIds); |
131 |
|
132 if (!contactIds.isEmpty()) |
|
133 d->that->_contactsAdded(contactIds); |
131 } |
134 } |
132 |
135 |
133 static void contactsChangedCB(OssoABookRoster *roster, OssoABookContact **contacts, gpointer data) |
136 static void contactsChangedCB(OssoABookRoster *roster, OssoABookContact **contacts, gpointer data) |
134 { |
137 { |
135 QCM5_DEBUG << "CONTACT CHANGED"; |
138 QCM5_DEBUG << "CONTACT CHANGED"; |
136 Q_UNUSED(roster) |
139 Q_UNUSED(roster) |
137 |
140 |
138 cbSharedData* d = static_cast<cbSharedData*>(data); |
141 cbSharedData* d = static_cast<cbSharedData*>(data); |
139 if (!d){ |
142 if (!d){ |
140 qWarning() << "d has been deleted"; |
143 //qWarning() << "d has been deleted"; |
141 return; |
144 return; |
142 } |
145 } |
143 |
146 |
144 OssoABookContact **p; |
147 OssoABookContact **p; |
145 QList<QContactLocalId> contactIds; |
148 QList<QContactLocalId> contactIds; |
152 QContactLocalId id = d->hash->find(uid); |
155 QContactLocalId id = d->hash->find(uid); |
153 //FREE(uid); |
156 //FREE(uid); |
154 if (id) |
157 if (id) |
155 contactIds << id; |
158 contactIds << id; |
156 } |
159 } |
157 d->that->_contactsChanged(contactIds); |
160 |
|
161 if (!contactIds.isEmpty()) |
|
162 d->that->_contactsChanged(contactIds); |
158 } |
163 } |
159 |
164 |
160 static void contactsRemovedCB(OssoABookRoster *roster, const char **ids, gpointer data) |
165 static void contactsRemovedCB(OssoABookRoster *roster, const char **ids, gpointer data) |
161 { |
166 { |
162 QCM5_DEBUG << "CONTACT REMOVED"; |
167 QCM5_DEBUG << "CONTACT REMOVED"; |
163 Q_UNUSED(roster) |
168 Q_UNUSED(roster) |
164 |
169 |
165 cbSharedData* d = static_cast<cbSharedData*>(data); |
170 cbSharedData* d = static_cast<cbSharedData*>(data); |
166 if (!d){ |
171 if (!d){ |
167 qWarning() << "d has been deleted"; |
172 //qWarning() << "d has been deleted"; |
168 return; |
173 return; |
169 } |
174 } |
170 |
175 |
171 const char **p; |
176 const char **p; |
172 QList<QContactLocalId> contactIds; |
177 QList<QContactLocalId> contactIds; |
173 |
178 |
174 for (p = ids; *p; ++p) { |
179 for (p = ids; *p; ++p) { |
175 QContactLocalId id = d->hash->take(*p); |
180 QContactLocalId id = d->hash->take(*p); |
176 QCM5_DEBUG << "Contact" << id << "has been removed"; |
181 if (id) { |
177 if (id) |
182 QCM5_DEBUG << "Contact" << id << "has been removed"; |
178 contactIds << id; |
183 contactIds << id; |
179 } |
184 } |
180 |
185 } |
181 d->that->_contactsRemoved(contactIds); |
186 |
|
187 if (!contactIds.isEmpty()) |
|
188 d->that->_contactsRemoved(contactIds); |
182 } |
189 } |
183 |
190 |
184 void QContactABook::initAddressBook(){ |
191 void QContactABook::initAddressBook(){ |
185 /* Open AddressBook */ |
192 /* Open AddressBook */ |
186 GError *gError = NULL; |
193 GError *gError = NULL; |
259 } |
266 } |
260 |
267 |
261 QList<QContactLocalId> QContactABook::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const |
268 QList<QContactLocalId> QContactABook::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const |
262 { |
269 { |
263 QList<QContactLocalId> rtn; |
270 QList<QContactLocalId> rtn; |
264 |
271 |
265 /* Sorting */ |
272 // do this naively for now... |
|
273 *error = QContactManager::NoError; |
|
274 QContactManager::Error tempError = QContactManager::NoError; |
|
275 QList<QContactLocalId> allIds = m_localIds.keys(); |
|
276 QList<QContact> sortedAndFiltered; |
|
277 QContact *curr = 0; |
|
278 foreach (const QContactLocalId& currId, allIds) { |
|
279 curr = getQContact(currId, &tempError); |
|
280 if (tempError != QContactManager::NoError) |
|
281 *error = tempError; |
|
282 if (QContactManagerEngine::testFilter(filter, *curr)) { |
|
283 QContactManagerEngine::addSorted(&sortedAndFiltered, *curr, sortOrders); |
|
284 } |
|
285 delete curr; |
|
286 } |
|
287 |
|
288 foreach (const QContact& contact, sortedAndFiltered) { |
|
289 rtn.append(contact.localId()); |
|
290 } |
|
291 return rtn; |
|
292 |
|
293 /* |
|
294 // Sorting |
266 //NOTE Native sorting is possible thanks to g_list_sort. |
295 //NOTE Native sorting is possible thanks to g_list_sort. |
267 // It's limited just to one filter. |
296 // It's limited just to one filter. |
268 // Multi filters support need non native sorting. |
297 // Multi filters support need non native sorting. |
269 // Native filtering needs a lot of coding since we need |
298 // Native filtering needs a lot of coding since we need |
270 // detailDefinitionName * detailFieldName functions |
299 // detailDefinitionName * detailFieldName functions |
294 |
323 |
295 // Non native sorting |
324 // Non native sorting |
296 return QContactManagerEngine::sortContacts(contacts, sortOrders); |
325 return QContactManagerEngine::sortContacts(contacts, sortOrders); |
297 } |
326 } |
298 |
327 |
299 /* Matching action filter */ |
|
300 //NOTE The code was not really tested */ |
|
301 if(filter.type() == QContactFilter::ActionFilter){ |
|
302 QContactActionFilter af(filter); |
|
303 /* This looks a bit strange for me */ |
|
304 QList<QContactActionDescriptor> descriptors = QContactAction::actionDescriptors(af.actionName(), af.vendorName(), af.implementationVersion()); |
|
305 |
|
306 GList *masterContacts = osso_abook_aggregator_list_master_contacts(m_abookAgregator); |
|
307 for(; masterContacts; ){ |
|
308 OssoABookContact *masterContact = A_CONTACT(masterContacts->data); |
|
309 bool match = contactActionsMatch(masterContact, descriptors); |
|
310 if(!match) { |
|
311 GList *rosterContacts = osso_abook_contact_get_roster_contacts(masterContact); |
|
312 for(; rosterContacts && !match; ){ |
|
313 OssoABookContact *rosterContact = A_CONTACT(rosterContacts->data); |
|
314 match = contactActionsMatch(rosterContact, descriptors); |
|
315 rosterContacts = g_list_delete_link(rosterContacts, rosterContacts); |
|
316 } |
|
317 g_list_free(rosterContacts); |
|
318 } |
|
319 if(match){ |
|
320 EContact *contact = E_CONTACT(masterContact); |
|
321 const char* data = CONST_CHAR(e_contact_get_const(contact, E_CONTACT_UID)); |
|
322 QByteArray localId(data); |
|
323 m_localIds << localId; |
|
324 rtn.append(m_localIds[localId]); |
|
325 QCM5_DEBUG << "eContactID " << localId << "has been stored in m_localIDs with key" << m_localIds[localId]; |
|
326 } |
|
327 masterContacts = g_list_delete_link(masterContacts, masterContacts); |
|
328 } |
|
329 *error = QContactManager::NoError; |
|
330 return rtn; |
|
331 } |
|
332 |
|
333 EBookQuery* query = convert(filter); |
328 EBookQuery* query = convert(filter); |
334 |
329 |
335 GList* l = osso_abook_aggregator_find_contacts(m_abookAgregator, query); |
330 GList* l = osso_abook_aggregator_find_contacts(m_abookAgregator, query); |
336 if (query) |
331 if (query) |
337 e_book_query_unref(query); |
332 e_book_query_unref(query); |
346 l = g_list_delete_link(l, l); |
341 l = g_list_delete_link(l, l); |
347 } |
342 } |
348 |
343 |
349 *error = QContactManager::NoError; |
344 *error = QContactManager::NoError; |
350 return rtn; |
345 return rtn; |
|
346 */ |
351 } |
347 } |
352 |
348 |
353 QContact* QContactABook::getQContact(const QContactLocalId& contactId, QContactManager::Error* error) const |
349 QContact* QContactABook::getQContact(const QContactLocalId& contactId, QContactManager::Error* error) const |
354 { |
350 { |
355 QContact *rtn; |
351 QContact *rtn; |
356 OssoABookContact* aContact = getAContact(contactId); |
352 OssoABookContact* aContact = getAContact(contactId, error); |
357 if (!aContact) { |
353 if (!aContact) { |
358 qWarning() << "Unable to get a valid AContact"; |
354 //qWarning() << "Unable to get a valid AContact"; |
359 *error = QContactManager::DoesNotExistError; |
|
360 return new QContact; |
355 return new QContact; |
361 } |
356 } |
362 |
357 |
363 //Convert aContact => qContact |
358 //Convert aContact => qContact |
364 rtn = convert(E_CONTACT(aContact)); |
359 rtn = convert(E_CONTACT(aContact)); |
|
360 QContactId cId; |
|
361 cId.setLocalId(contactId); |
|
362 rtn->setId(cId); |
365 return rtn; |
363 return rtn; |
|
364 } |
|
365 |
|
366 static QContactManager::Error getErrorFromStatus(const EBookStatus status){ |
|
367 switch (status) { |
|
368 case E_BOOK_ERROR_OK: |
|
369 return QContactManager::NoError; |
|
370 case E_BOOK_ERROR_INVALID_ARG: |
|
371 return QContactManager::BadArgumentError; |
|
372 case E_BOOK_ERROR_BUSY: |
|
373 return QContactManager::LockedError; |
|
374 case E_BOOK_ERROR_PERMISSION_DENIED: |
|
375 case E_BOOK_ERROR_AUTHENTICATION_FAILED: |
|
376 case E_BOOK_ERROR_AUTHENTICATION_REQUIRED: |
|
377 //case E_BOOK_ERROR_UNSUPPORTED_AUTHENTICATION_METHOD: //Missing in current Maemo5 Ebook lib version |
|
378 return QContactManager::PermissionsError; |
|
379 case E_BOOK_ERROR_CONTACT_NOT_FOUND: |
|
380 return QContactManager::DoesNotExistError; |
|
381 case E_BOOK_ERROR_CONTACT_ID_ALREADY_EXISTS: |
|
382 return QContactManager::AlreadyExistsError; |
|
383 case E_BOOK_ERROR_NO_SPACE: |
|
384 return QContactManager::OutOfMemoryError; |
|
385 #if 0 |
|
386 case E_BOOK_ERROR_REPOSITORY_OFFLINE: |
|
387 case E_BOOK_ERROR_NO_SUCH_BOOK: |
|
388 case E_BOOK_ERROR_NO_SELF_CONTACT: |
|
389 case E_BOOK_ERROR_SOURCE_NOT_LOADED: |
|
390 case E_BOOK_ERROR_SOURCE_ALREADY_LOADED: |
|
391 case E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED: |
|
392 case E_BOOK_ERROR_CANCELLED: |
|
393 case E_BOOK_ERROR_COULD_NOT_CANCEL: |
|
394 case E_BOOK_ERROR_TLS_NOT_AVAILABLE: |
|
395 case E_BOOK_ERROR_CORBA_EXCEPTION: |
|
396 case E_BOOK_ERROR_NO_SUCH_SOURCE: |
|
397 case E_BOOK_ERROR_OFFLINE_UNAVAILABLE: |
|
398 case E_BOOK_ERROR_OTHER_ERROR: |
|
399 case E_BOOK_ERROR_INVALID_SERVER_VERSION: |
|
400 #endif |
|
401 default: |
|
402 return QContactManager::UnspecifiedError; |
|
403 } |
366 } |
404 } |
367 |
405 |
368 static void delContactCB(EBook *book, EBookStatus status, gpointer closure) |
406 static void delContactCB(EBook *book, EBookStatus status, gpointer closure) |
369 { |
407 { |
370 Q_UNUSED(book); |
408 Q_UNUSED(book); |
373 jobSharedData *sd = static_cast<jobSharedData*>(closure); |
411 jobSharedData *sd = static_cast<jobSharedData*>(closure); |
374 if (!sd) |
412 if (!sd) |
375 return; |
413 return; |
376 |
414 |
377 *sd->result = (status != E_BOOK_ERROR_OK && |
415 *sd->result = (status != E_BOOK_ERROR_OK && |
378 status != E_BOOK_ERROR_CONTACT_NOT_FOUND) ? false : true; |
416 status != E_BOOK_ERROR_CONTACT_NOT_FOUND) ? false : true; |
|
417 *sd->error = getErrorFromStatus(status); |
|
418 |
379 sd->that->_jobRemovingCompleted(); |
419 sd->that->_jobRemovingCompleted(); |
380 } |
420 } |
381 |
421 |
382 //### FIXME error is not managed |
|
383 bool QContactABook::removeContact(const QContactLocalId& contactId, QContactManager::Error* error) |
422 bool QContactABook::removeContact(const QContactLocalId& contactId, QContactManager::Error* error) |
384 { |
423 { |
385 Q_UNUSED(error); |
424 Q_UNUSED(error); |
386 QMutexLocker locker(&m_delContactMutex); |
425 QMutexLocker locker(&m_delContactMutex); |
387 |
426 |
388 bool ok = false; |
427 bool ok = false; |
389 |
428 |
390 OssoABookRoster *roster = A_ROSTER(m_abookAgregator); |
429 OssoABookRoster *roster = A_ROSTER(m_abookAgregator); |
391 EBook *book = osso_abook_roster_get_book(roster); |
430 EBook *book = osso_abook_roster_get_book(roster); |
392 OssoABookContact *aContact = getAContact(contactId); |
431 OssoABookContact *aContact = getAContact(contactId, error); |
393 if (!OSSO_ABOOK_IS_CONTACT(aContact)){ |
432 if (!OSSO_ABOOK_IS_CONTACT(aContact)){ |
394 qWarning() << "aCtontact is not a valid ABook contact"; |
433 //qWarning() << "Specified contact is not a valid ABook contact"; |
395 return false; |
434 return false; |
396 } |
435 } |
397 |
436 |
398 // ASync => Sync |
437 // ASync => Sync |
399 QEventLoop loop; |
438 QEventLoop loop; |
405 m_deleteJobSD = 0; |
444 m_deleteJobSD = 0; |
406 } |
445 } |
407 m_deleteJobSD = new jobSharedData; |
446 m_deleteJobSD = new jobSharedData; |
408 m_deleteJobSD->that = this; |
447 m_deleteJobSD->that = this; |
409 m_deleteJobSD->result = &ok; |
448 m_deleteJobSD->result = &ok; |
|
449 m_deleteJobSD->error = error; |
410 |
450 |
411 //Remove photos |
451 //Remove photos |
412 EContactPhoto *photo = NULL; |
452 EContactPhoto *photo = NULL; |
413 GFile *file = NULL; |
453 GFile *file = NULL; |
414 photo = (EContactPhoto*) e_contact_get(E_CONTACT (aContact), E_CONTACT_PHOTO); |
454 photo = (EContactPhoto*) e_contact_get(E_CONTACT (aContact), E_CONTACT_PHOTO); |
423 |
463 |
424 //Remove all roster contacts from their roster |
464 //Remove all roster contacts from their roster |
425 GList* rosterContacts = NULL; |
465 GList* rosterContacts = NULL; |
426 rosterContacts = osso_abook_contact_get_roster_contacts(aContact); |
466 rosterContacts = osso_abook_contact_get_roster_contacts(aContact); |
427 const char *masterUid = CONST_CHAR(e_contact_get_const(E_CONTACT(aContact), E_CONTACT_UID)); |
467 const char *masterUid = CONST_CHAR(e_contact_get_const(E_CONTACT(aContact), E_CONTACT_UID)); |
|
468 char *contactUidCopy = strdup(masterUid); |
428 while(rosterContacts){ |
469 while(rosterContacts){ |
429 OssoABookContact *rosterContact = A_CONTACT(rosterContacts->data); |
470 OssoABookContact *rosterContact = A_CONTACT(rosterContacts->data); |
430 osso_abook_contact_reject_for_uid(rosterContact, masterUid, NULL); |
471 osso_abook_contact_reject_for_uid(rosterContact, masterUid, NULL); |
431 rosterContacts = rosterContacts->next; |
472 rosterContacts = rosterContacts->next; |
432 } |
473 } |
434 // Remove contact |
475 // Remove contact |
435 e_book_async_remove_contact(book, E_CONTACT(aContact), |
476 e_book_async_remove_contact(book, E_CONTACT(aContact), |
436 delContactCB, m_deleteJobSD); |
477 delContactCB, m_deleteJobSD); |
437 |
478 |
438 loop.exec(QEventLoop::AllEvents|QEventLoop::WaitForMoreEvents); |
479 loop.exec(QEventLoop::AllEvents|QEventLoop::WaitForMoreEvents); |
|
480 |
|
481 // update our list of ids... |
|
482 QContactLocalId id = m_localIds[contactUidCopy]; |
|
483 m_localIds.remove(contactUidCopy); |
|
484 if (contactUidCopy) |
|
485 free(contactUidCopy); |
|
486 |
|
487 if (id) |
|
488 _contactsRemoved(QList<QContactLocalId>() << id); |
439 |
489 |
440 return ok; |
490 return ok; |
441 } |
491 } |
442 |
492 |
443 static void commitContactCB(EBook* book, EBookStatus status, gpointer user_data) |
493 static void commitContactCB(EBook* book, EBookStatus status, gpointer user_data) |
444 { |
494 { |
445 Q_UNUSED(book) |
495 Q_UNUSED(book) |
446 jobSharedData *sd = static_cast<jobSharedData*>(user_data); |
496 jobSharedData *sd = static_cast<jobSharedData*>(user_data); |
447 |
497 if (!sd) |
448 *sd->result = (status == E_BOOK_ERROR_OK) ? true : false; |
498 return; |
|
499 |
|
500 *sd->result = (status == E_BOOK_ERROR_OK) ? true : false; |
|
501 *sd->error = getErrorFromStatus(status); |
449 sd->that->_jobSavingCompleted(); |
502 sd->that->_jobSavingCompleted(); |
450 } |
503 } |
451 |
504 |
452 static void addContactCB(EBook* book, EBookStatus status, const char *uid, gpointer user_data) |
505 static void addContactCB(EBook* book, EBookStatus status, const char *uid, gpointer user_data) |
453 { |
506 { |
454 jobSharedData *sd = static_cast<jobSharedData*>(user_data); |
507 jobSharedData *sd = static_cast<jobSharedData*>(user_data); |
|
508 if (!sd) |
|
509 return; |
|
510 |
455 if (uid) |
511 if (uid) |
456 sd->uid = strdup(uid); |
512 sd->uid = strdup(uid); |
457 |
513 |
458 //osso_abook_contact_set_roster(OssoABookContact *contact, OssoABookRoster *roster) |
514 //### FIXME IS THIS LINE REALLY NEEDED: osso_abook_contact_set_roster(OssoABookContact *contact, OssoABookRoster *roster) |
|
515 *sd->result = (status == E_BOOK_ERROR_OK) ? true : false; |
459 commitContactCB(book, status, user_data); |
516 commitContactCB(book, status, user_data); |
460 } |
517 } |
461 |
518 |
462 bool QContactABook::saveContact(QContact* contact, QContactManager::Error* error) |
519 bool QContactABook::saveContact(QContact* contact, QContactManager::Error* error) |
463 { |
520 { |
495 m_saveJobSD = 0; |
551 m_saveJobSD = 0; |
496 } |
552 } |
497 m_saveJobSD = new jobSharedData; |
553 m_saveJobSD = new jobSharedData; |
498 m_saveJobSD->that = this; |
554 m_saveJobSD->that = this; |
499 m_saveJobSD->result = &ok; |
555 m_saveJobSD->result = &ok; |
|
556 m_saveJobSD->error = error; |
|
557 m_saveJobSD->uid = 0; |
500 |
558 |
501 // Add/Commit the contact |
559 // Add/Commit the contact |
502 uid = CONST_CHAR(e_contact_get_const(E_CONTACT (aContact), E_CONTACT_UID)); |
560 uid = CONST_CHAR(e_contact_get_const(E_CONTACT (aContact), E_CONTACT_UID)); |
503 if (uid) { |
561 if (uid) { |
|
562 m_saveJobSD->uid = strdup(uid); |
504 osso_abook_contact_async_commit(aContact, book, commitContactCB, m_saveJobSD); |
563 osso_abook_contact_async_commit(aContact, book, commitContactCB, m_saveJobSD); |
505 } else { |
564 } else { |
506 osso_abook_contact_async_add(aContact, book, addContactCB, m_saveJobSD); |
565 osso_abook_contact_async_add(aContact, book, addContactCB, m_saveJobSD); |
507 } |
566 } |
508 |
567 |
509 loop.exec(QEventLoop::AllEvents|QEventLoop::WaitForMoreEvents); |
568 loop.exec(QEventLoop::AllEvents|QEventLoop::WaitForMoreEvents); |
|
569 |
|
570 // save the newly saved contact's id in the hash. |
|
571 m_localIds << m_saveJobSD->uid; |
510 |
572 |
511 // set the id of the contact. |
573 // set the id of the contact. |
512 QContactId cId; |
574 QContactId cId; |
513 cId.setLocalId(m_localIds[m_saveJobSD->uid]); |
575 cId.setLocalId(m_localIds[m_saveJobSD->uid]); |
514 contact->setId(cId); |
576 contact->setId(cId); |
515 //free(m_saveJobSD->uid); |
577 if (m_saveJobSD->uid) |
|
578 free(m_saveJobSD->uid); |
516 |
579 |
517 return ok; |
580 return ok; |
518 } |
581 } |
519 |
582 |
520 QContactLocalId QContactABook::selfContactId(QContactManager::Error* errors) const |
583 QContactLocalId QContactABook::selfContactId(QContactManager::Error* errors) const |
532 m_localIds << eContactUID; //FIXME MemLeak |
595 m_localIds << eContactUID; //FIXME MemLeak |
533 id = m_localIds[eContactUID]; |
596 id = m_localIds[eContactUID]; |
534 QCM5_DEBUG << "eContactID " << eContactUID << "has been stored in m_localIDs with key" << id; |
597 QCM5_DEBUG << "eContactID " << eContactUID << "has been stored in m_localIDs with key" << id; |
535 } |
598 } |
536 } else { |
599 } else { |
537 qWarning() << "Cannot find self contact"; |
600 //qWarning() << "Cannot find self contact"; |
538 *errors = QContactManager::DoesNotExistError; |
601 *errors = QContactManager::DoesNotExistError; |
539 id = 0; |
602 id = 0; |
540 } |
603 } |
541 g_object_unref(self); |
604 g_object_unref(self); |
542 return id; |
605 return id; |
543 } |
|
544 |
|
545 bool QContactABook::contactActionsMatch(OssoABookContact *contact, QList<QContactActionDescriptor> descriptors) const |
|
546 { |
|
547 OssoABookCapsFlags capsFlags = osso_abook_caps_get_capabilities(OSSO_ABOOK_CAPS(contact)); |
|
548 |
|
549 if(capsFlags & OSSO_ABOOK_CAPS_NONE) |
|
550 return false; |
|
551 |
|
552 /* ActionNames could be incorrect */ |
|
553 OssoABookCapsFlags actionFlags = OSSO_ABOOK_CAPS_NONE; |
|
554 for(int i = 0; i < descriptors.size(); i++){ |
|
555 QString actionName = descriptors.at(i).actionName(); |
|
556 QCM5_DEBUG << actionName; |
|
557 if(!actionName.compare("Phone")) |
|
558 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_PHONE); |
|
559 else if(!actionName.compare("Voice")) |
|
560 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_VOICE); |
|
561 else if(!actionName.compare("SendEmail")) |
|
562 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_EMAIL); |
|
563 else if(!actionName.compare("Chat")) |
|
564 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_CHAT); |
|
565 else if(!actionName.compare("ChatAdditional")) |
|
566 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_CHAT_ADDITIONAL); |
|
567 else if(!actionName.compare("VoiceAdditional")) |
|
568 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_VOICE_ADDITIONAL); |
|
569 else if(!actionName.compare("Video")) |
|
570 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_VIDEO); |
|
571 else if(!actionName.compare("Addressbook")) |
|
572 actionFlags = (OssoABookCapsFlags)(actionFlags | OSSO_ABOOK_CAPS_ADDRESSBOOK); |
|
573 } |
|
574 return ((actionFlags & capsFlags) == actionFlags); |
|
575 } |
606 } |
576 |
607 |
577 EBookQuery* QContactABook::convert(const QContactFilter& filter) const |
608 EBookQuery* QContactABook::convert(const QContactFilter& filter) const |
578 { |
609 { |
579 EBookQuery* query = NULL; |
610 EBookQuery* query = NULL; |
624 case QContactFilter::MatchExactly: queryStr = "is"; break; |
655 case QContactFilter::MatchExactly: queryStr = "is"; break; |
625 case QContactFilter::MatchStartsWith: queryStr = "beginswith"; break; |
656 case QContactFilter::MatchStartsWith: queryStr = "beginswith"; break; |
626 case QContactFilter::MatchEndsWith: queryStr = "endswith"; break; |
657 case QContactFilter::MatchEndsWith: queryStr = "endswith"; break; |
627 default: |
658 default: |
628 queryStr = "contains"; |
659 queryStr = "contains"; |
629 qWarning() << "Match flag not supported"; |
660 //qWarning() << "Match flag not supported"; |
630 } |
661 } |
631 static QHash<QString,QString> hash; |
662 static QHash<QString,QString> hash; |
632 if (hash.isEmpty()){ |
663 if (hash.isEmpty()){ |
633 hash[QContactAddress::DefinitionName] = "address"; |
664 hash[QContactAddress::DefinitionName] = "address"; |
634 hash[QContactBirthday::DefinitionName] = "birth-date"; |
665 hash[QContactBirthday::DefinitionName] = "birth-date"; |
642 hash[QContactUrl::DefinitionName] = "homepage-url"; |
673 hash[QContactUrl::DefinitionName] = "homepage-url"; |
643 } |
674 } |
644 |
675 |
645 QString eDetail = hash[f.detailDefinitionName()]; |
676 QString eDetail = hash[f.detailDefinitionName()]; |
646 if (eDetail.isEmpty()){ |
677 if (eDetail.isEmpty()){ |
647 qWarning() << "Unable to found an ebook detail for " << f.detailDefinitionName(); |
678 //qWarning() << "Unable to found an ebook detail for " << f.detailDefinitionName(); |
648 return NULL; |
679 return NULL; |
649 } |
680 } |
650 queryStr = queryStr + " \"" + eDetail + "\" \"" + f.value().toString() + "\""; |
681 queryStr = queryStr + " \"" + eDetail + "\" \"" + f.value().toString() + "\""; |
651 query = e_book_query_from_string(qPrintable(queryStr)); |
682 query = e_book_query_from_string(qPrintable(queryStr)); |
652 } break; |
683 } break; |
653 case QContactFilter::ActionFilter: |
684 case QContactFilter::ActionFilter: |
654 QCM5_DEBUG << "ActionFilter"; //eQuery doesn't support ActionFilter |
|
655 break; |
685 break; |
656 case QContactFilter::IntersectionFilter: |
686 case QContactFilter::IntersectionFilter: |
657 { |
687 { |
658 QCM5_DEBUG << "IntersectionFilter"; |
688 QCM5_DEBUG << "IntersectionFilter"; |
659 const QContactIntersectionFilter f(filter); |
689 const QContactIntersectionFilter f(filter); |
660 const QList<QContactFilter> fs= f.filters(); |
690 const QList<QContactFilter> fs= f.filters(); |
661 QContactFilter i; |
691 QContactFilter i; |
662 foreach(i, fs){ |
692 foreach(i, fs){ |
663 EBookQuery* q = convert(i); |
693 EBookQuery* q = convert(i); |
664 if (!q){ |
694 if (!q){ |
665 qWarning() << "Query is null"; |
695 //qWarning() << "Query is null"; |
666 continue; |
696 continue; |
667 } |
697 } |
668 if (query) |
698 if (query) |
669 query = e_book_query_andv(query, q, NULL); |
699 query = e_book_query_andv(query, q, NULL); |
670 else |
700 else |
694 QCM5_DEBUG << "InvalidFilter"; |
724 QCM5_DEBUG << "InvalidFilter"; |
695 query = e_book_query_from_string("(is \"id\" \"-1\")"); |
725 query = e_book_query_from_string("(is \"id\" \"-1\")"); |
696 } break; |
726 } break; |
697 default: |
727 default: |
698 QCM5_DEBUG << "Filter not supported"; |
728 QCM5_DEBUG << "Filter not supported"; |
|
729 query = convert(QContactInvalidFilter()); |
699 } |
730 } |
700 |
731 |
701 //Debugging |
732 //Debugging |
702 const char *queryString = e_book_query_to_string(query); |
733 const char *queryString = e_book_query_to_string(query); |
703 QCM5_DEBUG << "QUERY" << queryString; |
734 QCM5_DEBUG << "QUERY" << queryString; |
810 if (detail->isEmpty()) |
841 if (detail->isEmpty()) |
811 return false; |
842 return false; |
812 return true; |
843 return true; |
813 } |
844 } |
814 |
845 |
815 OssoABookContact* QContactABook::getAContact(const QContactLocalId& contactId) const |
846 OssoABookContact* QContactABook::getAContact(const QContactLocalId& contactId, QContactManager::Error* error) const |
816 { |
847 { |
817 OssoABookContact* rtn = NULL; |
848 OssoABookContact* rtn = NULL; |
818 |
849 |
819 QCM5_DEBUG << "Getting aContact with id " << m_localIds[contactId] << "local contactId is" << contactId; |
850 QCM5_DEBUG << "Getting aContact with id " << m_localIds[contactId] << "local contactId is" << contactId; |
820 |
851 |
821 if(QString(m_localIds[contactId]).compare("osso-abook-self") == 0) { |
852 if(QString(m_localIds[contactId]).compare("osso-abook-self") == 0) { |
|
853 *error = QContactManager::NoError; |
822 rtn = A_CONTACT(osso_abook_self_contact_get_default()); |
854 rtn = A_CONTACT(osso_abook_self_contact_get_default()); |
823 } else { |
855 } else { |
824 EBookQuery* query; |
856 EBookQuery* query; |
825 GList* contacts; |
857 GList* contacts; |
826 |
858 |
828 contacts = osso_abook_aggregator_find_contacts(m_abookAgregator, query); |
860 contacts = osso_abook_aggregator_find_contacts(m_abookAgregator, query); |
829 if (query) |
861 if (query) |
830 e_book_query_unref(query); |
862 e_book_query_unref(query); |
831 |
863 |
832 if (g_list_length(contacts) == 1) { |
864 if (g_list_length(contacts) == 1) { |
|
865 *error = QContactManager::NoError; |
833 rtn = A_CONTACT(contacts->data); |
866 rtn = A_CONTACT(contacts->data); |
|
867 } else if (g_list_length(contacts) == 0) { |
|
868 *error = QContactManager::DoesNotExistError; |
834 } else { |
869 } else { |
835 qWarning("List is empty or several contacts have the same UID or contactId belongs to a roster contact."); |
870 //qWarning("Several contacts have the same UID or contactId belongs to a roster contact."); |
|
871 *error = QContactManager::UnspecifiedError; |
836 } |
872 } |
837 if (contacts) |
873 if (contacts) |
838 g_list_free(contacts); |
874 g_list_free(contacts); |
839 } |
875 } |
840 |
876 |
848 { |
884 { |
849 const char* data = CONST_CHAR(e_contact_get_const(eContact, E_CONTACT_UID)); |
885 const char* data = CONST_CHAR(e_contact_get_const(eContact, E_CONTACT_UID)); |
850 const QByteArray eContactUID(data); |
886 const QByteArray eContactUID(data); |
851 QContactLocalId localId = m_localIds[eContactUID]; |
887 QContactLocalId localId = m_localIds[eContactUID]; |
852 if (!localId) |
888 if (!localId) |
853 qWarning("Unable to get valid localId for the specified eContaact UID"); |
889 //qWarning("Unable to get valid localId for the specified eContaact UID"); |
854 rtn.setLocalId(localId); |
890 rtn.setLocalId(localId); |
855 } |
891 } |
856 return rtn; |
892 return rtn; |
857 } |
893 } |
858 |
894 |
861 QList<QContactAddress*> rtnList; |
897 QList<QContactAddress*> rtnList; |
862 |
898 |
863 //Ordered list of Fields |
899 //Ordered list of Fields |
864 QStringList addressFields; |
900 QStringList addressFields; |
865 addressFields << QContactAddress::FieldPostOfficeBox |
901 addressFields << QContactAddress::FieldPostOfficeBox |
866 << "Estension" //FIXME I'm not sure we have to use a new field |
902 << AddressFieldExtension //XXX FIXME I'm not sure we have to use a new field |
867 << QContactAddress::FieldStreet |
903 << QContactAddress::FieldStreet |
868 << QContactAddress::FieldLocality |
904 << QContactAddress::FieldLocality |
869 << QContactAddress::FieldRegion |
905 << QContactAddress::FieldRegion |
870 << QContactAddress::FieldPostcode |
906 << QContactAddress::FieldPostcode |
871 << QContactAddress::FieldCountry; |
907 << QContactAddress::FieldCountry; |
931 EContactName* eContactName = static_cast<EContactName*> (e_contact_get(eContact, E_CONTACT_NAME)); |
967 EContactName* eContactName = static_cast<EContactName*> (e_contact_get(eContact, E_CONTACT_NAME)); |
932 if (eContactName){ |
968 if (eContactName){ |
933 map[QContactName::FieldCustomLabel] = eContactName->additional; |
969 map[QContactName::FieldCustomLabel] = eContactName->additional; |
934 map[QContactName::FieldFirstName] = eContactName->given; |
970 map[QContactName::FieldFirstName] = eContactName->given; |
935 map[QContactName::FieldLastName] = eContactName->family; |
971 map[QContactName::FieldLastName] = eContactName->family; |
936 //map[QContactName::FieldMiddleName] = eContactName-> |
|
937 map[QContactName::FieldPrefix] = eContactName->prefixes; |
972 map[QContactName::FieldPrefix] = eContactName->prefixes; |
938 map[QContactName::FieldSuffix] = eContactName->suffixes; |
973 map[QContactName::FieldSuffix] = eContactName->suffixes; |
939 e_contact_name_free (eContactName); |
974 e_contact_name_free (eContactName); |
940 } else { |
975 } else { |
941 //Looks that Maemo use just these two fields |
976 //Looks that Maemo use just these two fields |
1192 |
1227 |
1193 if(!ossoValidIsOk) |
1228 if(!ossoValidIsOk) |
1194 attrIsOssoValid = paramName.contains("X-OSSO-VALID"); |
1229 attrIsOssoValid = paramName.contains("X-OSSO-VALID"); |
1195 |
1230 |
1196 if (!attrIsType && !attrIsOssoValid) { |
1231 if (!attrIsType && !attrIsOssoValid) { |
1197 qWarning () << "Skipping attribute parameter checking for" << paramName; |
1232 //qWarning () << "Skipping attribute parameter checking for" << paramName; |
1198 continue; |
1233 continue; |
1199 } |
1234 } |
1200 |
1235 |
1201 GList *values = e_vcard_attribute_param_get_values(p); |
1236 GList *values = e_vcard_attribute_param_get_values(p); |
1202 GList *node; |
1237 GList *node; |
1203 for (node = values; node != NULL; node = g_list_next (node)) { |
1238 for (node = values; node != NULL; node = g_list_next (node)) { |
1204 QString attributeParameterValue = QString::fromLatin1(CONST_CHAR(node->data)); |
1239 QString attributeParameterValue = QString::fromLatin1(CONST_CHAR(node->data)); |
1205 if (attrIsOssoValid) { |
1240 if (attrIsOssoValid) { |
1206 ossoValidIsOk = (attributeParameterValue == "yes")? true : false; |
1241 ossoValidIsOk = (attributeParameterValue == "yes")? true : false; |
1207 if (!ossoValidIsOk) { |
1242 if (!ossoValidIsOk) { |
1208 qWarning() << "X-OSSO-VALID is false."; |
1243 //qWarning() << "X-OSSO-VALID is false."; |
1209 break; |
1244 break; |
1210 } |
1245 } |
1211 } else if (type.isEmpty()) { |
1246 } else if (type.isEmpty()) { |
1212 type = attributeParameterValue; |
1247 type = attributeParameterValue; |
1213 if (type.isEmpty()) |
1248 if (type.isEmpty()) |
1231 |
1266 |
1232 QContactOrganization* QContactABook::getOrganizationDetail(EContact *eContact) const |
1267 QContactOrganization* QContactABook::getOrganizationDetail(EContact *eContact) const |
1233 { |
1268 { |
1234 QContactOrganization* rtn = new QContactOrganization; |
1269 QContactOrganization* rtn = new QContactOrganization; |
1235 QVariantMap map; |
1270 QVariantMap map; |
1236 const char* title = CONST_CHAR(e_contact_get(eContact, E_CONTACT_TITLE)); |
1271 const char* title = CONST_CHAR(e_contact_get(eContact, E_CONTACT_ORG)); |
1237 map[QContactOrganization::FieldTitle] = title; |
1272 map[QContactOrganization::FieldTitle] = title; |
1238 FREE(title); |
1273 FREE(title); |
1239 setDetailValues(map, rtn); |
1274 setDetailValues(map, rtn); |
1240 return rtn; |
1275 return rtn; |
1241 } |
1276 } |
1377 |
1412 |
1378 if(!ossoValidIsOk) |
1413 if(!ossoValidIsOk) |
1379 attrIsOssoValid = paramName.contains("X-OSSO-VALID"); |
1414 attrIsOssoValid = paramName.contains("X-OSSO-VALID"); |
1380 |
1415 |
1381 if (!attrIsType && !attrIsOssoValid) { |
1416 if (!attrIsType && !attrIsOssoValid) { |
1382 qWarning () << "Skipping attribute parameter checking for" << paramName; |
1417 //qWarning () << "Skipping attribute parameter checking for" << paramName; |
1383 continue; |
1418 continue; |
1384 } |
1419 } |
1385 |
1420 |
1386 GList *values = e_vcard_attribute_param_get_values(p); |
1421 GList *values = e_vcard_attribute_param_get_values(p); |
1387 GList *node; |
1422 GList *node; |
1388 for (node = values; node != NULL; node = g_list_next (node)) { |
1423 for (node = values; node != NULL; node = g_list_next (node)) { |
1389 QString attributeParameterValue = QString::fromLatin1(CONST_CHAR(node->data)); |
1424 QString attributeParameterValue = QString::fromLatin1(CONST_CHAR(node->data)); |
1390 if (attrIsOssoValid) { |
1425 if (attrIsOssoValid) { |
1391 ossoValidIsOk = (attributeParameterValue == "yes")? true : false; |
1426 ossoValidIsOk = (attributeParameterValue == "yes")? true : false; |
1392 if (!ossoValidIsOk) { |
1427 if (!ossoValidIsOk) { |
1393 qWarning() << "X-OSSO-VALID is false."; |
1428 //qWarning() << "X-OSSO-VALID is false."; |
1394 break; |
1429 break; |
1395 } |
1430 } |
1396 } else if (type.isEmpty()) { |
1431 } else if (type.isEmpty()) { |
1397 type = attributeParameterValue; |
1432 type = attributeParameterValue; |
1398 if (type.isEmpty()) |
1433 if (type.isEmpty()) |
1566 QCM5_DEBUG << "Modified VCard" << dbgStr; |
1601 QCM5_DEBUG << "Modified VCard" << dbgStr; |
1567 FREE(dbgStr); |
1602 FREE(dbgStr); |
1568 } |
1603 } |
1569 } |
1604 } |
1570 |
1605 |
1571 OssoABookContact* QContactABook::convert(const QContact *contact) const |
1606 OssoABookContact* QContactABook::convert(const QContact *contact, QContactManager::Error* error) const |
1572 { |
1607 { |
1573 Q_CHECK_PTR(contact); |
1608 Q_CHECK_PTR(contact); |
1574 |
1609 |
1575 OssoABookContact* rtn; |
1610 OssoABookContact* rtn; |
1576 |
1611 |
1577 // Get aContact if it exists or create a new one if it doesn't |
1612 // Get aContact if it exists or create a new one if it doesn't |
1578 QContactLocalId id = contact->localId(); |
1613 QContactLocalId id = contact->localId(); |
1579 QCM5_DEBUG << "Converting QContact id:" << id << " to aContact"; |
1614 QCM5_DEBUG << "Converting QContact id:" << id << " to aContact"; |
1580 if (id){ |
1615 if (id) { |
1581 rtn = getAContact(id); |
1616 rtn = getAContact(id, error); |
1582 // It's not safe to commit changes to a contact that has been modified. |
|
1583 // This problem affects attributes with the same name and parameters such as |
|
1584 // EMail, Address... |
|
1585 QContactTimestamp* ts = getTimestampDetail(E_CONTACT(rtn)); |
|
1586 if (*ts != contact->detail<QContactTimestamp>()){ |
|
1587 delete ts; |
|
1588 return NULL; |
|
1589 } |
|
1590 delete ts; |
|
1591 } else { |
1617 } else { |
1592 rtn = osso_abook_contact_new(); |
1618 rtn = osso_abook_contact_new(); |
1593 } |
1619 } |
1594 |
1620 |
1595 QList<QContactDetail> allDetails = contact->details(); |
1621 QList<QContactDetail> allDetails = contact->details(); |
1669 i.next(); |
1695 i.next(); |
1670 int index = -1; |
1696 int index = -1; |
1671 QString key = i.key(); |
1697 QString key = i.key(); |
1672 |
1698 |
1673 if (key == QContactAddress::FieldPostOfficeBox) index = 0; |
1699 if (key == QContactAddress::FieldPostOfficeBox) index = 0; |
1674 else if (key == "Estension") index = 1; |
1700 else if (key == AddressFieldExtension) index = 1; |
1675 else if (key == QContactAddress::FieldStreet) index = 2; |
1701 else if (key == QContactAddress::FieldStreet) index = 2; |
1676 else if (key == QContactAddress::FieldLocality) index = 3; |
1702 else if (key == QContactAddress::FieldLocality) index = 3; |
1677 else if (key == QContactAddress::FieldRegion) index = 4; |
1703 else if (key == QContactAddress::FieldRegion) index = 4; |
1678 else if (key == QContactAddress::FieldPostcode) index = 5; |
1704 else if (key == QContactAddress::FieldPostcode) index = 5; |
1679 else if (key == QContactAddress::FieldCountry) index = 6; |
1705 else if (key == QContactAddress::FieldCountry) index = 6; |
1680 else if (key == QContactDetail::FieldContext) continue; |
1706 else if (key == QContactDetail::FieldContext) continue; |
1681 else if (key == QContactDetail::FieldDetailUri) detailUri = i.value().toInt(); |
1707 else if (key == QContactDetail::FieldDetailUri) detailUri = i.value().toInt(); |
1682 else { |
1708 else { |
1683 qWarning() << "Address contains an invalid field:" << key; |
1709 //qWarning() << "Address contains an invalid field:" << key; |
1684 return; |
1710 return; |
1685 } |
1711 } |
1686 |
1712 |
1687 if (index != -1) |
1713 if (index != -1) |
1688 adrAttrValues[index] = i.value().toString(); |
1714 adrAttrValues[index] = i.value().toString(); |
1821 |
1847 |
1822 QStringList attrValues; |
1848 QStringList attrValues; |
1823 // Save First and Last name in the N vcard attribute |
1849 // Save First and Last name in the N vcard attribute |
1824 { |
1850 { |
1825 QStringList supportedDetailValues; |
1851 QStringList supportedDetailValues; |
1826 supportedDetailValues << QContactName::FieldFirstName << QContactName::FieldLastName; |
1852 supportedDetailValues << QContactName::FieldLastName << QContactName::FieldFirstName; |
1827 |
1853 |
1828 foreach(QString key, supportedDetailValues){ |
1854 foreach(QString key, supportedDetailValues){ |
1829 attrValues << detail.value(key); |
1855 attrValues << detail.value(key); |
1830 } |
1856 } |
1831 |
1857 |
1832 //REMOVE ME - We don't want to support custom label |
1858 //REMOVE ME - We don't want to support custom label |
1833 if (attrValues[0].isEmpty()){ |
1859 if (attrValues[1].isEmpty()){ |
1834 qWarning() << "QContactName::FieldFirstName is empty"; |
1860 //qWarning() << "QContactName::FieldFirstName is empty"; |
1835 attrValues[0] = detail.customLabel(); |
1861 attrValues[1] = detail.customLabel(); |
1836 } |
1862 } |
1837 |
1863 |
1838 addAttributeToAContact(aContact, EVC_N, attrValues); |
1864 addAttributeToAContact(aContact, EVC_N, attrValues); |
1839 } |
1865 } |
1840 |
1866 |
1905 if (key == QContactDetail::FieldContext || |
1931 if (key == QContactDetail::FieldContext || |
1906 key == QContactPhoneNumber::FieldSubTypes){ |
1932 key == QContactPhoneNumber::FieldSubTypes){ |
1907 QString value = i.value().toString(); |
1933 QString value = i.value().toString(); |
1908 if (value == QContactPhoneNumber::SubTypeMobile) |
1934 if (value == QContactPhoneNumber::SubTypeMobile) |
1909 value = "CELL"; |
1935 value = "CELL"; |
|
1936 else if (value == QContactPhoneNumber::SubTypeVoice) |
|
1937 value = "VOICE"; |
1910 paramValues << value.toUpper(); |
1938 paramValues << value.toUpper(); |
1911 } else |
1939 } else |
1912 attrValues << i.value().toString(); |
1940 attrValues << i.value().toString(); |
1913 } |
1941 } |
1914 |
1942 |
1915 // Avoid unsupported type |
1943 // Avoid unsupported type |
1916 if (paramValues.isEmpty()) |
1944 if (paramValues.isEmpty()) |
1917 paramValues << "VOICE"; |
1945 paramValues << "VOICE"; |
1918 |
1946 |
1919 addAttributeToAContact(aContact, EVC_TEL, attrValues, EVC_TYPE, paramValues, true, detail.detailUri().toInt()); |
1947 addAttributeToAContact(aContact, EVC_TEL, attrValues, EVC_TYPE, paramValues, false, detail.detailUri().toInt()); |
1920 } |
1948 } |
1921 |
1949 |
1922 void QContactABook::setUrlDetail(const OssoABookContact* aContact, const QContactUrl& detail) const |
1950 void QContactABook::setUrlDetail(const OssoABookContact* aContact, const QContactUrl& detail) const |
1923 { |
1951 { |
1924 if (!aContact) return; |
1952 if (!aContact) return; |