Merge lp:~renatofilho/address-book-service/fix-edit into lp:address-book-service

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Bill Filler
Approved revision: no longer in the source branch.
Merged at revision: 36
Proposed branch: lp:~renatofilho/address-book-service/fix-edit
Merge into: lp:address-book-service
Prerequisite: lp:~renatofilho/address-book-service/wait-for-server
Diff against target: 2729 lines (+1310/-735)
11 files modified
common/vcard-parser.cpp (+46/-8)
common/vcard-parser.h (+2/-0)
src/addressbook-adaptor.h (+4/-4)
src/addressbook.cpp (+68/-70)
src/addressbook.h (+8/-3)
src/contacts-map.cpp (+11/-0)
src/contacts-map.h (+1/-0)
src/qindividual.cpp (+1107/-622)
src/qindividual.h (+56/-26)
src/view-adaptor.h (+2/-2)
src/view.cpp (+5/-0)
To merge this branch: bzr merge lp:~renatofilho/address-book-service/fix-edit
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Bill Filler (community) Approve
Review via email: mp+170609@code.launchpad.net

This proposal supersedes a proposal from 2013-06-17.

Commit message

Added support to edit contacts with multiple persona.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Bill Filler (bfiller) wrote :

approved

review: Approve
35. By Renato Araujo Oliveira Filho

Fixed qcontacts plugins to wait for server fully start before request any data.

Approved by PS Jenkins bot, Bill Filler.

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)
36. By Renato Araujo Oliveira Filho

Added support to edit contacts with multiple persona.

Approved by PS Jenkins bot, Bill Filler.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'common/vcard-parser.cpp'
--- common/vcard-parser.cpp 2013-05-18 01:11:38 +0000
+++ common/vcard-parser.cpp 2013-06-20 20:58:26 +0000
@@ -55,7 +55,7 @@
5555
56 if (detail.type() == QContactDetail::TypeExtendedDetail) {56 if (detail.type() == QContactDetail::TypeExtendedDetail) {
57 const QContactExtendedDetail *extendedDetail = static_cast<const QContactExtendedDetail *>(&detail);57 const QContactExtendedDetail *extendedDetail = static_cast<const QContactExtendedDetail *>(&detail);
58 if (extendedDetail->name() == "CLIENTPIDMAP") {58 if (extendedDetail->name() == galera::VCardParser::PidMapFieldName) {
59 QVersitProperty prop;59 QVersitProperty prop;
60 prop.setName(extendedDetail->name());60 prop.setName(extendedDetail->name());
61 QStringList value;61 QStringList value;
@@ -70,11 +70,12 @@
70 }70 }
7171
72 if (!detail.detailUri().isEmpty()) {72 if (!detail.detailUri().isEmpty()) {
73 QVersitProperty prop = toBeAdded->takeLast();73 if (toBeAdded->size() > 0) {
74 QMultiHash<QString, QString> params = prop.parameters();74 QVersitProperty &prop = toBeAdded->last();
75 params.insert("PID", detail.detailUri());75 QMultiHash<QString, QString> params = prop.parameters();
76 prop.setParameters(params);76 params.insert(galera::VCardParser::PidFieldName, detail.detailUri());
77 *toBeAdded << prop;77 prop.setParameters(params);
78 }
78 }79 }
79 }80 }
8081
@@ -102,16 +103,50 @@
102 Q_UNUSED(document);103 Q_UNUSED(document);
103 Q_UNUSED(contact);104 Q_UNUSED(contact);
104105
105 if (!*alreadyProcessed && (property.name() == "CLIENTPIDMAP")) {106 if (!*alreadyProcessed && (property.name() == galera::VCardParser::PidMapFieldName)) {
106 QContactExtendedDetail detail;107 QContactExtendedDetail detail;
107 detail.setName(property.name());108 detail.setName(property.name());
108 QStringList value = property.value<QStringList>();109 QStringList value = property.value<QString>().split(";");
109 detail.setValue(QContactExtendedDetail::FieldData, value[0]);110 detail.setValue(QContactExtendedDetail::FieldData, value[0]);
110 detail.setValue(QContactExtendedDetail::FieldData + 1, value[1]);111 detail.setValue(QContactExtendedDetail::FieldData + 1, value[1]);
111 *updatedDetails << detail;112 *updatedDetails << detail;
112 *alreadyProcessed = true;113 *alreadyProcessed = true;
113 }114 }
114115
116 QString pid = property.parameters().value(galera::VCardParser::PidFieldName);
117 if (!pid.isEmpty()) {
118 QContactDetail &det = updatedDetails->last();
119 det.setDetailUri(pid);
120 }
121
122 // Remove empty phone and address subtypes
123 // Remove this after this fix get merged: https://codereview.qt-project.org/#change,59156
124 if (updatedDetails->size() > 0) {
125 QContactDetail &det = updatedDetails->last();
126 switch (det.type()) {
127 case QContactDetail::TypePhoneNumber:
128 {
129 QContactPhoneNumber phone = static_cast<QContactPhoneNumber>(det);
130 if (phone.subTypes().isEmpty()) {
131 det.setValue(QContactPhoneNumber::FieldSubTypes, QVariant());
132 }
133 break;
134 }
135 case QContactDetail::TypeAddress:
136 {
137 QContactAddress addr = static_cast<QContactAddress>(det);
138 if (addr.subTypes().isEmpty()) {
139 det.setValue(QContactAddress::FieldSubTypes, QVariant());
140 } else {
141 QSet<int> subtypes = addr.subTypes().toSet();
142 det.setValue(QContactAddress::FieldSubTypes, QVariant::fromValue<QList<int> >(subtypes.toList()));
143 }
144 break;
145 }
146 default:
147 break;
148 }
149 }
115 }150 }
116151
117 virtual void documentProcessed(const QVersitDocument& document, QContact* contact)152 virtual void documentProcessed(const QVersitDocument& document, QContact* contact)
@@ -125,6 +160,9 @@
125namespace galera160namespace galera
126{161{
127162
163const QString VCardParser::PidMapFieldName = QString("CLIENTPIDMAP");
164const QString VCardParser::PidFieldName = QString("PID");
165
128QStringList VCardParser::contactToVcard(QList<QtContacts::QContact> contacts)166QStringList VCardParser::contactToVcard(QList<QtContacts::QContact> contacts)
129{167{
130 QStringList result;168 QStringList result;
131169
=== modified file 'common/vcard-parser.h'
--- common/vcard-parser.h 2013-05-18 01:11:38 +0000
+++ common/vcard-parser.h 2013-06-20 20:58:26 +0000
@@ -29,6 +29,8 @@
29class VCardParser29class VCardParser
30{30{
31public:31public:
32 static const QString PidMapFieldName;
33 static const QString PidFieldName;
3234
33 static QStringList contactToVcard(QList<QtContacts::QContact> contacts);35 static QStringList contactToVcard(QList<QtContacts::QContact> contacts);
34 static QtContacts::QContact vcardToContact(const QString &vcard);36 static QtContacts::QContact vcardToContact(const QString &vcard);
3537
=== modified file 'src/addressbook-adaptor.h'
--- src/addressbook-adaptor.h 2013-06-20 20:58:26 +0000
+++ src/addressbook-adaptor.h 2013-06-20 20:58:26 +0000
@@ -99,13 +99,13 @@
9999
100public Q_SLOTS:100public Q_SLOTS:
101 SourceList availableSources();101 SourceList availableSources();
102 QStringList sortFields();
103 QDBusObjectPath query(const QString &clause, const QString &sort, const QStringList &sources);
104 int removeContacts(const QStringList &contactIds, const QDBusMessage &message);
102 QString createContact(const QString &contact, const QString &source, const QDBusMessage &message);105 QString createContact(const QString &contact, const QString &source, const QDBusMessage &message);
106 QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message);
103 QString linkContacts(const QStringList &contacts);107 QString linkContacts(const QStringList &contacts);
104 QDBusObjectPath query(const QString &clause, const QString &sort, const QStringList &sources);
105 int removeContacts(const QStringList &contactIds, const QDBusMessage &message);
106 QStringList sortFields();
107 bool unlinkContacts(const QString &parentId, const QStringList &contactsIds);108 bool unlinkContacts(const QString &parentId, const QStringList &contactsIds);
108 QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message);
109 bool isReady();109 bool isReady();
110110
111Q_SIGNALS:111Q_SIGNALS:
112112
=== modified file 'src/addressbook.cpp'
--- src/addressbook.cpp 2013-06-20 20:58:26 +0000
+++ src/addressbook.cpp 2013-06-20 20:58:26 +0000
@@ -26,7 +26,6 @@
2626
27#include <QtCore/QPair>27#include <QtCore/QPair>
28#include <QtCore/QUuid>28#include <QtCore/QUuid>
29#include <QtContacts/QContact>
3029
31using namespace QtContacts;30using namespace QtContacts;
3231
@@ -240,76 +239,75 @@
240239
241QStringList AddressBook::updateContacts(const QStringList &contacts, const QDBusMessage &message)240QStringList AddressBook::updateContacts(const QStringList &contacts, const QDBusMessage &message)
242{241{
243 UpdateContactsData *data = 0;242 //TODO: support multiple update contacts calls
244243 Q_ASSERT(m_updateCommandPendingContacts.isEmpty());
245 if (!contacts.isEmpty()) {244
246 data = new UpdateContactsData;245 qDebug() << "update contacts:" << contacts;
247 data->m_contacts = VCardParser::vcardToContact(contacts);246 m_updateCommandReplyMessage = message;
248 data->m_request = contacts;247 m_updateCommandResult = contacts;
249 data->m_currentIndex = -1;248 m_updateCommandPendingContacts << VCardParser::vcardToContact(contacts);
250 data->m_addressbook = this;249
251 data->m_message = message;250 updateContactsDone(0, QString());
252
253 }
254 updateContacts("", data);
255251
256 return QStringList();252 return QStringList();
257}253}
258254
259void AddressBook::updateContacts(const QString &error, void *userData)255void AddressBook::updateContactsDone(galera::QIndividual *individual, const QString &error)
260{256{
261 qDebug() << Q_FUNC_INFO << userData;257 Q_UNUSED(individual);
262 UpdateContactsData *data = static_cast<UpdateContactsData*>(userData);258 qDebug() << Q_FUNC_INFO;
263 QDBusMessage reply;259
264260 if (!error.isEmpty()) {
265 if (data) {261 // update the result with the error
266 if (!error.isEmpty()) {262 m_updateCommandResult[m_updateCommandResult.size() - m_updateCommandPendingContacts.size() - 1] = error;
267 data->m_result << error;263 }
268 } else if (data->m_currentIndex > -1) {264
269 data->m_result << data->m_request[data->m_currentIndex];265 if (!m_updateCommandPendingContacts.isEmpty()) {
270 }266 QContact newContact = m_updateCommandPendingContacts.takeFirst();
271267 ContactEntry *entry = m_contacts->value(newContact.detail<QContactGuid>().guid());
272 if (!data->m_contacts.isEmpty()) {268 if (entry) {
273 QContact newContact = data->m_contacts.takeFirst();269 entry->individual()->update(newContact, this, "updateContactsDone(galera::QIndividual*, const QString&)"); //));
274 data->m_currentIndex++;270 } else {
275271 updateContactsDone(0, "Contact not found!");
276 ContactEntry *entry = data->m_addressbook->m_contacts->value(newContact.detail<QContactGuid>().guid());272 }
277 if (entry) {
278 entry->individual()->update(newContact, updateContacts, userData);
279 } else {
280 updateContacts("Contact not found!", userData);
281 }
282 return;
283 }
284 folks_persona_store_flush(folks_individual_aggregator_get_primary_store(data->m_addressbook->m_individualAggregator), 0, 0);
285 reply = data->m_message.createReply(data->m_result);
286 } else {273 } else {
287 reply = data->m_message.createReply(QStringList());274 folks_persona_store_flush(folks_individual_aggregator_get_primary_store(m_individualAggregator), 0, 0);
275 QDBusMessage reply = m_updateCommandReplyMessage.createReply(m_updateCommandResult);
276 QDBusConnection::sessionBus().send(reply);
277
278 // clear command data
279 m_updateCommandResult.clear();
280 m_updateCommandReplyMessage = QDBusMessage();
288 }281 }
289
290 QDBusConnection::sessionBus().send(reply);
291 delete data;
292}282}
293283
294284
295QString AddressBook::removeContact(FolksIndividual *individual)285QString AddressBook::removeContact(FolksIndividual *individual)
296{286{
297 Q_ASSERT(m_contacts->contains(individual));287 if (m_contacts->contains(individual)) {
298 ContactEntry *ci = m_contacts->take(individual);288 ContactEntry *ci = m_contacts->take(individual);
299 if (ci) {289 if (ci) {
300 QString id = QString::fromUtf8(folks_individual_get_id(individual));290 QString id = QString::fromUtf8(folks_individual_get_id(individual));
301 delete ci;291 qDebug() << "Remove contact" << id;
302 return id;292 delete ci;
293 return id;
294 }
303 }295 }
304 return QString();296 return QString();
305}297}
306298
307QString AddressBook::addContact(FolksIndividual *individual)299QString AddressBook::addContact(FolksIndividual *individual)
308{300{
309 Q_ASSERT(!m_contacts->contains(individual));301 QString id = QString::fromUtf8(folks_individual_get_id(individual));
310 m_contacts->insert(new ContactEntry(new QIndividual(individual, m_individualAggregator)));302 ContactEntry *entry = m_contacts->value(id);
311 //TODO: Notify view303 if (entry) {
312 return QString::fromUtf8(folks_individual_get_id(individual));304 entry->individual()->setIndividual(individual);
305 } else {
306 m_contacts->insert(new ContactEntry(new QIndividual(individual, m_individualAggregator)));
307 qDebug() << "Add contact" << folks_individual_get_id(individual);
308 //TODO: Notify view
309 }
310 return id;
313}311}
314312
315void AddressBook::individualsChangedCb(FolksIndividualAggregator *individualAggregator,313void AddressBook::individualsChangedCb(FolksIndividualAggregator *individualAggregator,
@@ -322,28 +320,28 @@
322320
323 GeeIterator *iter;321 GeeIterator *iter;
324 GeeSet *removed = gee_multi_map_get_keys(changes);322 GeeSet *removed = gee_multi_map_get_keys(changes);
325 iter = gee_iterable_iterator(GEE_ITERABLE(removed));
326
327 while(gee_iterator_next(iter)) {
328 FolksIndividual *individual = FOLKS_INDIVIDUAL(gee_iterator_get(iter));
329 if (individual) {
330 QString id = self->removeContact(individual);
331 if(!id.isEmpty()) {
332 removedIds << id;
333 }
334 g_object_unref(individual);
335 }
336 }
337 g_object_unref (iter);
338
339 GeeCollection *added = gee_multi_map_get_values(changes);323 GeeCollection *added = gee_multi_map_get_values(changes);
324
340 iter = gee_iterable_iterator(GEE_ITERABLE(added));325 iter = gee_iterable_iterator(GEE_ITERABLE(added));
341 while(gee_iterator_next(iter)) {326 while(gee_iterator_next(iter)) {
342 FolksIndividual *individual = FOLKS_INDIVIDUAL(gee_iterator_get(iter));327 FolksIndividual *individual = FOLKS_INDIVIDUAL(gee_iterator_get(iter));
343 if (individual) {328 if (individual) {
344 QString id = self->addContact(individual);329 // add contact to the map
345 if(!id.isEmpty()) {330 addedIds << self->addContact(individual);
346 addedIds << id;331 g_object_unref(individual);
332 }
333 }
334 g_object_unref (iter);
335
336
337 iter = gee_iterable_iterator(GEE_ITERABLE(removed));
338 while(gee_iterator_next(iter)) {
339 FolksIndividual *individual = FOLKS_INDIVIDUAL(gee_iterator_get(iter));
340 if (individual) {
341 QString id = QString::fromUtf8(folks_individual_get_id(individual));
342 if (!addedIds.contains(id)) {
343 // delete from contact map
344 removedIds << self->removeContact(individual);
347 }345 }
348 g_object_unref(individual);346 g_object_unref(individual);
349 }347 }
350348
=== modified file 'src/addressbook.h'
--- src/addressbook.h 2013-06-20 20:58:26 +0000
+++ src/addressbook.h 2013-06-20 20:58:26 +0000
@@ -28,6 +28,8 @@
2828
29#include <QtDBus/QtDBus>29#include <QtDBus/QtDBus>
3030
31#include <QtContacts/QContact>
32
31#include <folks/folks.h>33#include <folks/folks.h>
32#include <glib.h>34#include <glib.h>
33#include <glib-object.h>35#include <glib-object.h>
@@ -37,6 +39,7 @@
37class View;39class View;
38class ContactsMap;40class ContactsMap;
39class AddressBookAdaptor;41class AddressBookAdaptor;
42class QIndividual;
4043
41class AddressBook: public QObject44class AddressBook: public QObject
42{45{
@@ -60,6 +63,7 @@
60 QString createContact(const QString &contact, const QString &source, const QDBusMessage &message);63 QString createContact(const QString &contact, const QString &source, const QDBusMessage &message);
61 int removeContacts(const QStringList &contactIds, const QDBusMessage &message);64 int removeContacts(const QStringList &contactIds, const QDBusMessage &message);
62 QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message);65 QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message);
66 void updateContactsDone(galera::QIndividual *individual, const QString &error);
6367
64private Q_SLOTS:68private Q_SLOTS:
65 void viewClosed();69 void viewClosed();
@@ -71,14 +75,15 @@
71 bool m_ready;75 bool m_ready;
72 AddressBookAdaptor *m_adaptor;76 AddressBookAdaptor *m_adaptor;
7377
78 // Update command
79 QDBusMessage m_updateCommandReplyMessage;
80 QStringList m_updateCommandResult;
81 QList<QtContacts::QContact> m_updateCommandPendingContacts;
7482
75 void prepareFolks();83 void prepareFolks();
76 QString removeContact(FolksIndividual *individual);84 QString removeContact(FolksIndividual *individual);
77 QString addContact(FolksIndividual *individual);85 QString addContact(FolksIndividual *individual);
7886
79
80 static void updateContacts(const QString &error, void *userData);
81
82 static void individualsChangedCb(FolksIndividualAggregator *individualAggregator,87 static void individualsChangedCb(FolksIndividualAggregator *individualAggregator,
83 GeeMultiMap *changes,88 GeeMultiMap *changes,
84 AddressBook *self);89 AddressBook *self);
8590
=== modified file 'src/contacts-map.cpp'
--- src/contacts-map.cpp 2013-06-11 13:00:01 +0000
+++ src/contacts-map.cpp 2013-06-20 20:58:26 +0000
@@ -28,6 +28,7 @@
28ContactEntry::ContactEntry(QIndividual *individual)28ContactEntry::ContactEntry(QIndividual *individual)
29 : m_individual(individual)29 : m_individual(individual)
30{30{
31 Q_ASSERT(individual);
31}32}
3233
33ContactEntry::~ContactEntry()34ContactEntry::~ContactEntry()
@@ -75,6 +76,16 @@
75 return 0;76 return 0;
76}77}
7778
79void ContactsMap::remove(const QString &id)
80{
81 ContactEntry *entry = m_idToEntry[id];
82 if (entry) {
83 m_individualsToEntry.remove(entry->individual()->individual());
84 m_idToEntry.remove(id);
85 delete entry;
86 }
87}
88
78bool ContactsMap::contains(FolksIndividual *individual) const89bool ContactsMap::contains(FolksIndividual *individual) const
79{90{
80 return m_individualsToEntry.contains(individual);91 return m_individualsToEntry.contains(individual);
8192
=== modified file 'src/contacts-map.h'
--- src/contacts-map.h 2013-06-11 13:00:01 +0000
+++ src/contacts-map.h 2013-06-20 20:58:26 +0000
@@ -60,6 +60,7 @@
60 ContactEntry *value(FolksIndividual *individual) const;60 ContactEntry *value(FolksIndividual *individual) const;
61 ContactEntry *value(const QString &id) const;61 ContactEntry *value(const QString &id) const;
62 ContactEntry *take(FolksIndividual *individual);62 ContactEntry *take(FolksIndividual *individual);
63 void remove(const QString &id);
63 void insert(ContactEntry *entry);64 void insert(ContactEntry *entry);
64 int size() const;65 int size() const;
6566
6667
=== modified file 'src/qindividual.cpp'
--- src/qindividual.cpp 2013-06-11 21:49:45 +0000
+++ src/qindividual.cpp 2013-06-20 20:58:26 +0000
@@ -53,14 +53,14 @@
53class UpdateContactData53class UpdateContactData
54{54{
55public:55public:
56 QContactDetail::DetailType m_currentDetailType;
57 QContact m_newContact;56 QContact m_newContact;
58 galera::QIndividual *m_self;57 galera::QIndividual *m_self;
59 FolksPersona *m_persona;58
6059 QList<QContactDetail> m_details;
61 QList<QContactDetail> m_detailsChanged;60 QContactDetail m_currentDetail;
62 galera::UpdateDoneCB m_doneCB;61
63 void *m_doneData;62 QObject *m_object;
63 QMetaMethod m_slot;
64};64};
6565
66#ifdef FOLKS_0_9_066#ifdef FOLKS_0_9_0
@@ -82,9 +82,6 @@
82namespace galera82namespace galera
83{83{
8484
85// TODO: find a better way to link abstract field with details
86#define FOLKS_DATA_FIELD 10000
87
88#ifdef FOLKS_0_9_085#ifdef FOLKS_0_9_0
89 #define SET_AFD_NEW() \86 #define SET_AFD_NEW() \
90 GEE_SET(gee_hash_set_new(FOLKS_TYPE_ABSTRACT_FIELD_DETAILS, \87 GEE_SET(gee_hash_set_new(FOLKS_TYPE_ABSTRACT_FIELD_DETAILS, \
@@ -96,6 +93,16 @@
96 NULL, \93 NULL, \
97 NULL))94 NULL))
9895
96 #define SET_PERSONA_NEW() \
97 GEE_SET(gee_hash_set_new(FOLKS_TYPE_PERSONA, \
98 (GBoxedCopyFunc) g_object_ref, g_object_unref, \
99 NULL, \
100 NULL, \
101 NULL, \
102 NULL, \
103 NULL, \
104 NULL))
105
99 #define GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE) \106 #define GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE) \
100 GEE_MULTI_MAP(gee_hash_multi_map_new(G_TYPE_STRING,\107 GEE_MULTI_MAP(gee_hash_multi_map_new(G_TYPE_STRING,\
101 (GBoxedCopyFunc) g_strdup, g_free, \108 (GBoxedCopyFunc) g_strdup, g_free, \
@@ -120,6 +127,13 @@
120 (GHashFunc) folks_abstract_field_details_hash, \127 (GHashFunc) folks_abstract_field_details_hash, \
121 (GEqualFunc) folks_abstract_field_details_equal))128 (GEqualFunc) folks_abstract_field_details_equal))
122129
130 #define SET_PERSONA_NEW() \
131 GEE_SET(gee_hash_set_new(FOLKS_TYPE_PERSONA, \
132 (GBoxedCopyFunc) g_object_ref, g_object_unref, \
133 NULL, \
134 NULL))
135
136
123 #define GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE) \137 #define GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE) \
124 GEE_MULTI_MAP(gee_hash_multi_map_new(G_TYPE_STRING, \138 GEE_MULTI_MAP(gee_hash_multi_map_new(G_TYPE_STRING, \
125 (GBoxedCopyFunc) g_strdup, \139 (GBoxedCopyFunc) g_strdup, \
@@ -131,16 +145,17 @@
131 (GHashFunc) folks_abstract_field_details_hash, \145 (GHashFunc) folks_abstract_field_details_hash, \
132 (GEqualFunc) folks_abstract_field_details_equal));146 (GEqualFunc) folks_abstract_field_details_equal));
133147
148
149
134#endif150#endif
135151
136152
137#define PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(\153#define PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(\
138 details, key, value, q_type, g_type, member) \154 details, cDetails, key, value, q_type, g_type, member) \
139{ \155{ \
140 QList<q_type> contactDetails = contact.details<q_type>(); \156 if(cDetails.size() > 0) { \
141 if(contactDetails.size() > 0) { \
142 value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); \157 value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); \
143 Q_FOREACH(const q_type& detail, contact.details<q_type>()) { \158 Q_FOREACH(const q_type& detail, cDetails) { \
144 if(!detail.isEmpty()) { \159 if(!detail.isEmpty()) { \
145 QIndividualUtils::gValueGeeSetAddStringFieldDetails(value, (g_type), \160 QIndividualUtils::gValueGeeSetAddStringFieldDetails(value, (g_type), \
146 detail.member().toUtf8().data(), \161 detail.member().toUtf8().data(), \
@@ -242,10 +257,53 @@
242 return retval;257 return retval;
243 }258 }
244259
260 static FolksAbstractFieldDetails *getDetails(GeeSet *set, const QString &uri)
261 {
262 Q_ASSERT(set);
263
264 int pos = 0;
265 int size = 0;
266 QStringList index = uri.split(".");
267 gpointer* values = gee_collection_to_array(GEE_COLLECTION(set), &size);
268
269 if (size == 0) {
270 return 0;
271 } else if (index.count() == 2) {
272 pos = index[1].toInt() - 1;
273 Q_ASSERT(pos >= 0);
274 Q_ASSERT(pos < size);
275 }
276 return FOLKS_ABSTRACT_FIELD_DETAILS(values[pos]);
277 }
278
279 static FolksPersona *personaFromUri(const QString &uri, FolksIndividual *individual, FolksPersona *defaultPersona)
280 {
281 Q_ASSERT(individual);
282
283 if (uri.isEmpty()) {
284 //TODO
285 qWarning() << "NO PERSONA";
286 return defaultPersona;
287 } else {
288
289 GeeSet *personas = folks_individual_get_personas(individual);
290 QStringList index = uri.split(".");
291 Q_ASSERT(index.count() >= 1);
292 int pos = index[0].toInt() - 1;
293 int size = 0;
294 gpointer* values = gee_collection_to_array(GEE_COLLECTION(personas), &size);
295 Q_ASSERT(pos >= 0);
296 Q_ASSERT(pos < size);
297
298 return FOLKS_PERSONA(values[pos]);
299 }
300 }
301
245}; // class302}; // class
246303
247QIndividual::QIndividual(FolksIndividual *individual, FolksIndividualAggregator *aggregator)304QIndividual::QIndividual(FolksIndividual *individual, FolksIndividualAggregator *aggregator)
248 : m_individual(individual),305 : m_individual(individual),
306 m_primaryPersona(0),
249 m_aggregator(aggregator)307 m_aggregator(aggregator)
250{308{
251 g_object_ref(m_individual);309 g_object_ref(m_individual);
@@ -267,7 +325,6 @@
267QList<QtContacts::QContactDetail> QIndividual::getClientPidMap() const325QList<QtContacts::QContactDetail> QIndividual::getClientPidMap() const
268{326{
269 QList<QtContacts::QContactDetail> details;327 QList<QtContacts::QContactDetail> details;
270 /*
271 int index = 1;328 int index = 1;
272 GeeSet *personas = folks_individual_get_personas(m_individual);329 GeeSet *personas = folks_individual_get_personas(m_individual);
273 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas));330 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas));
@@ -282,16 +339,75 @@
282 }339 }
283340
284 g_object_unref(iter);341 g_object_unref(iter);
285 */342 return details;
286 return details;343}
287}344
288345void QIndividual::appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QtContacts::QContactDetail detail, const QString &personaIndex, bool readOnly) const
289346{
290QtContacts::QContactDetail QIndividual::getName() const347 if (!detail.isEmpty()) {
291{348 detail.setDetailUri(personaIndex);
349 if (readOnly) {
350 QContactManagerEngine::setDetailAccessConstraints(&detail, QContactDetail::ReadOnly);
351 }
352 list->append(detail);
353 }
354}
355
356void QIndividual::appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QList<QtContacts::QContactDetail> details, const QString &personaIndex, bool readOnly) const
357{
358 int subIndex = 1;
359 Q_FOREACH(QContactDetail detail, details) {
360 appendDetailsForPersona(list, detail, QString("%1.%2").arg(personaIndex).arg(subIndex), readOnly);
361 subIndex++;
362 }
363}
364
365
366QList<QContactDetail> QIndividual::getDetails() const
367{
368 int personaIndex = 1;
369 QList<QContactDetail> details;
370 GeeSet *personas = folks_individual_get_personas(m_individual);
371 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas));
372
373 while(gee_iterator_next(iter)) {
374 FolksPersona *persona = FOLKS_PERSONA(gee_iterator_get(iter));
375
376 int wsize = 0;
377 gchar **wproperties = folks_persona_get_writeable_properties(persona, &wsize);
378 //"gender", "local-ids", "avatar", "postal-addresses", "urls", "phone-numbers", "structured-name",
379 //"anti-links", "im-addresses", "is-favourite", "birthday", "notes", "roles", "email-addresses",
380 //"web-service-addresses", "groups", "full-name"
381 QStringList wPropList;
382 for(int i=0; i < wsize; i++) {
383 wPropList << wproperties[i];
384 }
385
386 QString index = QString::number(personaIndex);
387
388 appendDetailsForPersona(&details, getPersonaName(persona), index, !wPropList.contains("structured-name"));
389 appendDetailsForPersona(&details, getPersonaFullName(persona), index, !wPropList.contains("full-name"));
390 appendDetailsForPersona(&details, getPersonaNickName(persona), index, !wPropList.contains("nickname"));
391 appendDetailsForPersona(&details, getPersonaBirthday(persona), index, !wPropList.contains("birthday"));
392 appendDetailsForPersona(&details, getPersonaRoles(persona), index, !wPropList.contains("roles"));
393 appendDetailsForPersona(&details, getPersonaEmails(persona), index, !wPropList.contains("email-addresses"));
394 appendDetailsForPersona(&details, getPersonaPhones(persona), index, !wPropList.contains("phone-numbers"));
395 appendDetailsForPersona(&details, getPersonaAddresses(persona), index, !wPropList.contains("postal-addresses"));
396 appendDetailsForPersona(&details, getPersonaIms(persona), index, !wPropList.contains("im-addresses"));
397 appendDetailsForPersona(&details, getPersonaUrls(persona), index, !wPropList.contains("urls"));
398 personaIndex++;
399 }
400 return details;
401}
402
403QContactDetail QIndividual::getPersonaName(FolksPersona *persona) const
404{
405 if (!FOLKS_IS_NAME_DETAILS(persona)) {
406 return QContactDetail();
407 }
408
292 QContactName detail;409 QContactName detail;
293 FolksStructuredName *sn = folks_name_details_get_structured_name(FOLKS_NAME_DETAILS(m_individual));410 FolksStructuredName *sn = folks_name_details_get_structured_name(FOLKS_NAME_DETAILS(persona));
294
295 if (sn) {411 if (sn) {
296 const char *name = folks_structured_name_get_given_name(sn);412 const char *name = folks_structured_name_get_given_name(sn);
297 if (name && strlen(name)) {413 if (name && strlen(name)) {
@@ -317,30 +433,42 @@
317 return detail;433 return detail;
318}434}
319435
320QtContacts::QContactDetail QIndividual::getFullName() const436QtContacts::QContactDetail QIndividual::getPersonaFullName(FolksPersona *persona) const
321{437{
438 if (!FOLKS_IS_NAME_DETAILS(persona)) {
439 return QContactDetail();
440 }
441
322 QContactDisplayLabel detail;442 QContactDisplayLabel detail;
323 const gchar *fullName = folks_name_details_get_full_name(FOLKS_NAME_DETAILS(m_individual));443 const gchar *fullName = folks_name_details_get_full_name(FOLKS_NAME_DETAILS(persona));
324 if (fullName && strlen(fullName)) {444 if (fullName && strlen(fullName)) {
325 detail.setLabel(QString::fromUtf8(fullName));445 detail.setLabel(QString::fromUtf8(fullName));
326 }446 }
327 return detail;447 return detail;
328}448}
329449
330QtContacts::QContactDetail QIndividual::getNickname() const450QtContacts::QContactDetail QIndividual::getPersonaNickName(FolksPersona *persona) const
331{451{
452 if (!FOLKS_IS_NAME_DETAILS(persona)) {
453 return QContactDetail();
454 }
455
332 QContactNickname detail;456 QContactNickname detail;
333 const gchar* nickname = folks_name_details_get_nickname(FOLKS_NAME_DETAILS(m_individual));457 const gchar* nickname = folks_name_details_get_nickname(FOLKS_NAME_DETAILS(persona));
334 if (nickname && strlen(nickname)) {458 if (nickname && strlen(nickname)) {
335 detail.setNickname(QString::fromUtf8(nickname));459 detail.setNickname(QString::fromUtf8(nickname));
336 }460 }
337 return detail;461 return detail;
338}462}
339463
340QtContacts::QContactDetail QIndividual::getBirthday() const464QtContacts::QContactDetail QIndividual::getPersonaBirthday(FolksPersona *persona) const
341{465{
466 if (!FOLKS_IS_BIRTHDAY_DETAILS(persona)) {
467 return QContactDetail();
468 }
469
342 QContactBirthday detail;470 QContactBirthday detail;
343 GDateTime* datetime = folks_birthday_details_get_birthday(FOLKS_BIRTHDAY_DETAILS(m_individual));471 GDateTime* datetime = folks_birthday_details_get_birthday(FOLKS_BIRTHDAY_DETAILS(persona));
344 if (datetime) {472 if (datetime) {
345 QDate date(g_date_time_get_year(datetime), g_date_time_get_month(datetime), g_date_time_get_day_of_month(datetime));473 QDate date(g_date_time_get_year(datetime), g_date_time_get_month(datetime), g_date_time_get_day_of_month(datetime));
346 QTime time(g_date_time_get_hour(datetime), g_date_time_get_minute(datetime), g_date_time_get_second(datetime));474 QTime time(g_date_time_get_hour(datetime), g_date_time_get_minute(datetime), g_date_time_get_second(datetime));
@@ -349,16 +477,20 @@
349 return detail;477 return detail;
350}478}
351479
352QtContacts::QContactDetail QIndividual::getPhoto() const480QtContacts::QContactDetail QIndividual::getPersonaPhoto(FolksPersona *persona) const
353{481{
354 // TODO482 // TODO
355 return QContactAvatar();483 return QContactAvatar();
356}484}
357485
358QList<QtContacts::QContactDetail> QIndividual::getRoles() const486QList<QtContacts::QContactDetail> QIndividual::getPersonaRoles(FolksPersona *persona) const
359{487{
488 if (!FOLKS_IS_ROLE_DETAILS(persona)) {
489 return QList<QtContacts::QContactDetail>();
490 }
491
360 QList<QtContacts::QContactDetail> details;492 QList<QtContacts::QContactDetail> details;
361 GeeSet *roles = folks_role_details_get_roles(FOLKS_ROLE_DETAILS(m_individual));493 GeeSet *roles = folks_role_details_get_roles(FOLKS_ROLE_DETAILS(persona));
362 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(roles));494 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(roles));
363495
364 while(gee_iterator_next(iter)) {496 while(gee_iterator_next(iter)) {
@@ -366,8 +498,15 @@
366 FolksRole *role = FOLKS_ROLE(folks_abstract_field_details_get_value(fd));498 FolksRole *role = FOLKS_ROLE(folks_abstract_field_details_get_value(fd));
367499
368 QContactOrganization org;500 QContactOrganization org;
369 org.setName(QString::fromUtf8(folks_role_get_organisation_name(role)));501 QString field;
370 org.setTitle(QString::fromUtf8(folks_role_get_title(role)));502 field = QString::fromUtf8(folks_role_get_organisation_name(role));
503 if (field.isEmpty()) {
504 org.setName(field);
505 }
506 field = QString::fromUtf8(folks_role_get_title(role));
507 if (!field.isEmpty()) {
508 org.setTitle(field);
509 }
371 parseParameters(org, fd);510 parseParameters(org, fd);
372511
373 g_object_unref(fd);512 g_object_unref(fd);
@@ -379,10 +518,14 @@
379 return details;518 return details;
380}519}
381520
382QList<QtContacts::QContactDetail> QIndividual::getEmails() const521QList<QtContacts::QContactDetail> QIndividual::getPersonaEmails(FolksPersona *persona) const
383{522{
523 if (!FOLKS_IS_EMAIL_DETAILS(persona)) {
524 return QList<QtContacts::QContactDetail>();
525 }
526
384 QList<QtContacts::QContactDetail> details;527 QList<QtContacts::QContactDetail> details;
385 GeeSet *emails = folks_email_details_get_email_addresses(FOLKS_EMAIL_DETAILS(m_individual));528 GeeSet *emails = folks_email_details_get_email_addresses(FOLKS_EMAIL_DETAILS(persona));
386 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(emails));529 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(emails));
387530
388 while(gee_iterator_next(iter)) {531 while(gee_iterator_next(iter)) {
@@ -402,10 +545,14 @@
402 return details;545 return details;
403}546}
404547
405QList<QtContacts::QContactDetail> QIndividual::getPhones() const548QList<QtContacts::QContactDetail> QIndividual::getPersonaPhones(FolksPersona *persona) const
406{549{
550 if (!FOLKS_IS_PHONE_DETAILS(persona)) {
551 return QList<QtContacts::QContactDetail>();
552 }
553
407 QList<QtContacts::QContactDetail> details;554 QList<QtContacts::QContactDetail> details;
408 GeeSet *phones = folks_phone_details_get_phone_numbers(FOLKS_PHONE_DETAILS(m_individual));555 GeeSet *phones = folks_phone_details_get_phone_numbers(FOLKS_PHONE_DETAILS(persona));
409 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(phones));556 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(phones));
410557
411 while(gee_iterator_next(iter)) {558 while(gee_iterator_next(iter)) {
@@ -425,10 +572,14 @@
425 return details;572 return details;
426}573}
427574
428QList<QtContacts::QContactDetail> QIndividual::getAddresses() const575QList<QtContacts::QContactDetail> QIndividual::getPersonaAddresses(FolksPersona *persona) const
429{576{
577 if (!FOLKS_IS_POSTAL_ADDRESS_DETAILS(persona)) {
578 return QList<QtContacts::QContactDetail>();
579 }
580
430 QList<QtContacts::QContactDetail> details;581 QList<QtContacts::QContactDetail> details;
431 GeeSet *addresses = folks_postal_address_details_get_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(m_individual));582 GeeSet *addresses = folks_postal_address_details_get_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(persona));
432 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(addresses));583 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(addresses));
433584
434 while(gee_iterator_next(iter)) {585 while(gee_iterator_next(iter)) {
@@ -476,10 +627,14 @@
476 return details;627 return details;
477}628}
478629
479QList<QtContacts::QContactDetail> QIndividual::getIms() const630QList<QtContacts::QContactDetail> QIndividual::getPersonaIms(FolksPersona *persona) const
480{631{
632 if (!FOLKS_IS_IM_DETAILS(persona)) {
633 return QList<QtContacts::QContactDetail>();
634 }
635
481 QList<QtContacts::QContactDetail> details;636 QList<QtContacts::QContactDetail> details;
482 GeeMultiMap *ims = folks_im_details_get_im_addresses(FOLKS_IM_DETAILS(m_individual));637 GeeMultiMap *ims = folks_im_details_get_im_addresses(FOLKS_IM_DETAILS(persona));
483 GeeSet *keys = gee_multi_map_get_keys(ims);638 GeeSet *keys = gee_multi_map_get_keys(ims);
484 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(keys));639 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(keys));
485640
@@ -508,16 +663,14 @@
508 return details;663 return details;
509}664}
510665
511QtContacts::QContactDetail QIndividual::getTimeZone() const666QList<QtContacts::QContactDetail> QIndividual::getPersonaUrls(FolksPersona *persona) const
512{667{
513 //TODO668 if (!FOLKS_IS_URL_DETAILS(persona)) {
514 return QContactDetail();669 return QList<QtContacts::QContactDetail>();
515}670 }
516671
517QList<QtContacts::QContactDetail> QIndividual::getUrls() const
518{
519 QList<QtContacts::QContactDetail> details;672 QList<QtContacts::QContactDetail> details;
520 GeeSet *urls = folks_url_details_get_urls(FOLKS_URL_DETAILS(m_individual));673 GeeSet *urls = folks_url_details_get_urls(FOLKS_URL_DETAILS(persona));
521 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(urls));674 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(urls));
522675
523 while(gee_iterator_next(iter)) {676 while(gee_iterator_next(iter)) {
@@ -635,519 +788,696 @@
635{788{
636 m_contact = QContact();789 m_contact = QContact();
637 m_contact.appendDetail(getUid());790 m_contact.appendDetail(getUid());
638 m_contact.appendDetail(getName());
639 m_contact.appendDetail(getFullName());
640 m_contact.appendDetail(getNickname());
641 m_contact.appendDetail(getBirthday());
642 m_contact.appendDetail(getPhoto());
643 m_contact.appendDetail(getTimeZone());
644 Q_FOREACH(QContactDetail detail, getClientPidMap()) {791 Q_FOREACH(QContactDetail detail, getClientPidMap()) {
645 m_contact.appendDetail(detail);792 m_contact.appendDetail(detail);
646 }793 }
647 Q_FOREACH(QContactDetail detail, getRoles()) {794
648 m_contact.appendDetail(detail);795 Q_FOREACH(QContactDetail detail, getDetails()) {
649 }796 m_contact.appendDetail(detail);
650 Q_FOREACH(QContactDetail detail, getEmails()) {797 }
651 m_contact.appendDetail(detail);798}
652 }799
653 Q_FOREACH(QContactDetail detail, getPhones()) {800void QIndividual::createPersonaForDetail(QList<QtContacts::QContactDetail> cDetails, ParseDetailsFunc parseFunc, void *data) const
654 m_contact.appendDetail(detail);801{
655 }802 GHashTable *details = g_hash_table_new_full(g_str_hash,
656 Q_FOREACH(QContactDetail detail, getAddresses()) {803 g_str_equal,
657 m_contact.appendDetail(detail);804 NULL,
658 }805 (GDestroyNotify) QIndividualUtils::gValueSliceFree);
659 Q_FOREACH(QContactDetail detail, getIms()) {806
660 m_contact.appendDetail(detail);807 parseFunc(details, cDetails);
661 }808
662 Q_FOREACH(QContactDetail detail, getUrls()) {809 folks_individual_aggregator_add_persona_from_details(m_aggregator,
663 m_contact.appendDetail(detail);810 NULL, // we should pass the m_individual here but due a bug on folks lest do a work around
664 }811 folks_individual_aggregator_get_primary_store(m_aggregator),
812 details,
813 (GAsyncReadyCallback) createPersonaDone,
814 (void*) data);
815
816 g_hash_table_destroy(details);
665}817}
666818
667void QIndividual::updateFullName(const QtContacts::QContactDetail &detail, void* data)819void QIndividual::updateFullName(const QtContacts::QContactDetail &detail, void* data)
668{820{
669 UpdateContactData *udata = static_cast<UpdateContactData*>(data);821 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
670 QContactDetail originalLabel = m_contact.detail(QContactDetail::TypeDisplayLabel);822 QContactDetail originalLabel = detailFromUri(QContactDetail::TypeDisplayLabel, detail.detailUri());
671 if (FOLKS_IS_NAME_DETAILS(udata->m_persona) && (originalLabel != detail)) {823
824 if (persona == 0) {
825 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseFullNameDetails, data);
826 } else if (FOLKS_IS_NAME_DETAILS(persona) && (originalLabel != detail)) {
827 qDebug() << "Full Name diff";
828 qDebug() << "\t" << originalLabel << "\n\t" << detail;
829
672 const QContactDisplayLabel *label = static_cast<const QContactDisplayLabel*>(&detail);830 const QContactDisplayLabel *label = static_cast<const QContactDisplayLabel*>(&detail);
673831
674 folks_name_details_change_full_name(FOLKS_NAME_DETAILS(udata->m_persona),832 folks_name_details_change_full_name(FOLKS_NAME_DETAILS(persona),
675 label->label().toUtf8().data(),833 label->label().toUtf8().data(),
676 (GAsyncReadyCallback) updateDetailsDone,834 (GAsyncReadyCallback) updateDetailsDone,
677 data);835 data);
678 } else {836 } else {
679 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);837 updateDetailsDone(G_OBJECT(persona), NULL, data);
680 }838 }
681}839}
682840
683void QIndividual::updateName(const QtContacts::QContactDetail &detail, void* data)841void QIndividual::updateName(const QtContacts::QContactDetail &detail, void* data)
684{842{
685 UpdateContactData *udata = static_cast<UpdateContactData*>(data);843 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
686 QContactDetail originalName = m_contact.detail(QContactDetail::TypeName);844 QContactDetail originalName = detailFromUri(QContactDetail::TypeName, detail.detailUri());
687 if (FOLKS_IS_NAME_DETAILS(udata->m_persona) && (originalName != detail)) {845
846 if (persona == 0) {
847 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseNameDetails, data);
848 } else if (FOLKS_IS_NAME_DETAILS(persona) && (originalName != detail)) {
849 qDebug() << "Name diff";
850 qDebug() << "\t" << originalName << "\n\t" << detail;
851
688 const QContactName *name = static_cast<const QContactName*>(&detail);852 const QContactName *name = static_cast<const QContactName*>(&detail);
689 FolksStructuredName *sn = folks_name_details_get_structured_name(FOLKS_NAME_DETAILS(m_individual));853 FolksStructuredName *sn;
690 if (!sn) {854 sn = folks_structured_name_new(name->lastName().toUtf8().data(),
691 sn = folks_structured_name_new(name->lastName().toUtf8().data(),855 name->firstName().toUtf8().data(),
692 name->firstName().toUtf8().data(),856 name->middleName().toUtf8().data(),
693 name->middleName().toUtf8().data(),857 name->prefix().toUtf8().data(),
694 name->prefix().toUtf8().data(),858 name->suffix().toUtf8().data());
695 name->suffix().toUtf8().data());
696 } else {
697 folks_structured_name_set_family_name(sn, name->lastName().toUtf8().data());
698 folks_structured_name_set_given_name(sn, name->firstName().toUtf8().data());
699 folks_structured_name_set_additional_names(sn, name->middleName().toUtf8().data());
700 folks_structured_name_set_prefixes(sn, name->prefix().toUtf8().data());
701 folks_structured_name_set_suffixes(sn, name->suffix().toUtf8().data());
702 }
703859
704 folks_name_details_change_structured_name(FOLKS_NAME_DETAILS(udata->m_persona),860 folks_name_details_change_structured_name(FOLKS_NAME_DETAILS(persona),
705 sn,861 sn,
706 (GAsyncReadyCallback) updateDetailsDone,862 (GAsyncReadyCallback) updateDetailsDone,
707 data);863 data);
864
708 g_object_unref(sn);865 g_object_unref(sn);
709 } else {866 } else {
710 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);867 updateDetailsDone(G_OBJECT(persona), NULL, data);
711 }868 }
712}869}
713870
714void QIndividual::updateNickname(const QtContacts::QContactDetail &detail, void* data)871void QIndividual::updateNickname(const QtContacts::QContactDetail &detail, void* data)
715{872{
716 UpdateContactData *udata = static_cast<UpdateContactData*>(data);873 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
717 QContactDetail originalNickname = m_contact.detail(QContactDetail::TypeNickname);874 QContactDetail originalNickname = detailFromUri(QContactDetail::TypeNickname, detail.detailUri());
718 if (FOLKS_IS_NAME_DETAILS(udata->m_persona) && (originalNickname != detail)) {875
876 if (persona == 0) {
877 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseNicknameDetails, data);
878 } else if (FOLKS_IS_NAME_DETAILS(persona) && (originalNickname != detail)) {
719 const QContactNickname *nickname = static_cast<const QContactNickname*>(&detail);879 const QContactNickname *nickname = static_cast<const QContactNickname*>(&detail);
720 folks_name_details_change_nickname(FOLKS_NAME_DETAILS(udata->m_persona),880 folks_name_details_change_nickname(FOLKS_NAME_DETAILS(persona),
721 nickname->nickname().toUtf8().data(),881 nickname->nickname().toUtf8().data(),
722 (GAsyncReadyCallback) updateDetailsDone,882 (GAsyncReadyCallback) updateDetailsDone,
723 data);883 data);
724 } else {884 } else {
725 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);885 updateDetailsDone(G_OBJECT(persona), NULL, data);
726 }886 }
727}887}
728888
729void QIndividual::updateBirthday(const QtContacts::QContactDetail &detail, void* data)889void QIndividual::updateBirthday(const QtContacts::QContactDetail &detail, void* data)
730{890{
731 UpdateContactData *udata = static_cast<UpdateContactData*>(data);891 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
732 QContactDetail originalBirthday = m_contact.detail(QContactDetail::TypeBirthday);892 QContactDetail originalBirthday = detailFromUri(QContactDetail::TypeBirthday, detail.detailUri());
733 if (FOLKS_IS_BIRTHDAY_DETAILS(udata->m_persona) && (originalBirthday != detail)) {893
894 if (persona == 0) {
895 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseBirthdayDetails, data);
896 } else if (FOLKS_IS_BIRTHDAY_DETAILS(persona) && (originalBirthday != detail)) {
734 const QContactBirthday *birthday = static_cast<const QContactBirthday*>(&detail);897 const QContactBirthday *birthday = static_cast<const QContactBirthday*>(&detail);
898
735 GDateTime *dateTime = NULL;899 GDateTime *dateTime = NULL;
736 if (!birthday->isEmpty()) {900 if (!birthday->isEmpty()) {
737 dateTime = g_date_time_new_from_unix_utc(birthday->dateTime().toMSecsSinceEpoch() / 1000);901 dateTime = g_date_time_new_from_unix_utc(birthday->dateTime().toMSecsSinceEpoch() / 1000);
738 }902 }
739 folks_birthday_details_change_birthday(FOLKS_BIRTHDAY_DETAILS(udata->m_persona),903 folks_birthday_details_change_birthday(FOLKS_BIRTHDAY_DETAILS(persona),
740 dateTime,904 dateTime,
741 (GAsyncReadyCallback) updateDetailsDone,905 (GAsyncReadyCallback) updateDetailsDone,
742 data);906 data);
743 g_date_time_unref(dateTime);907 g_date_time_unref(dateTime);
744 } else {908 } else {
745 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);909 updateDetailsDone(G_OBJECT(persona), NULL, data);
746 }910 }
747}911}
748912
749void QIndividual::updatePhoto(const QtContacts::QContactDetail &detail, void* data)913void QIndividual::updatePhoto(const QtContacts::QContactDetail &detail, void* data)
750{914{
751 UpdateContactData *udata = static_cast<UpdateContactData*>(data);915 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
752 QContactDetail originalAvatar = m_contact.detail(QContactDetail::TypeAvatar);916 QContactDetail originalAvatar = detailFromUri(QContactDetail::TypeAvatar, detail.detailUri());
753 if (FOLKS_IS_AVATAR_DETAILS(udata->m_persona) && (detail != originalAvatar)) {917
918 if (persona == 0) {
919 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parsePhotoDetails, data);
920 } else if (FOLKS_IS_AVATAR_DETAILS(persona) && (detail != originalAvatar)) {
754 //TODO:921 //TODO:
755 //const QContactAvatar *avatar = static_cast<const QContactAvatar*>(&detail);922 //const QContactAvatar *avatar = static_cast<const QContactAvatar*>(&detail);
756 folks_avatar_details_change_avatar(FOLKS_AVATAR_DETAILS(udata->m_persona),923 folks_avatar_details_change_avatar(FOLKS_AVATAR_DETAILS(persona),
757 0,924 0,
758 (GAsyncReadyCallback) updateDetailsDone,925 (GAsyncReadyCallback) updateDetailsDone,
759 data);926 data);
760 } else {927 } else {
761 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);928 updateDetailsDone(G_OBJECT(persona), NULL, data);
762 }929 }
763}930}
764931
765void QIndividual::updateTimezone(const QtContacts::QContactDetail &detail, void* data)932void QIndividual::updateRole(QtContacts::QContactDetail detail, void* data)
766{933{
767 //TODO934 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
768 UpdateContactData *udata = static_cast<UpdateContactData*>(data);935 QContactDetail originalRole = detailFromUri(QContactDetail::TypeOrganization, detail.detailUri());
769 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);936
770}937 if (!persona) {
771938 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseOrganizationDetails, data);
772void QIndividual::updateRoles(QList<QtContacts::QContactDetail> details, void* data)939 } else if (FOLKS_IS_ROLE_DETAILS(persona) && (originalRole != detail)) {
773{940 qDebug() << "Role diff";
774 UpdateContactData *udata = static_cast<UpdateContactData*>(data);941 qDebug() << "\t" << originalRole << "\n\t" << detail;
775 QList<QContactDetail> originalOrganizations = m_contact.details(QContactDetail::TypeOrganization);942
776943 FolksRoleFieldDetails *roleDetails = 0;
777 if (FOLKS_IS_ROLE_DETAILS(udata->m_persona) && !detailListIsEqual(originalOrganizations, details)) {944 const QContactOrganization *cRole = static_cast<const QContactOrganization*>(&detail);
778 GeeSet *roleSet = SET_AFD_NEW();945 GeeSet *roleSet = folks_role_details_get_roles(FOLKS_ROLE_DETAILS(persona));
779 Q_FOREACH(const QContactDetail& detail, details) {946
780 const QContactOrganization *org = static_cast<const QContactOrganization*>(&detail);947 if (!roleSet || (gee_collection_get_size(GEE_COLLECTION(roleSet)) == 0)) {
781948 roleSet = SET_AFD_NEW();
782 // The role values can not be NULL949 } else {
783 const gchar* title = org->title().toUtf8().data();950 roleDetails = FOLKS_ROLE_FIELD_DETAILS(QIndividualUtils::getDetails(roleSet, detail.detailUri()));
784 const gchar* name = org->name().toUtf8().data();951 // this will be unref at the end of the function
785 const gchar* roleName = org->role().toUtf8().data();952 g_object_ref(roleSet);
786953 g_object_ref(roleDetails);
787 FolksRole *role = folks_role_new(title ? title : "", name ? name : "", "");954 }
788 folks_role_set_role(role, roleName ? roleName : "");955
789956 const gchar* title = cRole->title().isEmpty() ? "" : cRole->title().toUtf8().data();
790 FolksRoleFieldDetails *fieldDetails = folks_role_field_details_new(role, NULL);957 const gchar* name = cRole->name().isEmpty() ? "" : cRole->name().toUtf8().data();
791 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(fieldDetails), detail);958 const gchar* roleName = cRole->role().isEmpty() ? "" : cRole->role().toUtf8().data();
792 gee_collection_add(GEE_COLLECTION(roleSet), fieldDetails);959
793960 FolksRole *roleValue;
794 g_object_unref(role);961 if (!roleDetails) {
795 g_object_unref(fieldDetails);962 roleValue = folks_role_new(title, name, "");
796 }963 folks_role_set_role(roleValue, roleName);
797964
798 folks_role_details_change_roles(FOLKS_ROLE_DETAILS(udata->m_persona),965 roleDetails = folks_role_field_details_new(roleValue, NULL);
966 gee_collection_add(GEE_COLLECTION(roleSet), roleDetails);
967 } else {
968 roleValue = FOLKS_ROLE(folks_abstract_field_details_get_value(FOLKS_ABSTRACT_FIELD_DETAILS(roleDetails)));
969 folks_role_set_organisation_name(roleValue, name);
970 folks_role_set_title(roleValue, title);
971 folks_role_set_role(roleValue, roleName);
972 }
973
974 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(roleDetails), detail);
975 folks_role_details_change_roles(FOLKS_ROLE_DETAILS(persona),
799 roleSet,976 roleSet,
800 (GAsyncReadyCallback) updateDetailsDone,977 (GAsyncReadyCallback) updateDetailsDone,
801 data);978 data);
979
980 g_object_unref(roleDetails);
802 g_object_unref(roleSet);981 g_object_unref(roleSet);
982 g_object_unref(roleValue);
803 } else {983 } else {
804 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);984 updateDetailsDone(G_OBJECT(persona), NULL, data);
805 }985 }
806}986}
807987
808void QIndividual::updateEmails(QList<QtContacts::QContactDetail> details, void* data)988void QIndividual::updateEmail(QtContacts::QContactDetail detail, void* data)
809{989{
810 UpdateContactData *udata = static_cast<UpdateContactData*>(data);990 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
811 QList<QContactDetail> originalEmails = m_contact.details(QContactDetail::TypeEmailAddress);991 QContactDetail originalEmail = detailFromUri(QContactDetail::TypeEmailAddress, detail.detailUri());
812992
813 if (FOLKS_IS_EMAIL_DETAILS(udata->m_persona) && !detailListIsEqual(originalEmails, details)) {993 if (!persona) {
814 GeeSet *emailSet = SET_AFD_NEW();994 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseEmailDetails, data);
815 Q_FOREACH(const QContactDetail& detail, details) {995 } else if (FOLKS_IS_EMAIL_DETAILS(persona) && (originalEmail != detail)) {
816 const QContactEmailAddress *email = static_cast<const QContactEmailAddress*>(&detail);996 qDebug() << "email diff";
817997 qDebug() << "\t" << originalEmail << "\n\t" << detail;
818 if(!email->isEmpty()) {998
819 FolksEmailFieldDetails *emailDetails = folks_email_field_details_new(email->emailAddress().toUtf8().data(), NULL);999 FolksEmailFieldDetails *emailDetails = 0;
820 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(emailDetails), detail);1000 const QContactEmailAddress *email = static_cast<const QContactEmailAddress*>(&detail);
821 gee_collection_add(GEE_COLLECTION(emailSet), emailDetails);1001 GeeSet *emailSet = folks_email_details_get_email_addresses(FOLKS_EMAIL_DETAILS(persona));
822 g_object_unref(emailDetails);1002 if (!emailSet || (gee_collection_get_size(GEE_COLLECTION(emailSet)) == 0)) {
823 }1003 emailSet = SET_AFD_NEW();
824 }1004 } else {
825 folks_email_details_change_email_addresses(FOLKS_EMAIL_DETAILS(udata->m_persona),1005 emailDetails = FOLKS_EMAIL_FIELD_DETAILS(QIndividualUtils::getDetails(emailSet, detail.detailUri()));
1006 // this will be unref at the end of the function
1007 g_object_ref(emailSet);
1008 g_object_ref(emailDetails);
1009 }
1010
1011 if (!emailDetails) {
1012 emailDetails = folks_email_field_details_new(email->emailAddress().toUtf8().data(), NULL);
1013 gee_collection_add(GEE_COLLECTION(emailSet), emailDetails);
1014 } else {
1015 folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(emailDetails),
1016 email->emailAddress().toUtf8().data());
1017 }
1018
1019 folks_email_details_change_email_addresses(FOLKS_EMAIL_DETAILS(persona),
826 emailSet,1020 emailSet,
827 (GAsyncReadyCallback) updateDetailsDone,1021 (GAsyncReadyCallback) updateDetailsDone,
828 data);1022 data);
1023
829 g_object_unref(emailSet);1024 g_object_unref(emailSet);
1025 g_object_unref(emailDetails);
830 } else {1026 } else {
831 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);1027 updateDetailsDone(G_OBJECT(persona), NULL, data);
832 }1028 }
833}1029}
8341030
835void QIndividual::updatePhones(QList<QtContacts::QContactDetail> details, void* data)1031void QIndividual::updatePhone(QtContacts::QContactDetail detail, void* data)
836{1032{
837 UpdateContactData *udata = static_cast<UpdateContactData*>(data);1033 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
838 QList<QContactDetail> originalPhones = m_contact.details(QContactDetail::TypePhoneNumber);1034 QContactDetail originalPhone = detailFromUri(QContactDetail::TypePhoneNumber, detail.detailUri());
8391035 // if we do not have a persona for this detail we need to create one
840 if (FOLKS_IS_PHONE_DETAILS(udata->m_persona) && !detailListIsEqual(originalPhones, details)) {1036 if (!persona) {
841 GeeSet *phoneSet = SET_AFD_NEW();1037 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parsePhoneNumbersDetails, data);
842 Q_FOREACH(const QContactDetail& detail, details) {1038 } else if (FOLKS_IS_PHONE_DETAILS(persona) && (originalPhone != detail)) {
843 const QContactPhoneNumber *phone = static_cast<const QContactPhoneNumber*>(&detail);1039 qDebug() << "Phone diff";
8441040 qDebug() << "\t" << originalPhone << "\n\t" << detail;
845 if(!phone->isEmpty()) {1041
846 FolksPhoneFieldDetails *phoneDetails = folks_phone_field_details_new(phone->number().toUtf8().data(), NULL);1042 /// Only update the details on the current persona
847 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(phoneDetails), detail);1043 FolksPhoneFieldDetails *phoneDetails = 0;
848 gee_collection_add(GEE_COLLECTION(phoneSet), phoneDetails);1044 const QContactPhoneNumber *phone = static_cast<const QContactPhoneNumber*>(&detail);
849 g_object_unref(phoneDetails);1045 GeeSet *phoneSet = folks_phone_details_get_phone_numbers(FOLKS_PHONE_DETAILS(persona));
850 }1046
851 }1047 if (!phoneSet || (gee_collection_get_size(GEE_COLLECTION(phoneSet)) == 0)) {
852 folks_phone_details_change_phone_numbers(FOLKS_PHONE_DETAILS(udata->m_persona),1048 phoneSet = SET_AFD_NEW();
1049 } else {
1050 phoneDetails = FOLKS_PHONE_FIELD_DETAILS(QIndividualUtils::getDetails(phoneSet, detail.detailUri()));
1051 // this will be unref at the end of the function
1052 g_object_ref(phoneSet);
1053 g_object_ref(phoneDetails);
1054 }
1055
1056 if (!phoneDetails) {
1057 phoneDetails = folks_phone_field_details_new(phone->number().toUtf8().data(), NULL);
1058 gee_collection_add(GEE_COLLECTION(phoneSet), phoneDetails);
1059 } else {
1060 folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(phoneDetails),
1061 phone->number().toUtf8().data());
1062 }
1063
1064 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(phoneDetails), detail);
1065 folks_phone_details_change_phone_numbers(FOLKS_PHONE_DETAILS(persona),
853 phoneSet,1066 phoneSet,
854 (GAsyncReadyCallback) updateDetailsDone,1067 (GAsyncReadyCallback) updateDetailsDone,
855 data);1068 data);
1069 g_object_unref(phoneDetails);
856 g_object_unref(phoneSet);1070 g_object_unref(phoneSet);
857 } else {1071 } else {
858 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);1072 updateDetailsDone(G_OBJECT(persona), NULL, data);
859 }1073 }
860}1074}
8611075
862bool QIndividual::detailListIsEqual(QList<QtContacts::QContactDetail> original, QList<QtContacts::QContactDetail> details)1076void QIndividual::updateAddress(QtContacts::QContactDetail detail, void* data)
863{1077{
864 if (original.size() != details.size()) {1078 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
865 return false;1079 QContactDetail originalAddress = detailFromUri(QContactDetail::TypeAddress, detail.detailUri());
866 }1080
8671081 if (!persona) {
868 Q_FOREACH(const QContactDetail& detail, details) {1082 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseAddressDetails, data);
869 if (!original.contains(detail)) {1083 } else if (FOLKS_IS_POSTAL_ADDRESS_DETAILS(persona) && (originalAddress != detail)) {
870 return false;1084
871 }1085
872 }1086 FolksPostalAddressFieldDetails *addrDetails = 0;
8731087 const QContactAddress *addr = static_cast<const QContactAddress*>(&detail);
874 return true;1088 const QContactAddress *addro = static_cast<const QContactAddress*>(&originalAddress);
875}1089
8761090 qDebug() << "Adderess diff";
877void QIndividual::updateAddresses(QList<QtContacts::QContactDetail> details, void* data)1091 qDebug() << "\t" << *addro << "subtypes:" << addro->subTypes() << "context" << addro->contexts();
878{1092 qDebug() << "\t" << *addr << "subtypes:" << addr->subTypes() << "context" << addr->contexts();
879 UpdateContactData *udata = static_cast<UpdateContactData*>(data);1093
880 QList<QContactDetail> originalAddress = m_contact.details(QContactDetail::TypeAddress);1094
8811095 qDebug() << "SubTypes:" << addr->subTypes();
882 if (FOLKS_IS_POSTAL_ADDRESS_DETAILS(udata->m_persona) && !detailListIsEqual(originalAddress, details)) {1096 GeeSet *addrSet = folks_postal_address_details_get_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(persona));
883 GeeSet *addressSet = SET_AFD_NEW();1097
884 Q_FOREACH(const QContactDetail& detail, details) {1098 if (!addrSet || (gee_collection_get_size(GEE_COLLECTION(addrSet)) == 0)) {
885 const QContactAddress *address = static_cast<const QContactAddress*>(&detail);1099 addrSet = SET_AFD_NEW();
886 if (!address->isEmpty()) {1100 } else {
887 FolksPostalAddress *postalAddress = folks_postal_address_new(address->postOfficeBox().toUtf8().data(),1101 addrDetails = FOLKS_POSTAL_ADDRESS_FIELD_DETAILS(QIndividualUtils::getDetails(addrSet, detail.detailUri()));
888 NULL,1102 // this will be unref at the end of the function
889 address->street().toUtf8().data(),1103 g_object_ref(addrSet);
890 address->locality().toUtf8().data(),1104 g_object_ref(addrDetails);
891 address->region().toUtf8().data(),1105 }
892 address->postcode().toUtf8().data(),1106
893 address->country().toUtf8().data(),1107 FolksPostalAddress *addrValue;
894 NULL,1108 if (!addrDetails) {
895 NULL);1109 addrValue = folks_postal_address_new(addr->postOfficeBox().toUtf8().data(),
896 FolksPostalAddressFieldDetails *pafd = folks_postal_address_field_details_new(postalAddress, NULL);1110 NULL,
8971111 addr->street().toUtf8().data(),
898 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(pafd), detail);1112 addr->locality().toUtf8().data(),
899 gee_collection_add(GEE_COLLECTION(addressSet), pafd);1113 addr->region().toUtf8().data(),
9001114 addr->postcode().toUtf8().data(),
901 g_object_unref(postalAddress);1115 addr->country().toUtf8().data(),
902 g_object_unref(pafd);1116 NULL,
903 }1117 NULL);
904 }1118 addrDetails = folks_postal_address_field_details_new(addrValue, NULL);
9051119 gee_collection_add(GEE_COLLECTION(addrSet), addrDetails);
906 folks_postal_address_details_change_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(udata->m_persona),1120 } else {
907 addressSet,1121 addrValue = FOLKS_POSTAL_ADDRESS(folks_abstract_field_details_get_value(FOLKS_ABSTRACT_FIELD_DETAILS(addrDetails)));
1122 Q_ASSERT(addrValue);
1123 folks_postal_address_set_po_box(addrValue, addr->postOfficeBox().toUtf8().data());
1124 folks_postal_address_set_street(addrValue, addr->street().toUtf8().data());
1125 folks_postal_address_set_locality(addrValue, addr->locality().toUtf8().data());
1126 folks_postal_address_set_region(addrValue, addr->region().toUtf8().data());
1127 folks_postal_address_set_postal_code(addrValue, addr->postcode().toUtf8().data());
1128 folks_postal_address_set_country(addrValue, addr->country().toUtf8().data());
1129 }
1130
1131 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(addrDetails), detail);
1132 folks_postal_address_details_change_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(persona),
1133 addrSet,
908 (GAsyncReadyCallback) updateDetailsDone,1134 (GAsyncReadyCallback) updateDetailsDone,
909 data);1135 data);
910 g_object_unref(addressSet);1136 g_object_unref(addrDetails);
1137 g_object_unref(addrSet);
1138 g_object_unref(addrValue);
911 } else {1139 } else {
912 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);1140 updateDetailsDone(G_OBJECT(persona), NULL, data);
913 }1141 }
914}1142}
9151143
916void QIndividual::updateIms(QList<QtContacts::QContactDetail> details, void* data)1144void QIndividual::updateIm(QtContacts::QContactDetail detail, void* data)
917{1145{
918 UpdateContactData *udata = static_cast<UpdateContactData*>(data);1146 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
919 QList<QContactDetail> originalIms = m_contact.details(QContactDetail::TypeOnlineAccount);1147 QContactDetail originalIm = detailFromUri(QContactDetail::TypeOnlineAccount, detail.detailUri());
9201148
921 if (FOLKS_IS_IM_DETAILS(udata->m_persona) && !detailListIsEqual(originalIms, details)) {1149 if (!persona) {
922 GeeMultiMap *imAddressHash = GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE_IM_FIELD_DETAILS);1150 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseImDetails, data);
923 Q_FOREACH(const QContactDetail& detail, details) {1151 } else if (FOLKS_IS_IM_DETAILS(persona) && (originalIm != detail)) {
924 const QContactOnlineAccount *im = static_cast<const QContactOnlineAccount*>(&detail);1152 qDebug() << "Im diff";
925 if (!im->accountUri().isEmpty()) {1153 qDebug() << "\t" << originalIm << "\n\t" << detail;
926 FolksImFieldDetails *imfd = folks_im_field_details_new(im->accountUri().toUtf8().data(), NULL);1154
927 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(imfd), detail);1155 const QContactOnlineAccount *im = static_cast<const QContactOnlineAccount*>(&detail);
928 gee_multi_map_set(imAddressHash,1156 GeeMultiMap *imSet = folks_im_details_get_im_addresses(FOLKS_IM_DETAILS(persona));
929 onlineAccountProtocolFromEnum(im->protocol()).toUtf8().data(), imfd);1157
930 g_object_unref(imfd);1158 if (!imSet || (gee_multi_map_get_size(GEE_MULTI_MAP(imSet)) == 0)) {
1159 imSet = GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE_IM_FIELD_DETAILS);
1160 } else {
1161 // We can not relay on the index inside of detailUri because online account are stored in a hash
1162 QContactOnlineAccount oldIm = static_cast<QContactOnlineAccount>(originalIm);
1163 QString oldProtocolName = onlineAccountProtocolFromEnum(oldIm.protocol());
1164 GeeCollection *value = gee_multi_map_get(imSet, oldProtocolName.toUtf8().data());
1165
1166 // Remove the old one
1167 if (value) {
1168 // if there is more than one address only remove the correct one
1169 if (gee_collection_get_size(value) > 1) {
1170 gee_collection_remove(value, oldIm.accountUri().toUtf8().data());
1171 } else {
1172 // otherwise remove the key
1173 gee_multi_map_remove_all(imSet, oldProtocolName.toUtf8().data());
1174 }
931 }1175 }
1176
1177 g_object_ref(imSet);
932 }1178 }
9331179
934 folks_im_details_change_im_addresses(FOLKS_IM_DETAILS(udata->m_persona),1180 // Append the new one
935 imAddressHash,1181 FolksImFieldDetails *imDetails = folks_im_field_details_new(im->accountUri().toUtf8().data(), NULL);
1182 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(imDetails), detail);
1183
1184 gee_multi_map_set(imSet,
1185 onlineAccountProtocolFromEnum(im->protocol()).toUtf8().data(),
1186 imDetails);
1187
1188 folks_im_details_change_im_addresses(FOLKS_IM_DETAILS(persona),
1189 imSet,
936 (GAsyncReadyCallback) updateDetailsDone,1190 (GAsyncReadyCallback) updateDetailsDone,
937 data);1191 data);
938 g_object_unref(imAddressHash);1192 g_object_unref(imSet);
1193 g_object_unref(imDetails);
939 } else {1194 } else {
940 updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data);1195 updateDetailsDone(G_OBJECT(persona), NULL, data);
941 }1196 }
942}1197}
9431198
944void QIndividual::updateUrls(QList<QtContacts::QContactDetail> details, void* data)1199void QIndividual::updateUrl(QtContacts::QContactDetail detail, void* data)
945{1200{
946 UpdateContactData *udata = static_cast<UpdateContactData*>(data);1201 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
947 QList<QContactDetail> originalUrls = m_contact.details(QContactDetail::TypeUrl);1202 QContactDetail originalUrl = detailFromUri(QContactDetail::TypeUrl, detail.detailUri());
9481203
949 if (FOLKS_IS_URL_DETAILS(udata->m_persona) && !detailListIsEqual(originalUrls, details)) {1204 if (!persona) {
950 GeeSet *urlSet = SET_AFD_NEW();1205 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseUrlDetails, data);
951 Q_FOREACH(const QContactDetail& detail, details) {1206 } else if (FOLKS_IS_URL_DETAILS(persona) && (originalUrl != detail)) {
952 const QContactUrl *url = static_cast<const QContactUrl*>(&detail);1207 qDebug() << "Url diff";
9531208 qDebug() << "\t" << originalUrl << "\n\t" << detail;
954 if(!url->isEmpty()) {1209
955 FolksUrlFieldDetails *urlDetails = folks_url_field_details_new(url->url().toUtf8().data(), NULL);1210 FolksUrlFieldDetails *urlDetails = 0;
956 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(urlDetails), detail);1211 const QContactUrl *url = static_cast<const QContactUrl*>(&detail);
957 gee_collection_add(GEE_COLLECTION(urlSet), urlDetails);1212 GeeSet *urlSet = folks_url_details_get_urls(FOLKS_URL_DETAILS(persona));
958 g_object_unref(urlDetails);1213
959 }1214 if (!urlSet || (gee_collection_get_size(GEE_COLLECTION(urlSet)) == 0)) {
960 }1215 urlSet = SET_AFD_NEW();
961 folks_url_details_change_urls(FOLKS_URL_DETAILS(udata->m_persona),1216 } else {
1217 urlDetails = FOLKS_URL_FIELD_DETAILS(QIndividualUtils::getDetails(urlSet, detail.detailUri()));
1218
1219 // this will be unref at the end of the function
1220 g_object_ref(urlSet);
1221 g_object_ref(urlDetails);
1222 }
1223
1224 if (!urlDetails) {
1225 urlDetails = folks_url_field_details_new(url->url().toUtf8().data(), NULL);
1226 gee_collection_add(GEE_COLLECTION(urlSet), urlDetails);
1227 } else {
1228 folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(urlDetails),
1229 url->url().toUtf8().data());
1230 }
1231
1232 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(urlDetails), detail);
1233 folks_url_details_change_urls(FOLKS_URL_DETAILS(persona),
962 urlSet,1234 urlSet,
963 (GAsyncReadyCallback) updateDetailsDone,1235 (GAsyncReadyCallback) updateDetailsDone,
964 data);1236 data);
1237 g_object_unref(urlDetails);
965 g_object_unref(urlSet);1238 g_object_unref(urlSet);
966 } else {1239 } else {
967 updateDetailsDone(G_OBJECT(m_individual), NULL, data);1240 updateDetailsDone(G_OBJECT(persona), NULL, data);
968 }1241 }
969}1242}
9701243
971void QIndividual::updateNotes(QList<QtContacts::QContactDetail> details, void* data)1244void QIndividual::updateNote(QtContacts::QContactDetail detail, void* data)
972{1245{
973 UpdateContactData *udata = static_cast<UpdateContactData*>(data);1246 FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona());
974 QList<QContactDetail> originalNotes = m_contact.details(QContactDetail::TypeNote);1247 QContactDetail originalNote = detailFromUri(QContactDetail::TypeNote, detail.detailUri());
9751248
976 if (FOLKS_IS_NOTE_DETAILS(udata->m_persona) && !detailListIsEqual(originalNotes, details)) {1249 if (!persona) {
977 GeeSet *noteSet = SET_AFD_NEW();1250 createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseNoteDetails, data);
978 Q_FOREACH(const QContactDetail& detail, details) {1251 } else if (FOLKS_IS_URL_DETAILS(persona) && (originalNote != detail)) {
979 const QContactNote *note = static_cast<const QContactNote*>(&detail);1252 qDebug() << "Note diff";
9801253 qDebug() << "\t" << originalNote << "\n\t" << detail;
981 if(!note->isEmpty()) {1254
982 FolksNoteFieldDetails *noteDetails = folks_note_field_details_new(note->note().toUtf8().data(), NULL, 0);1255 FolksNoteFieldDetails *noteDetails = 0;
9831256 const QContactNote *note = static_cast<const QContactNote*>(&detail);
984 //TODO: set context1257 GeeSet *noteSet = folks_note_details_get_notes(FOLKS_NOTE_DETAILS(persona));
985 gee_collection_add(GEE_COLLECTION(noteSet), noteDetails);1258
986 g_object_unref(noteDetails);1259 if (!noteSet || (gee_collection_get_size(GEE_COLLECTION(noteSet)) == 0)) {
987 }1260 noteSet = SET_AFD_NEW();
988 }1261 } else {
989 folks_note_details_change_notes(FOLKS_NOTE_DETAILS(udata->m_persona),1262 noteDetails = FOLKS_NOTE_FIELD_DETAILS(QIndividualUtils::getDetails(noteSet, detail.detailUri()));
1263
1264 // this will be unref at the end of the function
1265 g_object_ref(noteSet);
1266 g_object_ref(noteDetails);
1267 }
1268
1269 if (!noteDetails) {
1270 noteDetails = folks_note_field_details_new(note->note().toUtf8().data(), NULL, 0);
1271 gee_collection_add(GEE_COLLECTION(noteSet), noteDetails);
1272 } else {
1273 folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(noteDetails),
1274 note->note().toUtf8().data());
1275 }
1276
1277 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(noteDetails), detail);
1278 folks_note_details_change_notes(FOLKS_NOTE_DETAILS(persona),
990 noteSet,1279 noteSet,
991 (GAsyncReadyCallback) updateDetailsDone,1280 (GAsyncReadyCallback) updateDetailsDone,
992 data);1281 data);;
1282 g_object_unref(noteDetails);
993 g_object_unref(noteSet);1283 g_object_unref(noteSet);
994 } else {1284 } else {
995 updateDetailsDone(G_OBJECT(m_individual), NULL, data);1285 updateDetailsDone(G_OBJECT(persona), NULL, data);
996 }1286 }
997}1287}
9981288
1289QString QIndividual::callDetailChangeFinish(QtContacts::QContactDetail::DetailType detailType,
1290 FolksPersona *persona,
1291 GAsyncResult *result)
1292{
1293 Q_ASSERT(persona);
1294 Q_ASSERT(result);
1295
1296 GError *error = 0;
1297 switch(detailType) {
1298 case QContactDetail::TypeAddress:
1299 folks_postal_address_details_change_postal_addresses_finish(FOLKS_POSTAL_ADDRESS_DETAILS(persona), result, &error);
1300 break;
1301 case QContactDetail::TypeAvatar:
1302 folks_avatar_details_change_avatar_finish(FOLKS_AVATAR_DETAILS(persona), result, &error);
1303 break;
1304 case QContactDetail::TypeBirthday:
1305 folks_birthday_details_change_birthday_finish(FOLKS_BIRTHDAY_DETAILS(persona), result, &error);
1306 break;
1307 case QContactDetail::TypeDisplayLabel:
1308 folks_name_details_change_full_name_finish(FOLKS_NAME_DETAILS(persona), result, &error);
1309 break;
1310 case QContactDetail::TypeEmailAddress:
1311 folks_email_details_change_email_addresses_finish(FOLKS_EMAIL_DETAILS(persona), result, &error);
1312 break;
1313 case QContactDetail::TypeName:
1314 folks_name_details_change_structured_name_finish(FOLKS_NAME_DETAILS(persona), result, &error);
1315 break;
1316 case QContactDetail::TypeNickname:
1317 folks_name_details_change_nickname_finish(FOLKS_NAME_DETAILS(persona), result, &error);
1318 break;
1319 case QContactDetail::TypeNote:
1320 folks_note_details_change_notes_finish(FOLKS_NOTE_DETAILS(persona), result, &error);
1321 break;
1322 case QContactDetail::TypeOnlineAccount:
1323 folks_im_details_change_im_addresses_finish(FOLKS_IM_DETAILS(persona), result, &error);
1324 break;
1325 case QContactDetail::TypeOrganization:
1326 folks_role_details_change_roles_finish(FOLKS_ROLE_DETAILS(persona), result, &error);
1327 break;
1328 case QContactDetail::TypePhoneNumber:
1329 folks_phone_details_change_phone_numbers_finish(FOLKS_PHONE_DETAILS(persona), result, &error);
1330 break;
1331 case QContactDetail::TypeUrl:
1332 folks_url_details_change_urls_finish(FOLKS_URL_DETAILS(persona), result, &error);
1333 default:
1334 break;
1335 }
1336
1337 QString errorMessage;
1338 if (error) {
1339 errorMessage = QString::fromUtf8(error->message);
1340 g_error_free(error);
1341 }
1342 return errorMessage;
1343}
1344
1345void QIndividual::updateDetailsSendReply(gpointer userdata, const QString &errorMessage)
1346{
1347 UpdateContactData *data = static_cast<UpdateContactData*>(userdata);
1348 data->m_slot.invoke(data->m_object,
1349 Q_ARG(QIndividual*, data->m_self), Q_ARG(QString, errorMessage));
1350 delete data;
1351}
1352
1353void QIndividual::updateDetailsSendReply(gpointer userdata, GError *error)
1354{
1355 QString errorMessage;
1356 if (error) {
1357 errorMessage = QString::fromUtf8(error->message);
1358 qWarning() << error->message;
1359 g_error_free(error);
1360 }
1361 updateDetailsSendReply(userdata, errorMessage);
1362}
1363
1364
1365void QIndividual::createPersonaDone(GObject *aggregator, GAsyncResult *result, gpointer userdata)
1366{
1367 qDebug() << Q_FUNC_INFO;
1368 UpdateContactData *data = static_cast<UpdateContactData*>(userdata);
1369
1370 // A new persona was create to store the new data
1371 GError *error = 0;
1372 FolksPersona *newPersona = folks_individual_aggregator_add_persona_from_details_finish(FOLKS_INDIVIDUAL_AGGREGATOR(aggregator),
1373 result,
1374 &error);
1375 if (error) {
1376 updateDetailsSendReply(data, error);
1377 } else {
1378 // Link the new personas
1379 GeeSet *personas = folks_individual_get_personas(data->m_self->m_individual);
1380 GeeSet *newPersonas = SET_PERSONA_NEW();
1381 gee_collection_add_all(GEE_COLLECTION(newPersonas), GEE_COLLECTION(personas));
1382 gee_collection_add(GEE_COLLECTION(newPersonas), newPersona);
1383 data->m_self->m_primaryPersona = newPersona;
1384 folks_individual_aggregator_link_personas(data->m_self->m_aggregator, newPersonas, updateDetailsDone, userdata);
1385 }
1386}
9991387
1000void QIndividual::updateDetailsDone(GObject *detail, GAsyncResult *result, gpointer userdata)1388void QIndividual::updateDetailsDone(GObject *detail, GAsyncResult *result, gpointer userdata)
1001{1389{
1002 GError *error = 0;1390 QString errorMessage;
1003 UpdateContactData *data = static_cast<UpdateContactData*>(userdata);1391 UpdateContactData *data = static_cast<UpdateContactData*>(userdata);
10041392 if (result && !data->m_currentDetail.isEmpty()) {
1005 switch(data->m_currentDetailType) {1393 if (FOLKS_IS_PERSONA(detail)) {
1394 // This is a normal field update
1395 errorMessage = QIndividual::callDetailChangeFinish(data->m_currentDetail.type(),
1396 FOLKS_PERSONA(detail),
1397 result);
1398 } else if (FOLKS_IS_INDIVIDUAL_AGGREGATOR(detail)) {
1399 GError *error = 0;
1400 folks_individual_aggregator_link_personas_finish(FOLKS_INDIVIDUAL_AGGREGATOR(detail), result, &error);
1401 if (error) {
1402 errorMessage = QString::fromUtf8(error->message);
1403 }
1404 }
1405
1406 if (!errorMessage.isEmpty()) {
1407 updateDetailsSendReply(data, errorMessage);
1408 return;
1409 }
1410 }
1411
1412 if (data->m_details.isEmpty()) {
1413 updateDetailsSendReply(data, 0);
1414 return;
1415 }
1416
1417
1418 data->m_currentDetail = data->m_details.takeFirst();
1419 switch(data->m_currentDetail.type()) {
1006 case QContactDetail::TypeAddress:1420 case QContactDetail::TypeAddress:
1007 if (result) {1421 data->m_self->updateAddress(data->m_currentDetail, data);
1008 folks_postal_address_details_change_postal_addresses_finish(FOLKS_POSTAL_ADDRESS_DETAILS(data->m_persona), result, &error);
1009 }
1010 if (!error) {
1011 data->m_currentDetailType = QContactDetail::TypeAvatar;
1012 data->m_self->updatePhoto(data->m_newContact.detail(QContactDetail::TypeAvatar), data);
1013 return;
1014 }
1015 break;1422 break;
1016 case QContactDetail::TypeAvatar:1423 case QContactDetail::TypeAvatar:
1017 if (result) {1424 data->m_self->updatePhoto(data->m_currentDetail, data);
1018 folks_avatar_details_change_avatar_finish(FOLKS_AVATAR_DETAILS(data->m_persona), result, &error);
1019 }
1020 if (!error) {
1021 data->m_currentDetailType = QContactDetail::TypeBirthday;
1022 data->m_self->updateBirthday(data->m_newContact.detail(QContactDetail::TypeBirthday), data);
1023 return;
1024 }
1025 break;1425 break;
1026 case QContactDetail::TypeBirthday:1426 case QContactDetail::TypeBirthday:
1027 if (result) {1427 data->m_self->updateBirthday(data->m_currentDetail, data);
1028 folks_birthday_details_change_birthday_finish(FOLKS_BIRTHDAY_DETAILS(data->m_persona), result, &error);
1029 }
1030 if (!error) {
1031 data->m_currentDetailType = QContactDetail::TypeDisplayLabel;
1032 data->m_self->updateFullName(data->m_newContact.detail(QContactDetail::TypeDisplayLabel), data);
1033 return;
1034 }
1035 break;1428 break;
1036 case QContactDetail::TypeDisplayLabel:1429 case QContactDetail::TypeDisplayLabel:
1037 if (result) {1430 data->m_self->updateFullName(data->m_currentDetail, data);
1038 folks_name_details_change_full_name_finish(FOLKS_NAME_DETAILS(data->m_persona), result, &error);
1039 }
1040 if (!error) {
1041 data->m_currentDetailType = QContactDetail::TypeEmailAddress;
1042 data->m_self->updateEmails(data->m_newContact.details(QContactDetail::TypeEmailAddress), data);
1043 return;
1044 }
1045 break;1431 break;
1046
1047 case QContactDetail::TypeEmailAddress:1432 case QContactDetail::TypeEmailAddress:
1048 if (result) {1433 data->m_self->updateEmail(data->m_currentDetail, data);
1049 folks_email_details_change_email_addresses_finish(FOLKS_EMAIL_DETAILS(data->m_persona), result, &error);
1050 }
1051 if (!error) {
1052 data->m_currentDetailType = QContactDetail::TypeName;
1053 data->m_self->updateName(data->m_newContact.detail(QContactDetail::TypeName), data);
1054 return;
1055 }
1056 break;1434 break;
1057 case QContactDetail::TypeName:1435 case QContactDetail::TypeName:
1058 if (result) {1436 data->m_self->updateName(data->m_currentDetail, data);
1059 folks_name_details_change_structured_name_finish(FOLKS_NAME_DETAILS(data->m_persona), result, &error);
1060 }
1061 if (!error) {
1062 data->m_currentDetailType = QContactDetail::TypeNickname;
1063 data->m_self->updateNickname(data->m_newContact.detail(QContactDetail::TypeNickname), data);
1064 return;
1065 }
1066 break;1437 break;
1067 case QContactDetail::TypeNickname:1438 case QContactDetail::TypeNickname:
1068 if (result) {1439 data->m_self->updateNickname(data->m_currentDetail, data);
1069 folks_name_details_change_nickname_finish(FOLKS_NAME_DETAILS(data->m_persona), result, &error);
1070 }
1071 if (!error) {
1072 data->m_currentDetailType = QContactDetail::TypeNote;
1073 data->m_self->updateNotes(data->m_newContact.details(QContactDetail::TypeNote), data);
1074 return;
1075 }
1076 break;1440 break;
1077 case QContactDetail::TypeNote:1441 case QContactDetail::TypeNote:
1078 if (result) {1442 data->m_self->updateNote(data->m_currentDetail, data);
1079 folks_note_details_change_notes_finish(FOLKS_NOTE_DETAILS(data->m_persona), result, &error);
1080 }
1081 if (!error) {
1082 data->m_currentDetailType = QContactDetail::TypeOnlineAccount;
1083 data->m_self->updateIms(data->m_newContact.details(QContactDetail::TypeOnlineAccount), data);
1084 return;
1085 }
1086 break;1443 break;
1087 case QContactDetail::TypeOnlineAccount:1444 case QContactDetail::TypeOnlineAccount:
1088 if (result) {1445 data->m_self->updateIm(data->m_currentDetail, data);
1089 folks_im_details_change_im_addresses_finish(FOLKS_IM_DETAILS(data->m_persona), result, &error);
1090 }
1091 if (!error) {
1092 data->m_currentDetailType = QContactDetail::TypeOrganization;
1093 data->m_self->updateRoles(data->m_newContact.details(QContactDetail::TypeOrganization), data);
1094 return;
1095 }
1096 break;1446 break;
1097 case QContactDetail::TypeOrganization:1447 case QContactDetail::TypeOrganization:
1098 if (result) {1448 data->m_self->updateRole(data->m_currentDetail, data);
1099 folks_role_details_change_roles_finish(FOLKS_ROLE_DETAILS(data->m_persona), result, &error);
1100 }
1101 if (!error) {
1102 data->m_currentDetailType = QContactDetail::TypePhoneNumber;
1103 data->m_self->updatePhones(data->m_newContact.details(QContactDetail::TypePhoneNumber), data);
1104 return;
1105 }
1106 break;1449 break;
1107 case QContactDetail::TypePhoneNumber:1450 case QContactDetail::TypePhoneNumber:
1108 if (result) {1451 data->m_self->updatePhone(data->m_currentDetail, data);
1109 folks_phone_details_change_phone_numbers_finish(FOLKS_PHONE_DETAILS(data->m_persona), result, &error);
1110 }
1111 if (!error) {
1112 data->m_currentDetailType = QContactDetail::TypeUrl;
1113 data->m_self->updateUrls(data->m_newContact.details(QContactDetail::TypeUrl), data);
1114 return;
1115 }
1116 break;1452 break;
1117 case QContactDetail::TypeUrl:1453 case QContactDetail::TypeUrl:
1118 if (result) {1454 data->m_self->updateUrl(data->m_currentDetail, data);
1119 folks_url_details_change_urls_finish(FOLKS_URL_DETAILS(data->m_persona), result, &error);1455 break;
1120 }
1121 default:1456 default:
1457 qWarning() << "Update not implemented for" << data->m_currentDetail.type();
1458 updateDetailsDone(0, 0, data);
1122 break;1459 break;
1123 }1460 }
1124
1125 QString errorMessage;
1126 if (error) {
1127 errorMessage = QString::fromUtf8(error->message);
1128 g_error_free(error);
1129 }
1130
1131 qDebug() << "Update done" << errorMessage;
1132 data->m_doneCB(errorMessage, data->m_doneData);
1133 delete data;
1134}1461}
11351462
11361463bool QIndividual::update(const QtContacts::QContact &newContact, QObject *object, const QString &slot)
1137bool QIndividual::update(const QtContacts::QContact &newContact, UpdateDoneCB cb, void* userData)
1138{1464{
1465 int slotIndex = object->metaObject()->indexOfSlot(QMetaObject::normalizedSignature(slot.toUtf8().data()));
1466 if (slotIndex == -1) {
1467 qWarning() << "Invalid slot:" << slot << "for object" << object;
1468 return false;
1469 }
1470
1139 QContact &originalContact = contact();1471 QContact &originalContact = contact();
1140 if (newContact != originalContact) {1472 if (newContact != originalContact) {
11411473
1142 UpdateContactData *data = new UpdateContactData;1474 UpdateContactData *data = new UpdateContactData;
1143 data->m_currentDetailType = QContactDetail::TypeAddress;1475 data->m_details = newContact.details();
1144 data->m_newContact = newContact;1476 data->m_newContact = newContact;
1145 data->m_self = this;1477 data->m_self = this;
1146 data->m_doneCB = cb;1478 data->m_object = object;
1147 data->m_doneData = userData;1479 data->m_slot = object->metaObject()->method(slotIndex);
1148 data->m_persona = primaryPersona();1480 updateDetailsDone(0, 0, data);
1149
1150 updateAddresses(newContact.details(QContactDetail::TypeAddress), data);
1151 return true;1481 return true;
1152 } else {1482 } else {
1153 qDebug() << "Contact is equal";1483 qDebug() << "Contact is equal";
@@ -1160,10 +1490,26 @@
1160 return m_individual;1490 return m_individual;
1161}1491}
11621492
1163bool QIndividual::update(const QString &vcard, UpdateDoneCB cb, void* data)1493void QIndividual::setIndividual(FolksIndividual *individual)
1494{
1495 if (m_individual != individual) {
1496 if (m_individual) {
1497 g_object_unref(m_individual);
1498 }
1499 m_individual = individual;
1500 if (m_individual) {
1501 g_object_ref(m_individual);
1502 }
1503 // initialize qcontact
1504 m_contact = QContact();
1505 updateContact();
1506 }
1507}
1508
1509bool QIndividual::update(const QString &vcard, QObject *object, const QString &slot)
1164{1510{
1165 QContact contact = VCardParser::vcardToContact(vcard);1511 QContact contact = VCardParser::vcardToContact(vcard);
1166 return update(contact, cb, data);1512 return update(contact, object, slot);
1167}1513}
11681514
1169QStringList QIndividual::listParameters(FolksAbstractFieldDetails *details)1515QStringList QIndividual::listParameters(FolksAbstractFieldDetails *details)
@@ -1362,6 +1708,8 @@
1362{1708{
1363 static QMap<QString, int> map;1709 static QMap<QString, int> map;
13641710
1711 qDebug() << "PArse paramater:" << parameters;
1712
1365 // populate the map once1713 // populate the map once
1366 if (map.isEmpty()) {1714 if (map.isEmpty()) {
1367 map["home"] = QContactDetail::ContextHome;1715 map["home"] = QContactDetail::ContextHome;
@@ -1372,9 +1720,9 @@
1372 QList<int> values;1720 QList<int> values;
1373 QStringList accepted;1721 QStringList accepted;
1374 Q_FOREACH(const QString &param, parameters) {1722 Q_FOREACH(const QString &param, parameters) {
1375 if (map.contains(param)) {1723 if (map.contains(param.toLower())) {
1376 accepted << param;1724 accepted << param;
1377 values << map[param];1725 values << map[param.toLower()];
1378 }1726 }
1379 }1727 }
13801728
@@ -1382,6 +1730,8 @@
1382 parameters.removeOne(param);1730 parameters.removeOne(param);
1383 }1731 }
13841732
1733 qDebug() << "PArseed paramater (DONE):" << parameters;
1734
1385 return values;1735 return values;
1386}1736}
13871737
@@ -1407,8 +1757,8 @@
14071757
1408 QList<int> subTypes;1758 QList<int> subTypes;
1409 Q_FOREACH(const QString &param, params) {1759 Q_FOREACH(const QString &param, params) {
1410 if (mapTypes.contains(param)) {1760 if (mapTypes.contains(param.toLower())) {
1411 subTypes << mapTypes[param];1761 subTypes << mapTypes[param.toLower()];
1412 } else {1762 } else {
1413 qWarning() << "Invalid phone parameter:" << param;1763 qWarning() << "Invalid phone parameter:" << param;
1414 }1764 }
@@ -1434,8 +1784,8 @@
1434 QList<int> values;1784 QList<int> values;
14351785
1436 Q_FOREACH(const QString &param, parameters) {1786 Q_FOREACH(const QString &param, parameters) {
1437 if (map.contains(param)) {1787 if (map.contains(param.toLower())) {
1438 values << map[param];1788 values << map[param.toLower()];
1439 } else {1789 } else {
1440 qWarning() << "invalid Address subtype" << param;1790 qWarning() << "invalid Address subtype" << param;
1441 }1791 }
@@ -1461,8 +1811,8 @@
1461 QSet<int> values;1811 QSet<int> values;
14621812
1463 Q_FOREACH(const QString &param, parameters) {1813 Q_FOREACH(const QString &param, parameters) {
1464 if (map.contains(param)) {1814 if (map.contains(param.toLower())) {
1465 values << map[param];1815 values << map[param.toLower()];
1466 } else {1816 } else {
1467 qWarning() << "invalid IM subtype" << param;1817 qWarning() << "invalid IM subtype" << param;
1468 }1818 }
@@ -1497,8 +1847,8 @@
1497 map["yahoo"] = QContactOnlineAccount::ProtocolYahoo;1847 map["yahoo"] = QContactOnlineAccount::ProtocolYahoo;
1498 }1848 }
14991849
1500 if (map.contains(protocol)) {1850 if (map.contains(protocol.toLower())) {
1501 return map[protocol];1851 return map[protocol.toLower()];
1502 } else {1852 } else {
1503 qWarning() << "invalid IM protocol" << protocol;1853 qWarning() << "invalid IM protocol" << protocol;
1504 }1854 }
@@ -1532,31 +1882,26 @@
1532 return map[QContactOnlineAccount::ProtocolUnknown];1882 return map[QContactOnlineAccount::ProtocolUnknown];
1533}1883}
15341884
1535GHashTable *QIndividual::parseDetails(const QtContacts::QContact &contact)1885GHashTable *QIndividual::parseAddressDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1536{1886{
1537 GHashTable *details = g_hash_table_new_full(g_str_hash,1887 if(cDetails.size() == 0) {
1538 g_str_equal,1888 return details;
1539 NULL,1889 }
1540 (GDestroyNotify) QIndividualUtils::gValueSliceFree);1890
1541 GValue *value;1891 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT);
15421892
1543 /*1893 Q_FOREACH(const QContactDetail& detail, cDetails) {
1544 * Addresses1894 if(!detail.isEmpty()) {
1545 */1895 QContactAddress address = static_cast<QContactAddress>(detail);
1546 QList<QContactAddress> addresses = contact.details<QContactAddress>();
1547 if(addresses.size() > 0) {
1548 value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT);
1549 Q_FOREACH(const QContactAddress& address, addresses) {
1550 if(!address.isEmpty()) {
1551 FolksPostalAddress *postalAddress = folks_postal_address_new(address.postOfficeBox().toUtf8().data(),1896 FolksPostalAddress *postalAddress = folks_postal_address_new(address.postOfficeBox().toUtf8().data(),
1552 NULL, // extension1897 NULL, // extension
1553 address.street().toUtf8().data(),1898 address.street().toUtf8().data(),
1554 address.locality().toUtf8().data(),1899 address.locality().toUtf8().data(),
1555 address.region().toUtf8().data(),1900 address.region().toUtf8().data(),
1556 address.postcode().toUtf8().data(),1901 address.postcode().toUtf8().data(),
1557 address.country().toUtf8().data(),1902 address.country().toUtf8().data(),
1558 NULL, // address format1903 NULL, // address format
1559 NULL); //UID1904 NULL); //UID
15601905
1561 GeeCollection *collection = (GeeCollection*) g_value_get_object(value);1906 GeeCollection *collection = (GeeCollection*) g_value_get_object(value);
1562 if(collection == NULL) {1907 if(collection == NULL) {
@@ -1570,188 +1915,318 @@
15701915
1571 g_object_unref(pafd);1916 g_object_unref(pafd);
1572 g_object_unref(postalAddress);1917 g_object_unref(postalAddress);
1573 }
1574 }1918 }
1575 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_POSTAL_ADDRESSES, value);1919 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_POSTAL_ADDRESSES, value);
1576 }1920 }
15771921
15781922 return details;
1579 /*1923}
1580 * Avatar1924
1581 */1925GHashTable *QIndividual::parsePhotoDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1582 QContactAvatar avatar = contact.detail<QContactAvatar>();1926{
1583 if(!avatar.isEmpty()) {1927 if(cDetails.size() == 0) {
1584 value = QIndividualUtils::gValueSliceNew(G_TYPE_FILE_ICON);1928 return details;
1585 QUrl avatarUri = avatar.imageUrl();1929 }
1586 if(!avatarUri.isEmpty()) {1930
1587 QString formattedUri = avatarUri.toString(QUrl::RemoveUserInfo);1931 Q_FOREACH(const QContactDetail& detail, cDetails) {
1588 if(!formattedUri.isEmpty()) {1932 QContactAvatar avatar = static_cast<QContactAvatar>(detail);
1589 GFile *avatarFile = g_file_new_for_uri(formattedUri.toUtf8().data());1933 if(!avatar.isEmpty()) {
1590 GFileIcon *avatarFileIcon = G_FILE_ICON(g_file_icon_new(avatarFile));1934 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_FILE_ICON);
1591 g_value_take_object(value, avatarFileIcon);1935 QUrl avatarUri = avatar.imageUrl();
15921936 if(!avatarUri.isEmpty()) {
1593 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_AVATAR, value);1937 QString formattedUri = avatarUri.toString(QUrl::RemoveUserInfo);
1594 g_clear_object((GObject**) &avatarFile);1938 if(!formattedUri.isEmpty()) {
1595 }1939 GFile *avatarFile = g_file_new_for_uri(formattedUri.toUtf8().data());
1596 }1940 GFileIcon *avatarFileIcon = G_FILE_ICON(g_file_icon_new(avatarFile));
1597 }1941 g_value_take_object(value, avatarFileIcon);
15981942
1599 /*1943 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_AVATAR, value);
1600 * Birthday1944 g_clear_object((GObject**) &avatarFile);
1601 */1945 }
1602 QContactBirthday birthday = contact.detail<QContactBirthday>();1946 } else {
1603 if(!birthday.isEmpty()) {1947 g_object_unref(value);
1604 value = QIndividualUtils::gValueSliceNew(G_TYPE_DATE_TIME);1948 }
1605 GDateTime *dateTime = g_date_time_new_from_unix_utc(birthday.dateTime().toMSecsSinceEpoch() / 1000);1949 }
1606 g_value_set_boxed(value, dateTime);1950 }
16071951
1608 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_BIRTHDAY, value);1952 return details;
1609 g_date_time_unref(dateTime);1953}
1610 }1954
16111955GHashTable *QIndividual::parseBirthdayDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1612 /*1956{
1613 * Email addresses1957 if(cDetails.size() == 0) {
1614 */1958 return details;
1615 PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details,1959 }
1960
1961 Q_FOREACH(const QContactDetail& detail, cDetails) {
1962 QContactBirthday birthday = static_cast<QContactBirthday>(detail);
1963 if(!birthday.isEmpty()) {
1964 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_DATE_TIME);
1965 GDateTime *dateTime = g_date_time_new_from_unix_utc(birthday.dateTime().toMSecsSinceEpoch() / 1000);
1966 g_value_set_boxed(value, dateTime);
1967
1968 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_BIRTHDAY, value);
1969 g_date_time_unref(dateTime);
1970 }
1971 }
1972
1973 return details;
1974}
1975
1976GHashTable *QIndividual::parseEmailDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1977{
1978 if(cDetails.size() == 0) {
1979 return details;
1980 }
1981
1982 GValue *value;
1983 PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, cDetails,
1616 FOLKS_PERSONA_DETAIL_EMAIL_ADDRESSES, value, QContactEmailAddress,1984 FOLKS_PERSONA_DETAIL_EMAIL_ADDRESSES, value, QContactEmailAddress,
1617 FOLKS_TYPE_EMAIL_FIELD_DETAILS, emailAddress);1985 FOLKS_TYPE_EMAIL_FIELD_DETAILS, emailAddress);
16181986 return details;
1619 /*1987}
1620 * Favorite1988
1621 */1989GHashTable *QIndividual::parseFavoriteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1622 QContactFavorite favorite = contact.detail<QContactFavorite>();1990{
1623 if(!favorite.isEmpty()) {1991 if(cDetails.size() == 0) {
1624 value = QIndividualUtils::gValueSliceNew(G_TYPE_BOOLEAN);1992 return details;
1625 g_value_set_boolean(value, favorite.isFavorite());1993 }
16261994
1627 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IS_FAVOURITE, value);1995 Q_FOREACH(const QContactDetail& detail, cDetails) {
1628 }1996 QContactFavorite favorite = static_cast<QContactFavorite>(detail);
16291997 if(!favorite.isEmpty()) {
1630 /*1998 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_BOOLEAN);
1631 * Gender1999 g_value_set_boolean(value, favorite.isFavorite());
1632 */2000
1633 QContactGender gender = contact.detail<QContactGender>();2001 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IS_FAVOURITE, value);
1634 if(!gender.isEmpty()) {2002 }
1635 value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_GENDER);2003 }
1636 FolksGender genderEnum = FOLKS_GENDER_UNSPECIFIED;2004
1637 if(gender.gender() == QContactGender::GenderMale) {2005 return details;
1638 genderEnum = FOLKS_GENDER_MALE;2006}
1639 } else if(gender.gender() == QContactGender::GenderFemale) {2007
1640 genderEnum = FOLKS_GENDER_FEMALE;2008GHashTable *QIndividual::parseGenderDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1641 }2009{
1642 g_value_set_enum(value, genderEnum);2010 if(cDetails.size() == 0) {
16432011 return details;
1644 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_GENDER, value);2012 }
1645 }2013
16462014 Q_FOREACH(const QContactDetail& detail, cDetails) {
1647 /*2015 QContactGender gender = static_cast<QContactDetail>(detail);
1648 * Names2016 if(!gender.isEmpty()) {
1649 */2017 GValue *value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_GENDER);
1650 QContactName name = contact.detail<QContactName>();2018 FolksGender genderEnum = FOLKS_GENDER_UNSPECIFIED;
1651 if(!name.isEmpty()) {2019 if(gender.gender() == QContactGender::GenderMale) {
1652 value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_STRUCTURED_NAME);2020 genderEnum = FOLKS_GENDER_MALE;
1653 FolksStructuredName *sn = folks_structured_name_new(name.lastName().toUtf8().data(),2021 } else if(gender.gender() == QContactGender::GenderFemale) {
1654 name.firstName().toUtf8().data(),2022 genderEnum = FOLKS_GENDER_FEMALE;
1655 name.middleName().toUtf8().data(),2023 }
1656 name.prefix().toUtf8().data(),2024 g_value_set_enum(value, genderEnum);
1657 name.suffix().toUtf8().data());2025
1658 g_value_take_object(value, sn);2026 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_GENDER, value);
1659 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_STRUCTURED_NAME, value);2027 }
1660 }2028 }
16612029
1662 QContactDisplayLabel displayLabel = contact.detail<QContactDisplayLabel>();2030 return details;
1663 if(!displayLabel.label().isEmpty()) {2031}
1664 value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING);2032
1665 g_value_set_string(value, displayLabel.label().toUtf8().data());2033GHashTable *QIndividual::parseNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1666 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_FULL_NAME, value);2034{
16672035 if(cDetails.size() == 0) {
1668 // FIXME: check if those values should all be set to the same thing2036 return details;
1669 value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING);2037 }
1670 g_value_set_string(value, displayLabel.label().toUtf8().data());2038
1671 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ALIAS, value);2039 Q_FOREACH(const QContactDetail& detail, cDetails) {
1672 }2040 QContactName name = static_cast<QContactName>(detail);
16732041 if(!name.isEmpty()) {
1674 /*2042 GValue *value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_STRUCTURED_NAME);
1675 * Notes2043 FolksStructuredName *sn = folks_structured_name_new(name.lastName().toUtf8().data(),
1676 */2044 name.firstName().toUtf8().data(),
1677 PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details,2045 name.middleName().toUtf8().data(),
2046 name.prefix().toUtf8().data(),
2047 name.suffix().toUtf8().data());
2048 g_value_take_object(value, sn);
2049 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_STRUCTURED_NAME, value);
2050 }
2051 }
2052
2053 return details;
2054}
2055
2056GHashTable *QIndividual::parseFullNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
2057{
2058 if(cDetails.size() == 0) {
2059 return details;
2060 }
2061
2062 Q_FOREACH(const QContactDetail& detail, cDetails) {
2063 QContactDisplayLabel displayLabel = static_cast<QContactDisplayLabel>(detail);
2064 if(!displayLabel.label().isEmpty()) {
2065 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING);
2066 g_value_set_string(value, displayLabel.label().toUtf8().data());
2067 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_FULL_NAME, value);
2068
2069 // FIXME: check if those values should all be set to the same thing
2070 value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING);
2071 g_value_set_string(value, displayLabel.label().toUtf8().data());
2072 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ALIAS, value);
2073 }
2074 }
2075
2076 return details;
2077}
2078
2079GHashTable *QIndividual::parseNicknameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
2080{
2081 if(cDetails.size() == 0) {
2082 return details;
2083 }
2084
2085 Q_FOREACH(const QContactDetail& detail, cDetails) {
2086 QContactNickname nickname = static_cast<QContactNickname>(detail);
2087 if(!nickname.nickname().isEmpty()) {
2088 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING);
2089 g_value_set_string(value, nickname.nickname().toUtf8().data());
2090 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_NICKNAME, value);
2091
2092 // FIXME: check if those values should all be set to the same thing
2093 value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING);
2094 g_value_set_string(value, nickname.nickname().toUtf8().data());
2095 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ALIAS, value);
2096 }
2097 }
2098
2099 return details;
2100}
2101
2102GHashTable *QIndividual::parseNoteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
2103{
2104 if(cDetails.size() == 0) {
2105 return details;
2106 }
2107
2108 GValue *value;
2109 PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, cDetails,
1678 FOLKS_PERSONA_DETAIL_NOTES, value, QContactNote,2110 FOLKS_PERSONA_DETAIL_NOTES, value, QContactNote,
1679 FOLKS_TYPE_NOTE_FIELD_DETAILS, note);2111 FOLKS_TYPE_NOTE_FIELD_DETAILS, note);
16802112
16812113 return details;
16822114}
1683 /*2115
1684 * OnlineAccounts2116GHashTable *QIndividual::parseImDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1685 */2117{
1686 QList<QContactOnlineAccount> accounts = contact.details<QContactOnlineAccount>();2118 if(cDetails.size() == 0) {
1687 if(!accounts.isEmpty()) {2119 return details;
1688 QMultiMap<QString, QString> providerUidMap;2120 }
16892121
1690 Q_FOREACH(const QContactOnlineAccount &account, accounts) {2122 QMultiMap<QString, QString> providerUidMap;
1691 if (!account.isEmpty()) {2123 Q_FOREACH(const QContactDetail &detail, cDetails) {
1692 providerUidMap.insert(onlineAccountProtocolFromEnum(account.protocol()), account.accountUri());2124 QContactOnlineAccount account = static_cast<QContactOnlineAccount>(detail);
1693 }2125 if (!account.isEmpty()) {
1694 }2126 providerUidMap.insert(onlineAccountProtocolFromEnum(account.protocol()), account.accountUri());
16952127 }
1696 if(!providerUidMap.isEmpty()) {2128 }
1697 //TODO: add account type and subtype2129
1698 value = QIndividualUtils::asvSetStrNew(providerUidMap);2130 if(!providerUidMap.isEmpty()) {
1699 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IM_ADDRESSES, value);2131 //TODO: add account type and subtype
1700 }2132 GValue *value = QIndividualUtils::asvSetStrNew(providerUidMap);
1701 }2133 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IM_ADDRESSES, value);
17022134 }
1703 /*2135
1704 * Organization2136 return details;
1705 */2137}
1706 QList<QContactOrganization> orgs = contact.details<QContactOrganization>();2138
1707 if(orgs.size() > 0) {2139GHashTable *QIndividual::parseOrganizationDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1708 value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT);2140{
1709 Q_FOREACH(const QContactOrganization& org, orgs) {2141 if(cDetails.size() == 0) {
1710 if(!org.isEmpty()) {2142 return details;
1711 FolksRole *role = folks_role_new(org.title().toUtf8().data(),2143 }
1712 org.name().toUtf8().data(),2144
1713 NULL);2145 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT);
1714 folks_role_set_role(role, org.role().toUtf8().data());2146 Q_FOREACH(const QContactDetail& detail, cDetails) {
17152147 QContactOrganization org = static_cast<QContactOrganization>(detail);
1716 GeeCollection *collection = (GeeCollection*) g_value_get_object(value);2148 if(!org.isEmpty()) {
1717 if(collection == NULL) {2149 FolksRole *role = folks_role_new(org.title().toUtf8().data(),
1718 collection = GEE_COLLECTION(SET_AFD_NEW());2150 org.name().toUtf8().data(),
1719 g_value_take_object(value, collection);2151 NULL);
1720 }2152 folks_role_set_role(role, org.role().toUtf8().data());
1721 FolksRoleFieldDetails *rfd = folks_role_field_details_new(role, NULL);2153
1722 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(rfd), org);2154 GeeCollection *collection = (GeeCollection*) g_value_get_object(value);
1723 gee_collection_add(collection, rfd);2155 if(collection == NULL) {
17242156 collection = GEE_COLLECTION(SET_AFD_NEW());
1725 g_object_unref(rfd);2157 g_value_take_object(value, collection);
1726 g_object_unref(role);2158 }
1727 }2159 FolksRoleFieldDetails *rfd = folks_role_field_details_new(role, NULL);
1728 }2160 parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(rfd), org);
1729 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ROLES, value);2161 gee_collection_add(collection, rfd);
1730 }2162
17312163 g_object_unref(rfd);
1732 /*2164 g_object_unref(role);
1733 * Phone Numbers2165 }
1734 */2166 }
1735 QList<QContactPhoneNumber> phones = contact.details<QContactPhoneNumber>();2167 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ROLES, value);
1736 if (phones.size() > 0) {2168
1737 value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT);2169 return details;
1738 Q_FOREACH(const QContactPhoneNumber &phone, phones) {2170}
1739 if(!phone.isEmpty()) {2171
1740 QIndividualUtils::gValueGeeSetAddStringFieldDetails(value,2172GHashTable *QIndividual::parsePhoneNumbersDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
1741 FOLKS_TYPE_PHONE_FIELD_DETAILS,2173{
1742 phone.number().toUtf8().data(),2174 if(cDetails.size() == 0) {
1743 phone);2175 return details;
1744 }2176 }
1745 }2177
1746 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_PHONE_NUMBERS, value);2178 GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT);
1747 }2179 Q_FOREACH(const QContactDetail &detail, cDetails) {
17482180 QContactPhoneNumber phone = static_cast<QContactPhoneNumber>(detail);
1749 /*2181 if(!phone.isEmpty()) {
1750 * URLs2182 QIndividualUtils::gValueGeeSetAddStringFieldDetails(value,
1751 */2183 FOLKS_TYPE_PHONE_FIELD_DETAILS,
1752 PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details,2184 phone.number().toUtf8().data(),
2185 phone);
2186 }
2187 }
2188 QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_PHONE_NUMBERS, value);
2189
2190 return details;
2191}
2192
2193GHashTable *QIndividual::parseUrlDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails)
2194{
2195 if(cDetails.size() == 0) {
2196 return details;
2197 }
2198
2199 GValue *value;
2200 PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, cDetails,
1753 FOLKS_PERSONA_DETAIL_URLS, value, QContactUrl,2201 FOLKS_PERSONA_DETAIL_URLS, value, QContactUrl,
1754 FOLKS_TYPE_URL_FIELD_DETAILS, url);2202 FOLKS_TYPE_URL_FIELD_DETAILS, url);
2203
2204 return details;
2205}
2206
2207
2208GHashTable *QIndividual::parseDetails(const QtContacts::QContact &contact)
2209{
2210 GHashTable *details = g_hash_table_new_full(g_str_hash,
2211 g_str_equal,
2212 NULL,
2213 (GDestroyNotify) QIndividualUtils::gValueSliceFree);
2214
2215 parseAddressDetails(details, contact.details(QContactAddress::Type));
2216 parsePhotoDetails(details, contact.details(QContactAvatar::Type));
2217 parseBirthdayDetails(details, contact.details(QContactBirthday::Type));
2218 parseEmailDetails(details, contact.details(QContactEmailAddress::Type));
2219 parseFavoriteDetails(details, contact.details(QContactFavorite::Type));
2220 parseGenderDetails(details, contact.details(QContactGender::Type));
2221 parseNameDetails(details, contact.details(QContactName::Type));
2222 parseFullNameDetails(details, contact.details(QContactDisplayLabel::Type));
2223 parseNicknameDetails(details, contact.details(QContactNickname::Type));
2224 parseNoteDetails(details, contact.details(QContactNote::Type));
2225 parseImDetails(details, contact.details(QContactOnlineAccount::Type));
2226 parseOrganizationDetails(details, contact.details(QContactOrganization::Type));
2227 parsePhoneNumbersDetails(details, contact.details(QContactPhoneNumber::Type));
2228 parseUrlDetails(details, contact.details(QContactUrl::Type));
2229
1755 return details;2230 return details;
1756}2231}
17572232
@@ -1761,29 +2236,39 @@
1761{2236{
1762}2237}
17632238
1764FolksPersona* QIndividual::primaryPersona() const2239FolksPersona* QIndividual::primaryPersona()
1765{2240{
1766 if(m_individual == 0) {2241 Q_ASSERT(m_individual);
1767 return 0;2242
2243 if (m_primaryPersona) {
2244 return m_primaryPersona;
1768 }2245 }
17692246
1770 FolksPersona *retval = NULL;
1771 GeeSet *personas = folks_individual_get_personas(m_individual);2247 GeeSet *personas = folks_individual_get_personas(m_individual);
1772 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas));2248 GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas));
2249 FolksPersonaStore *primaryStore = folks_individual_aggregator_get_primary_store(m_aggregator);
17732250
1774 while(retval == NULL && gee_iterator_next(iter)) {2251 while(m_primaryPersona == NULL && gee_iterator_next(iter)) {
1775 FolksPersona *persona = FOLKS_PERSONA(gee_iterator_get(iter));2252 FolksPersona *persona = FOLKS_PERSONA(gee_iterator_get(iter));
1776 FolksPersonaStore *primaryStore = folks_individual_aggregator_get_primary_store(m_aggregator);
1777 if(folks_persona_get_store(persona) == primaryStore) {2253 if(folks_persona_get_store(persona) == primaryStore) {
1778 retval = persona;2254 m_primaryPersona = persona;
1779 g_object_ref(retval);2255 g_object_ref (persona);
1780 }2256 }
1781
1782 g_object_unref(persona);2257 g_object_unref(persona);
1783 }2258 }
1784 g_object_unref (iter);2259 g_object_unref (iter);
17852260
1786 return retval;2261 return m_primaryPersona;
2262}
2263
2264QtContacts::QContactDetail QIndividual::detailFromUri(QtContacts::QContactDetail::DetailType type, const QString &uri) const
2265{
2266 Q_FOREACH(QContactDetail detail, m_contact.details(type)) {
2267 if (detail.detailUri() == uri) {
2268 return detail;
2269 }
2270 }
2271 return m_contact.detail(type);
1787}2272}
17882273
1789} //namespace2274} //namespace
17902275
=== modified file 'src/qindividual.h'
--- src/qindividual.h 2013-06-11 13:00:01 +0000
+++ src/qindividual.h 2013-06-20 20:58:26 +0000
@@ -31,7 +31,7 @@
3131
32namespace galera32namespace galera
33{33{
34typedef void (*UpdateDoneCB)(const QString&, void*);34typedef GHashTable* (ParseDetailsFunc)(GHashTable*, const QList<QtContacts::QContactDetail> &);
3535
36typedef QList<QtVersit::QVersitProperty> PropertyList;36typedef QList<QtVersit::QVersitProperty> PropertyList;
37class QIndividual37class QIndividual
@@ -59,40 +59,47 @@
5959
60 QtContacts::QContact &contact();60 QtContacts::QContact &contact();
61 QtContacts::QContact copy(Fields fields = QIndividual::All);61 QtContacts::QContact copy(Fields fields = QIndividual::All);
62 bool update(const QString &vcard, UpdateDoneCB cb, void* data);62 bool update(const QString &vcard, QObject *object, const QString &slot);
63 bool update(const QtContacts::QContact &contact, UpdateDoneCB cb, void* data);63 bool update(const QtContacts::QContact &contact, QObject *object, const QString &slot);
64 FolksIndividual *individual() const;64 FolksIndividual *individual() const;
65 void setIndividual(FolksIndividual *individual);
6566
66 static GHashTable *parseDetails(const QtContacts::QContact &contact);67 static GHashTable *parseDetails(const QtContacts::QContact &contact);
67
68private:68private:
69 FolksIndividual *m_individual;69 FolksIndividual *m_individual;
70 FolksPersona *m_primaryPersona;
70 FolksIndividualAggregator *m_aggregator;71 FolksIndividualAggregator *m_aggregator;
71 QtContacts::QContact m_contact;72 QtContacts::QContact m_contact;
72 QMap<QString, QPair<QtContacts::QContactDetail, FolksAbstractFieldDetails*> > m_fieldsMap;73 QMap<QString, QPair<QtContacts::QContactDetail, FolksAbstractFieldDetails*> > m_fieldsMap;
73 unsigned int m_fieldMapNextKey;74
7475
75 bool fieldsContains(Fields fields, Field value) const;76 bool fieldsContains(Fields fields, Field value) const;
76 QList<QtVersit::QVersitProperty> parseFieldList(const QString &fieldName, GeeSet *values) const;77 QList<QtVersit::QVersitProperty> parseFieldList(const QString &fieldName, GeeSet *values) const;
77 QMultiHash<QString, QString> parseDetails(FolksAbstractFieldDetails *details) const;78 QMultiHash<QString, QString> parseDetails(FolksAbstractFieldDetails *details) const;
78 void updateContact();79 void updateContact();
79 FolksPersona *primaryPersona() const;80
81 FolksPersona *primaryPersona();
82 QtContacts::QContactDetail detailFromUri(QtContacts::QContactDetail::DetailType type, const QString &uri) const;
8083
81 // QContact84 // QContact
85 QList<QtContacts::QContactDetail> getDetails() const;
86 void appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QtContacts::QContactDetail detail, const QString &personaIndex, bool readOnly) const;
87 void appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QList<QtContacts::QContactDetail> details, const QString &personaIndex, bool readOnly) const;
88
82 QtContacts::QContactDetail getUid() const;89 QtContacts::QContactDetail getUid() const;
83 QList<QtContacts::QContactDetail> getClientPidMap() const;90 QList<QtContacts::QContactDetail> getClientPidMap() const;
84 QtContacts::QContactDetail getName() const;91 QtContacts::QContactDetail getPersonaName(FolksPersona *persona) const;
85 QtContacts::QContactDetail getFullName() const;92 QtContacts::QContactDetail getPersonaFullName(FolksPersona *persona) const;
86 QtContacts::QContactDetail getNickname() const;93 QtContacts::QContactDetail getPersonaNickName(FolksPersona *persona) const;
87 QtContacts::QContactDetail getBirthday() const;94 QtContacts::QContactDetail getPersonaBirthday(FolksPersona *persona) const;
88 QtContacts::QContactDetail getPhoto() const;95 QtContacts::QContactDetail getPersonaPhoto(FolksPersona *persona) const;
89 QList<QtContacts::QContactDetail> getRoles() const;96 //TODO: organization
90 QList<QtContacts::QContactDetail> getEmails() const;97 QList<QtContacts::QContactDetail> getPersonaRoles(FolksPersona *persona) const;
91 QList<QtContacts::QContactDetail> getPhones() const;98 QList<QtContacts::QContactDetail> getPersonaEmails(FolksPersona *persona) const;
92 QList<QtContacts::QContactDetail> getAddresses() const;99 QList<QtContacts::QContactDetail> getPersonaPhones(FolksPersona *persona) const;
93 QList<QtContacts::QContactDetail> getIms() const;100 QList<QtContacts::QContactDetail> getPersonaAddresses(FolksPersona *persona) const;
94 QtContacts::QContactDetail getTimeZone() const;101 QList<QtContacts::QContactDetail> getPersonaIms(FolksPersona *persona) const;
95 QList<QtContacts::QContactDetail> getUrls() const;102 QList<QtContacts::QContactDetail> getPersonaUrls(FolksPersona *persona) const;
96103
97104
98 // update105 // update
@@ -102,15 +109,38 @@
102 void updateBirthday(const QtContacts::QContactDetail &detail, void* data);109 void updateBirthday(const QtContacts::QContactDetail &detail, void* data);
103 void updatePhoto(const QtContacts::QContactDetail &detail, void* data);110 void updatePhoto(const QtContacts::QContactDetail &detail, void* data);
104 void updateTimezone(const QtContacts::QContactDetail &detail, void* data);111 void updateTimezone(const QtContacts::QContactDetail &detail, void* data);
105 void updateRoles(QList<QtContacts::QContactDetail> details, void* data);112 void updateRole(QtContacts::QContactDetail detail, void* data);
106 void updatePhones(QList<QtContacts::QContactDetail> details, void* data);113 void updatePhone(QtContacts::QContactDetail detail, void* data);
107 void updateEmails(QList<QtContacts::QContactDetail> details, void* data);114 void updateEmail(QtContacts::QContactDetail detail, void* data);
108 void updateIms(QList<QtContacts::QContactDetail> details, void* data);115 void updateIm(QtContacts::QContactDetail detail, void* data);
109 void updateUrls(QList<QtContacts::QContactDetail> details, void* data);116 void updateUrl(QtContacts::QContactDetail details, void* data);
110 void updateNotes(QList<QtContacts::QContactDetail> details, void* data);117 void updateNote(QtContacts::QContactDetail detail, void* data);
111 void updateAddresses(QList<QtContacts::QContactDetail> details, void* data);118 void updateAddress(QtContacts::QContactDetail detail, void* data);
119 void createPersonaForDetail(QList<QtContacts::QContactDetail> detail, ParseDetailsFunc parseFunc, void *data) const;
120
121 static void createPersonaDone(GObject *detail, GAsyncResult *result, gpointer userdata);
112 static void updateDetailsDone(GObject *detail, GAsyncResult *result, gpointer userdata);122 static void updateDetailsDone(GObject *detail, GAsyncResult *result, gpointer userdata);
113 static bool detailListIsEqual(QList<QtContacts::QContactDetail> original, QList<QtContacts::QContactDetail> details);123 static void updateDetailsSendReply(gpointer userdata, GError *error);
124 static void updateDetailsSendReply(gpointer userdata, const QString &errorMessage);
125 static QString callDetailChangeFinish(QtContacts::QContactDetail::DetailType type, FolksPersona *persona, GAsyncResult *result);
126 //static bool detailListIsEqual(QList<QtContacts::QContactDetail> original, QList<QtContacts::QContactDetail> details);
127
128 // translate details
129 static GHashTable *parseAddressDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
130 static GHashTable *parsePhotoDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
131 static GHashTable *parsePhoneNumbersDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
132 static GHashTable *parseOrganizationDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
133 static GHashTable *parseImDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
134 static GHashTable *parseNoteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
135 static GHashTable *parseFullNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
136 static GHashTable *parseNicknameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
137 static GHashTable *parseNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
138 static GHashTable *parseGenderDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
139 static GHashTable *parseFavoriteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
140 static GHashTable *parseEmailDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
141 static GHashTable *parseBirthdayDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
142 static GHashTable *parseUrlDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails);
143
114144
115 // parse context and parameters145 // parse context and parameters
116 static void parseParameters(QtContacts::QContactDetail &detail, FolksAbstractFieldDetails *fd);146 static void parseParameters(QtContacts::QContactDetail &detail, FolksAbstractFieldDetails *fd);
117147
=== modified file 'src/view-adaptor.h'
--- src/view-adaptor.h 2013-06-13 14:00:42 +0000
+++ src/view-adaptor.h 2013-06-20 20:58:26 +0000
@@ -45,7 +45,7 @@
45" <arg direction=\"out\" type=\"i\" name=\"pos\"/>\n"45" <arg direction=\"out\" type=\"i\" name=\"pos\"/>\n"
46" <arg direction=\"out\" type=\"i\" name=\"lenght\"/>\n"46" <arg direction=\"out\" type=\"i\" name=\"lenght\"/>\n"
47" </signal>\n"47" </signal>\n"
48" <signal name=\"contactsCreated\">\n"48" <signal name=\"contactsAdded\">\n"
49" <arg direction=\"out\" type=\"i\" name=\"pos\"/>\n"49" <arg direction=\"out\" type=\"i\" name=\"pos\"/>\n"
50" <arg direction=\"out\" type=\"i\" name=\"lenght\"/>\n"50" <arg direction=\"out\" type=\"i\" name=\"lenght\"/>\n"
51" </signal>\n"51" </signal>\n"
@@ -81,7 +81,7 @@
81 void close();81 void close();
8282
83Q_SIGNALS:83Q_SIGNALS:
84 void contactsCreated(int pos, int lenght);84 void contactsAdded(int pos, int lenght);
85 void contactsRemoved(int pos, int lenght);85 void contactsRemoved(int pos, int lenght);
86 void contactsUpdated(int pos, int lenght);86 void contactsUpdated(int pos, int lenght);
8787
8888
=== modified file 'src/view.cpp'
--- src/view.cpp 2013-06-13 14:35:08 +0000
+++ src/view.cpp 2013-06-20 20:58:26 +0000
@@ -166,6 +166,11 @@
166 }166 }
167167
168 QStringList ret = VCardParser::contactToVcard(contacts);168 QStringList ret = VCardParser::contactToVcard(contacts);
169 qDebug() << "fetch" << ret;
170 QList<QContact> cs = VCardParser::vcardToContact(ret);
171 QStringList ret2 = VCardParser::contactToVcard(cs);
172 qDebug() << "fetch2" << ret2;
173
169 QDBusMessage reply = message.createReply(ret);174 QDBusMessage reply = message.createReply(ret);
170 QDBusConnection::sessionBus().send(reply);175 QDBusConnection::sessionBus().send(reply);
171 return ret;176 return ret;

Subscribers

People subscribed via source and target branches