Merge lp:~renatofilho/address-book-service/fix-edit into lp:address-book-service
- fix-edit
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~renatofilho/address-book-service/fix-edit |
Merge into: | lp:address-book-service |
Diff against target: |
2842 lines (+1306/-735) 13 files modified
common/vcard-parser.cpp (+29/-8) common/vcard-parser.h (+2/-0) qcontacts/contacts-service.cpp (+26/-6) qcontacts/contacts-service.h (+5/-1) src/addressbook-adaptor.cpp (+5/-0) src/addressbook-adaptor.h (+9/-4) src/addressbook.cpp (+98/-74) src/addressbook.h (+12/-4) src/contacts-map.cpp (+11/-0) src/contacts-map.h (+1/-0) src/qindividual.cpp (+1050/-610) src/qindividual.h (+56/-26) src/view-adaptor.h (+2/-2) |
To merge this branch: | bzr merge lp:~renatofilho/address-book-service/fix-edit |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Ubuntu Phablet Team | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2013-06-20.
Commit message
Added support to edit contacts with multiple persona.
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:35
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:36
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 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.
- 36. By Renato Araujo Oliveira Filho
-
Added support to edit contacts with multiple persona.
Approved by PS Jenkins bot, Bill Filler.
- 37. By Renato Araujo Oliveira Filho
-
Implemented AddressBook:
:availableSourc es.
Implemented support to change sort clause in the view.
Implemented AddressBook::sortFields. Approved by PS Jenkins bot, Bill Filler.
- 38. By Renato Araujo Oliveira Filho
-
Update server contact cache with the new contact info if update operation finish without error. Fixes: https:/
/bugs.launchpad .net/bugs/ 1193195. Approved by Bill Filler, PS Jenkins bot.
- 39. By PS Jenkins bot
-
Releasing 0.1.0daily13.
06.25-0ubuntu1 to ubuntu. Approved by PS Jenkins bot.
- 40. By Renato Araujo Oliveira Filho
-
Changed View.count from signal to property.
Renamed callback functions to follow the code style.Approved by Gustavo Pichorim Boiko, PS Jenkins bot.
- 41. By PS Jenkins bot
-
Releasing 0.1.0+13.
10.20130627- 0ubuntu1 to ubuntu. Approved by PS Jenkins bot.
- 42. By Renato Araujo Oliveira Filho
-
Initial implementation of FetchHint.
Approved by Bill Filler, PS Jenkins bot.
- 43. By PS Jenkins bot
-
Releasing 0.1.0+13.
10.20130628- 0ubuntu1 to ubuntu. Approved by PS Jenkins bot.
- 44. By Renato Araujo Oliveira Filho
-
[package]Added evolution and folks-eds into dependency list.
Approved by Sergio Schvezov, PS Jenkins bot.
- 45. By PS Jenkins bot
-
Releasing 0.1.0+13.
10.20130702- 0ubuntu1 to ubuntu. Approved by PS Jenkins bot.
- 46. By Renato Araujo Oliveira Filho
-
Implemented avatars support.
Approved by Gustavo Pichorim Boiko, PS Jenkins bot.
- 47. By Renato Araujo Oliveira Filho
-
Fixed contact edit when adding a new field.
Folks return a read only list of details we need to copy it before start to modify it.
Approved by PS Jenkins bot, Gustavo Pichorim Boiko.
- 48. By Renato Araujo Oliveira Filho
-
Fixed contact update crash.
- 49. By Renato Araujo Oliveira Filho
-
Fixed contact address update.
Avoid do destroy contact address field durint the contact update.
- 50. By Renato Araujo Oliveira Filho
-
Emit the signal ¨contactUpdated¨ after a contact has been changed.
Unmerged revisions
Preview Diff
1 | === modified file 'common/vcard-parser.cpp' |
2 | --- common/vcard-parser.cpp 2013-05-18 01:11:38 +0000 |
3 | +++ common/vcard-parser.cpp 2013-06-20 13:17:29 +0000 |
4 | @@ -55,7 +55,7 @@ |
5 | |
6 | if (detail.type() == QContactDetail::TypeExtendedDetail) { |
7 | const QContactExtendedDetail *extendedDetail = static_cast<const QContactExtendedDetail *>(&detail); |
8 | - if (extendedDetail->name() == "CLIENTPIDMAP") { |
9 | + if (extendedDetail->name() == galera::VCardParser::PidMapFieldName) { |
10 | QVersitProperty prop; |
11 | prop.setName(extendedDetail->name()); |
12 | QStringList value; |
13 | @@ -70,11 +70,12 @@ |
14 | } |
15 | |
16 | if (!detail.detailUri().isEmpty()) { |
17 | - QVersitProperty prop = toBeAdded->takeLast(); |
18 | - QMultiHash<QString, QString> params = prop.parameters(); |
19 | - params.insert("PID", detail.detailUri()); |
20 | - prop.setParameters(params); |
21 | - *toBeAdded << prop; |
22 | + if (toBeAdded->size() > 0) { |
23 | + QVersitProperty &prop = toBeAdded->last(); |
24 | + QMultiHash<QString, QString> params = prop.parameters(); |
25 | + params.insert(galera::VCardParser::PidFieldName, detail.detailUri()); |
26 | + prop.setParameters(params); |
27 | + } |
28 | } |
29 | } |
30 | |
31 | @@ -102,16 +103,33 @@ |
32 | Q_UNUSED(document); |
33 | Q_UNUSED(contact); |
34 | |
35 | - if (!*alreadyProcessed && (property.name() == "CLIENTPIDMAP")) { |
36 | + if (!*alreadyProcessed && (property.name() == galera::VCardParser::PidMapFieldName)) { |
37 | QContactExtendedDetail detail; |
38 | detail.setName(property.name()); |
39 | - QStringList value = property.value<QStringList>(); |
40 | + QStringList value = property.value<QString>().split(";"); |
41 | detail.setValue(QContactExtendedDetail::FieldData, value[0]); |
42 | detail.setValue(QContactExtendedDetail::FieldData + 1, value[1]); |
43 | *updatedDetails << detail; |
44 | *alreadyProcessed = true; |
45 | } |
46 | |
47 | + QString pid = property.parameters().value(galera::VCardParser::PidFieldName); |
48 | + if (!pid.isEmpty()) { |
49 | + QContactDetail &det = updatedDetails->last(); |
50 | + det.setDetailUri(pid); |
51 | + } |
52 | + |
53 | + // Remove empty phone subtypes |
54 | + // Remove this after this fix get merged: https://codereview.qt-project.org/#change,59156 |
55 | + if (updatedDetails->size() > 0) { |
56 | + QContactDetail &det = updatedDetails->last(); |
57 | + if (det.type() == QContactPhoneNumber::Type) { |
58 | + QContactPhoneNumber phone = static_cast<QContactPhoneNumber>(det); |
59 | + if (phone.subTypes().size() == 0) { |
60 | + det.setValue(QContactPhoneNumber::FieldSubTypes, QVariant()); |
61 | + } |
62 | + } |
63 | + } |
64 | } |
65 | |
66 | virtual void documentProcessed(const QVersitDocument& document, QContact* contact) |
67 | @@ -125,6 +143,9 @@ |
68 | namespace galera |
69 | { |
70 | |
71 | +const QString VCardParser::PidMapFieldName = QString("CLIENTPIDMAP"); |
72 | +const QString VCardParser::PidFieldName = QString("PID"); |
73 | + |
74 | QStringList VCardParser::contactToVcard(QList<QtContacts::QContact> contacts) |
75 | { |
76 | QStringList result; |
77 | |
78 | === modified file 'common/vcard-parser.h' |
79 | --- common/vcard-parser.h 2013-05-18 01:11:38 +0000 |
80 | +++ common/vcard-parser.h 2013-06-20 13:17:29 +0000 |
81 | @@ -29,6 +29,8 @@ |
82 | class VCardParser |
83 | { |
84 | public: |
85 | + static const QString PidMapFieldName; |
86 | + static const QString PidFieldName; |
87 | |
88 | static QStringList contactToVcard(QList<QtContacts::QContact> contacts); |
89 | static QtContacts::QContact vcardToContact(const QString &vcard); |
90 | |
91 | === modified file 'qcontacts/contacts-service.cpp' |
92 | --- qcontacts/contacts-service.cpp 2013-06-13 14:35:08 +0000 |
93 | +++ qcontacts/contacts-service.cpp 2013-06-20 13:17:29 +0000 |
94 | @@ -54,6 +54,7 @@ |
95 | GaleraContactsService::GaleraContactsService(const QString &managerUri) |
96 | : m_selfContactId(), |
97 | m_managerUri(managerUri), |
98 | + m_serviceIsReady(false), |
99 | m_iface(0) |
100 | { |
101 | RequestData::registerMetaType(); |
102 | @@ -78,7 +79,12 @@ |
103 | |
104 | GaleraContactsService::~GaleraContactsService() |
105 | { |
106 | - Q_ASSERT(m_pendingRequests.size() == 0); |
107 | + while(!m_pendingRequests.isEmpty()) { |
108 | + QContactManagerEngine::updateRequestState(m_pendingRequests.takeFirst(), |
109 | + QContactAbstractRequest::CanceledState); |
110 | + } |
111 | + |
112 | + Q_ASSERT(m_runningRequests.size() == 0); |
113 | delete m_serviceWatcher; |
114 | } |
115 | |
116 | @@ -96,6 +102,14 @@ |
117 | } |
118 | } |
119 | |
120 | +void GaleraContactsService::onServiceReady() |
121 | +{ |
122 | + m_serviceIsReady = true; |
123 | + while(!m_pendingRequests.isEmpty()) { |
124 | + addRequest(m_pendingRequests.takeFirst()); |
125 | + } |
126 | +} |
127 | + |
128 | void GaleraContactsService::initialize() |
129 | { |
130 | if (m_iface.isNull()) { |
131 | @@ -103,6 +117,8 @@ |
132 | CPIM_ADDRESSBOOK_OBJECT_PATH, |
133 | CPIM_ADDRESSBOOK_IFACE_NAME)); |
134 | if (!m_iface->lastError().isValid()) { |
135 | + m_serviceIsReady = m_iface.data()->property("isReady").toBool(); |
136 | + connect(m_iface.data(), SIGNAL(ready()), this, SLOT(onServiceReady())); |
137 | connect(m_iface.data(), SIGNAL(contactsAdded(QStringList)), this, SLOT(onContactsAdded(QStringList))); |
138 | connect(m_iface.data(), SIGNAL(contactsRemoved(QStringList)), this, SLOT(onContactsRemoved(QStringList))); |
139 | } else { |
140 | @@ -159,7 +175,7 @@ |
141 | CPIM_ADDRESSBOOK_VIEW_IFACE_NAME); |
142 | |
143 | RequestData *requestData = new RequestData(request, view); |
144 | - m_pendingRequests << requestData; |
145 | + m_runningRequests << requestData; |
146 | QMetaObject::invokeMethod(this, "fetchContactsPage", Qt::QueuedConnection, Q_ARG(galera::RequestData*, requestData)); |
147 | } |
148 | |
149 | @@ -295,7 +311,7 @@ |
150 | QDBusPendingCall pcall = m_iface->asyncCall("createContact", contact, ""); |
151 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0); |
152 | RequestData *requestData = new RequestData(request, 0, watcher); |
153 | - m_pendingRequests << requestData; |
154 | + m_runningRequests << requestData; |
155 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, |
156 | [=](QDBusPendingCallWatcher *call) { |
157 | this->createContactsDone(requestData, call); |
158 | @@ -367,7 +383,7 @@ |
159 | } else { |
160 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0); |
161 | RequestData *requestData = new RequestData(request, 0, watcher); |
162 | - m_pendingRequests << requestData; |
163 | + m_runningRequests << requestData; |
164 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, |
165 | [=](QDBusPendingCallWatcher *call) { |
166 | this->removeContactDone(requestData, call); |
167 | @@ -423,7 +439,7 @@ |
168 | } else { |
169 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0); |
170 | RequestData *requestData = new RequestData(request, 0, watcher); |
171 | - m_pendingRequests << requestData; |
172 | + m_runningRequests << requestData; |
173 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, |
174 | [=](QDBusPendingCallWatcher *call) { |
175 | this->updateContactDone(requestData, call); |
176 | @@ -471,6 +487,10 @@ |
177 | void GaleraContactsService::addRequest(QtContacts::QContactAbstractRequest *request) |
178 | { |
179 | qDebug() << Q_FUNC_INFO << request->state(); |
180 | + if (!m_serviceIsReady) { |
181 | + m_pendingRequests << request; |
182 | + return; |
183 | + } |
184 | if (!isOnline()) { |
185 | QContactManagerEngine::updateRequestState(request, QContactAbstractRequest::FinishedState); |
186 | return; |
187 | @@ -511,7 +531,7 @@ |
188 | void GaleraContactsService::destroyRequest(RequestData *request) |
189 | { |
190 | qDebug() << Q_FUNC_INFO; |
191 | - m_pendingRequests.remove(request); |
192 | + m_runningRequests.remove(request); |
193 | delete request; |
194 | } |
195 | |
196 | |
197 | === modified file 'qcontacts/contacts-service.h' |
198 | --- qcontacts/contacts-service.h 2013-06-12 22:41:11 +0000 |
199 | +++ qcontacts/contacts-service.h 2013-06-20 13:17:29 +0000 |
200 | @@ -24,6 +24,7 @@ |
201 | #include <QtCore/QStringList> |
202 | #include <QtCore/QSet> |
203 | #include <QtCore/QMutex> |
204 | +#include <QtCore/QQueue> |
205 | |
206 | #include <QtContacts/QContact> |
207 | #include <QtContacts/QContactManagerEngine> |
208 | @@ -68,6 +69,7 @@ |
209 | void onContactsAdded(QStringList ids); |
210 | void onContactsRemoved(QStringList ids); |
211 | void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); |
212 | + void onServiceReady(); |
213 | |
214 | private: |
215 | QString m_id; |
216 | @@ -78,9 +80,11 @@ |
217 | QMap<QtContacts::QContactId, QList<QtContacts::QContactRelationship> > m_orderedRelationships; // map of ordered lists of contact relationships |
218 | QString m_managerUri; // for faster lookup. |
219 | QDBusServiceWatcher *m_serviceWatcher; |
220 | + bool m_serviceIsReady; |
221 | |
222 | QSharedPointer<QDBusInterface> m_iface; |
223 | - QSet<RequestData*> m_pendingRequests; |
224 | + QSet<RequestData*> m_runningRequests; |
225 | + QQueue<QtContacts::QContactAbstractRequest*> m_pendingRequests; |
226 | |
227 | Q_INVOKABLE void initialize(); |
228 | Q_INVOKABLE void deinitialize(); |
229 | |
230 | === modified file 'src/addressbook-adaptor.cpp' |
231 | --- src/addressbook-adaptor.cpp 2013-06-13 14:00:42 +0000 |
232 | +++ src/addressbook-adaptor.cpp 2013-06-20 13:17:29 +0000 |
233 | @@ -94,4 +94,9 @@ |
234 | return QStringList(); |
235 | } |
236 | |
237 | +bool AddressBookAdaptor::isReady() |
238 | +{ |
239 | + return m_addressBook->isReady(); |
240 | +} |
241 | + |
242 | } //namespace |
243 | |
244 | === modified file 'src/addressbook-adaptor.h' |
245 | --- src/addressbook-adaptor.h 2013-06-07 18:54:26 +0000 |
246 | +++ src/addressbook-adaptor.h 2013-06-20 13:17:29 +0000 |
247 | @@ -37,6 +37,7 @@ |
248 | Q_CLASSINFO("D-Bus Interface", CPIM_ADDRESSBOOK_IFACE_NAME) |
249 | Q_CLASSINFO("D-Bus Introspection", "" |
250 | " <interface name=\"com.canonical.pim.AddressBook\">\n" |
251 | +" <property name=\"isReady\" type=\"b\" access=\"read\"/>\n" |
252 | " <signal name=\"contactsUpdated\">\n" |
253 | " <arg direction=\"out\" type=\"as\" name=\"ids\"/>\n" |
254 | " </signal>\n" |
255 | @@ -49,6 +50,7 @@ |
256 | " <signal name=\"asyncOperationResult\">\n" |
257 | " <arg direction=\"out\" type=\"a(ss)\" name=\"errorMap\"/>\n" |
258 | " </signal>\n" |
259 | +" <signal name=\"ready\"/>\n" |
260 | " <method name=\"availableSources\">\n" |
261 | " <arg direction=\"out\" type=\"a(sb)\"/>\n" |
262 | " <annotation value=\"SourceList\" name=\"com.trolltech.QtDBus.QtTypeName.Out0\"/>\n" |
263 | @@ -90,25 +92,28 @@ |
264 | " </method>\n" |
265 | " </interface>\n" |
266 | "") |
267 | + Q_PROPERTY(bool isReady READ isReady NOTIFY ready) |
268 | public: |
269 | AddressBookAdaptor(const QDBusConnection &connection, AddressBook *parent); |
270 | virtual ~AddressBookAdaptor(); |
271 | |
272 | public Q_SLOTS: |
273 | SourceList availableSources(); |
274 | + QStringList sortFields(); |
275 | + QDBusObjectPath query(const QString &clause, const QString &sort, const QStringList &sources); |
276 | + int removeContacts(const QStringList &contactIds, const QDBusMessage &message); |
277 | QString createContact(const QString &contact, const QString &source, const QDBusMessage &message); |
278 | + QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message); |
279 | QString linkContacts(const QStringList &contacts); |
280 | - QDBusObjectPath query(const QString &clause, const QString &sort, const QStringList &sources); |
281 | - int removeContacts(const QStringList &contactIds, const QDBusMessage &message); |
282 | - QStringList sortFields(); |
283 | bool unlinkContacts(const QString &parentId, const QStringList &contactsIds); |
284 | - QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message); |
285 | + bool isReady(); |
286 | |
287 | Q_SIGNALS: |
288 | void contactsAdded(const QStringList &ids); |
289 | void contactsRemoved(const QStringList &ids); |
290 | void contactsUpdated(const QStringList &ids); |
291 | void asyncOperationResult(QMap<QString, QString> errors); |
292 | + void ready(); |
293 | |
294 | private: |
295 | AddressBook *m_addressBook; |
296 | |
297 | === modified file 'src/addressbook.cpp' |
298 | --- src/addressbook.cpp 2013-06-13 14:35:08 +0000 |
299 | +++ src/addressbook.cpp 2013-06-20 13:17:29 +0000 |
300 | @@ -26,7 +26,6 @@ |
301 | |
302 | #include <QtCore/QPair> |
303 | #include <QtCore/QUuid> |
304 | -#include <QtContacts/QContact> |
305 | |
306 | using namespace QtContacts; |
307 | |
308 | @@ -60,7 +59,7 @@ |
309 | AddressBook::AddressBook(QObject *parent) |
310 | : QObject(parent), |
311 | m_contacts(new ContactsMap), |
312 | - m_initializing(true), |
313 | + m_ready(false), |
314 | m_adaptor(0) |
315 | { |
316 | prepareFolks(); |
317 | @@ -97,10 +96,20 @@ |
318 | { |
319 | //TODO: filter EDS (FolksBackendStore) |
320 | m_individualAggregator = folks_individual_aggregator_new(); |
321 | + g_object_get(G_OBJECT(m_individualAggregator), "is-quiescent", &m_ready, NULL); |
322 | + if (m_ready) { |
323 | + AddressBook::isQuiescentChanged(G_OBJECT(m_individualAggregator), NULL, this); |
324 | + } |
325 | + g_signal_connect(m_individualAggregator, |
326 | + "notify::is-quiescent", |
327 | + (GCallback)AddressBook::isQuiescentChanged, |
328 | + this); |
329 | + |
330 | g_signal_connect(m_individualAggregator, |
331 | "individuals-changed-detailed", |
332 | (GCallback) AddressBook::individualsChangedCb, |
333 | this); |
334 | + |
335 | folks_individual_aggregator_prepare(m_individualAggregator, |
336 | (GAsyncReadyCallback) AddressBook::aggregatorPrepareCb, |
337 | this); |
338 | @@ -223,78 +232,81 @@ |
339 | return false; |
340 | } |
341 | |
342 | +bool AddressBook::isReady() const |
343 | +{ |
344 | + return m_ready; |
345 | +} |
346 | + |
347 | QStringList AddressBook::updateContacts(const QStringList &contacts, const QDBusMessage &message) |
348 | { |
349 | - UpdateContactsData *data = 0; |
350 | - |
351 | - if (!contacts.isEmpty()) { |
352 | - data = new UpdateContactsData; |
353 | - data->m_contacts = VCardParser::vcardToContact(contacts); |
354 | - data->m_request = contacts; |
355 | - data->m_currentIndex = -1; |
356 | - data->m_addressbook = this; |
357 | - data->m_message = message; |
358 | - |
359 | - } |
360 | - updateContacts("", data); |
361 | + //TODO: support multiple update contacts calls |
362 | + Q_ASSERT(m_updateCommandPendingContacts.isEmpty()); |
363 | + |
364 | + m_updateCommandReplyMessage = message; |
365 | + m_updateCommandResult = contacts; |
366 | + m_updateCommandPendingContacts << VCardParser::vcardToContact(contacts); |
367 | + |
368 | + updateContactsDone(0, QString()); |
369 | |
370 | return QStringList(); |
371 | } |
372 | |
373 | -void AddressBook::updateContacts(const QString &error, void *userData) |
374 | +void AddressBook::updateContactsDone(galera::QIndividual *individual, const QString &error) |
375 | { |
376 | - qDebug() << Q_FUNC_INFO << userData; |
377 | - UpdateContactsData *data = static_cast<UpdateContactsData*>(userData); |
378 | - QDBusMessage reply; |
379 | - |
380 | - if (data) { |
381 | - if (!error.isEmpty()) { |
382 | - data->m_result << error; |
383 | - } else if (data->m_currentIndex > -1) { |
384 | - data->m_result << data->m_request[data->m_currentIndex]; |
385 | - } |
386 | - |
387 | - if (!data->m_contacts.isEmpty()) { |
388 | - QContact newContact = data->m_contacts.takeFirst(); |
389 | - data->m_currentIndex++; |
390 | - |
391 | - ContactEntry *entry = data->m_addressbook->m_contacts->value(newContact.detail<QContactGuid>().guid()); |
392 | - if (entry) { |
393 | - entry->individual()->update(newContact, updateContacts, userData); |
394 | - } else { |
395 | - updateContacts("Contact not found!", userData); |
396 | - } |
397 | - return; |
398 | - } |
399 | - folks_persona_store_flush(folks_individual_aggregator_get_primary_store(data->m_addressbook->m_individualAggregator), 0, 0); |
400 | - reply = data->m_message.createReply(data->m_result); |
401 | + Q_UNUSED(individual); |
402 | + qDebug() << Q_FUNC_INFO; |
403 | + |
404 | + if (!error.isEmpty()) { |
405 | + // update the result with the error |
406 | + m_updateCommandResult[m_updateCommandResult.size() - m_updateCommandPendingContacts.size()] = error; |
407 | + } |
408 | + |
409 | + if (!m_updateCommandPendingContacts.isEmpty()) { |
410 | + QContact newContact = m_updateCommandPendingContacts.takeFirst(); |
411 | + ContactEntry *entry = m_contacts->value(newContact.detail<QContactGuid>().guid()); |
412 | + if (entry) { |
413 | + entry->individual()->update(newContact, this, "updateContactsDone(galera::QIndividual*, const QString&)"); //)); |
414 | + } else { |
415 | + updateContactsDone(0, "Contact not found!"); |
416 | + } |
417 | } else { |
418 | - reply = data->m_message.createReply(QStringList()); |
419 | + folks_persona_store_flush(folks_individual_aggregator_get_primary_store(m_individualAggregator), 0, 0); |
420 | + QDBusMessage reply = m_updateCommandReplyMessage.createReply(m_updateCommandResult); |
421 | + QDBusConnection::sessionBus().send(reply); |
422 | + |
423 | + // clear command data |
424 | + m_updateCommandResult.clear(); |
425 | + m_updateCommandReplyMessage = QDBusMessage(); |
426 | } |
427 | - |
428 | - QDBusConnection::sessionBus().send(reply); |
429 | - delete data; |
430 | } |
431 | |
432 | |
433 | QString AddressBook::removeContact(FolksIndividual *individual) |
434 | { |
435 | - Q_ASSERT(m_contacts->contains(individual)); |
436 | - ContactEntry *ci = m_contacts->take(individual); |
437 | - if (ci) { |
438 | - QString id = QString::fromUtf8(folks_individual_get_id(individual)); |
439 | - delete ci; |
440 | - return id; |
441 | + if (m_contacts->contains(individual)) { |
442 | + ContactEntry *ci = m_contacts->take(individual); |
443 | + if (ci) { |
444 | + QString id = QString::fromUtf8(folks_individual_get_id(individual)); |
445 | + qDebug() << "Remove contact" << id; |
446 | + delete ci; |
447 | + return id; |
448 | + } |
449 | } |
450 | return QString(); |
451 | } |
452 | |
453 | QString AddressBook::addContact(FolksIndividual *individual) |
454 | { |
455 | - Q_ASSERT(!m_contacts->contains(individual)); |
456 | - m_contacts->insert(new ContactEntry(new QIndividual(individual, m_individualAggregator))); |
457 | - //TODO: Notify view |
458 | - return QString::fromUtf8(folks_individual_get_id(individual)); |
459 | + QString id = QString::fromUtf8(folks_individual_get_id(individual)); |
460 | + ContactEntry *entry = m_contacts->value(id); |
461 | + if (entry) { |
462 | + entry->individual()->setIndividual(individual); |
463 | + } else { |
464 | + m_contacts->insert(new ContactEntry(new QIndividual(individual, m_individualAggregator))); |
465 | + qDebug() << "Add contact" << folks_individual_get_id(individual); |
466 | + //TODO: Notify view |
467 | + } |
468 | + return id; |
469 | } |
470 | |
471 | void AddressBook::individualsChangedCb(FolksIndividualAggregator *individualAggregator, |
472 | @@ -307,28 +319,28 @@ |
473 | |
474 | GeeIterator *iter; |
475 | GeeSet *removed = gee_multi_map_get_keys(changes); |
476 | - iter = gee_iterable_iterator(GEE_ITERABLE(removed)); |
477 | - |
478 | - while(gee_iterator_next(iter)) { |
479 | - FolksIndividual *individual = FOLKS_INDIVIDUAL(gee_iterator_get(iter)); |
480 | - if (individual) { |
481 | - QString id = self->removeContact(individual); |
482 | - if(!id.isEmpty()) { |
483 | - removedIds << id; |
484 | - } |
485 | - g_object_unref(individual); |
486 | - } |
487 | - } |
488 | - g_object_unref (iter); |
489 | - |
490 | GeeCollection *added = gee_multi_map_get_values(changes); |
491 | + |
492 | iter = gee_iterable_iterator(GEE_ITERABLE(added)); |
493 | while(gee_iterator_next(iter)) { |
494 | FolksIndividual *individual = FOLKS_INDIVIDUAL(gee_iterator_get(iter)); |
495 | if (individual) { |
496 | - QString id = self->addContact(individual); |
497 | - if(!id.isEmpty()) { |
498 | - addedIds << id; |
499 | + // add contact to the map |
500 | + addedIds << self->addContact(individual); |
501 | + g_object_unref(individual); |
502 | + } |
503 | + } |
504 | + g_object_unref (iter); |
505 | + |
506 | + |
507 | + iter = gee_iterable_iterator(GEE_ITERABLE(removed)); |
508 | + while(gee_iterator_next(iter)) { |
509 | + FolksIndividual *individual = FOLKS_INDIVIDUAL(gee_iterator_get(iter)); |
510 | + if (individual) { |
511 | + QString id = QString::fromUtf8(folks_individual_get_id(individual)); |
512 | + if (!addedIds.contains(id)) { |
513 | + // delete from contact map |
514 | + removedIds << self->removeContact(individual); |
515 | } |
516 | g_object_unref(individual); |
517 | } |
518 | @@ -336,14 +348,14 @@ |
519 | g_object_unref (iter); |
520 | |
521 | //TODO: check for linked and unliked contacts |
522 | - if (!removedIds.isEmpty()) { |
523 | + if (!removedIds.isEmpty() && self->m_ready) { |
524 | Q_EMIT self->m_adaptor->contactsRemoved(removedIds); |
525 | } |
526 | |
527 | - if (!addedIds.isEmpty()) { |
528 | + if (!addedIds.isEmpty() && self->m_ready) { |
529 | Q_EMIT self->m_adaptor->contactsAdded(addedIds); |
530 | } |
531 | - self->m_initializing = false; |
532 | + qDebug() << "Added" << addedIds; |
533 | } |
534 | |
535 | void AddressBook::aggregatorPrepareCb(GObject *source, |
536 | @@ -379,4 +391,16 @@ |
537 | delete msg; |
538 | } |
539 | |
540 | +void AddressBook::isQuiescentChanged(GObject *source, GParamSpec *param, AddressBook *self) |
541 | +{ |
542 | + Q_UNUSED(source); |
543 | + Q_UNUSED(param); |
544 | + |
545 | + g_object_get(source, "is-quiescent", &self->m_ready, NULL); |
546 | + if (self->m_ready) { |
547 | + Q_EMIT self->m_adaptor->ready(); |
548 | + } |
549 | +} |
550 | + |
551 | + |
552 | } //namespace |
553 | |
554 | === modified file 'src/addressbook.h' |
555 | --- src/addressbook.h 2013-06-13 14:35:08 +0000 |
556 | +++ src/addressbook.h 2013-06-20 13:17:29 +0000 |
557 | @@ -28,6 +28,8 @@ |
558 | |
559 | #include <QtDBus/QtDBus> |
560 | |
561 | +#include <QtContacts/QContact> |
562 | + |
563 | #include <folks/folks.h> |
564 | #include <glib.h> |
565 | #include <glib-object.h> |
566 | @@ -37,6 +39,7 @@ |
567 | class View; |
568 | class ContactsMap; |
569 | class AddressBookAdaptor; |
570 | +class QIndividual; |
571 | |
572 | class AddressBook: public QObject |
573 | { |
574 | @@ -54,11 +57,13 @@ |
575 | View *query(const QString &clause, const QString &sort, const QStringList &sources); |
576 | QStringList sortFields(); |
577 | bool unlinkContacts(const QString &parent, const QStringList &contacts); |
578 | + bool isReady() const; |
579 | |
580 | public Q_SLOTS: |
581 | QString createContact(const QString &contact, const QString &source, const QDBusMessage &message); |
582 | int removeContacts(const QStringList &contactIds, const QDBusMessage &message); |
583 | QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message); |
584 | + void updateContactsDone(galera::QIndividual *individual, const QString &error); |
585 | |
586 | private Q_SLOTS: |
587 | void viewClosed(); |
588 | @@ -67,16 +72,18 @@ |
589 | FolksIndividualAggregator *m_individualAggregator; |
590 | ContactsMap *m_contacts; |
591 | QSet<View*> m_views; |
592 | - bool m_initializing; |
593 | + bool m_ready; |
594 | AddressBookAdaptor *m_adaptor; |
595 | |
596 | + // Update command |
597 | + QDBusMessage m_updateCommandReplyMessage; |
598 | + QStringList m_updateCommandResult; |
599 | + QList<QtContacts::QContact> m_updateCommandPendingContacts; |
600 | + |
601 | void prepareFolks(); |
602 | QString removeContact(FolksIndividual *individual); |
603 | QString addContact(FolksIndividual *individual); |
604 | |
605 | - |
606 | - static void updateContacts(const QString &error, void *userData); |
607 | - |
608 | static void individualsChangedCb(FolksIndividualAggregator *individualAggregator, |
609 | GeeMultiMap *changes, |
610 | AddressBook *self); |
611 | @@ -89,6 +96,7 @@ |
612 | static void removeContactContinue(FolksIndividualAggregator *individualAggregator, |
613 | GAsyncResult *result, |
614 | void *data); |
615 | + static void isQuiescentChanged(GObject *source, GParamSpec *param, AddressBook *self); |
616 | }; |
617 | |
618 | } //namespace |
619 | |
620 | === modified file 'src/contacts-map.cpp' |
621 | --- src/contacts-map.cpp 2013-06-11 13:00:01 +0000 |
622 | +++ src/contacts-map.cpp 2013-06-20 13:17:29 +0000 |
623 | @@ -28,6 +28,7 @@ |
624 | ContactEntry::ContactEntry(QIndividual *individual) |
625 | : m_individual(individual) |
626 | { |
627 | + Q_ASSERT(individual); |
628 | } |
629 | |
630 | ContactEntry::~ContactEntry() |
631 | @@ -75,6 +76,16 @@ |
632 | return 0; |
633 | } |
634 | |
635 | +void ContactsMap::remove(const QString &id) |
636 | +{ |
637 | + ContactEntry *entry = m_idToEntry[id]; |
638 | + if (entry) { |
639 | + m_individualsToEntry.remove(entry->individual()->individual()); |
640 | + m_idToEntry.remove(id); |
641 | + delete entry; |
642 | + } |
643 | +} |
644 | + |
645 | bool ContactsMap::contains(FolksIndividual *individual) const |
646 | { |
647 | return m_individualsToEntry.contains(individual); |
648 | |
649 | === modified file 'src/contacts-map.h' |
650 | --- src/contacts-map.h 2013-06-11 13:00:01 +0000 |
651 | +++ src/contacts-map.h 2013-06-20 13:17:29 +0000 |
652 | @@ -60,6 +60,7 @@ |
653 | ContactEntry *value(FolksIndividual *individual) const; |
654 | ContactEntry *value(const QString &id) const; |
655 | ContactEntry *take(FolksIndividual *individual); |
656 | + void remove(const QString &id); |
657 | void insert(ContactEntry *entry); |
658 | int size() const; |
659 | |
660 | |
661 | === modified file 'src/qindividual.cpp' |
662 | --- src/qindividual.cpp 2013-06-11 21:49:45 +0000 |
663 | +++ src/qindividual.cpp 2013-06-20 13:17:29 +0000 |
664 | @@ -53,14 +53,14 @@ |
665 | class UpdateContactData |
666 | { |
667 | public: |
668 | - QContactDetail::DetailType m_currentDetailType; |
669 | QContact m_newContact; |
670 | galera::QIndividual *m_self; |
671 | - FolksPersona *m_persona; |
672 | - |
673 | - QList<QContactDetail> m_detailsChanged; |
674 | - galera::UpdateDoneCB m_doneCB; |
675 | - void *m_doneData; |
676 | + |
677 | + QList<QContactDetail> m_details; |
678 | + QContactDetail m_currentDetail; |
679 | + |
680 | + QObject *m_object; |
681 | + QMetaMethod m_slot; |
682 | }; |
683 | |
684 | #ifdef FOLKS_0_9_0 |
685 | @@ -82,9 +82,6 @@ |
686 | namespace galera |
687 | { |
688 | |
689 | -// TODO: find a better way to link abstract field with details |
690 | -#define FOLKS_DATA_FIELD 10000 |
691 | - |
692 | #ifdef FOLKS_0_9_0 |
693 | #define SET_AFD_NEW() \ |
694 | GEE_SET(gee_hash_set_new(FOLKS_TYPE_ABSTRACT_FIELD_DETAILS, \ |
695 | @@ -96,6 +93,16 @@ |
696 | NULL, \ |
697 | NULL)) |
698 | |
699 | + #define SET_PERSONA_NEW() \ |
700 | + GEE_SET(gee_hash_set_new(FOLKS_TYPE_PERSONA, \ |
701 | + (GBoxedCopyFunc) g_object_ref, g_object_unref, \ |
702 | + NULL, \ |
703 | + NULL, \ |
704 | + NULL, \ |
705 | + NULL, \ |
706 | + NULL, \ |
707 | + NULL)) |
708 | + |
709 | #define GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE) \ |
710 | GEE_MULTI_MAP(gee_hash_multi_map_new(G_TYPE_STRING,\ |
711 | (GBoxedCopyFunc) g_strdup, g_free, \ |
712 | @@ -120,6 +127,13 @@ |
713 | (GHashFunc) folks_abstract_field_details_hash, \ |
714 | (GEqualFunc) folks_abstract_field_details_equal)) |
715 | |
716 | + #define SET_PERSONA_NEW() \ |
717 | + GEE_SET(gee_hash_set_new(FOLKS_TYPE_PERSONA, \ |
718 | + (GBoxedCopyFunc) g_object_ref, g_object_unref, \ |
719 | + NULL, \ |
720 | + NULL)) |
721 | + |
722 | + |
723 | #define GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE) \ |
724 | GEE_MULTI_MAP(gee_hash_multi_map_new(G_TYPE_STRING, \ |
725 | (GBoxedCopyFunc) g_strdup, \ |
726 | @@ -131,16 +145,17 @@ |
727 | (GHashFunc) folks_abstract_field_details_hash, \ |
728 | (GEqualFunc) folks_abstract_field_details_equal)); |
729 | |
730 | + |
731 | + |
732 | #endif |
733 | |
734 | |
735 | #define PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(\ |
736 | - details, key, value, q_type, g_type, member) \ |
737 | + details, cDetails, key, value, q_type, g_type, member) \ |
738 | { \ |
739 | - QList<q_type> contactDetails = contact.details<q_type>(); \ |
740 | - if(contactDetails.size() > 0) { \ |
741 | + if(cDetails.size() > 0) { \ |
742 | value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); \ |
743 | - Q_FOREACH(const q_type& detail, contact.details<q_type>()) { \ |
744 | + Q_FOREACH(const q_type& detail, cDetails) { \ |
745 | if(!detail.isEmpty()) { \ |
746 | QIndividualUtils::gValueGeeSetAddStringFieldDetails(value, (g_type), \ |
747 | detail.member().toUtf8().data(), \ |
748 | @@ -242,10 +257,53 @@ |
749 | return retval; |
750 | } |
751 | |
752 | + static FolksAbstractFieldDetails *getDetails(GeeSet *set, const QString &uri) |
753 | + { |
754 | + Q_ASSERT(set); |
755 | + |
756 | + int pos = 0; |
757 | + int size = 0; |
758 | + QStringList index = uri.split("."); |
759 | + gpointer* values = gee_collection_to_array(GEE_COLLECTION(set), &size); |
760 | + |
761 | + if (size == 0) { |
762 | + return 0; |
763 | + } else if (index.count() == 2) { |
764 | + pos = index[1].toInt() - 1; |
765 | + Q_ASSERT(pos >= 0); |
766 | + Q_ASSERT(pos < size); |
767 | + } |
768 | + return FOLKS_ABSTRACT_FIELD_DETAILS(values[pos]); |
769 | + } |
770 | + |
771 | + static FolksPersona *personaFromUri(const QString &uri, FolksIndividual *individual, FolksPersona *defaultPersona) |
772 | + { |
773 | + Q_ASSERT(individual); |
774 | + |
775 | + if (uri.isEmpty()) { |
776 | + //TODO |
777 | + qWarning() << "NO PERSONA"; |
778 | + return defaultPersona; |
779 | + } else { |
780 | + |
781 | + GeeSet *personas = folks_individual_get_personas(individual); |
782 | + QStringList index = uri.split("."); |
783 | + Q_ASSERT(index.count() >= 1); |
784 | + int pos = index[0].toInt() - 1; |
785 | + int size = 0; |
786 | + gpointer* values = gee_collection_to_array(GEE_COLLECTION(personas), &size); |
787 | + Q_ASSERT(pos >= 0); |
788 | + Q_ASSERT(pos < size); |
789 | + |
790 | + return FOLKS_PERSONA(values[pos]); |
791 | + } |
792 | + } |
793 | + |
794 | }; // class |
795 | |
796 | QIndividual::QIndividual(FolksIndividual *individual, FolksIndividualAggregator *aggregator) |
797 | : m_individual(individual), |
798 | + m_primaryPersona(0), |
799 | m_aggregator(aggregator) |
800 | { |
801 | g_object_ref(m_individual); |
802 | @@ -267,7 +325,6 @@ |
803 | QList<QtContacts::QContactDetail> QIndividual::getClientPidMap() const |
804 | { |
805 | QList<QtContacts::QContactDetail> details; |
806 | - /* |
807 | int index = 1; |
808 | GeeSet *personas = folks_individual_get_personas(m_individual); |
809 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas)); |
810 | @@ -282,16 +339,75 @@ |
811 | } |
812 | |
813 | g_object_unref(iter); |
814 | - */ |
815 | - return details; |
816 | -} |
817 | - |
818 | - |
819 | -QtContacts::QContactDetail QIndividual::getName() const |
820 | -{ |
821 | + return details; |
822 | +} |
823 | + |
824 | +void QIndividual::appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QtContacts::QContactDetail detail, const QString &personaIndex, bool readOnly) const |
825 | +{ |
826 | + if (!detail.isEmpty()) { |
827 | + detail.setDetailUri(personaIndex); |
828 | + if (readOnly) { |
829 | + QContactManagerEngine::setDetailAccessConstraints(&detail, QContactDetail::ReadOnly); |
830 | + } |
831 | + list->append(detail); |
832 | + } |
833 | +} |
834 | + |
835 | +void QIndividual::appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QList<QtContacts::QContactDetail> details, const QString &personaIndex, bool readOnly) const |
836 | +{ |
837 | + int subIndex = 1; |
838 | + Q_FOREACH(QContactDetail detail, details) { |
839 | + appendDetailsForPersona(list, detail, QString("%1.%2").arg(personaIndex).arg(subIndex), readOnly); |
840 | + subIndex++; |
841 | + } |
842 | +} |
843 | + |
844 | + |
845 | +QList<QContactDetail> QIndividual::getDetails() const |
846 | +{ |
847 | + int personaIndex = 1; |
848 | + QList<QContactDetail> details; |
849 | + GeeSet *personas = folks_individual_get_personas(m_individual); |
850 | + GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas)); |
851 | + |
852 | + while(gee_iterator_next(iter)) { |
853 | + FolksPersona *persona = FOLKS_PERSONA(gee_iterator_get(iter)); |
854 | + |
855 | + int wsize = 0; |
856 | + gchar **wproperties = folks_persona_get_writeable_properties(persona, &wsize); |
857 | + //"gender", "local-ids", "avatar", "postal-addresses", "urls", "phone-numbers", "structured-name", |
858 | + //"anti-links", "im-addresses", "is-favourite", "birthday", "notes", "roles", "email-addresses", |
859 | + //"web-service-addresses", "groups", "full-name" |
860 | + QStringList wPropList; |
861 | + for(int i=0; i < wsize; i++) { |
862 | + wPropList << wproperties[i]; |
863 | + } |
864 | + |
865 | + QString index = QString::number(personaIndex); |
866 | + |
867 | + appendDetailsForPersona(&details, getPersonaName(persona), index, !wPropList.contains("structured-name")); |
868 | + appendDetailsForPersona(&details, getPersonaFullName(persona), index, !wPropList.contains("full-name")); |
869 | + appendDetailsForPersona(&details, getPersonaNickName(persona), index, !wPropList.contains("nickname")); |
870 | + appendDetailsForPersona(&details, getPersonaBirthday(persona), index, !wPropList.contains("birthday")); |
871 | + appendDetailsForPersona(&details, getPersonaRoles(persona), index, !wPropList.contains("roles")); |
872 | + appendDetailsForPersona(&details, getPersonaEmails(persona), index, !wPropList.contains("email-addresses")); |
873 | + appendDetailsForPersona(&details, getPersonaPhones(persona), index, !wPropList.contains("phone-numbers")); |
874 | + appendDetailsForPersona(&details, getPersonaAddresses(persona), index, !wPropList.contains("postal-addresses")); |
875 | + appendDetailsForPersona(&details, getPersonaIms(persona), index, !wPropList.contains("im-addresses")); |
876 | + appendDetailsForPersona(&details, getPersonaUrls(persona), index, !wPropList.contains("urls")); |
877 | + personaIndex++; |
878 | + } |
879 | + return details; |
880 | +} |
881 | + |
882 | +QContactDetail QIndividual::getPersonaName(FolksPersona *persona) const |
883 | +{ |
884 | + if (!FOLKS_IS_NAME_DETAILS(persona)) { |
885 | + return QContactDetail(); |
886 | + } |
887 | + |
888 | QContactName detail; |
889 | - FolksStructuredName *sn = folks_name_details_get_structured_name(FOLKS_NAME_DETAILS(m_individual)); |
890 | - |
891 | + FolksStructuredName *sn = folks_name_details_get_structured_name(FOLKS_NAME_DETAILS(persona)); |
892 | if (sn) { |
893 | const char *name = folks_structured_name_get_given_name(sn); |
894 | if (name && strlen(name)) { |
895 | @@ -317,30 +433,42 @@ |
896 | return detail; |
897 | } |
898 | |
899 | -QtContacts::QContactDetail QIndividual::getFullName() const |
900 | +QtContacts::QContactDetail QIndividual::getPersonaFullName(FolksPersona *persona) const |
901 | { |
902 | + if (!FOLKS_IS_NAME_DETAILS(persona)) { |
903 | + return QContactDetail(); |
904 | + } |
905 | + |
906 | QContactDisplayLabel detail; |
907 | - const gchar *fullName = folks_name_details_get_full_name(FOLKS_NAME_DETAILS(m_individual)); |
908 | + const gchar *fullName = folks_name_details_get_full_name(FOLKS_NAME_DETAILS(persona)); |
909 | if (fullName && strlen(fullName)) { |
910 | detail.setLabel(QString::fromUtf8(fullName)); |
911 | } |
912 | return detail; |
913 | } |
914 | |
915 | -QtContacts::QContactDetail QIndividual::getNickname() const |
916 | +QtContacts::QContactDetail QIndividual::getPersonaNickName(FolksPersona *persona) const |
917 | { |
918 | + if (!FOLKS_IS_NAME_DETAILS(persona)) { |
919 | + return QContactDetail(); |
920 | + } |
921 | + |
922 | QContactNickname detail; |
923 | - const gchar* nickname = folks_name_details_get_nickname(FOLKS_NAME_DETAILS(m_individual)); |
924 | + const gchar* nickname = folks_name_details_get_nickname(FOLKS_NAME_DETAILS(persona)); |
925 | if (nickname && strlen(nickname)) { |
926 | detail.setNickname(QString::fromUtf8(nickname)); |
927 | } |
928 | return detail; |
929 | } |
930 | |
931 | -QtContacts::QContactDetail QIndividual::getBirthday() const |
932 | +QtContacts::QContactDetail QIndividual::getPersonaBirthday(FolksPersona *persona) const |
933 | { |
934 | + if (!FOLKS_IS_BIRTHDAY_DETAILS(persona)) { |
935 | + return QContactDetail(); |
936 | + } |
937 | + |
938 | QContactBirthday detail; |
939 | - GDateTime* datetime = folks_birthday_details_get_birthday(FOLKS_BIRTHDAY_DETAILS(m_individual)); |
940 | + GDateTime* datetime = folks_birthday_details_get_birthday(FOLKS_BIRTHDAY_DETAILS(persona)); |
941 | if (datetime) { |
942 | QDate date(g_date_time_get_year(datetime), g_date_time_get_month(datetime), g_date_time_get_day_of_month(datetime)); |
943 | QTime time(g_date_time_get_hour(datetime), g_date_time_get_minute(datetime), g_date_time_get_second(datetime)); |
944 | @@ -349,16 +477,20 @@ |
945 | return detail; |
946 | } |
947 | |
948 | -QtContacts::QContactDetail QIndividual::getPhoto() const |
949 | +QtContacts::QContactDetail QIndividual::getPersonaPhoto(FolksPersona *persona) const |
950 | { |
951 | // TODO |
952 | return QContactAvatar(); |
953 | } |
954 | |
955 | -QList<QtContacts::QContactDetail> QIndividual::getRoles() const |
956 | +QList<QtContacts::QContactDetail> QIndividual::getPersonaRoles(FolksPersona *persona) const |
957 | { |
958 | + if (!FOLKS_IS_ROLE_DETAILS(persona)) { |
959 | + return QList<QtContacts::QContactDetail>(); |
960 | + } |
961 | + |
962 | QList<QtContacts::QContactDetail> details; |
963 | - GeeSet *roles = folks_role_details_get_roles(FOLKS_ROLE_DETAILS(m_individual)); |
964 | + GeeSet *roles = folks_role_details_get_roles(FOLKS_ROLE_DETAILS(persona)); |
965 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(roles)); |
966 | |
967 | while(gee_iterator_next(iter)) { |
968 | @@ -379,10 +511,14 @@ |
969 | return details; |
970 | } |
971 | |
972 | -QList<QtContacts::QContactDetail> QIndividual::getEmails() const |
973 | +QList<QtContacts::QContactDetail> QIndividual::getPersonaEmails(FolksPersona *persona) const |
974 | { |
975 | + if (!FOLKS_IS_EMAIL_DETAILS(persona)) { |
976 | + return QList<QtContacts::QContactDetail>(); |
977 | + } |
978 | + |
979 | QList<QtContacts::QContactDetail> details; |
980 | - GeeSet *emails = folks_email_details_get_email_addresses(FOLKS_EMAIL_DETAILS(m_individual)); |
981 | + GeeSet *emails = folks_email_details_get_email_addresses(FOLKS_EMAIL_DETAILS(persona)); |
982 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(emails)); |
983 | |
984 | while(gee_iterator_next(iter)) { |
985 | @@ -402,10 +538,14 @@ |
986 | return details; |
987 | } |
988 | |
989 | -QList<QtContacts::QContactDetail> QIndividual::getPhones() const |
990 | +QList<QtContacts::QContactDetail> QIndividual::getPersonaPhones(FolksPersona *persona) const |
991 | { |
992 | + if (!FOLKS_IS_PHONE_DETAILS(persona)) { |
993 | + return QList<QtContacts::QContactDetail>(); |
994 | + } |
995 | + |
996 | QList<QtContacts::QContactDetail> details; |
997 | - GeeSet *phones = folks_phone_details_get_phone_numbers(FOLKS_PHONE_DETAILS(m_individual)); |
998 | + GeeSet *phones = folks_phone_details_get_phone_numbers(FOLKS_PHONE_DETAILS(persona)); |
999 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(phones)); |
1000 | |
1001 | while(gee_iterator_next(iter)) { |
1002 | @@ -425,10 +565,14 @@ |
1003 | return details; |
1004 | } |
1005 | |
1006 | -QList<QtContacts::QContactDetail> QIndividual::getAddresses() const |
1007 | +QList<QtContacts::QContactDetail> QIndividual::getPersonaAddresses(FolksPersona *persona) const |
1008 | { |
1009 | + if (!FOLKS_IS_POSTAL_ADDRESS_DETAILS(persona)) { |
1010 | + return QList<QtContacts::QContactDetail>(); |
1011 | + } |
1012 | + |
1013 | QList<QtContacts::QContactDetail> details; |
1014 | - GeeSet *addresses = folks_postal_address_details_get_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(m_individual)); |
1015 | + GeeSet *addresses = folks_postal_address_details_get_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(persona)); |
1016 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(addresses)); |
1017 | |
1018 | while(gee_iterator_next(iter)) { |
1019 | @@ -476,10 +620,14 @@ |
1020 | return details; |
1021 | } |
1022 | |
1023 | -QList<QtContacts::QContactDetail> QIndividual::getIms() const |
1024 | +QList<QtContacts::QContactDetail> QIndividual::getPersonaIms(FolksPersona *persona) const |
1025 | { |
1026 | + if (!FOLKS_IS_IM_DETAILS(persona)) { |
1027 | + return QList<QtContacts::QContactDetail>(); |
1028 | + } |
1029 | + |
1030 | QList<QtContacts::QContactDetail> details; |
1031 | - GeeMultiMap *ims = folks_im_details_get_im_addresses(FOLKS_IM_DETAILS(m_individual)); |
1032 | + GeeMultiMap *ims = folks_im_details_get_im_addresses(FOLKS_IM_DETAILS(persona)); |
1033 | GeeSet *keys = gee_multi_map_get_keys(ims); |
1034 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(keys)); |
1035 | |
1036 | @@ -508,16 +656,14 @@ |
1037 | return details; |
1038 | } |
1039 | |
1040 | -QtContacts::QContactDetail QIndividual::getTimeZone() const |
1041 | +QList<QtContacts::QContactDetail> QIndividual::getPersonaUrls(FolksPersona *persona) const |
1042 | { |
1043 | - //TODO |
1044 | - return QContactDetail(); |
1045 | -} |
1046 | + if (!FOLKS_IS_URL_DETAILS(persona)) { |
1047 | + return QList<QtContacts::QContactDetail>(); |
1048 | + } |
1049 | |
1050 | -QList<QtContacts::QContactDetail> QIndividual::getUrls() const |
1051 | -{ |
1052 | QList<QtContacts::QContactDetail> details; |
1053 | - GeeSet *urls = folks_url_details_get_urls(FOLKS_URL_DETAILS(m_individual)); |
1054 | + GeeSet *urls = folks_url_details_get_urls(FOLKS_URL_DETAILS(persona)); |
1055 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(urls)); |
1056 | |
1057 | while(gee_iterator_next(iter)) { |
1058 | @@ -635,519 +781,662 @@ |
1059 | { |
1060 | m_contact = QContact(); |
1061 | m_contact.appendDetail(getUid()); |
1062 | - m_contact.appendDetail(getName()); |
1063 | - m_contact.appendDetail(getFullName()); |
1064 | - m_contact.appendDetail(getNickname()); |
1065 | - m_contact.appendDetail(getBirthday()); |
1066 | - m_contact.appendDetail(getPhoto()); |
1067 | - m_contact.appendDetail(getTimeZone()); |
1068 | Q_FOREACH(QContactDetail detail, getClientPidMap()) { |
1069 | m_contact.appendDetail(detail); |
1070 | } |
1071 | - Q_FOREACH(QContactDetail detail, getRoles()) { |
1072 | - m_contact.appendDetail(detail); |
1073 | - } |
1074 | - Q_FOREACH(QContactDetail detail, getEmails()) { |
1075 | - m_contact.appendDetail(detail); |
1076 | - } |
1077 | - Q_FOREACH(QContactDetail detail, getPhones()) { |
1078 | - m_contact.appendDetail(detail); |
1079 | - } |
1080 | - Q_FOREACH(QContactDetail detail, getAddresses()) { |
1081 | - m_contact.appendDetail(detail); |
1082 | - } |
1083 | - Q_FOREACH(QContactDetail detail, getIms()) { |
1084 | - m_contact.appendDetail(detail); |
1085 | - } |
1086 | - Q_FOREACH(QContactDetail detail, getUrls()) { |
1087 | - m_contact.appendDetail(detail); |
1088 | - } |
1089 | + |
1090 | + Q_FOREACH(QContactDetail detail, getDetails()) { |
1091 | + m_contact.appendDetail(detail); |
1092 | + } |
1093 | +} |
1094 | + |
1095 | +void QIndividual::createPersonaForDetail(QList<QtContacts::QContactDetail> cDetails, ParseDetailsFunc parseFunc, void *data) const |
1096 | +{ |
1097 | + GHashTable *details = g_hash_table_new_full(g_str_hash, |
1098 | + g_str_equal, |
1099 | + NULL, |
1100 | + (GDestroyNotify) QIndividualUtils::gValueSliceFree); |
1101 | + |
1102 | + parseFunc(details, cDetails); |
1103 | + |
1104 | + folks_individual_aggregator_add_persona_from_details(m_aggregator, |
1105 | + NULL, // we should pass the m_individual here but due a bug on folks lest do a work around |
1106 | + folks_individual_aggregator_get_primary_store(m_aggregator), |
1107 | + details, |
1108 | + (GAsyncReadyCallback) createPersonaDone, |
1109 | + (void*) data); |
1110 | + |
1111 | + g_hash_table_destroy(details); |
1112 | } |
1113 | |
1114 | void QIndividual::updateFullName(const QtContacts::QContactDetail &detail, void* data) |
1115 | { |
1116 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1117 | - QContactDetail originalLabel = m_contact.detail(QContactDetail::TypeDisplayLabel); |
1118 | - if (FOLKS_IS_NAME_DETAILS(udata->m_persona) && (originalLabel != detail)) { |
1119 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1120 | + QContactDetail originalLabel = detailFromUri(QContactDetail::TypeDisplayLabel, detail.detailUri()); |
1121 | + |
1122 | + if (persona == 0) { |
1123 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseFullNameDetails, data); |
1124 | + } else if (FOLKS_IS_NAME_DETAILS(persona) && (originalLabel != detail)) { |
1125 | const QContactDisplayLabel *label = static_cast<const QContactDisplayLabel*>(&detail); |
1126 | |
1127 | - folks_name_details_change_full_name(FOLKS_NAME_DETAILS(udata->m_persona), |
1128 | + folks_name_details_change_full_name(FOLKS_NAME_DETAILS(persona), |
1129 | label->label().toUtf8().data(), |
1130 | (GAsyncReadyCallback) updateDetailsDone, |
1131 | data); |
1132 | } else { |
1133 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1134 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1135 | } |
1136 | } |
1137 | |
1138 | void QIndividual::updateName(const QtContacts::QContactDetail &detail, void* data) |
1139 | { |
1140 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1141 | - QContactDetail originalName = m_contact.detail(QContactDetail::TypeName); |
1142 | - if (FOLKS_IS_NAME_DETAILS(udata->m_persona) && (originalName != detail)) { |
1143 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1144 | + QContactDetail originalName = detailFromUri(QContactDetail::TypeName, detail.detailUri()); |
1145 | + |
1146 | + if (persona == 0) { |
1147 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseNameDetails, data); |
1148 | + } else if (FOLKS_IS_NAME_DETAILS(persona) && (originalName != detail)) { |
1149 | const QContactName *name = static_cast<const QContactName*>(&detail); |
1150 | - FolksStructuredName *sn = folks_name_details_get_structured_name(FOLKS_NAME_DETAILS(m_individual)); |
1151 | - if (!sn) { |
1152 | - sn = folks_structured_name_new(name->lastName().toUtf8().data(), |
1153 | - name->firstName().toUtf8().data(), |
1154 | - name->middleName().toUtf8().data(), |
1155 | - name->prefix().toUtf8().data(), |
1156 | - name->suffix().toUtf8().data()); |
1157 | - } else { |
1158 | - folks_structured_name_set_family_name(sn, name->lastName().toUtf8().data()); |
1159 | - folks_structured_name_set_given_name(sn, name->firstName().toUtf8().data()); |
1160 | - folks_structured_name_set_additional_names(sn, name->middleName().toUtf8().data()); |
1161 | - folks_structured_name_set_prefixes(sn, name->prefix().toUtf8().data()); |
1162 | - folks_structured_name_set_suffixes(sn, name->suffix().toUtf8().data()); |
1163 | - } |
1164 | + FolksStructuredName *sn; |
1165 | + sn = folks_structured_name_new(name->lastName().toUtf8().data(), |
1166 | + name->firstName().toUtf8().data(), |
1167 | + name->middleName().toUtf8().data(), |
1168 | + name->prefix().toUtf8().data(), |
1169 | + name->suffix().toUtf8().data()); |
1170 | |
1171 | - folks_name_details_change_structured_name(FOLKS_NAME_DETAILS(udata->m_persona), |
1172 | + folks_name_details_change_structured_name(FOLKS_NAME_DETAILS(persona), |
1173 | sn, |
1174 | (GAsyncReadyCallback) updateDetailsDone, |
1175 | data); |
1176 | + |
1177 | g_object_unref(sn); |
1178 | } else { |
1179 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1180 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1181 | } |
1182 | } |
1183 | |
1184 | void QIndividual::updateNickname(const QtContacts::QContactDetail &detail, void* data) |
1185 | { |
1186 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1187 | - QContactDetail originalNickname = m_contact.detail(QContactDetail::TypeNickname); |
1188 | - if (FOLKS_IS_NAME_DETAILS(udata->m_persona) && (originalNickname != detail)) { |
1189 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1190 | + QContactDetail originalNickname = detailFromUri(QContactDetail::TypeNickname, detail.detailUri()); |
1191 | + |
1192 | + if (persona == 0) { |
1193 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseNicknameDetails, data); |
1194 | + } else if (FOLKS_IS_NAME_DETAILS(persona) && (originalNickname != detail)) { |
1195 | const QContactNickname *nickname = static_cast<const QContactNickname*>(&detail); |
1196 | - folks_name_details_change_nickname(FOLKS_NAME_DETAILS(udata->m_persona), |
1197 | + folks_name_details_change_nickname(FOLKS_NAME_DETAILS(persona), |
1198 | nickname->nickname().toUtf8().data(), |
1199 | (GAsyncReadyCallback) updateDetailsDone, |
1200 | data); |
1201 | } else { |
1202 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1203 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1204 | } |
1205 | } |
1206 | |
1207 | void QIndividual::updateBirthday(const QtContacts::QContactDetail &detail, void* data) |
1208 | { |
1209 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1210 | - QContactDetail originalBirthday = m_contact.detail(QContactDetail::TypeBirthday); |
1211 | - if (FOLKS_IS_BIRTHDAY_DETAILS(udata->m_persona) && (originalBirthday != detail)) { |
1212 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1213 | + QContactDetail originalBirthday = detailFromUri(QContactDetail::TypeBirthday, detail.detailUri()); |
1214 | + |
1215 | + if (persona == 0) { |
1216 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseBirthdayDetails, data); |
1217 | + } else if (FOLKS_IS_BIRTHDAY_DETAILS(persona) && (originalBirthday != detail)) { |
1218 | const QContactBirthday *birthday = static_cast<const QContactBirthday*>(&detail); |
1219 | + |
1220 | GDateTime *dateTime = NULL; |
1221 | if (!birthday->isEmpty()) { |
1222 | dateTime = g_date_time_new_from_unix_utc(birthday->dateTime().toMSecsSinceEpoch() / 1000); |
1223 | } |
1224 | - folks_birthday_details_change_birthday(FOLKS_BIRTHDAY_DETAILS(udata->m_persona), |
1225 | + folks_birthday_details_change_birthday(FOLKS_BIRTHDAY_DETAILS(persona), |
1226 | dateTime, |
1227 | (GAsyncReadyCallback) updateDetailsDone, |
1228 | data); |
1229 | g_date_time_unref(dateTime); |
1230 | } else { |
1231 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1232 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1233 | } |
1234 | } |
1235 | |
1236 | void QIndividual::updatePhoto(const QtContacts::QContactDetail &detail, void* data) |
1237 | { |
1238 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1239 | - QContactDetail originalAvatar = m_contact.detail(QContactDetail::TypeAvatar); |
1240 | - if (FOLKS_IS_AVATAR_DETAILS(udata->m_persona) && (detail != originalAvatar)) { |
1241 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1242 | + QContactDetail originalAvatar = detailFromUri(QContactDetail::TypeAvatar, detail.detailUri()); |
1243 | + |
1244 | + if (persona == 0) { |
1245 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parsePhotoDetails, data); |
1246 | + } else if (FOLKS_IS_AVATAR_DETAILS(persona) && (detail != originalAvatar)) { |
1247 | //TODO: |
1248 | //const QContactAvatar *avatar = static_cast<const QContactAvatar*>(&detail); |
1249 | - folks_avatar_details_change_avatar(FOLKS_AVATAR_DETAILS(udata->m_persona), |
1250 | + folks_avatar_details_change_avatar(FOLKS_AVATAR_DETAILS(persona), |
1251 | 0, |
1252 | (GAsyncReadyCallback) updateDetailsDone, |
1253 | data); |
1254 | } else { |
1255 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1256 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1257 | } |
1258 | } |
1259 | |
1260 | -void QIndividual::updateTimezone(const QtContacts::QContactDetail &detail, void* data) |
1261 | -{ |
1262 | - //TODO |
1263 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1264 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1265 | -} |
1266 | - |
1267 | -void QIndividual::updateRoles(QList<QtContacts::QContactDetail> details, void* data) |
1268 | -{ |
1269 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1270 | - QList<QContactDetail> originalOrganizations = m_contact.details(QContactDetail::TypeOrganization); |
1271 | - |
1272 | - if (FOLKS_IS_ROLE_DETAILS(udata->m_persona) && !detailListIsEqual(originalOrganizations, details)) { |
1273 | - GeeSet *roleSet = SET_AFD_NEW(); |
1274 | - Q_FOREACH(const QContactDetail& detail, details) { |
1275 | - const QContactOrganization *org = static_cast<const QContactOrganization*>(&detail); |
1276 | - |
1277 | - // The role values can not be NULL |
1278 | - const gchar* title = org->title().toUtf8().data(); |
1279 | - const gchar* name = org->name().toUtf8().data(); |
1280 | - const gchar* roleName = org->role().toUtf8().data(); |
1281 | - |
1282 | - FolksRole *role = folks_role_new(title ? title : "", name ? name : "", ""); |
1283 | - folks_role_set_role(role, roleName ? roleName : ""); |
1284 | - |
1285 | - FolksRoleFieldDetails *fieldDetails = folks_role_field_details_new(role, NULL); |
1286 | - parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(fieldDetails), detail); |
1287 | - gee_collection_add(GEE_COLLECTION(roleSet), fieldDetails); |
1288 | - |
1289 | - g_object_unref(role); |
1290 | - g_object_unref(fieldDetails); |
1291 | - } |
1292 | - |
1293 | - folks_role_details_change_roles(FOLKS_ROLE_DETAILS(udata->m_persona), |
1294 | +void QIndividual::updateRole(QtContacts::QContactDetail detail, void* data) |
1295 | +{ |
1296 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1297 | + QContactDetail originalRole = detailFromUri(QContactDetail::TypeOrganization, detail.detailUri()); |
1298 | + |
1299 | + if (!persona) { |
1300 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseOrganizationDetails, data); |
1301 | + } else if (FOLKS_IS_ROLE_DETAILS(persona) && (originalRole != detail)) { |
1302 | + FolksRoleFieldDetails *roleDetails = 0; |
1303 | + const QContactOrganization *cRole = static_cast<const QContactOrganization*>(&detail); |
1304 | + GeeSet *roleSet = folks_role_details_get_roles(FOLKS_ROLE_DETAILS(persona)); |
1305 | + |
1306 | + if (!roleSet || (gee_collection_get_size(GEE_COLLECTION(roleSet)) == 0)) { |
1307 | + roleSet = SET_AFD_NEW(); |
1308 | + } else { |
1309 | + roleDetails = FOLKS_ROLE_FIELD_DETAILS(QIndividualUtils::getDetails(roleSet, detail.detailUri())); |
1310 | + // this will be unref at the end of the function |
1311 | + g_object_ref(roleSet); |
1312 | + g_object_ref(roleDetails); |
1313 | + } |
1314 | + |
1315 | + const gchar* title = cRole->title().isEmpty() ? "" : cRole->title().toUtf8().data(); |
1316 | + const gchar* name = cRole->name().isEmpty() ? "" : cRole->name().toUtf8().data(); |
1317 | + const gchar* roleName = cRole->role().isEmpty() ? "" : cRole->role().toUtf8().data(); |
1318 | + |
1319 | + FolksRole *roleValue; |
1320 | + if (!roleDetails) { |
1321 | + roleValue = folks_role_new(title, name, ""); |
1322 | + folks_role_set_role(roleValue, roleName); |
1323 | + |
1324 | + roleDetails = folks_role_field_details_new(roleValue, NULL); |
1325 | + gee_collection_add(GEE_COLLECTION(roleSet), roleDetails); |
1326 | + } else { |
1327 | + roleValue = FOLKS_ROLE(folks_abstract_field_details_get_value(FOLKS_ABSTRACT_FIELD_DETAILS(roleDetails))); |
1328 | + folks_role_set_organisation_name(roleValue, name); |
1329 | + folks_role_set_title(roleValue, title); |
1330 | + folks_role_set_role(roleValue, roleName); |
1331 | + } |
1332 | + |
1333 | + parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(roleDetails), detail); |
1334 | + folks_role_details_change_roles(FOLKS_ROLE_DETAILS(persona), |
1335 | roleSet, |
1336 | (GAsyncReadyCallback) updateDetailsDone, |
1337 | data); |
1338 | + |
1339 | + g_object_unref(roleDetails); |
1340 | g_object_unref(roleSet); |
1341 | + g_object_unref(roleValue); |
1342 | } else { |
1343 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1344 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1345 | } |
1346 | } |
1347 | |
1348 | -void QIndividual::updateEmails(QList<QtContacts::QContactDetail> details, void* data) |
1349 | +void QIndividual::updateEmail(QtContacts::QContactDetail detail, void* data) |
1350 | { |
1351 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1352 | - QList<QContactDetail> originalEmails = m_contact.details(QContactDetail::TypeEmailAddress); |
1353 | - |
1354 | - if (FOLKS_IS_EMAIL_DETAILS(udata->m_persona) && !detailListIsEqual(originalEmails, details)) { |
1355 | - GeeSet *emailSet = SET_AFD_NEW(); |
1356 | - Q_FOREACH(const QContactDetail& detail, details) { |
1357 | - const QContactEmailAddress *email = static_cast<const QContactEmailAddress*>(&detail); |
1358 | - |
1359 | - if(!email->isEmpty()) { |
1360 | - FolksEmailFieldDetails *emailDetails = folks_email_field_details_new(email->emailAddress().toUtf8().data(), NULL); |
1361 | - parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(emailDetails), detail); |
1362 | - gee_collection_add(GEE_COLLECTION(emailSet), emailDetails); |
1363 | - g_object_unref(emailDetails); |
1364 | - } |
1365 | - } |
1366 | - folks_email_details_change_email_addresses(FOLKS_EMAIL_DETAILS(udata->m_persona), |
1367 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1368 | + QContactDetail originalEmail = detailFromUri(QContactDetail::TypeEmailAddress, detail.detailUri()); |
1369 | + |
1370 | + if (!persona) { |
1371 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseEmailDetails, data); |
1372 | + } else if (FOLKS_IS_EMAIL_DETAILS(persona) && (originalEmail != detail)) { |
1373 | + FolksEmailFieldDetails *emailDetails = 0; |
1374 | + const QContactEmailAddress *email = static_cast<const QContactEmailAddress*>(&detail); |
1375 | + GeeSet *emailSet = folks_email_details_get_email_addresses(FOLKS_EMAIL_DETAILS(persona)); |
1376 | + if (!emailSet || (gee_collection_get_size(GEE_COLLECTION(emailSet)) == 0)) { |
1377 | + emailSet = SET_AFD_NEW(); |
1378 | + } else { |
1379 | + emailDetails = FOLKS_EMAIL_FIELD_DETAILS(QIndividualUtils::getDetails(emailSet, detail.detailUri())); |
1380 | + // this will be unref at the end of the function |
1381 | + g_object_ref(emailSet); |
1382 | + g_object_ref(emailDetails); |
1383 | + } |
1384 | + |
1385 | + if (!emailDetails) { |
1386 | + emailDetails = folks_email_field_details_new(email->emailAddress().toUtf8().data(), NULL); |
1387 | + gee_collection_add(GEE_COLLECTION(emailSet), emailDetails); |
1388 | + } else { |
1389 | + folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(emailDetails), |
1390 | + email->emailAddress().toUtf8().data()); |
1391 | + } |
1392 | + |
1393 | + folks_email_details_change_email_addresses(FOLKS_EMAIL_DETAILS(persona), |
1394 | emailSet, |
1395 | (GAsyncReadyCallback) updateDetailsDone, |
1396 | data); |
1397 | + |
1398 | g_object_unref(emailSet); |
1399 | + g_object_unref(emailDetails); |
1400 | } else { |
1401 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1402 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1403 | } |
1404 | } |
1405 | |
1406 | -void QIndividual::updatePhones(QList<QtContacts::QContactDetail> details, void* data) |
1407 | +void QIndividual::updatePhone(QtContacts::QContactDetail detail, void* data) |
1408 | { |
1409 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1410 | - QList<QContactDetail> originalPhones = m_contact.details(QContactDetail::TypePhoneNumber); |
1411 | - |
1412 | - if (FOLKS_IS_PHONE_DETAILS(udata->m_persona) && !detailListIsEqual(originalPhones, details)) { |
1413 | - GeeSet *phoneSet = SET_AFD_NEW(); |
1414 | - Q_FOREACH(const QContactDetail& detail, details) { |
1415 | - const QContactPhoneNumber *phone = static_cast<const QContactPhoneNumber*>(&detail); |
1416 | - |
1417 | - if(!phone->isEmpty()) { |
1418 | - FolksPhoneFieldDetails *phoneDetails = folks_phone_field_details_new(phone->number().toUtf8().data(), NULL); |
1419 | - parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(phoneDetails), detail); |
1420 | - gee_collection_add(GEE_COLLECTION(phoneSet), phoneDetails); |
1421 | - g_object_unref(phoneDetails); |
1422 | - } |
1423 | - } |
1424 | - folks_phone_details_change_phone_numbers(FOLKS_PHONE_DETAILS(udata->m_persona), |
1425 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1426 | + QContactDetail originalPhone = detailFromUri(QContactDetail::TypePhoneNumber, detail.detailUri()); |
1427 | + // if we do not have a persona for this detail we need to create one |
1428 | + if (!persona) { |
1429 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parsePhoneNumbersDetails, data); |
1430 | + } else if (FOLKS_IS_PHONE_DETAILS(persona) && (originalPhone != detail)) { |
1431 | + /// Only update the details on the current persona |
1432 | + FolksPhoneFieldDetails *phoneDetails = 0; |
1433 | + const QContactPhoneNumber *phone = static_cast<const QContactPhoneNumber*>(&detail); |
1434 | + GeeSet *phoneSet = folks_phone_details_get_phone_numbers(FOLKS_PHONE_DETAILS(persona)); |
1435 | + |
1436 | + if (!phoneSet || (gee_collection_get_size(GEE_COLLECTION(phoneSet)) == 0)) { |
1437 | + phoneSet = SET_AFD_NEW(); |
1438 | + } else { |
1439 | + phoneDetails = FOLKS_PHONE_FIELD_DETAILS(QIndividualUtils::getDetails(phoneSet, detail.detailUri())); |
1440 | + // this will be unref at the end of the function |
1441 | + g_object_ref(phoneSet); |
1442 | + g_object_ref(phoneDetails); |
1443 | + } |
1444 | + |
1445 | + if (!phoneDetails) { |
1446 | + phoneDetails = folks_phone_field_details_new(phone->number().toUtf8().data(), NULL); |
1447 | + gee_collection_add(GEE_COLLECTION(phoneSet), phoneDetails); |
1448 | + } else { |
1449 | + folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(phoneDetails), |
1450 | + phone->number().toUtf8().data()); |
1451 | + } |
1452 | + |
1453 | + parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(phoneDetails), detail); |
1454 | + folks_phone_details_change_phone_numbers(FOLKS_PHONE_DETAILS(persona), |
1455 | phoneSet, |
1456 | (GAsyncReadyCallback) updateDetailsDone, |
1457 | data); |
1458 | + g_object_unref(phoneDetails); |
1459 | g_object_unref(phoneSet); |
1460 | } else { |
1461 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1462 | - } |
1463 | -} |
1464 | - |
1465 | -bool QIndividual::detailListIsEqual(QList<QtContacts::QContactDetail> original, QList<QtContacts::QContactDetail> details) |
1466 | -{ |
1467 | - if (original.size() != details.size()) { |
1468 | - return false; |
1469 | - } |
1470 | - |
1471 | - Q_FOREACH(const QContactDetail& detail, details) { |
1472 | - if (!original.contains(detail)) { |
1473 | - return false; |
1474 | - } |
1475 | - } |
1476 | - |
1477 | - return true; |
1478 | -} |
1479 | - |
1480 | -void QIndividual::updateAddresses(QList<QtContacts::QContactDetail> details, void* data) |
1481 | -{ |
1482 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1483 | - QList<QContactDetail> originalAddress = m_contact.details(QContactDetail::TypeAddress); |
1484 | - |
1485 | - if (FOLKS_IS_POSTAL_ADDRESS_DETAILS(udata->m_persona) && !detailListIsEqual(originalAddress, details)) { |
1486 | - GeeSet *addressSet = SET_AFD_NEW(); |
1487 | - Q_FOREACH(const QContactDetail& detail, details) { |
1488 | - const QContactAddress *address = static_cast<const QContactAddress*>(&detail); |
1489 | - if (!address->isEmpty()) { |
1490 | - FolksPostalAddress *postalAddress = folks_postal_address_new(address->postOfficeBox().toUtf8().data(), |
1491 | - NULL, |
1492 | - address->street().toUtf8().data(), |
1493 | - address->locality().toUtf8().data(), |
1494 | - address->region().toUtf8().data(), |
1495 | - address->postcode().toUtf8().data(), |
1496 | - address->country().toUtf8().data(), |
1497 | - NULL, |
1498 | - NULL); |
1499 | - FolksPostalAddressFieldDetails *pafd = folks_postal_address_field_details_new(postalAddress, NULL); |
1500 | - |
1501 | - parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(pafd), detail); |
1502 | - gee_collection_add(GEE_COLLECTION(addressSet), pafd); |
1503 | - |
1504 | - g_object_unref(postalAddress); |
1505 | - g_object_unref(pafd); |
1506 | - } |
1507 | - } |
1508 | - |
1509 | - folks_postal_address_details_change_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(udata->m_persona), |
1510 | - addressSet, |
1511 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1512 | + } |
1513 | +} |
1514 | + |
1515 | +void QIndividual::updateAddress(QtContacts::QContactDetail detail, void* data) |
1516 | +{ |
1517 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1518 | + QContactDetail originalAddress = detailFromUri(QContactDetail::TypeAddress, detail.detailUri()); |
1519 | + |
1520 | + if (!persona) { |
1521 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseAddressDetails, data); |
1522 | + } else if (FOLKS_IS_POSTAL_ADDRESS_DETAILS(persona) && (originalAddress != detail)) { |
1523 | + FolksPostalAddressFieldDetails *addrDetails = 0; |
1524 | + const QContactAddress *addr = static_cast<const QContactAddress*>(&detail); |
1525 | + GeeSet *addrSet = folks_postal_address_details_get_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(persona)); |
1526 | + |
1527 | + if (!addrSet || (gee_collection_get_size(GEE_COLLECTION(addrSet)) == 0)) { |
1528 | + addrSet = SET_AFD_NEW(); |
1529 | + } else { |
1530 | + addrDetails = FOLKS_POSTAL_ADDRESS_FIELD_DETAILS(QIndividualUtils::getDetails(addrSet, detail.detailUri())); |
1531 | + // this will be unref at the end of the function |
1532 | + g_object_ref(addrSet); |
1533 | + g_object_ref(addrDetails); |
1534 | + } |
1535 | + |
1536 | + FolksPostalAddress *addrValue; |
1537 | + if (!addrDetails) { |
1538 | + addrValue = folks_postal_address_new(addr->postOfficeBox().toUtf8().data(), |
1539 | + NULL, |
1540 | + addr->street().toUtf8().data(), |
1541 | + addr->locality().toUtf8().data(), |
1542 | + addr->region().toUtf8().data(), |
1543 | + addr->postcode().toUtf8().data(), |
1544 | + addr->country().toUtf8().data(), |
1545 | + NULL, |
1546 | + NULL); |
1547 | + addrDetails = folks_postal_address_field_details_new(addrValue, NULL); |
1548 | + gee_collection_add(GEE_COLLECTION(addrSet), addrDetails); |
1549 | + } else { |
1550 | + addrValue = FOLKS_POSTAL_ADDRESS(folks_abstract_field_details_get_value(FOLKS_ABSTRACT_FIELD_DETAILS(addrDetails))); |
1551 | + Q_ASSERT(addrValue); |
1552 | + folks_postal_address_set_po_box(addrValue, addr->postOfficeBox().toUtf8().data()); |
1553 | + folks_postal_address_set_street(addrValue, addr->street().toUtf8().data()); |
1554 | + folks_postal_address_set_locality(addrValue, addr->locality().toUtf8().data()); |
1555 | + folks_postal_address_set_region(addrValue, addr->region().toUtf8().data()); |
1556 | + folks_postal_address_set_postal_code(addrValue, addr->postcode().toUtf8().data()); |
1557 | + folks_postal_address_set_country(addrValue, addr->country().toUtf8().data()); |
1558 | + } |
1559 | + |
1560 | + parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(addrDetails), detail); |
1561 | + folks_postal_address_details_change_postal_addresses(FOLKS_POSTAL_ADDRESS_DETAILS(persona), |
1562 | + addrSet, |
1563 | (GAsyncReadyCallback) updateDetailsDone, |
1564 | data); |
1565 | - g_object_unref(addressSet); |
1566 | + g_object_unref(addrDetails); |
1567 | + g_object_unref(addrSet); |
1568 | + g_object_unref(addrValue); |
1569 | } else { |
1570 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1571 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1572 | } |
1573 | } |
1574 | |
1575 | -void QIndividual::updateIms(QList<QtContacts::QContactDetail> details, void* data) |
1576 | +void QIndividual::updateIm(QtContacts::QContactDetail detail, void* data) |
1577 | { |
1578 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1579 | - QList<QContactDetail> originalIms = m_contact.details(QContactDetail::TypeOnlineAccount); |
1580 | - |
1581 | - if (FOLKS_IS_IM_DETAILS(udata->m_persona) && !detailListIsEqual(originalIms, details)) { |
1582 | - GeeMultiMap *imAddressHash = GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE_IM_FIELD_DETAILS); |
1583 | - Q_FOREACH(const QContactDetail& detail, details) { |
1584 | - const QContactOnlineAccount *im = static_cast<const QContactOnlineAccount*>(&detail); |
1585 | - if (!im->accountUri().isEmpty()) { |
1586 | - FolksImFieldDetails *imfd = folks_im_field_details_new(im->accountUri().toUtf8().data(), NULL); |
1587 | - parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(imfd), detail); |
1588 | - gee_multi_map_set(imAddressHash, |
1589 | - onlineAccountProtocolFromEnum(im->protocol()).toUtf8().data(), imfd); |
1590 | - g_object_unref(imfd); |
1591 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1592 | + QContactDetail originalIm = detailFromUri(QContactDetail::TypeOnlineAccount, detail.detailUri()); |
1593 | + |
1594 | + if (!persona) { |
1595 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseImDetails, data); |
1596 | + } else if (FOLKS_IS_IM_DETAILS(persona) && (originalIm != detail)) { |
1597 | + const QContactOnlineAccount *im = static_cast<const QContactOnlineAccount*>(&detail); |
1598 | + GeeMultiMap *imSet = folks_im_details_get_im_addresses(FOLKS_IM_DETAILS(persona)); |
1599 | + |
1600 | + if (!imSet || (gee_multi_map_get_size(GEE_MULTI_MAP(imSet)) == 0)) { |
1601 | + imSet = GEE_MULTI_MAP_AFD_NEW(FOLKS_TYPE_IM_FIELD_DETAILS); |
1602 | + } else { |
1603 | + // We can not relay on the index inside of detailUri because online account are stored in a hash |
1604 | + QContactOnlineAccount oldIm = static_cast<QContactOnlineAccount>(originalIm); |
1605 | + QString oldProtocolName = onlineAccountProtocolFromEnum(oldIm.protocol()); |
1606 | + GeeCollection *value = gee_multi_map_get(imSet, oldProtocolName.toUtf8().data()); |
1607 | + |
1608 | + // Remove the old one |
1609 | + if (value) { |
1610 | + // if there is more than one address only remove the correct one |
1611 | + if (gee_collection_get_size(value) > 1) { |
1612 | + gee_collection_remove(value, oldIm.accountUri().toUtf8().data()); |
1613 | + } else { |
1614 | + // otherwise remove the key |
1615 | + gee_multi_map_remove_all(imSet, oldProtocolName.toUtf8().data()); |
1616 | + } |
1617 | } |
1618 | + |
1619 | + g_object_ref(imSet); |
1620 | } |
1621 | |
1622 | - folks_im_details_change_im_addresses(FOLKS_IM_DETAILS(udata->m_persona), |
1623 | - imAddressHash, |
1624 | + // Append the new one |
1625 | + FolksImFieldDetails *imDetails = folks_im_field_details_new(im->accountUri().toUtf8().data(), NULL); |
1626 | + parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(imDetails), detail); |
1627 | + |
1628 | + gee_multi_map_set(imSet, |
1629 | + onlineAccountProtocolFromEnum(im->protocol()).toUtf8().data(), |
1630 | + imDetails); |
1631 | + |
1632 | + folks_im_details_change_im_addresses(FOLKS_IM_DETAILS(persona), |
1633 | + imSet, |
1634 | (GAsyncReadyCallback) updateDetailsDone, |
1635 | data); |
1636 | - g_object_unref(imAddressHash); |
1637 | + g_object_unref(imSet); |
1638 | + g_object_unref(imDetails); |
1639 | } else { |
1640 | - updateDetailsDone(G_OBJECT(udata->m_persona), NULL, data); |
1641 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1642 | } |
1643 | } |
1644 | |
1645 | -void QIndividual::updateUrls(QList<QtContacts::QContactDetail> details, void* data) |
1646 | +void QIndividual::updateUrl(QtContacts::QContactDetail detail, void* data) |
1647 | { |
1648 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1649 | - QList<QContactDetail> originalUrls = m_contact.details(QContactDetail::TypeUrl); |
1650 | - |
1651 | - if (FOLKS_IS_URL_DETAILS(udata->m_persona) && !detailListIsEqual(originalUrls, details)) { |
1652 | - GeeSet *urlSet = SET_AFD_NEW(); |
1653 | - Q_FOREACH(const QContactDetail& detail, details) { |
1654 | - const QContactUrl *url = static_cast<const QContactUrl*>(&detail); |
1655 | - |
1656 | - if(!url->isEmpty()) { |
1657 | - FolksUrlFieldDetails *urlDetails = folks_url_field_details_new(url->url().toUtf8().data(), NULL); |
1658 | - parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(urlDetails), detail); |
1659 | - gee_collection_add(GEE_COLLECTION(urlSet), urlDetails); |
1660 | - g_object_unref(urlDetails); |
1661 | - } |
1662 | - } |
1663 | - folks_url_details_change_urls(FOLKS_URL_DETAILS(udata->m_persona), |
1664 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1665 | + QContactDetail originalUrl = detailFromUri(QContactDetail::TypeUrl, detail.detailUri()); |
1666 | + |
1667 | + if (!persona) { |
1668 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseUrlDetails, data); |
1669 | + } else if (FOLKS_IS_URL_DETAILS(persona) && (originalUrl != detail)) { |
1670 | + FolksUrlFieldDetails *urlDetails = 0; |
1671 | + const QContactUrl *url = static_cast<const QContactUrl*>(&detail); |
1672 | + GeeSet *urlSet = folks_url_details_get_urls(FOLKS_URL_DETAILS(persona)); |
1673 | + |
1674 | + if (!urlSet || (gee_collection_get_size(GEE_COLLECTION(urlSet)) == 0)) { |
1675 | + urlSet = SET_AFD_NEW(); |
1676 | + } else { |
1677 | + urlDetails = FOLKS_URL_FIELD_DETAILS(QIndividualUtils::getDetails(urlSet, detail.detailUri())); |
1678 | + |
1679 | + // this will be unref at the end of the function |
1680 | + g_object_ref(urlSet); |
1681 | + g_object_ref(urlDetails); |
1682 | + } |
1683 | + |
1684 | + if (!urlDetails) { |
1685 | + urlDetails = folks_url_field_details_new(url->url().toUtf8().data(), NULL); |
1686 | + gee_collection_add(GEE_COLLECTION(urlSet), urlDetails); |
1687 | + } else { |
1688 | + folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(urlDetails), |
1689 | + url->url().toUtf8().data()); |
1690 | + } |
1691 | + |
1692 | + parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(urlDetails), detail); |
1693 | + folks_url_details_change_urls(FOLKS_URL_DETAILS(persona), |
1694 | urlSet, |
1695 | (GAsyncReadyCallback) updateDetailsDone, |
1696 | data); |
1697 | + g_object_unref(urlDetails); |
1698 | g_object_unref(urlSet); |
1699 | } else { |
1700 | - updateDetailsDone(G_OBJECT(m_individual), NULL, data); |
1701 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1702 | } |
1703 | } |
1704 | |
1705 | -void QIndividual::updateNotes(QList<QtContacts::QContactDetail> details, void* data) |
1706 | +void QIndividual::updateNote(QtContacts::QContactDetail detail, void* data) |
1707 | { |
1708 | - UpdateContactData *udata = static_cast<UpdateContactData*>(data); |
1709 | - QList<QContactDetail> originalNotes = m_contact.details(QContactDetail::TypeNote); |
1710 | - |
1711 | - if (FOLKS_IS_NOTE_DETAILS(udata->m_persona) && !detailListIsEqual(originalNotes, details)) { |
1712 | - GeeSet *noteSet = SET_AFD_NEW(); |
1713 | - Q_FOREACH(const QContactDetail& detail, details) { |
1714 | - const QContactNote *note = static_cast<const QContactNote*>(&detail); |
1715 | - |
1716 | - if(!note->isEmpty()) { |
1717 | - FolksNoteFieldDetails *noteDetails = folks_note_field_details_new(note->note().toUtf8().data(), NULL, 0); |
1718 | - |
1719 | - //TODO: set context |
1720 | - gee_collection_add(GEE_COLLECTION(noteSet), noteDetails); |
1721 | - g_object_unref(noteDetails); |
1722 | - } |
1723 | - } |
1724 | - folks_note_details_change_notes(FOLKS_NOTE_DETAILS(udata->m_persona), |
1725 | + FolksPersona *persona = QIndividualUtils::personaFromUri(detail.detailUri(), m_individual, primaryPersona()); |
1726 | + QContactDetail originalNote = detailFromUri(QContactDetail::TypeNote, detail.detailUri()); |
1727 | + |
1728 | + if (!persona) { |
1729 | + createPersonaForDetail(QList<QContactDetail>() << detail, QIndividual::parseNoteDetails, data); |
1730 | + } else if (FOLKS_IS_URL_DETAILS(persona) && (originalNote != detail)) { |
1731 | + FolksNoteFieldDetails *noteDetails = 0; |
1732 | + const QContactNote *note = static_cast<const QContactNote*>(&detail); |
1733 | + GeeSet *noteSet = folks_note_details_get_notes(FOLKS_NOTE_DETAILS(persona)); |
1734 | + |
1735 | + if (!noteSet || (gee_collection_get_size(GEE_COLLECTION(noteSet)) == 0)) { |
1736 | + noteSet = SET_AFD_NEW(); |
1737 | + } else { |
1738 | + noteDetails = FOLKS_NOTE_FIELD_DETAILS(QIndividualUtils::getDetails(noteSet, detail.detailUri())); |
1739 | + |
1740 | + // this will be unref at the end of the function |
1741 | + g_object_ref(noteSet); |
1742 | + g_object_ref(noteDetails); |
1743 | + } |
1744 | + |
1745 | + if (!noteDetails) { |
1746 | + noteDetails = folks_note_field_details_new(note->note().toUtf8().data(), NULL, 0); |
1747 | + gee_collection_add(GEE_COLLECTION(noteSet), noteDetails); |
1748 | + } else { |
1749 | + folks_abstract_field_details_set_value(FOLKS_ABSTRACT_FIELD_DETAILS(noteDetails), |
1750 | + note->note().toUtf8().data()); |
1751 | + } |
1752 | + |
1753 | + parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(noteDetails), detail); |
1754 | + folks_note_details_change_notes(FOLKS_NOTE_DETAILS(persona), |
1755 | noteSet, |
1756 | (GAsyncReadyCallback) updateDetailsDone, |
1757 | - data); |
1758 | + data);; |
1759 | + g_object_unref(noteDetails); |
1760 | g_object_unref(noteSet); |
1761 | } else { |
1762 | - updateDetailsDone(G_OBJECT(m_individual), NULL, data); |
1763 | - } |
1764 | -} |
1765 | - |
1766 | + updateDetailsDone(G_OBJECT(persona), NULL, data); |
1767 | + } |
1768 | +} |
1769 | + |
1770 | +QString QIndividual::callDetailChangeFinish(QtContacts::QContactDetail::DetailType detailType, |
1771 | + FolksPersona *persona, |
1772 | + GAsyncResult *result) |
1773 | +{ |
1774 | + Q_ASSERT(persona); |
1775 | + Q_ASSERT(result); |
1776 | + |
1777 | + GError *error = 0; |
1778 | + switch(detailType) { |
1779 | + case QContactDetail::TypeAddress: |
1780 | + folks_postal_address_details_change_postal_addresses_finish(FOLKS_POSTAL_ADDRESS_DETAILS(persona), result, &error); |
1781 | + break; |
1782 | + case QContactDetail::TypeAvatar: |
1783 | + folks_avatar_details_change_avatar_finish(FOLKS_AVATAR_DETAILS(persona), result, &error); |
1784 | + break; |
1785 | + case QContactDetail::TypeBirthday: |
1786 | + folks_birthday_details_change_birthday_finish(FOLKS_BIRTHDAY_DETAILS(persona), result, &error); |
1787 | + break; |
1788 | + case QContactDetail::TypeDisplayLabel: |
1789 | + folks_name_details_change_full_name_finish(FOLKS_NAME_DETAILS(persona), result, &error); |
1790 | + break; |
1791 | + case QContactDetail::TypeEmailAddress: |
1792 | + folks_email_details_change_email_addresses_finish(FOLKS_EMAIL_DETAILS(persona), result, &error); |
1793 | + break; |
1794 | + case QContactDetail::TypeName: |
1795 | + folks_name_details_change_structured_name_finish(FOLKS_NAME_DETAILS(persona), result, &error); |
1796 | + break; |
1797 | + case QContactDetail::TypeNickname: |
1798 | + folks_name_details_change_nickname_finish(FOLKS_NAME_DETAILS(persona), result, &error); |
1799 | + break; |
1800 | + case QContactDetail::TypeNote: |
1801 | + folks_note_details_change_notes_finish(FOLKS_NOTE_DETAILS(persona), result, &error); |
1802 | + break; |
1803 | + case QContactDetail::TypeOnlineAccount: |
1804 | + folks_im_details_change_im_addresses_finish(FOLKS_IM_DETAILS(persona), result, &error); |
1805 | + break; |
1806 | + case QContactDetail::TypeOrganization: |
1807 | + folks_role_details_change_roles_finish(FOLKS_ROLE_DETAILS(persona), result, &error); |
1808 | + break; |
1809 | + case QContactDetail::TypePhoneNumber: |
1810 | + folks_phone_details_change_phone_numbers_finish(FOLKS_PHONE_DETAILS(persona), result, &error); |
1811 | + break; |
1812 | + case QContactDetail::TypeUrl: |
1813 | + folks_url_details_change_urls_finish(FOLKS_URL_DETAILS(persona), result, &error); |
1814 | + default: |
1815 | + break; |
1816 | + } |
1817 | + |
1818 | + QString errorMessage; |
1819 | + if (error) { |
1820 | + errorMessage = QString::fromUtf8(error->message); |
1821 | + g_error_free(error); |
1822 | + } |
1823 | + return errorMessage; |
1824 | +} |
1825 | + |
1826 | +void QIndividual::updateDetailsSendReply(gpointer userdata, const QString &errorMessage) |
1827 | +{ |
1828 | + UpdateContactData *data = static_cast<UpdateContactData*>(userdata); |
1829 | + data->m_slot.invoke(data->m_object, |
1830 | + Q_ARG(QIndividual*, data->m_self), Q_ARG(QString, errorMessage)); |
1831 | + delete data; |
1832 | +} |
1833 | + |
1834 | +void QIndividual::updateDetailsSendReply(gpointer userdata, GError *error) |
1835 | +{ |
1836 | + QString errorMessage; |
1837 | + if (error) { |
1838 | + errorMessage = QString::fromUtf8(error->message); |
1839 | + qWarning() << error->message; |
1840 | + g_error_free(error); |
1841 | + } |
1842 | + updateDetailsSendReply(userdata, errorMessage); |
1843 | +} |
1844 | + |
1845 | + |
1846 | +void QIndividual::createPersonaDone(GObject *aggregator, GAsyncResult *result, gpointer userdata) |
1847 | +{ |
1848 | + qDebug() << Q_FUNC_INFO; |
1849 | + UpdateContactData *data = static_cast<UpdateContactData*>(userdata); |
1850 | + |
1851 | + // A new persona was create to store the new data |
1852 | + GError *error = 0; |
1853 | + FolksPersona *newPersona = folks_individual_aggregator_add_persona_from_details_finish(FOLKS_INDIVIDUAL_AGGREGATOR(aggregator), |
1854 | + result, |
1855 | + &error); |
1856 | + if (error) { |
1857 | + updateDetailsSendReply(data, error); |
1858 | + } else { |
1859 | + // Link the new personas |
1860 | + GeeSet *personas = folks_individual_get_personas(data->m_self->m_individual); |
1861 | + GeeSet *newPersonas = SET_PERSONA_NEW(); |
1862 | + gee_collection_add_all(GEE_COLLECTION(newPersonas), GEE_COLLECTION(personas)); |
1863 | + gee_collection_add(GEE_COLLECTION(newPersonas), newPersona); |
1864 | + data->m_self->m_primaryPersona = newPersona; |
1865 | + folks_individual_aggregator_link_personas(data->m_self->m_aggregator, newPersonas, updateDetailsDone, userdata); |
1866 | + } |
1867 | +} |
1868 | |
1869 | void QIndividual::updateDetailsDone(GObject *detail, GAsyncResult *result, gpointer userdata) |
1870 | { |
1871 | - GError *error = 0; |
1872 | + QString errorMessage; |
1873 | UpdateContactData *data = static_cast<UpdateContactData*>(userdata); |
1874 | - |
1875 | - switch(data->m_currentDetailType) { |
1876 | + if (result && !data->m_currentDetail.isEmpty()) { |
1877 | + if (FOLKS_IS_PERSONA(detail)) { |
1878 | + // This is a normal field update |
1879 | + errorMessage = QIndividual::callDetailChangeFinish(data->m_currentDetail.type(), |
1880 | + FOLKS_PERSONA(detail), |
1881 | + result); |
1882 | + } else if (FOLKS_IS_INDIVIDUAL_AGGREGATOR(detail)) { |
1883 | + GError *error = 0; |
1884 | + folks_individual_aggregator_link_personas_finish(FOLKS_INDIVIDUAL_AGGREGATOR(detail), result, &error); |
1885 | + if (error) { |
1886 | + errorMessage = QString::fromUtf8(error->message); |
1887 | + } |
1888 | + } |
1889 | + |
1890 | + if (!errorMessage.isEmpty()) { |
1891 | + updateDetailsSendReply(data, errorMessage); |
1892 | + return; |
1893 | + } |
1894 | + } |
1895 | + |
1896 | + if (data->m_details.isEmpty()) { |
1897 | + updateDetailsSendReply(data, 0); |
1898 | + return; |
1899 | + } |
1900 | + |
1901 | + |
1902 | + data->m_currentDetail = data->m_details.takeFirst(); |
1903 | + switch(data->m_currentDetail.type()) { |
1904 | case QContactDetail::TypeAddress: |
1905 | - if (result) { |
1906 | - folks_postal_address_details_change_postal_addresses_finish(FOLKS_POSTAL_ADDRESS_DETAILS(data->m_persona), result, &error); |
1907 | - } |
1908 | - if (!error) { |
1909 | - data->m_currentDetailType = QContactDetail::TypeAvatar; |
1910 | - data->m_self->updatePhoto(data->m_newContact.detail(QContactDetail::TypeAvatar), data); |
1911 | - return; |
1912 | - } |
1913 | + data->m_self->updateAddress(data->m_currentDetail, data); |
1914 | break; |
1915 | case QContactDetail::TypeAvatar: |
1916 | - if (result) { |
1917 | - folks_avatar_details_change_avatar_finish(FOLKS_AVATAR_DETAILS(data->m_persona), result, &error); |
1918 | - } |
1919 | - if (!error) { |
1920 | - data->m_currentDetailType = QContactDetail::TypeBirthday; |
1921 | - data->m_self->updateBirthday(data->m_newContact.detail(QContactDetail::TypeBirthday), data); |
1922 | - return; |
1923 | - } |
1924 | + data->m_self->updatePhoto(data->m_currentDetail, data); |
1925 | break; |
1926 | case QContactDetail::TypeBirthday: |
1927 | - if (result) { |
1928 | - folks_birthday_details_change_birthday_finish(FOLKS_BIRTHDAY_DETAILS(data->m_persona), result, &error); |
1929 | - } |
1930 | - if (!error) { |
1931 | - data->m_currentDetailType = QContactDetail::TypeDisplayLabel; |
1932 | - data->m_self->updateFullName(data->m_newContact.detail(QContactDetail::TypeDisplayLabel), data); |
1933 | - return; |
1934 | - } |
1935 | + data->m_self->updateBirthday(data->m_currentDetail, data); |
1936 | break; |
1937 | case QContactDetail::TypeDisplayLabel: |
1938 | - if (result) { |
1939 | - folks_name_details_change_full_name_finish(FOLKS_NAME_DETAILS(data->m_persona), result, &error); |
1940 | - } |
1941 | - if (!error) { |
1942 | - data->m_currentDetailType = QContactDetail::TypeEmailAddress; |
1943 | - data->m_self->updateEmails(data->m_newContact.details(QContactDetail::TypeEmailAddress), data); |
1944 | - return; |
1945 | - } |
1946 | + data->m_self->updateFullName(data->m_currentDetail, data); |
1947 | break; |
1948 | - |
1949 | case QContactDetail::TypeEmailAddress: |
1950 | - if (result) { |
1951 | - folks_email_details_change_email_addresses_finish(FOLKS_EMAIL_DETAILS(data->m_persona), result, &error); |
1952 | - } |
1953 | - if (!error) { |
1954 | - data->m_currentDetailType = QContactDetail::TypeName; |
1955 | - data->m_self->updateName(data->m_newContact.detail(QContactDetail::TypeName), data); |
1956 | - return; |
1957 | - } |
1958 | + data->m_self->updateEmail(data->m_currentDetail, data); |
1959 | break; |
1960 | case QContactDetail::TypeName: |
1961 | - if (result) { |
1962 | - folks_name_details_change_structured_name_finish(FOLKS_NAME_DETAILS(data->m_persona), result, &error); |
1963 | - } |
1964 | - if (!error) { |
1965 | - data->m_currentDetailType = QContactDetail::TypeNickname; |
1966 | - data->m_self->updateNickname(data->m_newContact.detail(QContactDetail::TypeNickname), data); |
1967 | - return; |
1968 | - } |
1969 | + data->m_self->updateName(data->m_currentDetail, data); |
1970 | break; |
1971 | case QContactDetail::TypeNickname: |
1972 | - if (result) { |
1973 | - folks_name_details_change_nickname_finish(FOLKS_NAME_DETAILS(data->m_persona), result, &error); |
1974 | - } |
1975 | - if (!error) { |
1976 | - data->m_currentDetailType = QContactDetail::TypeNote; |
1977 | - data->m_self->updateNotes(data->m_newContact.details(QContactDetail::TypeNote), data); |
1978 | - return; |
1979 | - } |
1980 | + data->m_self->updateNickname(data->m_currentDetail, data); |
1981 | break; |
1982 | case QContactDetail::TypeNote: |
1983 | - if (result) { |
1984 | - folks_note_details_change_notes_finish(FOLKS_NOTE_DETAILS(data->m_persona), result, &error); |
1985 | - } |
1986 | - if (!error) { |
1987 | - data->m_currentDetailType = QContactDetail::TypeOnlineAccount; |
1988 | - data->m_self->updateIms(data->m_newContact.details(QContactDetail::TypeOnlineAccount), data); |
1989 | - return; |
1990 | - } |
1991 | + data->m_self->updateNote(data->m_currentDetail, data); |
1992 | break; |
1993 | case QContactDetail::TypeOnlineAccount: |
1994 | - if (result) { |
1995 | - folks_im_details_change_im_addresses_finish(FOLKS_IM_DETAILS(data->m_persona), result, &error); |
1996 | - } |
1997 | - if (!error) { |
1998 | - data->m_currentDetailType = QContactDetail::TypeOrganization; |
1999 | - data->m_self->updateRoles(data->m_newContact.details(QContactDetail::TypeOrganization), data); |
2000 | - return; |
2001 | - } |
2002 | + data->m_self->updateIm(data->m_currentDetail, data); |
2003 | break; |
2004 | case QContactDetail::TypeOrganization: |
2005 | - if (result) { |
2006 | - folks_role_details_change_roles_finish(FOLKS_ROLE_DETAILS(data->m_persona), result, &error); |
2007 | - } |
2008 | - if (!error) { |
2009 | - data->m_currentDetailType = QContactDetail::TypePhoneNumber; |
2010 | - data->m_self->updatePhones(data->m_newContact.details(QContactDetail::TypePhoneNumber), data); |
2011 | - return; |
2012 | - } |
2013 | + data->m_self->updateRole(data->m_currentDetail, data); |
2014 | break; |
2015 | case QContactDetail::TypePhoneNumber: |
2016 | - if (result) { |
2017 | - folks_phone_details_change_phone_numbers_finish(FOLKS_PHONE_DETAILS(data->m_persona), result, &error); |
2018 | - } |
2019 | - if (!error) { |
2020 | - data->m_currentDetailType = QContactDetail::TypeUrl; |
2021 | - data->m_self->updateUrls(data->m_newContact.details(QContactDetail::TypeUrl), data); |
2022 | - return; |
2023 | - } |
2024 | + data->m_self->updatePhone(data->m_currentDetail, data); |
2025 | break; |
2026 | case QContactDetail::TypeUrl: |
2027 | - if (result) { |
2028 | - folks_url_details_change_urls_finish(FOLKS_URL_DETAILS(data->m_persona), result, &error); |
2029 | - } |
2030 | + data->m_self->updateUrl(data->m_currentDetail, data); |
2031 | + break; |
2032 | default: |
2033 | + qWarning() << "Update not implemented for" << data->m_currentDetail.type(); |
2034 | + updateDetailsDone(0, 0, data); |
2035 | break; |
2036 | } |
2037 | - |
2038 | - QString errorMessage; |
2039 | - if (error) { |
2040 | - errorMessage = QString::fromUtf8(error->message); |
2041 | - g_error_free(error); |
2042 | - } |
2043 | - |
2044 | - qDebug() << "Update done" << errorMessage; |
2045 | - data->m_doneCB(errorMessage, data->m_doneData); |
2046 | - delete data; |
2047 | } |
2048 | |
2049 | - |
2050 | -bool QIndividual::update(const QtContacts::QContact &newContact, UpdateDoneCB cb, void* userData) |
2051 | +bool QIndividual::update(const QtContacts::QContact &newContact, QObject *object, const QString &slot) |
2052 | { |
2053 | + int slotIndex = object->metaObject()->indexOfSlot(QMetaObject::normalizedSignature(slot.toUtf8().data())); |
2054 | + if (slotIndex == -1) { |
2055 | + qWarning() << "Invalid slot:" << slot << "for object" << object; |
2056 | + return false; |
2057 | + } |
2058 | + |
2059 | QContact &originalContact = contact(); |
2060 | if (newContact != originalContact) { |
2061 | |
2062 | UpdateContactData *data = new UpdateContactData; |
2063 | - data->m_currentDetailType = QContactDetail::TypeAddress; |
2064 | + data->m_details = newContact.details(); |
2065 | data->m_newContact = newContact; |
2066 | data->m_self = this; |
2067 | - data->m_doneCB = cb; |
2068 | - data->m_doneData = userData; |
2069 | - data->m_persona = primaryPersona(); |
2070 | - |
2071 | - updateAddresses(newContact.details(QContactDetail::TypeAddress), data); |
2072 | + data->m_object = object; |
2073 | + data->m_slot = object->metaObject()->method(slotIndex); |
2074 | + updateDetailsDone(0, 0, data); |
2075 | return true; |
2076 | } else { |
2077 | qDebug() << "Contact is equal"; |
2078 | @@ -1160,10 +1449,26 @@ |
2079 | return m_individual; |
2080 | } |
2081 | |
2082 | -bool QIndividual::update(const QString &vcard, UpdateDoneCB cb, void* data) |
2083 | +void QIndividual::setIndividual(FolksIndividual *individual) |
2084 | +{ |
2085 | + if (m_individual != individual) { |
2086 | + if (m_individual) { |
2087 | + g_object_unref(m_individual); |
2088 | + } |
2089 | + m_individual = individual; |
2090 | + if (m_individual) { |
2091 | + g_object_ref(m_individual); |
2092 | + } |
2093 | + // initialize qcontact |
2094 | + m_contact = QContact(); |
2095 | + updateContact(); |
2096 | + } |
2097 | +} |
2098 | + |
2099 | +bool QIndividual::update(const QString &vcard, QObject *object, const QString &slot) |
2100 | { |
2101 | QContact contact = VCardParser::vcardToContact(vcard); |
2102 | - return update(contact, cb, data); |
2103 | + return update(contact, object, slot); |
2104 | } |
2105 | |
2106 | QStringList QIndividual::listParameters(FolksAbstractFieldDetails *details) |
2107 | @@ -1532,31 +1837,26 @@ |
2108 | return map[QContactOnlineAccount::ProtocolUnknown]; |
2109 | } |
2110 | |
2111 | -GHashTable *QIndividual::parseDetails(const QtContacts::QContact &contact) |
2112 | +GHashTable *QIndividual::parseAddressDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2113 | { |
2114 | - GHashTable *details = g_hash_table_new_full(g_str_hash, |
2115 | - g_str_equal, |
2116 | - NULL, |
2117 | - (GDestroyNotify) QIndividualUtils::gValueSliceFree); |
2118 | - GValue *value; |
2119 | - |
2120 | - /* |
2121 | - * Addresses |
2122 | - */ |
2123 | - QList<QContactAddress> addresses = contact.details<QContactAddress>(); |
2124 | - if(addresses.size() > 0) { |
2125 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); |
2126 | - Q_FOREACH(const QContactAddress& address, addresses) { |
2127 | - if(!address.isEmpty()) { |
2128 | + if(cDetails.size() == 0) { |
2129 | + return details; |
2130 | + } |
2131 | + |
2132 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); |
2133 | + |
2134 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2135 | + if(!detail.isEmpty()) { |
2136 | + QContactAddress address = static_cast<QContactAddress>(detail); |
2137 | FolksPostalAddress *postalAddress = folks_postal_address_new(address.postOfficeBox().toUtf8().data(), |
2138 | - NULL, // extension |
2139 | - address.street().toUtf8().data(), |
2140 | - address.locality().toUtf8().data(), |
2141 | - address.region().toUtf8().data(), |
2142 | - address.postcode().toUtf8().data(), |
2143 | - address.country().toUtf8().data(), |
2144 | - NULL, // address format |
2145 | - NULL); //UID |
2146 | + NULL, // extension |
2147 | + address.street().toUtf8().data(), |
2148 | + address.locality().toUtf8().data(), |
2149 | + address.region().toUtf8().data(), |
2150 | + address.postcode().toUtf8().data(), |
2151 | + address.country().toUtf8().data(), |
2152 | + NULL, // address format |
2153 | + NULL); //UID |
2154 | |
2155 | GeeCollection *collection = (GeeCollection*) g_value_get_object(value); |
2156 | if(collection == NULL) { |
2157 | @@ -1570,188 +1870,318 @@ |
2158 | |
2159 | g_object_unref(pafd); |
2160 | g_object_unref(postalAddress); |
2161 | - } |
2162 | } |
2163 | QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_POSTAL_ADDRESSES, value); |
2164 | } |
2165 | |
2166 | - |
2167 | - /* |
2168 | - * Avatar |
2169 | - */ |
2170 | - QContactAvatar avatar = contact.detail<QContactAvatar>(); |
2171 | - if(!avatar.isEmpty()) { |
2172 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_FILE_ICON); |
2173 | - QUrl avatarUri = avatar.imageUrl(); |
2174 | - if(!avatarUri.isEmpty()) { |
2175 | - QString formattedUri = avatarUri.toString(QUrl::RemoveUserInfo); |
2176 | - if(!formattedUri.isEmpty()) { |
2177 | - GFile *avatarFile = g_file_new_for_uri(formattedUri.toUtf8().data()); |
2178 | - GFileIcon *avatarFileIcon = G_FILE_ICON(g_file_icon_new(avatarFile)); |
2179 | - g_value_take_object(value, avatarFileIcon); |
2180 | - |
2181 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_AVATAR, value); |
2182 | - g_clear_object((GObject**) &avatarFile); |
2183 | - } |
2184 | - } |
2185 | - } |
2186 | - |
2187 | - /* |
2188 | - * Birthday |
2189 | - */ |
2190 | - QContactBirthday birthday = contact.detail<QContactBirthday>(); |
2191 | - if(!birthday.isEmpty()) { |
2192 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_DATE_TIME); |
2193 | - GDateTime *dateTime = g_date_time_new_from_unix_utc(birthday.dateTime().toMSecsSinceEpoch() / 1000); |
2194 | - g_value_set_boxed(value, dateTime); |
2195 | - |
2196 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_BIRTHDAY, value); |
2197 | - g_date_time_unref(dateTime); |
2198 | - } |
2199 | - |
2200 | - /* |
2201 | - * Email addresses |
2202 | - */ |
2203 | - PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, |
2204 | + return details; |
2205 | +} |
2206 | + |
2207 | +GHashTable *QIndividual::parsePhotoDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2208 | +{ |
2209 | + if(cDetails.size() == 0) { |
2210 | + return details; |
2211 | + } |
2212 | + |
2213 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2214 | + QContactAvatar avatar = static_cast<QContactAvatar>(detail); |
2215 | + if(!avatar.isEmpty()) { |
2216 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_FILE_ICON); |
2217 | + QUrl avatarUri = avatar.imageUrl(); |
2218 | + if(!avatarUri.isEmpty()) { |
2219 | + QString formattedUri = avatarUri.toString(QUrl::RemoveUserInfo); |
2220 | + if(!formattedUri.isEmpty()) { |
2221 | + GFile *avatarFile = g_file_new_for_uri(formattedUri.toUtf8().data()); |
2222 | + GFileIcon *avatarFileIcon = G_FILE_ICON(g_file_icon_new(avatarFile)); |
2223 | + g_value_take_object(value, avatarFileIcon); |
2224 | + |
2225 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_AVATAR, value); |
2226 | + g_clear_object((GObject**) &avatarFile); |
2227 | + } |
2228 | + } else { |
2229 | + g_object_unref(value); |
2230 | + } |
2231 | + } |
2232 | + } |
2233 | + |
2234 | + return details; |
2235 | +} |
2236 | + |
2237 | +GHashTable *QIndividual::parseBirthdayDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2238 | +{ |
2239 | + if(cDetails.size() == 0) { |
2240 | + return details; |
2241 | + } |
2242 | + |
2243 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2244 | + QContactBirthday birthday = static_cast<QContactBirthday>(detail); |
2245 | + if(!birthday.isEmpty()) { |
2246 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_DATE_TIME); |
2247 | + GDateTime *dateTime = g_date_time_new_from_unix_utc(birthday.dateTime().toMSecsSinceEpoch() / 1000); |
2248 | + g_value_set_boxed(value, dateTime); |
2249 | + |
2250 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_BIRTHDAY, value); |
2251 | + g_date_time_unref(dateTime); |
2252 | + } |
2253 | + } |
2254 | + |
2255 | + return details; |
2256 | +} |
2257 | + |
2258 | +GHashTable *QIndividual::parseEmailDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2259 | +{ |
2260 | + if(cDetails.size() == 0) { |
2261 | + return details; |
2262 | + } |
2263 | + |
2264 | + GValue *value; |
2265 | + PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, cDetails, |
2266 | FOLKS_PERSONA_DETAIL_EMAIL_ADDRESSES, value, QContactEmailAddress, |
2267 | FOLKS_TYPE_EMAIL_FIELD_DETAILS, emailAddress); |
2268 | - |
2269 | - /* |
2270 | - * Favorite |
2271 | - */ |
2272 | - QContactFavorite favorite = contact.detail<QContactFavorite>(); |
2273 | - if(!favorite.isEmpty()) { |
2274 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_BOOLEAN); |
2275 | - g_value_set_boolean(value, favorite.isFavorite()); |
2276 | - |
2277 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IS_FAVOURITE, value); |
2278 | - } |
2279 | - |
2280 | - /* |
2281 | - * Gender |
2282 | - */ |
2283 | - QContactGender gender = contact.detail<QContactGender>(); |
2284 | - if(!gender.isEmpty()) { |
2285 | - value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_GENDER); |
2286 | - FolksGender genderEnum = FOLKS_GENDER_UNSPECIFIED; |
2287 | - if(gender.gender() == QContactGender::GenderMale) { |
2288 | - genderEnum = FOLKS_GENDER_MALE; |
2289 | - } else if(gender.gender() == QContactGender::GenderFemale) { |
2290 | - genderEnum = FOLKS_GENDER_FEMALE; |
2291 | - } |
2292 | - g_value_set_enum(value, genderEnum); |
2293 | - |
2294 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_GENDER, value); |
2295 | - } |
2296 | - |
2297 | - /* |
2298 | - * Names |
2299 | - */ |
2300 | - QContactName name = contact.detail<QContactName>(); |
2301 | - if(!name.isEmpty()) { |
2302 | - value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_STRUCTURED_NAME); |
2303 | - FolksStructuredName *sn = folks_structured_name_new(name.lastName().toUtf8().data(), |
2304 | - name.firstName().toUtf8().data(), |
2305 | - name.middleName().toUtf8().data(), |
2306 | - name.prefix().toUtf8().data(), |
2307 | - name.suffix().toUtf8().data()); |
2308 | - g_value_take_object(value, sn); |
2309 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_STRUCTURED_NAME, value); |
2310 | - } |
2311 | - |
2312 | - QContactDisplayLabel displayLabel = contact.detail<QContactDisplayLabel>(); |
2313 | - if(!displayLabel.label().isEmpty()) { |
2314 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING); |
2315 | - g_value_set_string(value, displayLabel.label().toUtf8().data()); |
2316 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_FULL_NAME, value); |
2317 | - |
2318 | - // FIXME: check if those values should all be set to the same thing |
2319 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING); |
2320 | - g_value_set_string(value, displayLabel.label().toUtf8().data()); |
2321 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ALIAS, value); |
2322 | - } |
2323 | - |
2324 | - /* |
2325 | - * Notes |
2326 | - */ |
2327 | - PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, |
2328 | + return details; |
2329 | +} |
2330 | + |
2331 | +GHashTable *QIndividual::parseFavoriteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2332 | +{ |
2333 | + if(cDetails.size() == 0) { |
2334 | + return details; |
2335 | + } |
2336 | + |
2337 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2338 | + QContactFavorite favorite = static_cast<QContactFavorite>(detail); |
2339 | + if(!favorite.isEmpty()) { |
2340 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_BOOLEAN); |
2341 | + g_value_set_boolean(value, favorite.isFavorite()); |
2342 | + |
2343 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IS_FAVOURITE, value); |
2344 | + } |
2345 | + } |
2346 | + |
2347 | + return details; |
2348 | +} |
2349 | + |
2350 | +GHashTable *QIndividual::parseGenderDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2351 | +{ |
2352 | + if(cDetails.size() == 0) { |
2353 | + return details; |
2354 | + } |
2355 | + |
2356 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2357 | + QContactGender gender = static_cast<QContactDetail>(detail); |
2358 | + if(!gender.isEmpty()) { |
2359 | + GValue *value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_GENDER); |
2360 | + FolksGender genderEnum = FOLKS_GENDER_UNSPECIFIED; |
2361 | + if(gender.gender() == QContactGender::GenderMale) { |
2362 | + genderEnum = FOLKS_GENDER_MALE; |
2363 | + } else if(gender.gender() == QContactGender::GenderFemale) { |
2364 | + genderEnum = FOLKS_GENDER_FEMALE; |
2365 | + } |
2366 | + g_value_set_enum(value, genderEnum); |
2367 | + |
2368 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_GENDER, value); |
2369 | + } |
2370 | + } |
2371 | + |
2372 | + return details; |
2373 | +} |
2374 | + |
2375 | +GHashTable *QIndividual::parseNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2376 | +{ |
2377 | + if(cDetails.size() == 0) { |
2378 | + return details; |
2379 | + } |
2380 | + |
2381 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2382 | + QContactName name = static_cast<QContactName>(detail); |
2383 | + if(!name.isEmpty()) { |
2384 | + GValue *value = QIndividualUtils::gValueSliceNew(FOLKS_TYPE_STRUCTURED_NAME); |
2385 | + FolksStructuredName *sn = folks_structured_name_new(name.lastName().toUtf8().data(), |
2386 | + name.firstName().toUtf8().data(), |
2387 | + name.middleName().toUtf8().data(), |
2388 | + name.prefix().toUtf8().data(), |
2389 | + name.suffix().toUtf8().data()); |
2390 | + g_value_take_object(value, sn); |
2391 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_STRUCTURED_NAME, value); |
2392 | + } |
2393 | + } |
2394 | + |
2395 | + return details; |
2396 | +} |
2397 | + |
2398 | +GHashTable *QIndividual::parseFullNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2399 | +{ |
2400 | + if(cDetails.size() == 0) { |
2401 | + return details; |
2402 | + } |
2403 | + |
2404 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2405 | + QContactDisplayLabel displayLabel = static_cast<QContactDisplayLabel>(detail); |
2406 | + if(!displayLabel.label().isEmpty()) { |
2407 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING); |
2408 | + g_value_set_string(value, displayLabel.label().toUtf8().data()); |
2409 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_FULL_NAME, value); |
2410 | + |
2411 | + // FIXME: check if those values should all be set to the same thing |
2412 | + value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING); |
2413 | + g_value_set_string(value, displayLabel.label().toUtf8().data()); |
2414 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ALIAS, value); |
2415 | + } |
2416 | + } |
2417 | + |
2418 | + return details; |
2419 | +} |
2420 | + |
2421 | +GHashTable *QIndividual::parseNicknameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2422 | +{ |
2423 | + if(cDetails.size() == 0) { |
2424 | + return details; |
2425 | + } |
2426 | + |
2427 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2428 | + QContactNickname nickname = static_cast<QContactNickname>(detail); |
2429 | + if(!nickname.nickname().isEmpty()) { |
2430 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING); |
2431 | + g_value_set_string(value, nickname.nickname().toUtf8().data()); |
2432 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_NICKNAME, value); |
2433 | + |
2434 | + // FIXME: check if those values should all be set to the same thing |
2435 | + value = QIndividualUtils::gValueSliceNew(G_TYPE_STRING); |
2436 | + g_value_set_string(value, nickname.nickname().toUtf8().data()); |
2437 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ALIAS, value); |
2438 | + } |
2439 | + } |
2440 | + |
2441 | + return details; |
2442 | +} |
2443 | + |
2444 | +GHashTable *QIndividual::parseNoteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2445 | +{ |
2446 | + if(cDetails.size() == 0) { |
2447 | + return details; |
2448 | + } |
2449 | + |
2450 | + GValue *value; |
2451 | + PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, cDetails, |
2452 | FOLKS_PERSONA_DETAIL_NOTES, value, QContactNote, |
2453 | FOLKS_TYPE_NOTE_FIELD_DETAILS, note); |
2454 | |
2455 | - |
2456 | - |
2457 | - /* |
2458 | - * OnlineAccounts |
2459 | - */ |
2460 | - QList<QContactOnlineAccount> accounts = contact.details<QContactOnlineAccount>(); |
2461 | - if(!accounts.isEmpty()) { |
2462 | - QMultiMap<QString, QString> providerUidMap; |
2463 | - |
2464 | - Q_FOREACH(const QContactOnlineAccount &account, accounts) { |
2465 | - if (!account.isEmpty()) { |
2466 | - providerUidMap.insert(onlineAccountProtocolFromEnum(account.protocol()), account.accountUri()); |
2467 | - } |
2468 | - } |
2469 | - |
2470 | - if(!providerUidMap.isEmpty()) { |
2471 | - //TODO: add account type and subtype |
2472 | - value = QIndividualUtils::asvSetStrNew(providerUidMap); |
2473 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IM_ADDRESSES, value); |
2474 | - } |
2475 | - } |
2476 | - |
2477 | - /* |
2478 | - * Organization |
2479 | - */ |
2480 | - QList<QContactOrganization> orgs = contact.details<QContactOrganization>(); |
2481 | - if(orgs.size() > 0) { |
2482 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); |
2483 | - Q_FOREACH(const QContactOrganization& org, orgs) { |
2484 | - if(!org.isEmpty()) { |
2485 | - FolksRole *role = folks_role_new(org.title().toUtf8().data(), |
2486 | - org.name().toUtf8().data(), |
2487 | - NULL); |
2488 | - folks_role_set_role(role, org.role().toUtf8().data()); |
2489 | - |
2490 | - GeeCollection *collection = (GeeCollection*) g_value_get_object(value); |
2491 | - if(collection == NULL) { |
2492 | - collection = GEE_COLLECTION(SET_AFD_NEW()); |
2493 | - g_value_take_object(value, collection); |
2494 | - } |
2495 | - FolksRoleFieldDetails *rfd = folks_role_field_details_new(role, NULL); |
2496 | - parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(rfd), org); |
2497 | - gee_collection_add(collection, rfd); |
2498 | - |
2499 | - g_object_unref(rfd); |
2500 | - g_object_unref(role); |
2501 | - } |
2502 | - } |
2503 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ROLES, value); |
2504 | - } |
2505 | - |
2506 | - /* |
2507 | - * Phone Numbers |
2508 | - */ |
2509 | - QList<QContactPhoneNumber> phones = contact.details<QContactPhoneNumber>(); |
2510 | - if (phones.size() > 0) { |
2511 | - value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); |
2512 | - Q_FOREACH(const QContactPhoneNumber &phone, phones) { |
2513 | - if(!phone.isEmpty()) { |
2514 | - QIndividualUtils::gValueGeeSetAddStringFieldDetails(value, |
2515 | - FOLKS_TYPE_PHONE_FIELD_DETAILS, |
2516 | - phone.number().toUtf8().data(), |
2517 | - phone); |
2518 | - } |
2519 | - } |
2520 | - QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_PHONE_NUMBERS, value); |
2521 | - } |
2522 | - |
2523 | - /* |
2524 | - * URLs |
2525 | - */ |
2526 | - PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, |
2527 | + return details; |
2528 | +} |
2529 | + |
2530 | +GHashTable *QIndividual::parseImDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2531 | +{ |
2532 | + if(cDetails.size() == 0) { |
2533 | + return details; |
2534 | + } |
2535 | + |
2536 | + QMultiMap<QString, QString> providerUidMap; |
2537 | + Q_FOREACH(const QContactDetail &detail, cDetails) { |
2538 | + QContactOnlineAccount account = static_cast<QContactOnlineAccount>(detail); |
2539 | + if (!account.isEmpty()) { |
2540 | + providerUidMap.insert(onlineAccountProtocolFromEnum(account.protocol()), account.accountUri()); |
2541 | + } |
2542 | + } |
2543 | + |
2544 | + if(!providerUidMap.isEmpty()) { |
2545 | + //TODO: add account type and subtype |
2546 | + GValue *value = QIndividualUtils::asvSetStrNew(providerUidMap); |
2547 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_IM_ADDRESSES, value); |
2548 | + } |
2549 | + |
2550 | + return details; |
2551 | +} |
2552 | + |
2553 | +GHashTable *QIndividual::parseOrganizationDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2554 | +{ |
2555 | + if(cDetails.size() == 0) { |
2556 | + return details; |
2557 | + } |
2558 | + |
2559 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); |
2560 | + Q_FOREACH(const QContactDetail& detail, cDetails) { |
2561 | + QContactOrganization org = static_cast<QContactOrganization>(detail); |
2562 | + if(!org.isEmpty()) { |
2563 | + FolksRole *role = folks_role_new(org.title().toUtf8().data(), |
2564 | + org.name().toUtf8().data(), |
2565 | + NULL); |
2566 | + folks_role_set_role(role, org.role().toUtf8().data()); |
2567 | + |
2568 | + GeeCollection *collection = (GeeCollection*) g_value_get_object(value); |
2569 | + if(collection == NULL) { |
2570 | + collection = GEE_COLLECTION(SET_AFD_NEW()); |
2571 | + g_value_take_object(value, collection); |
2572 | + } |
2573 | + FolksRoleFieldDetails *rfd = folks_role_field_details_new(role, NULL); |
2574 | + parseContext(FOLKS_ABSTRACT_FIELD_DETAILS(rfd), org); |
2575 | + gee_collection_add(collection, rfd); |
2576 | + |
2577 | + g_object_unref(rfd); |
2578 | + g_object_unref(role); |
2579 | + } |
2580 | + } |
2581 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_ROLES, value); |
2582 | + |
2583 | + return details; |
2584 | +} |
2585 | + |
2586 | +GHashTable *QIndividual::parsePhoneNumbersDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2587 | +{ |
2588 | + if(cDetails.size() == 0) { |
2589 | + return details; |
2590 | + } |
2591 | + |
2592 | + GValue *value = QIndividualUtils::gValueSliceNew(G_TYPE_OBJECT); |
2593 | + Q_FOREACH(const QContactDetail &detail, cDetails) { |
2594 | + QContactPhoneNumber phone = static_cast<QContactPhoneNumber>(detail); |
2595 | + if(!phone.isEmpty()) { |
2596 | + QIndividualUtils::gValueGeeSetAddStringFieldDetails(value, |
2597 | + FOLKS_TYPE_PHONE_FIELD_DETAILS, |
2598 | + phone.number().toUtf8().data(), |
2599 | + phone); |
2600 | + } |
2601 | + } |
2602 | + QIndividualUtils::personaDetailsInsert(details, FOLKS_PERSONA_DETAIL_PHONE_NUMBERS, value); |
2603 | + |
2604 | + return details; |
2605 | +} |
2606 | + |
2607 | +GHashTable *QIndividual::parseUrlDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails) |
2608 | +{ |
2609 | + if(cDetails.size() == 0) { |
2610 | + return details; |
2611 | + } |
2612 | + |
2613 | + GValue *value; |
2614 | + PERSONA_DETAILS_INSERT_STRING_FIELD_DETAILS(details, cDetails, |
2615 | FOLKS_PERSONA_DETAIL_URLS, value, QContactUrl, |
2616 | FOLKS_TYPE_URL_FIELD_DETAILS, url); |
2617 | + |
2618 | + return details; |
2619 | +} |
2620 | + |
2621 | + |
2622 | +GHashTable *QIndividual::parseDetails(const QtContacts::QContact &contact) |
2623 | +{ |
2624 | + GHashTable *details = g_hash_table_new_full(g_str_hash, |
2625 | + g_str_equal, |
2626 | + NULL, |
2627 | + (GDestroyNotify) QIndividualUtils::gValueSliceFree); |
2628 | + |
2629 | + parseAddressDetails(details, contact.details(QContactAddress::Type)); |
2630 | + parsePhotoDetails(details, contact.details(QContactAvatar::Type)); |
2631 | + parseBirthdayDetails(details, contact.details(QContactBirthday::Type)); |
2632 | + parseEmailDetails(details, contact.details(QContactEmailAddress::Type)); |
2633 | + parseFavoriteDetails(details, contact.details(QContactFavorite::Type)); |
2634 | + parseGenderDetails(details, contact.details(QContactGender::Type)); |
2635 | + parseNameDetails(details, contact.details(QContactName::Type)); |
2636 | + parseFullNameDetails(details, contact.details(QContactDisplayLabel::Type)); |
2637 | + parseNicknameDetails(details, contact.details(QContactNickname::Type)); |
2638 | + parseNoteDetails(details, contact.details(QContactNote::Type)); |
2639 | + parseImDetails(details, contact.details(QContactOnlineAccount::Type)); |
2640 | + parseOrganizationDetails(details, contact.details(QContactOrganization::Type)); |
2641 | + parsePhoneNumbersDetails(details, contact.details(QContactPhoneNumber::Type)); |
2642 | + parseUrlDetails(details, contact.details(QContactUrl::Type)); |
2643 | + |
2644 | return details; |
2645 | } |
2646 | |
2647 | @@ -1761,29 +2191,39 @@ |
2648 | { |
2649 | } |
2650 | |
2651 | -FolksPersona* QIndividual::primaryPersona() const |
2652 | +FolksPersona* QIndividual::primaryPersona() |
2653 | { |
2654 | - if(m_individual == 0) { |
2655 | - return 0; |
2656 | + Q_ASSERT(m_individual); |
2657 | + |
2658 | + if (m_primaryPersona) { |
2659 | + return m_primaryPersona; |
2660 | } |
2661 | |
2662 | - FolksPersona *retval = NULL; |
2663 | GeeSet *personas = folks_individual_get_personas(m_individual); |
2664 | GeeIterator *iter = gee_iterable_iterator(GEE_ITERABLE(personas)); |
2665 | + FolksPersonaStore *primaryStore = folks_individual_aggregator_get_primary_store(m_aggregator); |
2666 | |
2667 | - while(retval == NULL && gee_iterator_next(iter)) { |
2668 | + while(m_primaryPersona == NULL && gee_iterator_next(iter)) { |
2669 | FolksPersona *persona = FOLKS_PERSONA(gee_iterator_get(iter)); |
2670 | - FolksPersonaStore *primaryStore = folks_individual_aggregator_get_primary_store(m_aggregator); |
2671 | if(folks_persona_get_store(persona) == primaryStore) { |
2672 | - retval = persona; |
2673 | - g_object_ref(retval); |
2674 | + m_primaryPersona = persona; |
2675 | + g_object_ref (persona); |
2676 | } |
2677 | - |
2678 | g_object_unref(persona); |
2679 | } |
2680 | g_object_unref (iter); |
2681 | |
2682 | - return retval; |
2683 | + return m_primaryPersona; |
2684 | +} |
2685 | + |
2686 | +QtContacts::QContactDetail QIndividual::detailFromUri(QtContacts::QContactDetail::DetailType type, const QString &uri) const |
2687 | +{ |
2688 | + Q_FOREACH(QContactDetail detail, m_contact.details(type)) { |
2689 | + if (detail.detailUri() == uri) { |
2690 | + return detail; |
2691 | + } |
2692 | + } |
2693 | + return m_contact.detail(type); |
2694 | } |
2695 | |
2696 | } //namespace |
2697 | |
2698 | === modified file 'src/qindividual.h' |
2699 | --- src/qindividual.h 2013-06-11 13:00:01 +0000 |
2700 | +++ src/qindividual.h 2013-06-20 13:17:29 +0000 |
2701 | @@ -31,7 +31,7 @@ |
2702 | |
2703 | namespace galera |
2704 | { |
2705 | -typedef void (*UpdateDoneCB)(const QString&, void*); |
2706 | +typedef GHashTable* (ParseDetailsFunc)(GHashTable*, const QList<QtContacts::QContactDetail> &); |
2707 | |
2708 | typedef QList<QtVersit::QVersitProperty> PropertyList; |
2709 | class QIndividual |
2710 | @@ -59,40 +59,47 @@ |
2711 | |
2712 | QtContacts::QContact &contact(); |
2713 | QtContacts::QContact copy(Fields fields = QIndividual::All); |
2714 | - bool update(const QString &vcard, UpdateDoneCB cb, void* data); |
2715 | - bool update(const QtContacts::QContact &contact, UpdateDoneCB cb, void* data); |
2716 | + bool update(const QString &vcard, QObject *object, const QString &slot); |
2717 | + bool update(const QtContacts::QContact &contact, QObject *object, const QString &slot); |
2718 | FolksIndividual *individual() const; |
2719 | + void setIndividual(FolksIndividual *individual); |
2720 | |
2721 | static GHashTable *parseDetails(const QtContacts::QContact &contact); |
2722 | - |
2723 | private: |
2724 | FolksIndividual *m_individual; |
2725 | + FolksPersona *m_primaryPersona; |
2726 | FolksIndividualAggregator *m_aggregator; |
2727 | QtContacts::QContact m_contact; |
2728 | QMap<QString, QPair<QtContacts::QContactDetail, FolksAbstractFieldDetails*> > m_fieldsMap; |
2729 | - unsigned int m_fieldMapNextKey; |
2730 | + |
2731 | |
2732 | bool fieldsContains(Fields fields, Field value) const; |
2733 | QList<QtVersit::QVersitProperty> parseFieldList(const QString &fieldName, GeeSet *values) const; |
2734 | QMultiHash<QString, QString> parseDetails(FolksAbstractFieldDetails *details) const; |
2735 | void updateContact(); |
2736 | - FolksPersona *primaryPersona() const; |
2737 | + |
2738 | + FolksPersona *primaryPersona(); |
2739 | + QtContacts::QContactDetail detailFromUri(QtContacts::QContactDetail::DetailType type, const QString &uri) const; |
2740 | |
2741 | // QContact |
2742 | + QList<QtContacts::QContactDetail> getDetails() const; |
2743 | + void appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QtContacts::QContactDetail detail, const QString &personaIndex, bool readOnly) const; |
2744 | + void appendDetailsForPersona(QList<QtContacts::QContactDetail> *list, QList<QtContacts::QContactDetail> details, const QString &personaIndex, bool readOnly) const; |
2745 | + |
2746 | QtContacts::QContactDetail getUid() const; |
2747 | QList<QtContacts::QContactDetail> getClientPidMap() const; |
2748 | - QtContacts::QContactDetail getName() const; |
2749 | - QtContacts::QContactDetail getFullName() const; |
2750 | - QtContacts::QContactDetail getNickname() const; |
2751 | - QtContacts::QContactDetail getBirthday() const; |
2752 | - QtContacts::QContactDetail getPhoto() const; |
2753 | - QList<QtContacts::QContactDetail> getRoles() const; |
2754 | - QList<QtContacts::QContactDetail> getEmails() const; |
2755 | - QList<QtContacts::QContactDetail> getPhones() const; |
2756 | - QList<QtContacts::QContactDetail> getAddresses() const; |
2757 | - QList<QtContacts::QContactDetail> getIms() const; |
2758 | - QtContacts::QContactDetail getTimeZone() const; |
2759 | - QList<QtContacts::QContactDetail> getUrls() const; |
2760 | + QtContacts::QContactDetail getPersonaName(FolksPersona *persona) const; |
2761 | + QtContacts::QContactDetail getPersonaFullName(FolksPersona *persona) const; |
2762 | + QtContacts::QContactDetail getPersonaNickName(FolksPersona *persona) const; |
2763 | + QtContacts::QContactDetail getPersonaBirthday(FolksPersona *persona) const; |
2764 | + QtContacts::QContactDetail getPersonaPhoto(FolksPersona *persona) const; |
2765 | + //TODO: organization |
2766 | + QList<QtContacts::QContactDetail> getPersonaRoles(FolksPersona *persona) const; |
2767 | + QList<QtContacts::QContactDetail> getPersonaEmails(FolksPersona *persona) const; |
2768 | + QList<QtContacts::QContactDetail> getPersonaPhones(FolksPersona *persona) const; |
2769 | + QList<QtContacts::QContactDetail> getPersonaAddresses(FolksPersona *persona) const; |
2770 | + QList<QtContacts::QContactDetail> getPersonaIms(FolksPersona *persona) const; |
2771 | + QList<QtContacts::QContactDetail> getPersonaUrls(FolksPersona *persona) const; |
2772 | |
2773 | |
2774 | // update |
2775 | @@ -102,15 +109,38 @@ |
2776 | void updateBirthday(const QtContacts::QContactDetail &detail, void* data); |
2777 | void updatePhoto(const QtContacts::QContactDetail &detail, void* data); |
2778 | void updateTimezone(const QtContacts::QContactDetail &detail, void* data); |
2779 | - void updateRoles(QList<QtContacts::QContactDetail> details, void* data); |
2780 | - void updatePhones(QList<QtContacts::QContactDetail> details, void* data); |
2781 | - void updateEmails(QList<QtContacts::QContactDetail> details, void* data); |
2782 | - void updateIms(QList<QtContacts::QContactDetail> details, void* data); |
2783 | - void updateUrls(QList<QtContacts::QContactDetail> details, void* data); |
2784 | - void updateNotes(QList<QtContacts::QContactDetail> details, void* data); |
2785 | - void updateAddresses(QList<QtContacts::QContactDetail> details, void* data); |
2786 | + void updateRole(QtContacts::QContactDetail detail, void* data); |
2787 | + void updatePhone(QtContacts::QContactDetail detail, void* data); |
2788 | + void updateEmail(QtContacts::QContactDetail detail, void* data); |
2789 | + void updateIm(QtContacts::QContactDetail detail, void* data); |
2790 | + void updateUrl(QtContacts::QContactDetail details, void* data); |
2791 | + void updateNote(QtContacts::QContactDetail detail, void* data); |
2792 | + void updateAddress(QtContacts::QContactDetail detail, void* data); |
2793 | + void createPersonaForDetail(QList<QtContacts::QContactDetail> detail, ParseDetailsFunc parseFunc, void *data) const; |
2794 | + |
2795 | + static void createPersonaDone(GObject *detail, GAsyncResult *result, gpointer userdata); |
2796 | static void updateDetailsDone(GObject *detail, GAsyncResult *result, gpointer userdata); |
2797 | - static bool detailListIsEqual(QList<QtContacts::QContactDetail> original, QList<QtContacts::QContactDetail> details); |
2798 | + static void updateDetailsSendReply(gpointer userdata, GError *error); |
2799 | + static void updateDetailsSendReply(gpointer userdata, const QString &errorMessage); |
2800 | + static QString callDetailChangeFinish(QtContacts::QContactDetail::DetailType type, FolksPersona *persona, GAsyncResult *result); |
2801 | + //static bool detailListIsEqual(QList<QtContacts::QContactDetail> original, QList<QtContacts::QContactDetail> details); |
2802 | + |
2803 | + // translate details |
2804 | + static GHashTable *parseAddressDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2805 | + static GHashTable *parsePhotoDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2806 | + static GHashTable *parsePhoneNumbersDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2807 | + static GHashTable *parseOrganizationDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2808 | + static GHashTable *parseImDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2809 | + static GHashTable *parseNoteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2810 | + static GHashTable *parseFullNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2811 | + static GHashTable *parseNicknameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2812 | + static GHashTable *parseNameDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2813 | + static GHashTable *parseGenderDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2814 | + static GHashTable *parseFavoriteDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2815 | + static GHashTable *parseEmailDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2816 | + static GHashTable *parseBirthdayDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2817 | + static GHashTable *parseUrlDetails(GHashTable *details, const QList<QtContacts::QContactDetail> &cDetails); |
2818 | + |
2819 | |
2820 | // parse context and parameters |
2821 | static void parseParameters(QtContacts::QContactDetail &detail, FolksAbstractFieldDetails *fd); |
2822 | |
2823 | === modified file 'src/view-adaptor.h' |
2824 | --- src/view-adaptor.h 2013-06-13 14:00:42 +0000 |
2825 | +++ src/view-adaptor.h 2013-06-20 13:17:29 +0000 |
2826 | @@ -45,7 +45,7 @@ |
2827 | " <arg direction=\"out\" type=\"i\" name=\"pos\"/>\n" |
2828 | " <arg direction=\"out\" type=\"i\" name=\"lenght\"/>\n" |
2829 | " </signal>\n" |
2830 | -" <signal name=\"contactsCreated\">\n" |
2831 | +" <signal name=\"contactsAdded\">\n" |
2832 | " <arg direction=\"out\" type=\"i\" name=\"pos\"/>\n" |
2833 | " <arg direction=\"out\" type=\"i\" name=\"lenght\"/>\n" |
2834 | " </signal>\n" |
2835 | @@ -81,7 +81,7 @@ |
2836 | void close(); |
2837 | |
2838 | Q_SIGNALS: |
2839 | - void contactsCreated(int pos, int lenght); |
2840 | + void contactsAdded(int pos, int lenght); |
2841 | void contactsRemoved(int pos, int lenght); |
2842 | void contactsUpdated(int pos, int lenght); |
2843 |
FAILED: Continuous integration, rev:34 jenkins. qa.ubuntu. com/job/ address- book-service- ci/19/ jenkins. qa.ubuntu. com/job/ address- book-service- saucy-amd64- ci/19/console jenkins. qa.ubuntu. com/job/ address- book-service- saucy-armhf- ci/19/console jenkins. qa.ubuntu. com/job/ address- book-service- saucy-i386- ci/19/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ address- book-service- ci/19/rebuild
http://