Merge lp:~renatofilho/address-book-service/fetch-hint into lp:address-book-service
- fetch-hint
- Merge into trunk
Proposed by
Renato Araujo Oliveira Filho
Status: | Merged |
---|---|
Approved by: | Bill Filler |
Approved revision: | 46 |
Merged at revision: | 42 |
Proposed branch: | lp:~renatofilho/address-book-service/fetch-hint |
Merge into: | lp:address-book-service |
Prerequisite: | lp:~renatofilho/address-book-service/code-style-fix |
Diff against target: |
1054 lines (+477/-147) 13 files modified
common/CMakeLists.txt (+2/-0) common/fetch-hint.cpp (+153/-0) common/fetch-hint.h (+57/-0) qcontacts/contacts-service.cpp (+56/-85) qcontacts/contacts-service.h (+1/-0) qcontacts/request-data.cpp (+81/-10) qcontacts/request-data.h (+23/-3) src/qindividual.cpp (+12/-21) src/qindividual.h (+1/-19) src/view.cpp (+3/-8) src/view.h (+1/-1) tests/unittest/CMakeLists.txt (+1/-0) tests/unittest/fetch-hint-test.cpp (+86/-0) |
To merge this branch: | bzr merge lp:~renatofilho/address-book-service/fetch-hint |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Bill Filler (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+171430@code.launchpad.net |
Commit message
Initial implementation of FetchHint.
Description of the change
To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Approve
(continuous-integration)
- 46. By Renato Araujo Oliveira Filho
-
Implemented fetchContactById
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:46
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
review:
Approve
(continuous-integration)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'common/CMakeLists.txt' |
2 | --- common/CMakeLists.txt 2013-06-13 14:35:08 +0000 |
3 | +++ common/CMakeLists.txt 2013-06-26 15:26:36 +0000 |
4 | @@ -2,12 +2,14 @@ |
5 | |
6 | set(GALERA_COMMON_LIB_SRC |
7 | filter.cpp |
8 | + fetch-hint.cpp |
9 | sort-clause.cpp |
10 | vcard-parser.cpp |
11 | ) |
12 | |
13 | set(GALERA_COMMON_LIB_HEADERS |
14 | filter.h |
15 | + fetch-hint.h |
16 | sort-clause.h |
17 | vcard-parser.h |
18 | dbus-service-defs.h |
19 | |
20 | === added file 'common/fetch-hint.cpp' |
21 | --- common/fetch-hint.cpp 1970-01-01 00:00:00 +0000 |
22 | +++ common/fetch-hint.cpp 2013-06-26 15:26:36 +0000 |
23 | @@ -0,0 +1,153 @@ |
24 | +/* |
25 | + * Copyright 2013 Canonical Ltd. |
26 | + * |
27 | + * This file is part of contact-service-app. |
28 | + * |
29 | + * contact-service-app is free software; you can redistribute it and/or modify |
30 | + * it under the terms of the GNU General Public License as published by |
31 | + * the Free Software Foundation; version 3. |
32 | + * |
33 | + * contact-service-app is distributed in the hope that it will be useful, |
34 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
35 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
36 | + * GNU General Public License for more details. |
37 | + * |
38 | + * You should have received a copy of the GNU General Public License |
39 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
40 | + */ |
41 | + |
42 | +#include "fetch-hint.h" |
43 | + |
44 | +#include <QtContacts/qcontactdetails.h> |
45 | + |
46 | +using namespace QtContacts; |
47 | + |
48 | +namespace galera |
49 | +{ |
50 | + |
51 | +FetchHint::FetchHint() |
52 | +{ |
53 | + //empty |
54 | +} |
55 | + |
56 | +FetchHint::FetchHint(const QtContacts::QContactFetchHint &hint) |
57 | + : m_hint(hint) |
58 | +{ |
59 | + update(); |
60 | +} |
61 | + |
62 | +bool FetchHint::isEmpty() const |
63 | +{ |
64 | + return m_strHint.isEmpty(); |
65 | +} |
66 | + |
67 | +FetchHint::FetchHint(const QString &hint) |
68 | + : m_hint(buildFilter(hint)) |
69 | +{ |
70 | + update(); |
71 | +} |
72 | + |
73 | +FetchHint::FetchHint(const FetchHint &other) |
74 | + : m_hint(other.m_hint) |
75 | +{ |
76 | + update(); |
77 | +} |
78 | + |
79 | +QString FetchHint::toString() const |
80 | +{ |
81 | + return m_strHint; |
82 | +} |
83 | + |
84 | +QStringList FetchHint::fields() const |
85 | +{ |
86 | + return m_fields; |
87 | +} |
88 | + |
89 | +void FetchHint::update() |
90 | +{ |
91 | + m_strHint.clear(); |
92 | + m_fields.clear(); |
93 | + |
94 | + QMap<QString, QtContacts::QContactDetail::DetailType> map = contactFieldNames(); |
95 | + Q_FOREACH(QContactDetail::DetailType type, m_hint.detailTypesHint()) { |
96 | + QString fieldName = map.key(type, ""); |
97 | + if (!fieldName.isEmpty()) { |
98 | + m_fields << fieldName; |
99 | + } |
100 | + } |
101 | + |
102 | + if (!m_fields.isEmpty()) { |
103 | + m_strHint = QString("FIELDS:") + m_fields.join(","); |
104 | + } |
105 | +} |
106 | + |
107 | +QtContacts::QContactFetchHint FetchHint::toContactFetchHint() const |
108 | +{ |
109 | + return m_hint; |
110 | +} |
111 | + |
112 | +QMap<QString, QtContacts::QContactDetail::DetailType> FetchHint::contactFieldNames() |
113 | +{ |
114 | + static QMap<QString, QContactDetail::DetailType> map; |
115 | + if (map.isEmpty()) { |
116 | + map.insert("ADR", QContactAddress::Type); |
117 | + map.insert("BDAY", QContactBirthday::Type); |
118 | + map.insert("EMAIL", QContactEmailAddress::Type); |
119 | + map.insert("FN", QContactDisplayLabel::Type); |
120 | + map.insert("GENDER", QContactGender::Type); |
121 | + map.insert("N", QContactName::Type); |
122 | + map.insert("NICKNAME", QContactNickname::Type); |
123 | + map.insert("NOTE", QContactNote::Type); |
124 | + map.insert("ORG", QContactOrganization::Type); |
125 | + map.insert("PHOTO", QContactAvatar::Type); |
126 | + map.insert("TEL", QContactPhoneNumber::Type); |
127 | + map.insert("URL", QContactUrl::Type); |
128 | + } |
129 | + return map; |
130 | +} |
131 | + |
132 | +QList<QContactDetail::DetailType> FetchHint::parseFieldNames(QStringList fieldNames) |
133 | +{ |
134 | + QList<QContactDetail::DetailType> result; |
135 | + const QMap<QString, QtContacts::QContactDetail::DetailType> map = contactFieldNames(); |
136 | + Q_FOREACH(QString fieldName, fieldNames) { |
137 | + if (map.contains(fieldName)) { |
138 | + result << map[fieldName]; |
139 | + } |
140 | + } |
141 | + return result; |
142 | +} |
143 | + |
144 | + |
145 | +// Parse string |
146 | +// Format: <KEY0>:VALUE0,VALUE1;<KEY1>:VALUE0,VALUE1 |
147 | +QtContacts::QContactFetchHint FetchHint::buildFilter(const QString &originalHint) |
148 | +{ |
149 | + QString hint = QString(originalHint).replace(" ",""); |
150 | + QContactFetchHint result; |
151 | + QStringList groups = hint.split(";"); |
152 | + Q_FOREACH(QString group, groups) { |
153 | + QStringList values = group.split(":"); |
154 | + |
155 | + if (values.count() == 2) { |
156 | + if (values[0] == "FIELDS") { |
157 | + QList<QContactDetail::DetailType> fields; |
158 | + QMap<QString, QtContacts::QContactDetail::DetailType> map = contactFieldNames(); |
159 | + Q_FOREACH(QString field, values[1].split(",")) { |
160 | + if (map.contains(field)) { |
161 | + fields << map[field]; |
162 | + } |
163 | + } |
164 | + result.setDetailTypesHint(fields); |
165 | + } |
166 | + } else { |
167 | + qWarning() << "invalid fech hint: " << values; |
168 | + } |
169 | + } |
170 | + |
171 | + return result; |
172 | +} |
173 | + |
174 | +} |
175 | + |
176 | + |
177 | |
178 | === added file 'common/fetch-hint.h' |
179 | --- common/fetch-hint.h 1970-01-01 00:00:00 +0000 |
180 | +++ common/fetch-hint.h 2013-06-26 15:26:36 +0000 |
181 | @@ -0,0 +1,57 @@ |
182 | +/* |
183 | + * Copyright 2013 Canonical Ltd. |
184 | + * |
185 | + * This file is part of contact-service-app. |
186 | + * |
187 | + * contact-service-app is free software; you can redistribute it and/or modify |
188 | + * it under the terms of the GNU General Public License as published by |
189 | + * the Free Software Foundation; version 3. |
190 | + * |
191 | + * contact-service-app is distributed in the hope that it will be useful, |
192 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
193 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
194 | + * GNU General Public License for more details. |
195 | + * |
196 | + * You should have received a copy of the GNU General Public License |
197 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
198 | + */ |
199 | + |
200 | +#ifndef __GALERA_FETCH_HINT_H__ |
201 | +#define __GALERA_FETCH_HINT_H__ |
202 | + |
203 | +#include <QtContacts/QContactFetchHint> |
204 | +#include <QtContacts/QContactDetail> |
205 | +#include <QtContacts/QContact> |
206 | + |
207 | +namespace galera |
208 | +{ |
209 | + |
210 | +class FetchHint |
211 | +{ |
212 | +public: |
213 | + FetchHint(const QtContacts::QContactFetchHint &hint); |
214 | + FetchHint(const QString &hint); |
215 | + FetchHint(const FetchHint &other); |
216 | + FetchHint(); |
217 | + |
218 | + bool isEmpty() const; |
219 | + QString toString() const; |
220 | + QStringList fields() const; |
221 | + QtContacts::QContactFetchHint toContactFetchHint() const; |
222 | + static QMap<QString, QtContacts::QContactDetail::DetailType> contactFieldNames(); |
223 | + static QList<QtContacts::QContactDetail::DetailType> parseFieldNames(QStringList fieldNames); |
224 | + |
225 | +private: |
226 | + QtContacts::QContactFetchHint m_hint; |
227 | + QString m_strHint; |
228 | + QStringList m_fields; |
229 | + |
230 | + |
231 | + |
232 | + void update(); |
233 | + static QtContacts::QContactFetchHint buildFilter(const QString &originalHint); |
234 | +}; |
235 | + |
236 | +} |
237 | + |
238 | +#endif |
239 | |
240 | === modified file 'qcontacts/contacts-service.cpp' |
241 | --- qcontacts/contacts-service.cpp 2013-06-20 13:15:48 +0000 |
242 | +++ qcontacts/contacts-service.cpp 2013-06-26 15:26:36 +0000 |
243 | @@ -22,6 +22,7 @@ |
244 | |
245 | #include "common/vcard-parser.h" |
246 | #include "common/filter.h" |
247 | +#include "common/fetch-hint.h" |
248 | #include "common/sort-clause.h" |
249 | #include "common/dbus-service-defs.h" |
250 | |
251 | @@ -146,27 +147,49 @@ |
252 | return !m_iface.isNull(); |
253 | } |
254 | |
255 | +void GaleraContactsService::fetchContactsById(QtContacts::QContactFetchByIdRequest *request) |
256 | +{ |
257 | + qDebug() << Q_FUNC_INFO; |
258 | + |
259 | + if (!isOnline()) { |
260 | + RequestData::setError(request); |
261 | + return; |
262 | + } |
263 | + |
264 | + QContactIdFilter filter; |
265 | + filter.setIds(request->contactIds()); |
266 | + QString filterStr = Filter(filter).toString(); |
267 | + QDBusMessage result = m_iface->call("query", filterStr, "", QStringList()); |
268 | + if (result.type() == QDBusMessage::ErrorMessage) { |
269 | + qWarning() << result.errorName() << result.errorMessage(); |
270 | + RequestData::setError(request); |
271 | + return; |
272 | + } |
273 | + QDBusObjectPath viewObjectPath = result.arguments()[0].value<QDBusObjectPath>(); |
274 | + QDBusInterface *view = new QDBusInterface(CPIM_SERVICE_NAME, |
275 | + viewObjectPath.path(), |
276 | + CPIM_ADDRESSBOOK_VIEW_IFACE_NAME); |
277 | + |
278 | + RequestData *requestData = new RequestData(request, view, FetchHint()); |
279 | + m_runningRequests << requestData; |
280 | + QMetaObject::invokeMethod(this, "fetchContactsPage", Qt::QueuedConnection, Q_ARG(galera::RequestData*, requestData)); |
281 | +} |
282 | + |
283 | void GaleraContactsService::fetchContacts(QtContacts::QContactFetchRequest *request) |
284 | { |
285 | qDebug() << Q_FUNC_INFO; |
286 | |
287 | if (!isOnline()) { |
288 | - QContactManagerEngine::updateContactFetchRequest(request, QList<QContact>(), |
289 | - QContactManager::UnspecifiedError, |
290 | - QContactAbstractRequest::FinishedState); |
291 | + RequestData::setError(request); |
292 | return; |
293 | } |
294 | - QContactFetchRequest *r = static_cast<QContactFetchRequest*>(request); |
295 | - //QContactFetchHint fetchHint = r->fetchHint(); |
296 | - |
297 | - QString sortStr = SortClause(r->sorting()).toString(); |
298 | + QString sortStr = SortClause(request->sorting()).toString(); |
299 | QString filterStr = Filter(request->filter()).toString(); |
300 | + FetchHint fetchHint = FetchHint(request->fetchHint()).toString(); |
301 | QDBusMessage result = m_iface->call("query", filterStr, sortStr, QStringList()); |
302 | if (result.type() == QDBusMessage::ErrorMessage) { |
303 | qWarning() << result.errorName() << result.errorMessage(); |
304 | - QContactManagerEngine::updateContactFetchRequest(request, QList<QContact>(), |
305 | - QContactManager::UnspecifiedError, |
306 | - QContactAbstractRequest::FinishedState); |
307 | + RequestData::setError(request); |
308 | return; |
309 | } |
310 | QDBusObjectPath viewObjectPath = result.arguments()[0].value<QDBusObjectPath>(); |
311 | @@ -174,7 +197,7 @@ |
312 | viewObjectPath.path(), |
313 | CPIM_ADDRESSBOOK_VIEW_IFACE_NAME); |
314 | |
315 | - RequestData *requestData = new RequestData(request, view); |
316 | + RequestData *requestData = new RequestData(request, view, fetchHint); |
317 | m_runningRequests << requestData; |
318 | QMetaObject::invokeMethod(this, "fetchContactsPage", Qt::QueuedConnection, Q_ARG(galera::RequestData*, requestData)); |
319 | } |
320 | @@ -183,29 +206,26 @@ |
321 | { |
322 | qDebug() << Q_FUNC_INFO; |
323 | if (!isOnline()) { |
324 | - QContactManagerEngine::updateContactFetchRequest(static_cast<QContactFetchRequest*>(request->request()), |
325 | - QList<QContact>(), |
326 | - QContactManager::UnspecifiedError, |
327 | - QContactAbstractRequest::FinishedState); |
328 | + request->setError(QContactManager::UnspecifiedError); |
329 | destroyRequest(request); |
330 | return; |
331 | } |
332 | + |
333 | // Load contacs async |
334 | - QDBusPendingCall pcall = request->view()->asyncCall("contactsDetails", QStringList(), request->offset(), FETCH_PAGE_SIZE); |
335 | + QDBusPendingCall pcall = request->view()->asyncCall("contactsDetails", request->fields(), request->offset(), FETCH_PAGE_SIZE); |
336 | if (pcall.isError()) { |
337 | qWarning() << pcall.error().name() << pcall.error().message(); |
338 | - QContactManagerEngine::updateContactFetchRequest(static_cast<QContactFetchRequest*>(request->request()), |
339 | - QList<QContact>(), |
340 | - QContactManager::UnspecifiedError, |
341 | - QContactAbstractRequest::FinishedState); |
342 | + request->setError(QContactManager::UnspecifiedError); |
343 | destroyRequest(request); |
344 | return; |
345 | } |
346 | + |
347 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0); |
348 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, |
349 | [=](QDBusPendingCallWatcher *call) { |
350 | this->fetchContactsDone(request, call); |
351 | }); |
352 | + |
353 | request->updateWatcher(watcher); |
354 | } |
355 | |
356 | @@ -215,6 +235,7 @@ |
357 | QContactManager::Error opError = QContactManager::NoError; |
358 | QContactAbstractRequest::State opState = QContactAbstractRequest::FinishedState; |
359 | QDBusPendingReply<QStringList> reply = *call; |
360 | + QList<QContact> contacts; |
361 | |
362 | if (reply.isError()) { |
363 | qWarning() << reply.error().name() << reply.error().message(); |
364 | @@ -225,7 +246,7 @@ |
365 | opState = QContactAbstractRequest::ActiveState; |
366 | } |
367 | if (!vcards.isEmpty()) { |
368 | - QList<QContact> contacts = VCardParser::vcardToContact(vcards); |
369 | + contacts = VCardParser::vcardToContact(vcards); |
370 | QList<QContactId> contactsIds; |
371 | |
372 | QList<QContact>::iterator contact; |
373 | @@ -239,16 +260,12 @@ |
374 | contactsIds << newId; |
375 | } |
376 | } |
377 | - |
378 | m_contacts += contacts; |
379 | m_contactIds += contactsIds; |
380 | - request->appendResult(contacts); |
381 | } |
382 | } |
383 | - QContactManagerEngine::updateContactFetchRequest(static_cast<QContactFetchRequest*>(request->request()), |
384 | - request->result(), |
385 | - opError, |
386 | - opState); |
387 | + |
388 | + request->update(contacts, opState, opError); |
389 | |
390 | if (opState == QContactAbstractRequest::ActiveState) { |
391 | request->updateOffset(FETCH_PAGE_SIZE); |
392 | @@ -294,11 +311,7 @@ |
393 | { |
394 | qDebug() << Q_FUNC_INFO; |
395 | if (!isOnline()) { |
396 | - QContactManagerEngine::updateContactSaveRequest(request, |
397 | - QList<QContact>(), |
398 | - QContactManager::UnspecifiedError, |
399 | - QMap<int, QContactManager::Error>(), |
400 | - QContactAbstractRequest::FinishedState); |
401 | + RequestData::setError(request); |
402 | return; |
403 | } |
404 | |
405 | @@ -310,7 +323,7 @@ |
406 | Q_FOREACH(QString contact, contacts) { |
407 | QDBusPendingCall pcall = m_iface->asyncCall("createContact", contact, ""); |
408 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0); |
409 | - RequestData *requestData = new RequestData(request, 0, watcher); |
410 | + RequestData *requestData = new RequestData(request, watcher); |
411 | m_runningRequests << requestData; |
412 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, |
413 | [=](QDBusPendingCallWatcher *call) { |
414 | @@ -325,7 +338,6 @@ |
415 | qDebug() << Q_FUNC_INFO; |
416 | QDBusPendingReply<QString> reply = *call; |
417 | QList<QContact> contacts; |
418 | - QMap<int, QContactManager::Error> errorMap; |
419 | QContactManager::Error opError = QContactManager::NoError; |
420 | |
421 | if (reply.isError()) { |
422 | @@ -343,26 +355,14 @@ |
423 | } |
424 | } |
425 | |
426 | - if (opError != QContactManager::NoError) { |
427 | - QContactManagerEngine::updateContactSaveRequest(static_cast<QContactSaveRequest*>(request->request()), |
428 | - contacts, |
429 | - opError, |
430 | - errorMap, |
431 | - QContactAbstractRequest::FinishedState); |
432 | - } else { |
433 | - QContactManagerEngine::updateRequestState(request->request(), |
434 | - QContactAbstractRequest::FinishedState); |
435 | - } |
436 | + request->update(contacts, QContactAbstractRequest::FinishedState, opError); |
437 | destroyRequest(request); |
438 | } |
439 | |
440 | void GaleraContactsService::removeContact(QContactRemoveRequest *request) |
441 | { |
442 | if (!isOnline()) { |
443 | - QContactManagerEngine::updateContactRemoveRequest(request, |
444 | - QContactManager::UnspecifiedError, |
445 | - QMap<int, QContactManager::Error>(), |
446 | - QContactAbstractRequest::FinishedState); |
447 | + RequestData::setError(request); |
448 | return; |
449 | } |
450 | |
451 | @@ -376,13 +376,10 @@ |
452 | QDBusPendingCall pcall = m_iface->asyncCall("removeContacts", ids); |
453 | if (pcall.isError()) { |
454 | qWarning() << "Error" << pcall.error().name() << pcall.error().message(); |
455 | - QContactManagerEngine::updateContactRemoveRequest(request, |
456 | - QContactManager::UnspecifiedError, |
457 | - QMap<int, QContactManager::Error>(), |
458 | - QContactAbstractRequest::FinishedState); |
459 | + RequestData::setError(request); |
460 | } else { |
461 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0); |
462 | - RequestData *requestData = new RequestData(request, 0, watcher); |
463 | + RequestData *requestData = new RequestData(request, watcher); |
464 | m_runningRequests << requestData; |
465 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, |
466 | [=](QDBusPendingCallWatcher *call) { |
467 | @@ -403,16 +400,7 @@ |
468 | opError = QContactManager::UnspecifiedError; |
469 | } |
470 | |
471 | - |
472 | - if (opError != QContactManager::NoError) { |
473 | - QContactManagerEngine::updateContactRemoveRequest(static_cast<QContactRemoveRequest*>(request->request()), |
474 | - opError, |
475 | - errorMap, |
476 | - QContactAbstractRequest::FinishedState); |
477 | - } else { |
478 | - QContactManagerEngine::updateRequestState(request->request(), QContactAbstractRequest::FinishedState); |
479 | - } |
480 | - |
481 | + request->update(QContactAbstractRequest::FinishedState, opError); |
482 | destroyRequest(request); |
483 | } |
484 | |
485 | @@ -420,25 +408,17 @@ |
486 | { |
487 | qDebug() << Q_FUNC_INFO; |
488 | if (!isOnline()) { |
489 | - QContactManagerEngine::updateContactSaveRequest(request, |
490 | - QList<QContact>(), |
491 | - QContactManager::UnspecifiedError, |
492 | - QMap<int, QContactManager::Error>(), |
493 | - QContactAbstractRequest::FinishedState); |
494 | + RequestData::setError(request); |
495 | return; |
496 | } |
497 | |
498 | QDBusPendingCall pcall = m_iface->asyncCall("updateContacts", contacts); |
499 | if (pcall.isError()) { |
500 | qWarning() << "Error" << pcall.error().name() << pcall.error().message(); |
501 | - QContactManagerEngine::updateContactSaveRequest(request, |
502 | - QList<QContact>(), |
503 | - QContactManager::UnspecifiedError, |
504 | - QMap<int, QContactManager::Error>(), |
505 | - QContactAbstractRequest::FinishedState); |
506 | + RequestData::setError(request); |
507 | } else { |
508 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, 0); |
509 | - RequestData *requestData = new RequestData(request, 0, watcher); |
510 | + RequestData *requestData = new RequestData(request, watcher); |
511 | m_runningRequests << requestData; |
512 | QObject::connect(watcher, &QDBusPendingCallWatcher::finished, |
513 | [=](QDBusPendingCallWatcher *call) { |
514 | @@ -471,16 +451,7 @@ |
515 | } |
516 | } |
517 | |
518 | - if (opError != QContactManager::NoError) { |
519 | - QContactManagerEngine::updateContactSaveRequest(static_cast<QContactSaveRequest*>(request->request()), |
520 | - contacts, |
521 | - opError, |
522 | - saveError, |
523 | - QContactAbstractRequest::FinishedState); |
524 | - } else { |
525 | - QContactManagerEngine::updateRequestState(request->request(), |
526 | - QContactAbstractRequest::FinishedState); |
527 | - } |
528 | + request->update(contacts, QContactAbstractRequest::FinishedState, opError, saveError); |
529 | destroyRequest(request); |
530 | } |
531 | |
532 | @@ -501,7 +472,7 @@ |
533 | fetchContacts(static_cast<QContactFetchRequest*>(request)); |
534 | break; |
535 | case QContactAbstractRequest::ContactFetchByIdRequest: |
536 | - qDebug() << "Not implemented: ContactFetchByIdRequest"; |
537 | + fetchContactsById(static_cast<QContactFetchByIdRequest*>(request)); |
538 | break; |
539 | case QContactAbstractRequest::ContactIdFetchRequest: |
540 | qDebug() << "Not implemented: ContactIdFetchRequest"; |
541 | |
542 | === modified file 'qcontacts/contacts-service.h' |
543 | --- qcontacts/contacts-service.h 2013-06-20 01:26:15 +0000 |
544 | +++ qcontacts/contacts-service.h 2013-06-26 15:26:36 +0000 |
545 | @@ -92,6 +92,7 @@ |
546 | bool isOnline() const; |
547 | |
548 | void fetchContacts(QtContacts::QContactFetchRequest *request); |
549 | + void fetchContactsById(QtContacts::QContactFetchByIdRequest *request); |
550 | Q_INVOKABLE void fetchContactsPage(galera::RequestData *request); |
551 | void fetchContactsDone(RequestData *request, QDBusPendingCallWatcher *call); |
552 | |
553 | |
554 | === modified file 'qcontacts/request-data.cpp' |
555 | --- qcontacts/request-data.cpp 2013-06-12 22:41:11 +0000 |
556 | +++ qcontacts/request-data.cpp 2013-06-26 15:26:36 +0000 |
557 | @@ -18,15 +18,37 @@ |
558 | |
559 | #include "request-data.h" |
560 | |
561 | +#include <QtContacts/QContactManagerEngine> |
562 | + |
563 | using namespace QtContacts; |
564 | namespace galera |
565 | { |
566 | |
567 | RequestData::RequestData(QContactAbstractRequest *request, |
568 | QDBusInterface *view, |
569 | + const FetchHint &hint, |
570 | + QDBusPendingCallWatcher *watcher) |
571 | + : m_offset(0), |
572 | + m_hint(hint) |
573 | +{ |
574 | + init(request, view, watcher); |
575 | +} |
576 | + |
577 | +RequestData::RequestData(QtContacts::QContactAbstractRequest *request, |
578 | QDBusPendingCallWatcher *watcher) |
579 | : m_offset(0) |
580 | { |
581 | + init(request, 0, watcher); |
582 | +} |
583 | + |
584 | +RequestData::~RequestData() |
585 | +{ |
586 | +} |
587 | + |
588 | +void RequestData::init(QtContacts::QContactAbstractRequest *request, |
589 | + QDBusInterface *view, |
590 | + QDBusPendingCallWatcher *watcher) |
591 | +{ |
592 | m_request = QSharedPointer<QContactAbstractRequest>(request, RequestData::deleteRequest); |
593 | |
594 | if (view) { |
595 | @@ -36,10 +58,7 @@ |
596 | if (watcher) { |
597 | m_watcher = QSharedPointer<QDBusPendingCallWatcher>(watcher, RequestData::deleteWatcher); |
598 | } |
599 | -} |
600 | |
601 | -RequestData::~RequestData() |
602 | -{ |
603 | } |
604 | |
605 | QContactAbstractRequest* RequestData::request() const |
606 | @@ -57,6 +76,11 @@ |
607 | return m_view.data(); |
608 | } |
609 | |
610 | +QStringList RequestData::fields() const |
611 | +{ |
612 | + return m_hint.fields(); |
613 | +} |
614 | + |
615 | void RequestData::updateWatcher(QDBusPendingCallWatcher *watcher) |
616 | { |
617 | m_watcher.clear(); |
618 | @@ -70,26 +94,73 @@ |
619 | m_offset += offset; |
620 | } |
621 | |
622 | -void RequestData::setResults(QList<QContact> result) |
623 | -{ |
624 | - m_result = result; |
625 | -} |
626 | - |
627 | QList<QContact> RequestData::result() const |
628 | { |
629 | return m_result; |
630 | } |
631 | |
632 | -void RequestData::appendResult(QList<QContact> result) |
633 | +void RequestData::setError(QContactManager::Error error) |
634 | +{ |
635 | + m_result.clear(); |
636 | + update(QContactAbstractRequest::FinishedState, error); |
637 | +} |
638 | + |
639 | +void RequestData::update(QList<QContact> result, |
640 | + QContactAbstractRequest::State state, |
641 | + QContactManager::Error error, |
642 | + QMap<int, QContactManager::Error> errorMap) |
643 | { |
644 | m_result += result; |
645 | -} |
646 | + update(state, error, errorMap); |
647 | +} |
648 | + |
649 | +void RequestData::update(QContactAbstractRequest::State state, |
650 | + QContactManager::Error error, |
651 | + QMap<int, QContactManager::Error> errorMap) |
652 | +{ |
653 | + switch (m_request->type()) { |
654 | + case QContactAbstractRequest::ContactFetchRequest: |
655 | + QContactManagerEngine::updateContactFetchRequest(static_cast<QContactFetchRequest*>(m_request.data()), |
656 | + m_result, |
657 | + error, |
658 | + state); |
659 | + break; |
660 | + case QContactAbstractRequest::ContactFetchByIdRequest: |
661 | + QContactManagerEngine::updateContactFetchByIdRequest(static_cast<QContactFetchByIdRequest*>(m_request.data()), |
662 | + m_result, |
663 | + error, |
664 | + errorMap, |
665 | + state); |
666 | + break; |
667 | + case QContactAbstractRequest::ContactSaveRequest: |
668 | + QContactManagerEngine::updateContactSaveRequest(static_cast<QContactSaveRequest*>(m_request.data()), |
669 | + m_result, |
670 | + error, |
671 | + QMap<int, QContactManager::Error>(), |
672 | + state); |
673 | + case QContactAbstractRequest::ContactRemoveRequest: |
674 | + QContactManagerEngine::updateContactRemoveRequest(static_cast<QContactRemoveRequest*>(m_request.data()), |
675 | + error, |
676 | + errorMap, |
677 | + state); |
678 | + break; |
679 | + default: |
680 | + break; |
681 | + } |
682 | +} |
683 | + |
684 | |
685 | void RequestData::registerMetaType() |
686 | { |
687 | qRegisterMetaType<galera::RequestData*>(); |
688 | } |
689 | |
690 | +void RequestData::setError(QContactAbstractRequest *request, QContactManager::Error error) |
691 | +{ |
692 | + RequestData r(request); |
693 | + r.setError(error); |
694 | +} |
695 | + |
696 | void RequestData::deleteRequest(QContactAbstractRequest *obj) |
697 | { |
698 | //nothing |
699 | |
700 | === modified file 'qcontacts/request-data.h' |
701 | --- qcontacts/request-data.h 2013-06-12 22:41:11 +0000 |
702 | +++ qcontacts/request-data.h 2013-06-26 15:26:36 +0000 |
703 | @@ -19,6 +19,8 @@ |
704 | #ifndef __GALERA_REQUEST_DATA_H__ |
705 | #define __GALERA_REQUEST_DATA_H__ |
706 | |
707 | +#include <common/fetch-hint.h> |
708 | + |
709 | #include <QtCore/QList> |
710 | #include <QtCore/QSharedPointer> |
711 | |
712 | @@ -34,22 +36,38 @@ |
713 | public: |
714 | RequestData(QtContacts::QContactAbstractRequest *request, |
715 | QDBusInterface *view, |
716 | - QDBusPendingCallWatcher *watcher=0); |
717 | + const FetchHint &hint, |
718 | + QDBusPendingCallWatcher *watcher=0); |
719 | + |
720 | + RequestData(QtContacts::QContactAbstractRequest *request, |
721 | + QDBusPendingCallWatcher *watcher=0); |
722 | + |
723 | |
724 | ~RequestData(); |
725 | |
726 | QtContacts::QContactAbstractRequest* request() const; |
727 | QDBusInterface* view() const; |
728 | + QStringList fields() const; |
729 | + |
730 | |
731 | void updateWatcher(QDBusPendingCallWatcher *watcher); |
732 | |
733 | void updateOffset(int offset); |
734 | int offset() const; |
735 | |
736 | - void setResults(QList<QtContacts::QContact> result); |
737 | - void appendResult(QList<QtContacts::QContact> result); |
738 | QList<QtContacts::QContact> result() const; |
739 | |
740 | + void setError(QtContacts::QContactManager::Error error); |
741 | + void update(QList<QtContacts::QContact> result, |
742 | + QtContacts::QContactAbstractRequest::State state, |
743 | + QtContacts::QContactManager::Error error = QtContacts::QContactManager::NoError, |
744 | + QMap<int, QtContacts::QContactManager::Error> errorMap = QMap<int, QtContacts::QContactManager::Error>()); |
745 | + void update(QtContacts::QContactAbstractRequest::State state, |
746 | + QtContacts::QContactManager::Error error = QtContacts::QContactManager::NoError, |
747 | + QMap<int, QtContacts::QContactManager::Error> errorMap = QMap<int, QtContacts::QContactManager::Error>()); |
748 | + |
749 | + static void setError(QtContacts::QContactAbstractRequest *request, |
750 | + QtContacts::QContactManager::Error error = QtContacts::QContactManager::UnspecifiedError); |
751 | static void registerMetaType(); |
752 | |
753 | private: |
754 | @@ -58,7 +76,9 @@ |
755 | QSharedPointer<QDBusPendingCallWatcher> m_watcher; |
756 | QList<QtContacts::QContact> m_result; |
757 | int m_offset; |
758 | + FetchHint m_hint; |
759 | |
760 | + void init(QtContacts::QContactAbstractRequest *request, QDBusInterface *view, QDBusPendingCallWatcher *watcher); |
761 | static void deleteRequest(QtContacts::QContactAbstractRequest *obj); |
762 | static void deleteView(QDBusInterface *view); |
763 | static void deleteWatcher(QDBusPendingCallWatcher *watcher); |
764 | |
765 | === modified file 'src/qindividual.cpp' |
766 | --- src/qindividual.cpp 2013-06-26 15:26:36 +0000 |
767 | +++ src/qindividual.cpp 2013-06-26 15:26:36 +0000 |
768 | @@ -689,18 +689,13 @@ |
769 | return details; |
770 | } |
771 | |
772 | -bool QIndividual::fieldsContains(Fields fields, Field value) const |
773 | -{ |
774 | - return (fields.testFlag(QIndividual::All) || fields.testFlag(value)); |
775 | -} |
776 | - |
777 | -QtContacts::QContact QIndividual::copy(Fields fields) |
778 | +QtContacts::QContact QIndividual::copy(QList<QContactDetail::DetailType> fields) |
779 | { |
780 | QList<QContactDetail> details; |
781 | QContact result; |
782 | |
783 | |
784 | - if (fields.testFlag(QIndividual::All)) { |
785 | + if (fields.isEmpty()) { |
786 | result = contact(); |
787 | } else { |
788 | QContact fullContact = contact(); |
789 | @@ -711,61 +706,57 @@ |
790 | details << det; |
791 | } |
792 | |
793 | - if (fieldsContains(fields, QIndividual::Name)) { |
794 | + if (fields.contains(QContactDetail::TypeName)) { |
795 | details << fullContact.detail<QContactName>(); |
796 | } |
797 | |
798 | |
799 | - if (fieldsContains(fields, QIndividual::FullName)) { |
800 | + if (fields.contains(QContactDetail::TypeDisplayLabel)) { |
801 | details << fullContact.detail<QContactDisplayLabel>(); |
802 | } |
803 | |
804 | - if (fieldsContains(fields, QIndividual::NickName)) { |
805 | + if (fields.contains(QContactDetail::TypeNickname)) { |
806 | details << fullContact.detail<QContactNickname>(); |
807 | } |
808 | |
809 | - if (fieldsContains(fields, QIndividual::Birthday)) { |
810 | + if (fields.contains(QContactDetail::TypeBirthday)) { |
811 | details << fullContact.detail<QContactBirthday>(); |
812 | } |
813 | |
814 | - if (fieldsContains(fields, QIndividual::Photo)) { |
815 | + if (fields.contains(QContactDetail::TypeAvatar)) { |
816 | details << fullContact.detail<QContactAvatar>(); |
817 | } |
818 | |
819 | - if (fieldsContains(fields, QIndividual::Role)) { |
820 | + if (fields.contains(QContactDetail::TypeOrganization)) { |
821 | Q_FOREACH(QContactDetail det, fullContact.details<QContactOrganization>()) { |
822 | details << det; |
823 | } |
824 | } |
825 | |
826 | - if (fieldsContains(fields, QIndividual::Email)) { |
827 | + if (fields.contains(QContactDetail::TypeEmailAddress)) { |
828 | Q_FOREACH(QContactDetail det, fullContact.details<QContactEmailAddress>()) { |
829 | details << det; |
830 | } |
831 | } |
832 | |
833 | - if (fieldsContains(fields, QIndividual::Phone)) { |
834 | + if (fields.contains(QContactDetail::TypePhoneNumber)) { |
835 | Q_FOREACH(QContactDetail det, fullContact.details<QContactPhoneNumber>()) { |
836 | details << det; |
837 | } |
838 | } |
839 | |
840 | - if (fieldsContains(fields, QIndividual::Address)) { |
841 | + if (fields.contains(QContactDetail::TypeAddress)) { |
842 | Q_FOREACH(QContactDetail det, fullContact.details<QContactAddress>()) { |
843 | details << det; |
844 | } |
845 | } |
846 | |
847 | - if (fieldsContains(fields, QIndividual::Url)) { |
848 | + if (fields.contains(QContactDetail::TypeUrl)) { |
849 | Q_FOREACH(QContactDetail det, fullContact.details<QContactUrl>()) { |
850 | details << det; |
851 | } |
852 | } |
853 | |
854 | - if (fieldsContains(fields, QIndividual::TimeZone)) { |
855 | - //TODO |
856 | - } |
857 | - |
858 | Q_FOREACH(QContactDetail det, details) { |
859 | result.appendDetail(det); |
860 | } |
861 | |
862 | === modified file 'src/qindividual.h' |
863 | --- src/qindividual.h 2013-06-26 15:26:36 +0000 |
864 | +++ src/qindividual.h 2013-06-26 15:26:36 +0000 |
865 | @@ -37,28 +37,11 @@ |
866 | class QIndividual |
867 | { |
868 | public: |
869 | - enum Field { |
870 | - All = 0x0000, |
871 | - Name = 0x0001, |
872 | - FullName = 0x0002, |
873 | - NickName = 0x0004, |
874 | - Birthday = 0x0008, |
875 | - Photo = 0x0016, |
876 | - Role = 0x0032, |
877 | - Email = 0x0064, |
878 | - Phone = 0x0128, |
879 | - Address = 0x0256, |
880 | - Im = 0x512, |
881 | - TimeZone = 0x1024, |
882 | - Url = 0x2048 |
883 | - }; |
884 | - Q_DECLARE_FLAGS(Fields, Field) |
885 | - |
886 | QIndividual(FolksIndividual *individual, FolksIndividualAggregator *aggregator); |
887 | ~QIndividual(); |
888 | |
889 | QtContacts::QContact &contact(); |
890 | - QtContacts::QContact copy(Fields fields = QIndividual::All); |
891 | + QtContacts::QContact copy(QList<QtContacts::QContactDetail::DetailType> fields); |
892 | bool update(const QString &vcard, QObject *object, const char *slot); |
893 | bool update(const QtContacts::QContact &contact, QObject *object, const char *slot); |
894 | FolksIndividual *individual() const; |
895 | @@ -72,7 +55,6 @@ |
896 | QtContacts::QContact m_contact; |
897 | QMap<QString, QPair<QtContacts::QContactDetail, FolksAbstractFieldDetails*> > m_fieldsMap; |
898 | |
899 | - bool fieldsContains(Fields fields, Field value) const; |
900 | QMultiHash<QString, QString> parseDetails(FolksAbstractFieldDetails *details) const; |
901 | void updateContact(); |
902 | |
903 | |
904 | === modified file 'src/view.cpp' |
905 | --- src/view.cpp 2013-06-26 15:26:36 +0000 |
906 | +++ src/view.cpp 2013-06-26 15:26:36 +0000 |
907 | @@ -23,6 +23,7 @@ |
908 | |
909 | #include "common/vcard-parser.h" |
910 | #include "common/filter.h" |
911 | +#include "common/fetch-hint.h" |
912 | #include "common/dbus-service-defs.h" |
913 | |
914 | #include <QtContacts/QContact> |
915 | @@ -127,7 +128,7 @@ |
916 | { |
917 | m_filterThread->start(); |
918 | |
919 | - connect(m_filterThread, SIGNAL(finished()), SIGNAL(countChanged(int))); |
920 | + connect(m_filterThread, SIGNAL(finished()), SIGNAL(countChanged())); |
921 | } |
922 | |
923 | View::~View() |
924 | @@ -171,16 +172,10 @@ |
925 | |
926 | QList<QContact> contacts; |
927 | for(int i = startIndex, iMax = (startIndex + pageSize); i < iMax; i++) { |
928 | - // TODO: filter fields |
929 | - contacts << entries[i]->individual()->contact(); |
930 | + contacts << entries[i]->individual()->copy(FetchHint::parseFieldNames(fields)); |
931 | } |
932 | |
933 | QStringList ret = VCardParser::contactToVcard(contacts); |
934 | - qDebug() << "fetch" << ret; |
935 | - QList<QContact> cs = VCardParser::vcardToContact(ret); |
936 | - QStringList ret2 = VCardParser::contactToVcard(cs); |
937 | - qDebug() << "fetch2" << ret2; |
938 | - |
939 | QDBusMessage reply = message.createReply(ret); |
940 | QDBusConnection::sessionBus().send(reply); |
941 | return ret; |
942 | |
943 | === modified file 'src/view.h' |
944 | --- src/view.h 2013-06-26 15:26:36 +0000 |
945 | +++ src/view.h 2013-06-26 15:26:36 +0000 |
946 | @@ -66,7 +66,7 @@ |
947 | |
948 | Q_SIGNALS: |
949 | void closed(); |
950 | - void countChanged(int count); |
951 | + void countChanged(int count=0); |
952 | |
953 | private: |
954 | QStringList m_sources; |
955 | |
956 | === modified file 'tests/unittest/CMakeLists.txt' |
957 | --- tests/unittest/CMakeLists.txt 2013-06-11 13:00:01 +0000 |
958 | +++ tests/unittest/CMakeLists.txt 2013-06-26 15:26:36 +0000 |
959 | @@ -39,3 +39,4 @@ |
960 | declare_test(clause-test) |
961 | declare_test(contactmap-test) |
962 | declare_test(sort-clause-test) |
963 | +declare_test(fetch-hint-test) |
964 | |
965 | === added file 'tests/unittest/fetch-hint-test.cpp' |
966 | --- tests/unittest/fetch-hint-test.cpp 1970-01-01 00:00:00 +0000 |
967 | +++ tests/unittest/fetch-hint-test.cpp 2013-06-26 15:26:36 +0000 |
968 | @@ -0,0 +1,86 @@ |
969 | +/* |
970 | + * Copyright 2013 Canonical Ltd. |
971 | + * |
972 | + * This file is part of contact-service-app. |
973 | + * |
974 | + * contact-service-app is free software; you can redistribute it and/or modify |
975 | + * it under the terms of the GNU General Public License as published by |
976 | + * the Free Software Foundation; version 3. |
977 | + * |
978 | + * contact-service-app is distributed in the hope that it will be useful, |
979 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
980 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
981 | + * GNU General Public License for more details. |
982 | + * |
983 | + * You should have received a copy of the GNU General Public License |
984 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
985 | + */ |
986 | + |
987 | + |
988 | +#include <QObject> |
989 | +#include <QtTest> |
990 | +#include <QDebug> |
991 | + |
992 | +#include <QtContacts> |
993 | + |
994 | +#include "common/fetch-hint.h" |
995 | + |
996 | +using namespace QtContacts; |
997 | +using namespace galera; |
998 | + |
999 | +class FetchHintTest : public QObject |
1000 | +{ |
1001 | + Q_OBJECT |
1002 | + |
1003 | +private Q_SLOTS: |
1004 | + |
1005 | + void testSimpleFields() |
1006 | + { |
1007 | + const QString strHint = QString("FIELDS:N,TEL"); |
1008 | + FetchHint hint(strHint); |
1009 | + |
1010 | + QVERIFY(!hint.isEmpty()); |
1011 | + QCOMPARE(hint.fields(), QStringList() << "N" << "TEL"); |
1012 | + |
1013 | + QContactFetchHint cHint; |
1014 | + cHint.setDetailTypesHint(QList<QContactDetail::DetailType>() << QContactDetail::TypeName |
1015 | + << QContactDetail::TypePhoneNumber); |
1016 | + QVERIFY(cHint.detailTypesHint() == hint.toContactFetchHint().detailTypesHint()); |
1017 | + |
1018 | + FetchHint hint2(cHint); |
1019 | + QCOMPARE(hint2.toString(), strHint); |
1020 | + } |
1021 | + |
1022 | + void testInvalidHint() |
1023 | + { |
1024 | + const QString strHint = QString("FIELDSS:N,TEL"); |
1025 | + FetchHint hint(strHint); |
1026 | + |
1027 | + QVERIFY(hint.isEmpty()); |
1028 | + } |
1029 | + |
1030 | + void testInvalidFieldName() |
1031 | + { |
1032 | + const QString strHint = QString("FIELDS:N,NONE,TEL,INVALID"); |
1033 | + FetchHint hint(strHint); |
1034 | + |
1035 | + QVERIFY(!hint.isEmpty()); |
1036 | + QCOMPARE(hint.fields(), QStringList() << "N" << "TEL"); |
1037 | + } |
1038 | + |
1039 | + void testParseFieldNames() |
1040 | + { |
1041 | + QList<QContactDetail::DetailType> fields = FetchHint::parseFieldNames(QStringList() << "ADR" << "BDAY" << "N" << "TEL"); |
1042 | + QList<QContactDetail::DetailType> expectedFields; |
1043 | + expectedFields << QContactDetail::TypeAddress |
1044 | + << QContactDetail::TypeBirthday |
1045 | + << QContactDetail::TypeName |
1046 | + << QContactDetail::TypePhoneNumber; |
1047 | + |
1048 | + QCOMPARE(fields, expectedFields); |
1049 | + } |
1050 | +}; |
1051 | + |
1052 | +QTEST_MAIN(FetchHintTest) |
1053 | + |
1054 | +#include "fetch-hint-test.moc" |
PASSED: Continuous integration, rev:45 jenkins. qa.ubuntu. com/job/ address- book-service- ci/35/ jenkins. qa.ubuntu. com/job/ address- book-service- saucy-amd64- ci/35 jenkins. qa.ubuntu. com/job/ address- book-service- saucy-armhf- ci/35 jenkins. qa.ubuntu. com/job/ address- book-service- saucy-armhf- ci/35/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ address- book-service- saucy-i386- ci/35
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ address- book-service- ci/35/rebuild
http://