91 // no store given? new, anonymous store. |
93 // no store given? new, anonymous store. |
92 idValue = QUuid::createUuid().toString(); |
94 idValue = QUuid::createUuid().toString(); |
93 anonymous = true; |
95 anonymous = true; |
94 } |
96 } |
95 |
97 |
96 if (engines.contains(idValue)) { |
98 QContactMemoryEngineData* data = engineDatas.value(idValue); |
97 QContactMemoryEngine *engine = engines.value(idValue); |
99 if (data) { |
98 engine->d->m_refCount.ref(); |
100 data->m_refCount.ref(); |
99 engine->d->m_anonymous = anonymous; |
|
100 return engine; |
|
101 } else { |
101 } else { |
102 QContactMemoryEngine *engine = new QContactMemoryEngine(parameters); |
102 data = new QContactMemoryEngineData(); |
103 engine->d->m_engineName = QString(QLatin1String("memory")); |
103 data->m_id = idValue; |
104 engine->d->m_engineVersion = 1; |
104 data->m_anonymous = anonymous; |
105 engine->d->m_id = idValue; |
105 engineDatas.insert(idValue, data); |
106 engine->d->m_anonymous = anonymous; |
106 } |
107 engines.insert(idValue, engine); |
107 return new QContactMemoryEngine(data); |
108 return engine; |
|
109 } |
|
110 } |
108 } |
111 |
109 |
112 /*! |
110 /*! |
113 * Constructs a new in-memory backend. |
111 * Constructs a new in-memory backend which shares the given \a data with |
114 * |
112 * other shared memory engines. |
115 * Loads the in-memory data associated with the memory store identified by the "id" parameter |
|
116 * from the given \a parameters if it exists, or a new, anonymous store if it does not. |
|
117 */ |
113 */ |
118 QContactMemoryEngine::QContactMemoryEngine(const QMap<QString, QString>& parameters) |
114 QContactMemoryEngine::QContactMemoryEngine(QContactMemoryEngineData* data) |
119 : d(new QContactMemoryEngineData) |
115 : d(data) |
120 { |
116 { |
121 Q_UNUSED(parameters); |
117 d->m_sharedEngines.append(this); |
122 } |
118 } |
123 |
119 |
124 /*! \reimp */ |
120 /*! Frees any memory used by this engine */ |
125 void QContactMemoryEngine::deref() |
121 QContactMemoryEngine::~QContactMemoryEngine() |
126 { |
122 { |
|
123 d->m_sharedEngines.removeAll(this); |
127 if (!d->m_refCount.deref()) { |
124 if (!d->m_refCount.deref()) { |
128 engines.remove(d->m_id); |
125 engineDatas.remove(d->m_id); |
129 delete d; |
126 delete d; |
130 delete this; |
|
131 } |
127 } |
132 } |
128 } |
133 |
129 |
134 /*! \reimp */ |
130 /*! \reimp */ |
135 QString QContactMemoryEngine::managerName() const |
131 QString QContactMemoryEngine::managerName() const |
136 { |
132 { |
137 return d->m_engineName; |
133 return QLatin1String("memory"); |
138 } |
|
139 |
|
140 /*! This function is deprecated and should not be used. Use QContactMemoryEngine::managerVersion() instead! */ |
|
141 int QContactMemoryEngine::implementationVersion() const |
|
142 { |
|
143 return d->m_engineVersion; |
|
144 } |
134 } |
145 |
135 |
146 /*! \reimp */ |
136 /*! \reimp */ |
147 QMap<QString, QString> QContactMemoryEngine::managerParameters() const |
137 QMap<QString, QString> QContactMemoryEngine::managerParameters() const |
148 { |
138 { |
150 params.insert(QLatin1String("id"), d->m_id); |
140 params.insert(QLatin1String("id"), d->m_id); |
151 return params; |
141 return params; |
152 } |
142 } |
153 |
143 |
154 /*! \reimp */ |
144 /*! \reimp */ |
155 bool QContactMemoryEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error& error) |
145 bool QContactMemoryEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error* error) |
156 { |
146 { |
157 if (contactId == QContactLocalId(0) || d->m_contactIds.contains(contactId)) { |
147 if (contactId == QContactLocalId(0) || d->m_contactIds.contains(contactId)) { |
158 error = QContactManager::NoError; |
148 *error = QContactManager::NoError; |
159 QContactLocalId oldId = d->m_selfContactId; |
149 QContactLocalId oldId = d->m_selfContactId; |
160 d->m_selfContactId = contactId; |
150 d->m_selfContactId = contactId; |
161 |
151 |
162 QContactChangeSet cs; |
152 QContactChangeSet changeSet; |
163 cs.oldAndNewSelfContactId() = QPair<QContactLocalId, QContactLocalId>(oldId, contactId); |
153 changeSet.setOldAndNewSelfContactId(QPair<QContactLocalId, QContactLocalId>(oldId, contactId)); |
164 cs.emitSignals(this); |
154 d->emitSharedSignals(&changeSet); |
165 return true; |
155 return true; |
166 } |
156 } |
167 |
157 |
168 error = QContactManager::DoesNotExistError; |
158 *error = QContactManager::DoesNotExistError; |
169 return false; |
159 return false; |
170 } |
160 } |
171 |
161 |
172 /*! \reimp */ |
162 /*! \reimp */ |
173 QContactLocalId QContactMemoryEngine::selfContactId(QContactManager::Error& error) const |
163 QContactLocalId QContactMemoryEngine::selfContactId(QContactManager::Error* error) const |
174 { |
164 { |
175 error = QContactManager::DoesNotExistError; |
165 *error = QContactManager::DoesNotExistError; |
176 if (d->m_selfContactId != QContactLocalId(0)) |
166 if (d->m_selfContactId != QContactLocalId(0)) |
177 error = QContactManager::NoError; |
167 *error = QContactManager::NoError; |
178 return d->m_selfContactId; |
168 return d->m_selfContactId; |
179 } |
169 } |
180 |
170 |
181 /*! \reimp */ |
171 /*! \reimp */ |
182 QList<QContactLocalId> QContactMemoryEngine::contacts(const QList<QContactSortOrder>& sortOrders, QContactManager::Error& error) const |
172 QContact QContactMemoryEngine::contact(const QContactLocalId& contactId, const QContactFetchHint& fetchHint, QContactManager::Error* error) const |
183 { |
173 { |
184 return contactIds(sortOrders, error); |
174 Q_UNUSED(fetchHint); // no optimisations are possible in the memory backend; ignore the fetch hint. |
185 } |
|
186 |
|
187 /*! \reimp */ |
|
188 QList<QContactLocalId> QContactMemoryEngine::contactIds(const QList<QContactSortOrder> &sortOrders, QContactManager::Error &error) const |
|
189 { |
|
190 // TODO: this needs to be done properly... |
|
191 error = QContactManager::NoError; |
|
192 QList<QContactLocalId> sortedIds; |
|
193 QList<QContact> sortedContacts; |
|
194 for (int i = 0; i < d->m_contacts.size(); i++) |
|
195 QContactManagerEngine::addSorted(&sortedContacts, d->m_contacts.at(i), sortOrders); |
|
196 for (int i = 0; i < sortedContacts.size(); i++) |
|
197 sortedIds.append(sortedContacts.at(i).id().localId()); |
|
198 return sortedIds; |
|
199 } |
|
200 |
|
201 /*! \reimp */ |
|
202 QList<QContact> QContactMemoryEngine::contacts(const QList<QContactSortOrder> &sortOrders, const QStringList& definitionRestrictions, QContactManager::Error &error) const |
|
203 { |
|
204 Q_UNUSED(definitionRestrictions); |
|
205 error = QContactManager::NoError; |
|
206 QList<QContact> sortedContacts; |
|
207 for (int i = 0; i < d->m_contacts.size(); i++) |
|
208 QContactManagerEngine::addSorted(&sortedContacts, contact(d->m_contacts.at(i).localId(), QStringList(), error), sortOrders); |
|
209 // we ignore the restrictions - we don't want to do extra work to remove them. |
|
210 // note that the restriction is "optional" - it defines the minimum set of detail types which _must_ be returned |
|
211 // but doesn't require that they are the _only_ detail types which are returned. |
|
212 return sortedContacts; |
|
213 } |
|
214 |
|
215 /*! \reimp */ |
|
216 QContact QContactMemoryEngine::contact(const QContactLocalId& contactId, QContactManager::Error& error) const |
|
217 { |
|
218 int index = d->m_contactIds.indexOf(contactId); |
175 int index = d->m_contactIds.indexOf(contactId); |
219 if (index != -1) { |
176 if (index != -1) { |
220 // found the contact successfully. |
177 // found the contact successfully. |
221 error = QContactManager::NoError; |
178 *error = QContactManager::NoError; |
222 QContact retn = d->m_contacts.at(index); |
179 return d->m_contacts.at(index); |
223 |
180 } |
224 // synthesize the display label if we need to. |
181 |
225 QContactDisplayLabel dl = retn.detail(QContactDisplayLabel::DefinitionName); |
182 *error = QContactManager::DoesNotExistError; |
226 if (dl.label().isEmpty()) { |
|
227 QContactManager::Error synthError; |
|
228 retn = setContactDisplayLabel(synthesizedDisplayLabel(retn, synthError), retn); |
|
229 } |
|
230 |
|
231 // also, retrieve the current relationships the contact is involved with. |
|
232 QList<QContactRelationship> relationshipCache = d->m_orderedRelationships.value(contactId); |
|
233 QContactManagerEngine::setContactRelationships(&retn, relationshipCache); |
|
234 |
|
235 // and return the contact |
|
236 return retn; |
|
237 } |
|
238 |
|
239 error = QContactManager::DoesNotExistError; |
|
240 return QContact(); |
183 return QContact(); |
241 } |
184 } |
242 |
185 |
243 /*! \reimp */ |
186 /*! \reimp */ |
244 QContact QContactMemoryEngine::contact(const QContactLocalId& contactId, const QStringList& definitionRestrictions, QContactManager::Error& error) const |
187 QList<QContactLocalId> QContactMemoryEngine::contactIds(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, QContactManager::Error* error) const |
245 { |
188 { |
246 Q_UNUSED(definitionRestrictions); // return the entire contact (meets contract, no optimisations possible for memory engine). |
189 /* Special case the fast case */ |
247 int index = d->m_contactIds.indexOf(contactId); |
190 if (filter.type() == QContactFilter::DefaultFilter && sortOrders.count() == 0) { |
248 if (index != -1) { |
191 return d->m_contactIds; |
249 // found the contact successfully. |
192 } else { |
250 error = QContactManager::NoError; |
193 QList<QContact> clist = contacts(filter, sortOrders, QContactFetchHint(), error); |
251 QContact retn = d->m_contacts.at(index); |
194 |
252 |
195 /* Extract the ids */ |
253 // synthesize the display label if we need to. |
196 QList<QContactLocalId> ids; |
254 QContactDisplayLabel dl = retn.detail(QContactDisplayLabel::DefinitionName); |
197 foreach(const QContact& c, clist) |
255 if (dl.label().isEmpty()) { |
198 ids.append(c.localId()); |
256 QContactManager::Error synthError; |
199 |
257 retn = setContactDisplayLabel(synthesizedDisplayLabel(retn, synthError), retn); |
200 return ids; |
258 } |
201 } |
259 |
202 } |
260 // also, retrieve the current relationships the contact is involved with. |
203 |
261 QList<QContactRelationship> relationshipCache = d->m_orderedRelationships.value(contactId); |
204 /*! \reimp */ |
262 QContactManagerEngine::setContactRelationships(&retn, relationshipCache); |
205 QList<QContact> QContactMemoryEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fetchHint, QContactManager::Error* error) const |
263 |
206 { |
264 // and return the contact |
207 Q_UNUSED(fetchHint); // no optimisations are possible in the memory backend; ignore the fetch hint. |
265 return retn; |
208 Q_UNUSED(error); |
266 } |
209 |
267 |
210 QList<QContact> sorted; |
268 error = QContactManager::DoesNotExistError; |
211 |
269 return QContact(); |
212 /* First filter out contacts - check for default filter first */ |
270 } |
213 if (filter.type() == QContactFilter::DefaultFilter) { |
271 |
214 foreach(const QContact&c, d->m_contacts) { |
272 bool QContactMemoryEngine::saveContact(QContact* theContact, QContactChangeSet& changeSet, QContactManager::Error& error) |
215 QContactManagerEngine::addSorted(&sorted,c, sortOrders); |
|
216 } |
|
217 } else { |
|
218 foreach(const QContact&c, d->m_contacts) { |
|
219 if (QContactManagerEngine::testFilter(filter, c)) |
|
220 QContactManagerEngine::addSorted(&sorted,c, sortOrders); |
|
221 } |
|
222 } |
|
223 |
|
224 return sorted; |
|
225 } |
|
226 |
|
227 /*! Saves the given contact \a theContact, storing any error to \a error and |
|
228 filling the \a changeSet with ids of changed contacts as required */ |
|
229 bool QContactMemoryEngine::saveContact(QContact* theContact, QContactChangeSet& changeSet, QContactManager::Error* error) |
273 { |
230 { |
274 // ensure that the contact's details conform to their definitions |
231 // ensure that the contact's details conform to their definitions |
275 if (!validateContact(*theContact, error)) { |
232 if (!validateContact(*theContact, error)) { |
276 return false; |
233 return false; |
277 } |
234 } |
281 if (index != -1) { |
238 if (index != -1) { |
282 /* We also need to check that there are no modified create only details */ |
239 /* We also need to check that there are no modified create only details */ |
283 QContact oldContact = d->m_contacts.at(index); |
240 QContact oldContact = d->m_contacts.at(index); |
284 |
241 |
285 if (oldContact.type() != theContact->type()) { |
242 if (oldContact.type() != theContact->type()) { |
286 error = QContactManager::AlreadyExistsError; |
243 *error = QContactManager::AlreadyExistsError; |
287 return false; |
244 return false; |
288 } |
245 } |
289 |
246 |
290 QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName); |
247 QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName); |
291 ts.setLastModified(QDateTime::currentDateTime()); |
248 ts.setLastModified(QDateTime::currentDateTime()); |
292 QContactManagerEngine::setDetailAccessConstraints(&ts, QContactDetail::ReadOnly | QContactDetail::Irremovable); |
249 QContactManagerEngine::setDetailAccessConstraints(&ts, QContactDetail::ReadOnly | QContactDetail::Irremovable); |
293 theContact->saveDetail(&ts); |
250 theContact->saveDetail(&ts); |
294 |
251 |
295 /* And we need to check that the relationships are up-to-date or not modified */ |
|
296 QList<QContactRelationship> orderedList = theContact->relationshipOrder(); |
|
297 QList<QContactRelationship> upToDateList = d->m_orderedRelationships.value(theContact->localId()); |
|
298 if (theContact->relationships() != orderedList) { |
|
299 // the user has modified the order of relationships; we may need to update the lists etc. |
|
300 if (upToDateList.size() != orderedList.size()) { |
|
301 // the cache was stale; relationships have been added or removed in the meantime. |
|
302 error = QContactManager::InvalidRelationshipError; |
|
303 return false; |
|
304 } |
|
305 |
|
306 // size is the same, need to ensure that no invalid relationships are in the list. |
|
307 for (int i = 0; i < orderedList.size(); i++) { |
|
308 QContactRelationship currOrderedRel = orderedList.at(i); |
|
309 if (!upToDateList.contains(currOrderedRel)) { |
|
310 // the cache was stale; relationships have been added and removed in the meantime. |
|
311 error = QContactManager::InvalidRelationshipError; |
|
312 return false; |
|
313 } |
|
314 } |
|
315 |
|
316 // everything is fine. update the up-to-date list |
|
317 d->m_orderedRelationships.insert(theContact->localId(), orderedList); |
|
318 } |
|
319 |
|
320 // synthesize the display label for the contact. |
252 // synthesize the display label for the contact. |
321 QContact saveContact = setContactDisplayLabel(synthesizedDisplayLabel(*theContact, error), *theContact); |
253 setContactDisplayLabel(theContact, synthesizedDisplayLabel(*theContact, error)); |
322 *theContact = saveContact; |
|
323 |
254 |
324 // Looks ok, so continue |
255 // Looks ok, so continue |
325 d->m_contacts.replace(index, *theContact); |
256 d->m_contacts.replace(index, *theContact); |
326 changeSet.changedContacts().insert(theContact->localId()); |
257 changeSet.insertChangedContact(theContact->localId()); |
327 } else { |
258 } else { |
328 // id does not exist; if not zero, fail. |
259 // id does not exist; if not zero, fail. |
329 QContactId newId; |
260 QContactId newId; |
330 newId.setManagerUri(managerUri()); |
261 newId.setManagerUri(managerUri()); |
331 if (theContact->id() != QContactId() && theContact->id() != newId) { |
262 if (theContact->id() != QContactId() && theContact->id() != newId) { |
332 // the ID is not empty, and it doesn't identify an existing contact in our database either. |
263 // the ID is not empty, and it doesn't identify an existing contact in our database either. |
333 error = QContactManager::DoesNotExistError; |
264 *error = QContactManager::DoesNotExistError; |
334 return false; |
265 return false; |
335 } |
266 } |
336 |
267 |
337 /* New contact */ |
268 /* New contact */ |
338 QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName); |
269 QContactTimestamp ts = theContact->detail(QContactTimestamp::DefinitionName); |
344 // update the contact item - set its ID |
275 // update the contact item - set its ID |
345 newId.setLocalId(++d->m_nextContactId); |
276 newId.setLocalId(++d->m_nextContactId); |
346 theContact->setId(newId); |
277 theContact->setId(newId); |
347 |
278 |
348 // synthesize the display label for the contact. |
279 // synthesize the display label for the contact. |
349 QContact saveContact = setContactDisplayLabel(synthesizedDisplayLabel(*theContact, error), *theContact); |
280 setContactDisplayLabel(theContact, synthesizedDisplayLabel(*theContact, error)); |
350 *theContact = saveContact; |
|
351 |
281 |
352 // finally, add the contact to our internal lists and return |
282 // finally, add the contact to our internal lists and return |
353 d->m_contacts.append(*theContact); // add contact to list |
283 d->m_contacts.append(*theContact); // add contact to list |
354 d->m_contactIds.append(theContact->localId()); // track the contact id. |
284 d->m_contactIds.append(theContact->localId()); // track the contact id. |
355 |
285 |
356 changeSet.addedContacts().insert(theContact->localId()); |
286 changeSet.insertAddedContact(theContact->localId()); |
357 } |
287 } |
358 |
288 |
359 error = QContactManager::NoError; // successful. |
289 *error = QContactManager::NoError; // successful. |
360 return true; |
290 return true; |
361 } |
291 } |
362 |
292 |
363 /*! \reimp */ |
293 /*! \reimp */ |
364 bool QContactMemoryEngine::saveContact(QContact* contact, QContactManager::Error& error) |
294 bool QContactMemoryEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
365 { |
|
366 QContactChangeSet changeSet; |
|
367 bool retn = saveContact(contact, changeSet, error); |
|
368 changeSet.emitSignals(this); |
|
369 return retn; |
|
370 } |
|
371 |
|
372 /*! \reimp */ |
|
373 QList<QContactManager::Error> QContactMemoryEngine::saveContacts(QList<QContact>* contacts, QContactManager::Error& error) |
|
374 { |
|
375 QList<QContactManager::Error> ret; |
|
376 if (!contacts) { |
|
377 error = QContactManager::BadArgumentError; |
|
378 return ret; |
|
379 } else { |
|
380 // for batch processing, we store up the changes and emit at the end. |
|
381 QContactChangeSet changeSet; |
|
382 QContactManager::Error functionError = QContactManager::NoError; |
|
383 for (int i = 0; i < contacts->count(); i++) { |
|
384 QContact current = contacts->at(i); |
|
385 if (!saveContact(¤t, changeSet, error)) { |
|
386 functionError = error; |
|
387 ret.append(functionError); |
|
388 } else { |
|
389 (*contacts)[i] = current; |
|
390 ret.append(QContactManager::NoError); |
|
391 } |
|
392 } |
|
393 |
|
394 error = functionError; |
|
395 changeSet.emitSignals(this); |
|
396 return ret; |
|
397 } |
|
398 } |
|
399 |
|
400 /*! \reimp */ |
|
401 bool QContactMemoryEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error& error) |
|
402 { |
295 { |
403 if(errorMap) { |
296 if(errorMap) { |
404 errorMap->clear(); |
297 errorMap->clear(); |
405 } |
298 } |
406 |
299 |
407 if (!contacts) { |
300 if (!contacts) { |
408 error = QContactManager::BadArgumentError; |
301 *error = QContactManager::BadArgumentError; |
409 return false; |
302 return false; |
410 } |
303 } |
411 |
304 |
412 QContactChangeSet changeSet; |
305 QContactChangeSet changeSet; |
413 QContact current; |
306 QContact current; |
414 QContactManager::Error operationError = QContactManager::NoError; |
307 QContactManager::Error operationError = QContactManager::NoError; |
415 for (int i = 0; i < contacts->count(); i++) { |
308 for (int i = 0; i < contacts->count(); i++) { |
416 current = contacts->at(i); |
309 current = contacts->at(i); |
417 if (!saveContact(¤t, changeSet, error)) { |
310 if (!saveContact(¤t, changeSet, error)) { |
418 operationError = error; |
311 operationError = *error; |
419 errorMap->insert(i, operationError); |
312 errorMap->insert(i, operationError); |
420 } else { |
313 } else { |
421 (*contacts)[i] = current; |
314 (*contacts)[i] = current; |
422 } |
315 } |
423 } |
316 } |
424 |
317 |
425 error = operationError; |
318 *error = operationError; |
426 changeSet.emitSignals(this); |
319 d->emitSharedSignals(&changeSet); |
427 // return false if some error occurred |
320 // return false if some error occurred |
428 return error == QContactManager::NoError; |
321 return (*error == QContactManager::NoError); |
429 } |
322 } |
430 |
323 |
431 bool QContactMemoryEngine::removeContact(const QContactLocalId& contactId, QContactChangeSet& changeSet, QContactManager::Error& error) |
324 /*! Removes the contact identified by the given \a contactId, storing any error to \a error and |
|
325 filling the \a changeSet with ids of changed contacts and relationships as required */ |
|
326 bool QContactMemoryEngine::removeContact(const QContactLocalId& contactId, QContactChangeSet& changeSet, QContactManager::Error* error) |
432 { |
327 { |
433 int index = d->m_contactIds.indexOf(contactId); |
328 int index = d->m_contactIds.indexOf(contactId); |
434 |
329 |
435 if (index == -1) { |
330 if (index == -1) { |
436 error = QContactManager::DoesNotExistError; |
331 *error = QContactManager::DoesNotExistError; |
437 return false; |
332 return false; |
438 } |
333 } |
439 |
334 |
440 // remove the contact from any relationships it was in. |
335 // remove the contact from any relationships it was in. |
441 QContactId thisContact; |
336 QContactId thisContact; |
442 thisContact.setManagerUri(managerUri()); |
337 thisContact.setManagerUri(managerUri()); |
443 thisContact.setLocalId(contactId); |
338 thisContact.setLocalId(contactId); |
444 QList<QContactRelationship> allRelationships = relationships(QString(), thisContact, QContactRelationshipFilter::Either, error); |
339 QList<QContactRelationship> allRelationships = relationships(QString(), thisContact, QContactRelationship::Either, error); |
445 if (error != QContactManager::NoError && error != QContactManager::DoesNotExistError) { |
340 if (*error != QContactManager::NoError && *error != QContactManager::DoesNotExistError) { |
446 error = QContactManager::UnspecifiedError; // failed to clean up relationships |
341 *error = QContactManager::UnspecifiedError; // failed to clean up relationships |
447 return false; |
342 return false; |
448 } |
343 } |
449 |
344 |
450 // this is meant to be a transaction, so if any of these fail, we're in BIG TROUBLE. |
345 // this is meant to be a transaction, so if any of these fail, we're in BIG TROUBLE. |
451 // a real backend will use DBMS transactions to ensure database integrity. |
346 // a real backend will use DBMS transactions to ensure database integrity. |
452 for (int i = 0; i < allRelationships.size(); i++) { |
347 removeRelationships(allRelationships, 0, error); |
453 QContactRelationship currRel = allRelationships.at(i); |
|
454 removeRelationship(currRel, error); |
|
455 } |
|
456 |
348 |
457 // having cleaned up the relationships, remove the contact from the lists. |
349 // having cleaned up the relationships, remove the contact from the lists. |
458 d->m_contacts.removeAt(index); |
350 d->m_contacts.removeAt(index); |
459 d->m_contactIds.removeAt(index); |
351 d->m_contactIds.removeAt(index); |
460 error = QContactManager::NoError; |
352 *error = QContactManager::NoError; |
461 |
353 |
462 // and if it was the self contact, reset the self contact id |
354 // and if it was the self contact, reset the self contact id |
463 if (contactId == d->m_selfContactId) { |
355 if (contactId == d->m_selfContactId) { |
464 d->m_selfContactId = QContactLocalId(0); |
356 d->m_selfContactId = QContactLocalId(0); |
465 changeSet.oldAndNewSelfContactId() = QPair<QContactLocalId, QContactLocalId>(contactId, QContactLocalId(0)); |
357 changeSet.setOldAndNewSelfContactId(QPair<QContactLocalId, QContactLocalId>(contactId, QContactLocalId(0))); |
466 } |
358 } |
467 |
359 |
468 changeSet.removedContacts().insert(contactId); |
360 changeSet.insertRemovedContact(contactId); |
469 return true; |
361 return true; |
470 } |
362 } |
471 |
363 |
472 /*! \reimp */ |
364 /*! \reimp */ |
473 bool QContactMemoryEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error& error) |
365 bool QContactMemoryEngine::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
474 { |
366 { |
475 QContactChangeSet changeSet; |
367 if (contactIds.count() == 0) { |
476 bool retn = removeContact(contactId, changeSet, error); |
368 *error = QContactManager::BadArgumentError; |
477 changeSet.emitSignals(this); |
369 return false; |
478 return retn; |
370 } |
479 } |
371 |
480 |
|
481 /*! \reimp */ |
|
482 QList<QContactManager::Error> QContactMemoryEngine::removeContacts(QList<QContactLocalId>* contactIds, QContactManager::Error& error) |
|
483 { |
|
484 QList<QContactManager::Error> ret; |
|
485 if (!contactIds) { |
|
486 error = QContactManager::BadArgumentError; |
|
487 return ret; |
|
488 } |
|
489 |
|
490 // for batch processing, we store up the changes and emit at the end. |
|
491 QContactChangeSet changeSet; |
|
492 QContactManager::Error functionError = QContactManager::NoError; |
|
493 for (int i = 0; i < contactIds->count(); i++) { |
|
494 QContactLocalId current = contactIds->at(i); |
|
495 if (!removeContact(current, changeSet, error)) { |
|
496 functionError = error; |
|
497 ret.append(functionError); |
|
498 } else { |
|
499 (*contactIds)[i] = 0; |
|
500 ret.append(QContactManager::NoError); |
|
501 } |
|
502 } |
|
503 |
|
504 error = functionError; |
|
505 changeSet.emitSignals(this); |
|
506 return ret; |
|
507 } |
|
508 |
|
509 /*! \reimp */ |
|
510 bool QContactMemoryEngine::removeContacts(QList<QContactLocalId>* contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error& error) |
|
511 { |
|
512 if (!contactIds) { |
|
513 error = QContactManager::BadArgumentError; |
|
514 return false; |
|
515 } |
|
516 |
|
517 QContactChangeSet changeSet; |
372 QContactChangeSet changeSet; |
518 QContactLocalId current; |
373 QContactLocalId current; |
519 QContactManager::Error operationError = QContactManager::NoError; |
374 QContactManager::Error operationError = QContactManager::NoError; |
520 for (int i = 0; i < contactIds->count(); i++) { |
375 for (int i = 0; i < contactIds.count(); i++) { |
521 current = contactIds->at(i); |
376 current = contactIds.at(i); |
522 if (!removeContact(current, changeSet, error)) { |
377 if (!removeContact(current, changeSet, error)) { |
523 operationError = error; |
378 operationError = *error; |
524 errorMap->insert(i, operationError); |
379 errorMap->insert(i, operationError); |
525 } else { |
380 } |
526 (*contactIds)[i] = 0; |
381 } |
527 } |
382 |
528 } |
383 *error = operationError; |
529 |
384 d->emitSharedSignals(&changeSet); |
530 error = operationError; |
|
531 changeSet.emitSignals(this); |
|
532 // return false if some errors occurred |
385 // return false if some errors occurred |
533 return error == QContactManager::NoError; |
386 return (*error == QContactManager::NoError); |
534 } |
387 } |
535 |
388 |
536 /*! \reimp */ |
389 /*! \reimp */ |
537 QList<QContactRelationship> QContactMemoryEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationshipFilter::Role role, QContactManager::Error& error) const |
390 QList<QContactRelationship> QContactMemoryEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationship::Role role, QContactManager::Error* error) const |
538 { |
391 { |
539 QContactId defaultId; |
392 QContactId defaultId; |
540 QList<QContactRelationship> retn; |
393 QList<QContactRelationship> retn; |
541 for (int i = 0; i < d->m_relationships.size(); i++) { |
394 for (int i = 0; i < d->m_relationships.size(); i++) { |
542 QContactRelationship curr = d->m_relationships.at(i); |
395 QContactRelationship curr = d->m_relationships.at(i); |
550 retn.append(curr); |
403 retn.append(curr); |
551 continue; |
404 continue; |
552 } |
405 } |
553 |
406 |
554 // otherwise, check that the participant exists and plays the required role in the relationship. |
407 // otherwise, check that the participant exists and plays the required role in the relationship. |
555 if (role == QContactRelationshipFilter::First && curr.first() == participantId) { |
408 if (role == QContactRelationship::First && curr.first() == participantId) { |
556 retn.append(curr); |
409 retn.append(curr); |
557 } else if (role == QContactRelationshipFilter::Second && curr.second() == participantId) { |
410 } else if (role == QContactRelationship::Second && curr.second() == participantId) { |
558 retn.append(curr); |
411 retn.append(curr); |
559 } else if (role == QContactRelationshipFilter::Either && (curr.first() == participantId || curr.second() == participantId)) { |
412 } else if (role == QContactRelationship::Either && (curr.first() == participantId || curr.second() == participantId)) { |
560 retn.append(curr); |
413 retn.append(curr); |
561 } |
414 } |
562 } |
415 } |
563 |
416 |
564 error = QContactManager::NoError; |
417 *error = QContactManager::NoError; |
565 if (retn.isEmpty()) |
418 if (retn.isEmpty()) |
566 error = QContactManager::DoesNotExistError; |
419 *error = QContactManager::DoesNotExistError; |
567 return retn; |
420 return retn; |
568 } |
421 } |
569 |
422 |
570 bool QContactMemoryEngine::saveRelationship(QContactRelationship* relationship, QContactChangeSet& changeSet, QContactManager::Error& error) |
423 /*! Saves the given relationship \a relationship, storing any error to \a error and |
|
424 filling the \a changeSet with ids of changed contacts and relationships as required */ |
|
425 bool QContactMemoryEngine::saveRelationship(QContactRelationship* relationship, QContactChangeSet& changeSet, QContactManager::Error* error) |
571 { |
426 { |
572 // Attempt to validate the relationship. |
427 // Attempt to validate the relationship. |
573 // first, check that the source contact exists and is in this manager. |
428 // first, check that the source contact exists and is in this manager. |
574 QString myUri = managerUri(); |
429 QString myUri = managerUri(); |
|
430 int firstContactIndex = d->m_contactIds.indexOf(relationship->first().localId()); |
575 if ((!relationship->first().managerUri().isEmpty() && relationship->first().managerUri() != myUri) |
431 if ((!relationship->first().managerUri().isEmpty() && relationship->first().managerUri() != myUri) |
576 ||!d->m_contactIds.contains(relationship->first().localId())) { |
432 ||firstContactIndex == -1) { |
577 error = QContactManager::InvalidRelationshipError; |
433 *error = QContactManager::InvalidRelationshipError; |
578 return false; |
434 return false; |
579 } |
435 } |
580 |
436 |
581 // second, check that the second contact exists (if it's local); we cannot check other managers' contacts. |
437 // second, check that the second contact exists (if it's local); we cannot check other managers' contacts. |
582 QContactId dest = relationship->second(); |
438 QContactId dest = relationship->second(); |
|
439 int secondContactIndex = d->m_contactIds.indexOf(dest.localId()); |
583 |
440 |
584 if (dest.managerUri().isEmpty() || dest.managerUri() == myUri) { |
441 if (dest.managerUri().isEmpty() || dest.managerUri() == myUri) { |
585 // this entry in the destination list is supposedly stored in this manager. |
442 // this entry in the destination list is supposedly stored in this manager. |
586 // check that it exists, and that it isn't the source contact (circular) |
443 // check that it exists, and that it isn't the source contact (circular) |
587 if (!d->m_contactIds.contains(dest.localId()) || dest.localId() == relationship->first().localId()) { |
444 if (secondContactIndex == -1 || dest.localId() == relationship->first().localId()) { |
588 error = QContactManager::InvalidRelationshipError; |
445 *error = QContactManager::InvalidRelationshipError; |
589 return false; |
446 return false; |
590 } |
447 } |
591 } |
448 } |
592 |
449 |
593 // the relationship is valid. We need to update the manager URIs in the second contact if it is empty to our URI. |
450 // the relationship is valid. We need to update the manager URIs in the second contact if it is empty to our URI. |
616 QList<QContactRelationship> secondRelationships = d->m_orderedRelationships.value(relationship->second().localId()); |
471 QList<QContactRelationship> secondRelationships = d->m_orderedRelationships.value(relationship->second().localId()); |
617 firstRelationships.append(*relationship); |
472 firstRelationships.append(*relationship); |
618 secondRelationships.append(*relationship); |
473 secondRelationships.append(*relationship); |
619 d->m_orderedRelationships.insert(relationship->first().localId(), firstRelationships); |
474 d->m_orderedRelationships.insert(relationship->first().localId(), firstRelationships); |
620 d->m_orderedRelationships.insert(relationship->second().localId(), secondRelationships); |
475 d->m_orderedRelationships.insert(relationship->second().localId(), secondRelationships); |
621 changeSet.addedRelationshipsContacts().insert(relationship->first().localId()); |
476 changeSet.insertAddedRelationshipsContact(relationship->first().localId()); |
622 changeSet.addedRelationshipsContacts().insert(relationship->second().localId()); |
477 changeSet.insertAddedRelationshipsContact(relationship->second().localId()); |
|
478 |
|
479 // update the contacts involved |
|
480 QContactManagerEngine::setContactRelationships(&d->m_contacts[firstContactIndex], firstRelationships); |
|
481 QContactManagerEngine::setContactRelationships(&d->m_contacts[secondContactIndex], secondRelationships); |
623 |
482 |
624 // finally, insert into our list of all relationships, and return. |
483 // finally, insert into our list of all relationships, and return. |
625 d->m_relationships.append(*relationship); |
484 d->m_relationships.append(*relationship); |
626 return true; |
485 return true; |
627 } |
486 } |
628 |
487 |
629 /*! \reimp */ |
488 /*! \reimp */ |
630 bool QContactMemoryEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error& error) |
489 bool QContactMemoryEngine::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
631 { |
490 { |
632 QContactChangeSet changeSet; |
491 *error = QContactManager::NoError; |
633 bool retn = saveRelationship(relationship, changeSet, error); |
|
634 changeSet.emitSignals(this); |
|
635 return retn; |
|
636 } |
|
637 |
|
638 /*! \reimp */ |
|
639 QList<QContactManager::Error> QContactMemoryEngine::saveRelationships(QList<QContactRelationship>* relationships, QContactManager::Error& error) |
|
640 { |
|
641 error = QContactManager::NoError; |
|
642 QContactManager::Error functionError; |
492 QContactManager::Error functionError; |
643 QContactChangeSet changeSet; |
493 QContactChangeSet changeSet; |
644 QList<QContactManager::Error> retn; |
494 |
645 for (int i = 0; i < relationships->size(); i++) { |
495 for (int i = 0; i < relationships->size(); i++) { |
646 QContactRelationship curr = relationships->at(i); |
496 QContactRelationship curr = relationships->at(i); |
647 saveRelationship(&curr, changeSet, functionError); |
497 saveRelationship(&curr, changeSet, &functionError); |
648 retn.append(functionError); |
498 if (functionError != QContactManager::NoError && errorMap) |
|
499 errorMap->insert(i, functionError); |
649 |
500 |
650 // and replace the current relationship with the updated version. |
501 // and replace the current relationship with the updated version. |
651 relationships->replace(i, curr); |
502 relationships->replace(i, curr); |
652 |
503 |
653 // also, update the total error if it did not succeed. |
504 // also, update the total error if it did not succeed. |
654 if (functionError != QContactManager::NoError) |
505 if (functionError != QContactManager::NoError) |
655 error = functionError; |
506 *error = functionError; |
656 } |
507 } |
657 |
508 |
658 changeSet.emitSignals(this); |
509 d->emitSharedSignals(&changeSet); |
659 return retn; |
510 return (*error == QContactManager::NoError); |
660 } |
511 } |
661 |
512 |
662 bool QContactMemoryEngine::removeRelationship(const QContactRelationship& relationship, QContactChangeSet& changeSet, QContactManager::Error& error) |
513 /*! Removes the given relationship \a relationship, storing any error to \a error and |
|
514 filling the \a changeSet with ids of changed contacts and relationships as required */ |
|
515 bool QContactMemoryEngine::removeRelationship(const QContactRelationship& relationship, QContactChangeSet& changeSet, QContactManager::Error* error) |
663 { |
516 { |
664 // attempt to remove it from our list of relationships. |
517 // attempt to remove it from our list of relationships. |
665 if (!d->m_relationships.removeOne(relationship)) { |
518 if (!d->m_relationships.removeOne(relationship)) { |
666 error = QContactManager::DoesNotExistError; |
519 *error = QContactManager::DoesNotExistError; |
667 return false; |
520 return false; |
668 } |
521 } |
669 |
522 |
670 // if that worked, then we need to remove it from the two locations in our map, also. |
523 // if that worked, then we need to remove it from the two locations in our map, also. |
671 QList<QContactRelationship> firstRelationships = d->m_orderedRelationships.value(relationship.first().localId()); |
524 QList<QContactRelationship> firstRelationships = d->m_orderedRelationships.value(relationship.first().localId()); |
673 firstRelationships.removeOne(relationship); |
526 firstRelationships.removeOne(relationship); |
674 secondRelationships.removeOne(relationship); |
527 secondRelationships.removeOne(relationship); |
675 d->m_orderedRelationships.insert(relationship.first().localId(), firstRelationships); |
528 d->m_orderedRelationships.insert(relationship.first().localId(), firstRelationships); |
676 d->m_orderedRelationships.insert(relationship.second().localId(), secondRelationships); |
529 d->m_orderedRelationships.insert(relationship.second().localId(), secondRelationships); |
677 |
530 |
|
531 // Update the contacts as well |
|
532 int firstContactIndex = d->m_contactIds.indexOf(relationship.first().localId()); |
|
533 int secondContactIndex = relationship.second().managerUri() == managerUri() ? d->m_contactIds.indexOf(relationship.second().localId()) : -1; |
|
534 if (firstContactIndex != -1) |
|
535 QContactMemoryEngine::setContactRelationships(&d->m_contacts[firstContactIndex], firstRelationships); |
|
536 if (secondContactIndex != -1) |
|
537 QContactMemoryEngine::setContactRelationships(&d->m_contacts[secondContactIndex], secondRelationships); |
|
538 |
678 // set our changes, and return. |
539 // set our changes, and return. |
679 changeSet.removedRelationshipsContacts().insert(relationship.first().localId()); |
540 changeSet.insertRemovedRelationshipsContact(relationship.first().localId()); |
680 changeSet.removedRelationshipsContacts().insert(relationship.second().localId()); |
541 changeSet.insertRemovedRelationshipsContact(relationship.second().localId()); |
681 error = QContactManager::NoError; |
542 *error = QContactManager::NoError; |
682 return true; |
543 return true; |
683 } |
544 } |
684 |
545 |
685 /*! \reimp */ |
546 /*! \reimp */ |
686 bool QContactMemoryEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error& error) |
547 bool QContactMemoryEngine::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
687 { |
548 { |
688 QContactChangeSet changeSet; |
|
689 bool retn = removeRelationship(relationship, changeSet, error); |
|
690 changeSet.emitSignals(this); |
|
691 return retn; |
|
692 } |
|
693 |
|
694 /*! \reimp */ |
|
695 QList<QContactManager::Error> QContactMemoryEngine::removeRelationships(const QList<QContactRelationship>& relationships, QContactManager::Error& error) |
|
696 { |
|
697 QList<QContactManager::Error> retn; |
|
698 QContactManager::Error functionError; |
549 QContactManager::Error functionError; |
|
550 QContactChangeSet cs; |
699 for (int i = 0; i < relationships.size(); i++) { |
551 for (int i = 0; i < relationships.size(); i++) { |
700 removeRelationship(relationships.at(i), functionError); |
552 removeRelationship(relationships.at(i), cs, &functionError); |
701 retn.append(functionError); |
|
702 |
553 |
703 // update the total error if it did not succeed. |
554 // update the total error if it did not succeed. |
704 if (functionError != QContactManager::NoError) { |
555 if (functionError != QContactManager::NoError) { |
705 error = functionError; |
556 if (errorMap) |
706 } |
557 errorMap->insert(i, functionError); |
707 } |
558 *error = functionError; |
708 |
559 } |
709 return retn; |
560 } |
710 } |
561 |
711 |
562 d->emitSharedSignals(&cs); |
712 /*! \reimp */ |
563 return (*error == QContactManager::NoError); |
713 QMap<QString, QContactDetailDefinition> QContactMemoryEngine::detailDefinitions(const QString& contactType, QContactManager::Error& error) const |
564 } |
|
565 |
|
566 /*! \reimp */ |
|
567 QMap<QString, QContactDetailDefinition> QContactMemoryEngine::detailDefinitions(const QString& contactType, QContactManager::Error* error) const |
714 { |
568 { |
715 // lazy initialisation of schema definitions. |
569 // lazy initialisation of schema definitions. |
716 if (d->m_definitions.isEmpty()) { |
570 if (d->m_definitions.isEmpty()) { |
717 d->m_definitions = QContactManagerEngine::schemaDefinitions(); |
571 d->m_definitions = QContactManagerEngine::schemaDefinitions(); |
718 } |
572 } |
719 |
573 |
720 error = QContactManager::NoError; |
574 *error = QContactManager::NoError; |
721 return d->m_definitions.value(contactType); |
575 return d->m_definitions.value(contactType); |
722 } |
576 } |
723 |
577 |
724 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error& error) |
578 /*! Saves the given detail definition \a def, storing any error to \a error and |
|
579 filling the \a changeSet with ids of changed contacts as required */ |
|
580 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error* error) |
725 { |
581 { |
726 // we should check for changes to the database in this function, and add ids of changed data to changeSet. TODO. |
582 // we should check for changes to the database in this function, and add ids of changed data to changeSet. TODO. |
727 Q_UNUSED(changeSet); |
583 Q_UNUSED(changeSet); |
728 |
584 |
729 if (!validateDefinition(def, error)) { |
585 if (!validateDefinition(def, error)) { |
733 detailDefinitions(contactType, error); // just to populate the definitions if we haven't already. |
589 detailDefinitions(contactType, error); // just to populate the definitions if we haven't already. |
734 QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType); |
590 QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType); |
735 defsForThisType.insert(def.name(), def); |
591 defsForThisType.insert(def.name(), def); |
736 d->m_definitions.insert(contactType, defsForThisType); |
592 d->m_definitions.insert(contactType, defsForThisType); |
737 |
593 |
738 error = QContactManager::NoError; |
594 *error = QContactManager::NoError; |
739 return true; |
595 return true; |
740 } |
596 } |
741 |
597 |
742 /*! \reimp */ |
598 /*! \reimp */ |
743 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactManager::Error& error) |
599 bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactManager::Error* error) |
744 { |
600 { |
745 QContactChangeSet changeSet; |
601 QContactChangeSet changeSet; |
746 bool retn = saveDetailDefinition(def, contactType, changeSet, error); |
602 bool retn = saveDetailDefinition(def, contactType, changeSet, error); |
747 changeSet.emitSignals(this); |
603 d->emitSharedSignals(&changeSet); |
748 return retn; |
604 return retn; |
749 } |
605 } |
750 |
606 |
751 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error& error) |
607 /*! Removes the detail definition identified by \a definitionId, storing any error to \a error and |
|
608 filling the \a changeSet with ids of changed contacts as required */ |
|
609 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactChangeSet& changeSet, QContactManager::Error* error) |
752 { |
610 { |
753 // we should check for changes to the database in this function, and add ids of changed data to changeSet... |
611 // we should check for changes to the database in this function, and add ids of changed data to changeSet... |
754 // we should also check to see if the changes have invalidated any contact data, and add the ids of those contacts |
612 // we should also check to see if the changes have invalidated any contact data, and add the ids of those contacts |
755 // to the change set. TODO! |
613 // to the change set. TODO! |
756 Q_UNUSED(changeSet); |
614 Q_UNUSED(changeSet); |
757 |
615 |
758 if (definitionId.isEmpty()) { |
616 if (definitionId.isEmpty()) { |
759 error = QContactManager::BadArgumentError; |
617 *error = QContactManager::BadArgumentError; |
760 return false; |
618 return false; |
761 } |
619 } |
762 |
620 |
763 detailDefinitions(contactType, error); // just to populate the definitions if we haven't already. |
621 detailDefinitions(contactType, error); // just to populate the definitions if we haven't already. |
764 QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType); |
622 QMap<QString, QContactDetailDefinition> defsForThisType = d->m_definitions.value(contactType); |
765 bool success = defsForThisType.remove(definitionId); |
623 bool success = defsForThisType.remove(definitionId); |
766 d->m_definitions.insert(contactType, defsForThisType); |
624 d->m_definitions.insert(contactType, defsForThisType); |
767 if (success) |
625 if (success) |
768 error = QContactManager::NoError; |
626 *error = QContactManager::NoError; |
769 else |
627 else |
770 error = QContactManager::DoesNotExistError; |
628 *error = QContactManager::DoesNotExistError; |
771 return success; |
629 return success; |
772 } |
630 } |
773 |
631 |
774 /*! \reimp */ |
632 /*! \reimp */ |
775 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactManager::Error& error) |
633 bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactManager::Error* error) |
776 { |
634 { |
777 QContactChangeSet changeSet; |
635 QContactChangeSet changeSet; |
778 bool retn = removeDetailDefinition(definitionId, contactType, changeSet, error); |
636 bool retn = removeDetailDefinition(definitionId, contactType, changeSet, error); |
779 changeSet.emitSignals(this); |
637 d->emitSharedSignals(&changeSet); |
780 return retn; |
638 return retn; |
781 } |
639 } |
782 |
640 |
783 /*! \reimp */ |
641 /*! \reimp */ |
784 void QContactMemoryEngine::requestDestroyed(QContactAbstractRequest* req) |
642 void QContactMemoryEngine::requestDestroyed(QContactAbstractRequest* req) |
785 { |
643 { |
786 d->m_asynchronousOperations.removeOne(req); |
644 Q_UNUSED(req); |
787 } |
645 } |
788 |
646 |
789 /*! \reimp */ |
647 /*! \reimp */ |
790 bool QContactMemoryEngine::startRequest(QContactAbstractRequest* req) |
648 bool QContactMemoryEngine::startRequest(QContactAbstractRequest* req) |
791 { |
649 { |
792 if (!d->m_asynchronousOperations.contains(req)) |
650 if (!req) |
793 d->m_asynchronousOperations.enqueue(req); |
651 return false; |
794 updateRequestState(req, QContactAbstractRequest::ActiveState); |
652 updateRequestState(req, QContactAbstractRequest::ActiveState); |
795 QTimer::singleShot(0, this, SLOT(performAsynchronousOperation())); |
653 performAsynchronousOperation(req); |
796 return true; |
654 return true; |
797 } |
655 } |
798 |
656 |
799 /*! \reimp */ |
657 /*! \reimp */ |
800 bool QContactMemoryEngine::cancelRequest(QContactAbstractRequest* req) |
658 bool QContactMemoryEngine::cancelRequest(QContactAbstractRequest* req) |
801 { |
659 { |
802 updateRequestState(req, QContactAbstractRequest::CanceledState); |
660 Q_UNUSED(req); // we can't cancel since we complete immediately |
|
661 return false; |
|
662 } |
|
663 |
|
664 /*! \reimp */ |
|
665 bool QContactMemoryEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs) |
|
666 { |
|
667 // in our implementation, we always complete any operation we start. |
|
668 Q_UNUSED(msecs); |
|
669 Q_UNUSED(req); |
|
670 |
803 return true; |
671 return true; |
804 } |
|
805 |
|
806 /*! This function is deprecated! Use QContactMemoryEngine::waitForRequestFinished() instead! |
|
807 Waits up to \a msecs milliseconds for the request \a req to emit the progress() signal. |
|
808 Returns true if the progress() signal was emitted during the period, otherwise false. |
|
809 */ |
|
810 bool QContactMemoryEngine::waitForRequestProgress(QContactAbstractRequest* req, int msecs) |
|
811 { |
|
812 Q_UNUSED(msecs); |
|
813 |
|
814 if (!d->m_asynchronousOperations.removeOne(req)) |
|
815 return false; // didn't exist. |
|
816 |
|
817 // replace at head of queue |
|
818 d->m_asynchronousOperations.insert(0, req); |
|
819 |
|
820 // and perform the operation. |
|
821 performAsynchronousOperation(); |
|
822 |
|
823 return true; |
|
824 } |
|
825 |
|
826 /*! \reimp */ |
|
827 bool QContactMemoryEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs) |
|
828 { |
|
829 // in our implementation, we always complete any operation we start. |
|
830 // so, waitForRequestFinished is equivalent to waitForRequestProgress. |
|
831 return waitForRequestProgress(req, msecs); |
|
832 } |
672 } |
833 |
673 |
834 /*! |
674 /*! |
835 * This slot is called some time after an asynchronous request is started. |
675 * This slot is called some time after an asynchronous request is started. |
836 * It performs the required operation, sets the result and returns. |
676 * It performs the required operation, sets the result and returns. |
837 */ |
677 */ |
838 void QContactMemoryEngine::performAsynchronousOperation() |
678 void QContactMemoryEngine::performAsynchronousOperation(QContactAbstractRequest *currentRequest) |
839 { |
679 { |
840 QContactAbstractRequest *currentRequest; |
|
841 |
|
842 // take the first pending request and finish it |
|
843 if (d->m_asynchronousOperations.isEmpty()) |
|
844 return; |
|
845 currentRequest = d->m_asynchronousOperations.dequeue(); |
|
846 |
|
847 // check to see if it is cancelling; if so, remove it from the queue and return. |
|
848 if (currentRequest->state() == QContactAbstractRequest::CanceledState) { |
|
849 return; |
|
850 } |
|
851 |
|
852 // store up changes, and emit signals once at the end of the (possibly batch) operation. |
680 // store up changes, and emit signals once at the end of the (possibly batch) operation. |
853 QContactChangeSet changeSet; |
681 QContactChangeSet changeSet; |
854 |
682 |
855 // Now perform the active request and emit required signals. |
683 // Now perform the active request and emit required signals. |
856 Q_ASSERT(currentRequest->state() == QContactAbstractRequest::ActiveState); |
684 Q_ASSERT(currentRequest->state() == QContactAbstractRequest::ActiveState); |
858 case QContactAbstractRequest::ContactFetchRequest: |
686 case QContactAbstractRequest::ContactFetchRequest: |
859 { |
687 { |
860 QContactFetchRequest* r = static_cast<QContactFetchRequest*>(currentRequest); |
688 QContactFetchRequest* r = static_cast<QContactFetchRequest*>(currentRequest); |
861 QContactFilter filter = r->filter(); |
689 QContactFilter filter = r->filter(); |
862 QList<QContactSortOrder> sorting = r->sorting(); |
690 QList<QContactSortOrder> sorting = r->sorting(); |
863 QStringList defs = r->definitionRestrictions(); |
691 QContactFetchHint fetchHint = r->fetchHint(); |
864 |
692 |
865 QContactManager::Error operationError; |
693 QContactManager::Error operationError; |
866 QList<QContact> requestedContacts = QContactManagerEngine::contacts(filter, sorting, defs, operationError); |
694 QList<QContact> requestedContacts = contacts(filter, sorting, fetchHint, &operationError); |
867 |
695 |
868 // update the request with the results. |
696 // update the request with the results. |
869 if (!requestedContacts.isEmpty() || operationError != QContactManager::NoError) |
697 if (!requestedContacts.isEmpty() || operationError != QContactManager::NoError) |
870 updateContactFetchRequest(r, requestedContacts, operationError); // emit resultsAvailable() |
698 updateContactFetchRequest(r, requestedContacts, operationError, QContactAbstractRequest::FinishedState); |
871 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
699 else |
|
700 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
872 } |
701 } |
873 break; |
702 break; |
874 |
703 |
875 case QContactAbstractRequest::ContactLocalIdFetchRequest: |
704 case QContactAbstractRequest::ContactLocalIdFetchRequest: |
876 { |
705 { |
877 QContactLocalIdFetchRequest* r = static_cast<QContactLocalIdFetchRequest*>(currentRequest); |
706 QContactLocalIdFetchRequest* r = static_cast<QContactLocalIdFetchRequest*>(currentRequest); |
878 QContactFilter filter = r->filter(); |
707 QContactFilter filter = r->filter(); |
879 QList<QContactSortOrder> sorting = r->sorting(); |
708 QList<QContactSortOrder> sorting = r->sorting(); |
880 |
709 |
881 QContactManager::Error operationError = QContactManager::NoError; |
710 QContactManager::Error operationError = QContactManager::NoError; |
882 QList<QContactLocalId> requestedContactIds = QContactManagerEngine::contactIds(filter, sorting, operationError); |
711 QList<QContactLocalId> requestedContactIds = contactIds(filter, sorting, &operationError); |
883 |
712 |
884 if (!requestedContactIds.isEmpty() || operationError != QContactManager::NoError) |
713 if (!requestedContactIds.isEmpty() || operationError != QContactManager::NoError) |
885 updateContactLocalIdFetchRequest(r, requestedContactIds, operationError); // emit resultsAvailable() |
714 updateContactLocalIdFetchRequest(r, requestedContactIds, operationError, QContactAbstractRequest::FinishedState); |
886 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
715 else |
|
716 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
887 } |
717 } |
888 break; |
718 break; |
889 |
719 |
890 case QContactAbstractRequest::ContactSaveRequest: |
720 case QContactAbstractRequest::ContactSaveRequest: |
891 { |
721 { |
892 QContactSaveRequest* r = static_cast<QContactSaveRequest*>(currentRequest); |
722 QContactSaveRequest* r = static_cast<QContactSaveRequest*>(currentRequest); |
893 QList<QContact> contacts = r->contacts(); |
723 QList<QContact> contacts = r->contacts(); |
894 |
724 |
895 QContactManager::Error operationError = QContactManager::NoError; |
725 QContactManager::Error operationError = QContactManager::NoError; |
896 QMap<int, QContactManager::Error> errorMap; |
726 QMap<int, QContactManager::Error> errorMap; |
897 saveContacts(&contacts, &errorMap, operationError); |
727 saveContacts(&contacts, &errorMap, &operationError); |
898 |
728 |
899 updateContactSaveRequest(r, contacts, operationError, errorMap); // there will always be results of some form. emit resultsAvailable(). |
729 updateContactSaveRequest(r, contacts, operationError, errorMap, QContactAbstractRequest::FinishedState); |
900 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
|
901 } |
730 } |
902 break; |
731 break; |
903 |
732 |
904 case QContactAbstractRequest::ContactRemoveRequest: |
733 case QContactAbstractRequest::ContactRemoveRequest: |
905 { |
734 { |
935 QContactManager::Error operationError = QContactManager::NoError; |
765 QContactManager::Error operationError = QContactManager::NoError; |
936 QMap<int, QContactManager::Error> errorMap; |
766 QMap<int, QContactManager::Error> errorMap; |
937 QMap<QString, QContactDetailDefinition> requestedDefinitions; |
767 QMap<QString, QContactDetailDefinition> requestedDefinitions; |
938 QStringList names = r->definitionNames(); |
768 QStringList names = r->definitionNames(); |
939 if (names.isEmpty()) |
769 if (names.isEmpty()) |
940 names = detailDefinitions(r->contactType(), operationError).keys(); // all definitions. |
770 names = detailDefinitions(r->contactType(), &operationError).keys(); // all definitions. |
941 |
771 |
942 QContactManager::Error tempError; |
772 QContactManager::Error tempError; |
943 for (int i = 0; i < names.size(); i++) { |
773 for (int i = 0; i < names.size(); i++) { |
944 QContactDetailDefinition current = detailDefinition(names.at(i), r->contactType(), tempError); |
774 QContactDetailDefinition current = detailDefinition(names.at(i), r->contactType(), &tempError); |
945 requestedDefinitions.insert(names.at(i), current); |
775 requestedDefinitions.insert(names.at(i), current); |
946 |
776 |
947 if (tempError != QContactManager::NoError) { |
777 if (tempError != QContactManager::NoError) { |
948 errorMap.insert(i, tempError); |
778 errorMap.insert(i, tempError); |
949 operationError = tempError; |
779 operationError = tempError; |
950 } |
780 } |
951 } |
781 } |
952 |
782 |
953 if (!errorMap.isEmpty() || !requestedDefinitions.isEmpty() || operationError != QContactManager::NoError) |
783 if (!errorMap.isEmpty() || !requestedDefinitions.isEmpty() || operationError != QContactManager::NoError) |
954 updateDefinitionFetchRequest(r, requestedDefinitions, operationError, errorMap); // emit resultsAvailable() |
784 updateDefinitionFetchRequest(r, requestedDefinitions, operationError, errorMap, QContactAbstractRequest::FinishedState); |
955 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
785 else |
|
786 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
956 } |
787 } |
957 break; |
788 break; |
958 |
789 |
959 case QContactAbstractRequest::DetailDefinitionSaveRequest: |
790 case QContactAbstractRequest::DetailDefinitionSaveRequest: |
960 { |
791 { |
990 QContactManager::Error operationError = QContactManager::NoError; |
820 QContactManager::Error operationError = QContactManager::NoError; |
991 QMap<int, QContactManager::Error> errorMap; |
821 QMap<int, QContactManager::Error> errorMap; |
992 |
822 |
993 for (int i = 0; i < names.size(); i++) { |
823 for (int i = 0; i < names.size(); i++) { |
994 QContactManager::Error tempError; |
824 QContactManager::Error tempError; |
995 removeDetailDefinition(names.at(i), r->contactType(), changeSet, tempError); |
825 removeDetailDefinition(names.at(i), r->contactType(), changeSet, &tempError); |
996 |
826 |
997 if (tempError != QContactManager::NoError) { |
827 if (tempError != QContactManager::NoError) { |
998 errorMap.insert(i, tempError); |
828 errorMap.insert(i, tempError); |
999 operationError = tempError; |
829 operationError = tempError; |
1000 } |
830 } |
1001 } |
831 } |
1002 |
832 |
1003 // there are no results, so just update the status with the error. |
833 // there are no results, so just update the status with the error. |
1004 updateDefinitionRemoveRequest(r, operationError, errorMap); // emit resultsAvailable() |
834 updateDefinitionRemoveRequest(r, operationError, errorMap, QContactAbstractRequest::FinishedState); |
1005 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
|
1006 } |
835 } |
1007 break; |
836 break; |
1008 |
837 |
1009 case QContactAbstractRequest::RelationshipFetchRequest: |
838 case QContactAbstractRequest::RelationshipFetchRequest: |
1010 { |
839 { |
1011 QContactRelationshipFetchRequest* r = static_cast<QContactRelationshipFetchRequest*>(currentRequest); |
840 QContactRelationshipFetchRequest* r = static_cast<QContactRelationshipFetchRequest*>(currentRequest); |
1012 QContactManager::Error operationError = QContactManager::NoError; |
841 QContactManager::Error operationError = QContactManager::NoError; |
1013 QList<QContactManager::Error> operationErrors; |
842 QList<QContactManager::Error> operationErrors; |
1014 QList<QContactRelationship> allRelationships = relationships(QString(), QContactId(), QContactRelationshipFilter::Either, operationError); |
843 QList<QContactRelationship> allRelationships = relationships(QString(), QContactId(), QContactRelationship::Either, &operationError); |
1015 QList<QContactRelationship> requestedRelationships; |
844 QList<QContactRelationship> requestedRelationships; |
1016 |
845 |
1017 // select the requested relationships. |
846 // select the requested relationships. |
1018 for (int i = 0; i < allRelationships.size(); i++) { |
847 for (int i = 0; i < allRelationships.size(); i++) { |
1019 QContactRelationship currRel = allRelationships.at(i); |
848 QContactRelationship currRel = allRelationships.at(i); |
1026 requestedRelationships.append(currRel); |
855 requestedRelationships.append(currRel); |
1027 } |
856 } |
1028 |
857 |
1029 // update the request with the results. |
858 // update the request with the results. |
1030 if (!requestedRelationships.isEmpty() || operationError != QContactManager::NoError) |
859 if (!requestedRelationships.isEmpty() || operationError != QContactManager::NoError) |
1031 updateRelationshipFetchRequest(r, requestedRelationships, operationError); // emit resultsAvailable() |
860 updateRelationshipFetchRequest(r, requestedRelationships, operationError, QContactAbstractRequest::FinishedState); |
1032 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
861 else |
|
862 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
1033 } |
863 } |
1034 break; |
864 break; |
1035 |
865 |
1036 case QContactAbstractRequest::RelationshipRemoveRequest: |
866 case QContactAbstractRequest::RelationshipRemoveRequest: |
1037 { |
867 { |
1038 QContactRelationshipRemoveRequest* r = static_cast<QContactRelationshipRemoveRequest*>(currentRequest); |
868 QContactRelationshipRemoveRequest* r = static_cast<QContactRelationshipRemoveRequest*>(currentRequest); |
1039 QContactManager::Error operationError = QContactManager::NoError; |
869 QContactManager::Error operationError = QContactManager::NoError; |
1040 QList<QContactRelationship> relationshipsToRemove = r->relationships(); |
870 QList<QContactRelationship> relationshipsToRemove = r->relationships(); |
1041 QMap<int, QContactManager::Error> errorMap; |
871 QMap<int, QContactManager::Error> errorMap; |
1042 |
872 |
1043 bool foundMatch = false; |
873 removeRelationships(r->relationships(), &errorMap, &operationError); |
1044 for (int i = 0; i < relationshipsToRemove.size(); i++) { |
|
1045 QContactManager::Error tempError; |
|
1046 removeRelationship(relationshipsToRemove.at(i), tempError); |
|
1047 |
|
1048 if (tempError != QContactManager::NoError) { |
|
1049 errorMap.insert(i, tempError); |
|
1050 operationError = tempError; |
|
1051 } |
|
1052 } |
|
1053 |
|
1054 if (foundMatch == false && operationError == QContactManager::NoError) |
|
1055 operationError = QContactManager::DoesNotExistError; |
|
1056 |
874 |
1057 if (!errorMap.isEmpty() || operationError != QContactManager::NoError) |
875 if (!errorMap.isEmpty() || operationError != QContactManager::NoError) |
1058 updateRelationshipRemoveRequest(r, operationError, errorMap); // emit resultsAvailable() |
876 updateRelationshipRemoveRequest(r, operationError, errorMap, QContactAbstractRequest::FinishedState); |
1059 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
877 else |
|
878 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
1060 } |
879 } |
1061 break; |
880 break; |
1062 |
881 |
1063 case QContactAbstractRequest::RelationshipSaveRequest: |
882 case QContactAbstractRequest::RelationshipSaveRequest: |
1064 { |
883 { |
1065 QContactRelationshipSaveRequest* r = static_cast<QContactRelationshipSaveRequest*>(currentRequest); |
884 QContactRelationshipSaveRequest* r = static_cast<QContactRelationshipSaveRequest*>(currentRequest); |
1066 QContactManager::Error operationError = QContactManager::NoError; |
885 QContactManager::Error operationError = QContactManager::NoError; |
1067 QMap<int, QContactManager::Error> errorMap; |
886 QMap<int, QContactManager::Error> errorMap; |
1068 QList<QContactRelationship> requestRelationships = r->relationships(); |
887 QList<QContactRelationship> requestRelationships = r->relationships(); |
1069 QList<QContactRelationship> savedRelationships; |
888 |
1070 |
889 saveRelationships(&requestRelationships, &errorMap, &operationError); |
1071 QContactManager::Error tempError; |
|
1072 for (int i = 0; i < requestRelationships.size(); i++) { |
|
1073 QContactRelationship current = requestRelationships.at(i); |
|
1074 saveRelationship(¤t, tempError); |
|
1075 savedRelationships.append(current); |
|
1076 |
|
1077 if (tempError != QContactManager::NoError) { |
|
1078 errorMap.insert(i, tempError); |
|
1079 operationError = tempError; |
|
1080 } |
|
1081 } |
|
1082 |
890 |
1083 // update the request with the results. |
891 // update the request with the results. |
1084 updateRelationshipSaveRequest(r, savedRelationships, operationError, errorMap); // there will always be results of some form. emit resultsAvailable(). |
892 updateRelationshipSaveRequest(r, requestRelationships, operationError, errorMap, QContactAbstractRequest::FinishedState); |
1085 updateRequestState(currentRequest, QContactAbstractRequest::FinishedState); |
|
1086 } |
893 } |
1087 break; |
894 break; |
1088 |
895 |
1089 default: // unknown request type. |
896 default: // unknown request type. |
1090 break; |
897 break; |
1091 } |
898 } |
1092 |
899 |
1093 // now emit any signals we have to emit |
900 // now emit any signals we have to emit |
1094 changeSet.emitSignals(this); |
901 d->emitSharedSignals(&changeSet); |
1095 } |
902 } |
1096 |
903 |
1097 /*! |
904 /*! |
1098 * \reimp |
905 * \reimp |
1099 */ |
906 */ |