66 * - Voice subtype for phone, don't always assume |
66 * - Voice subtype for phone, don't always assume |
67 * - Address formatting - PIMPR_HOME_ADDRESS seems to be read only |
67 * - Address formatting - PIMPR_HOME_ADDRESS seems to be read only |
68 */ |
68 */ |
69 |
69 |
70 |
70 |
71 QContactWinCEEngine::QContactWinCEEngine(ContactWinceFactory* factory, const QString& engineName, const QMap<QString, QString>& , QContactManager::Error& error) |
71 QContactWinCEEngine::QContactWinCEEngine(ContactWinceFactory* factory, const QString& engineName, const QMap<QString, QString>& , QContactManager::Error* error) |
72 : d(new QContactWinCEEngineData) |
72 : d(new QContactWinCEEngineData) |
73 { |
73 { |
74 error = QContactManager::NoError; |
74 *error = QContactManager::NoError; |
75 |
75 |
76 buildHashForContactDetailToPoomPropId(); |
76 buildHashForContactDetailToPoomPropId(); |
77 d->m_engineName = engineName; |
77 d->m_engineName = engineName; |
78 d->m_factory = factory; |
78 d->m_factory = factory; |
79 if (SUCCEEDED(d->m_cominit.hr())) { |
79 if (SUCCEEDED(d->m_cominit.hr())) { |
135 d->m_app->Logoff(); |
135 d->m_app->Logoff(); |
136 } |
136 } |
137 d->m_factory->resetEngine(); |
137 d->m_factory->resetEngine(); |
138 } |
138 } |
139 |
139 |
140 void QContactWinCEEngine::deref() |
|
141 { |
|
142 if (!d->m_refCount.deref()) |
|
143 delete this; |
|
144 } |
|
145 |
|
146 QString QContactWinCEEngine::managerName() const |
140 QString QContactWinCEEngine::managerName() const |
147 { |
141 { |
148 return d->m_engineName; |
142 return d->m_engineName; |
149 } |
143 } |
150 |
144 |
151 QContact QContactWinCEEngine::contact(const QContactLocalId& contactId, const QStringList& definitionRestrictions, QContactManager::Error& error) const |
145 QContact QContactWinCEEngine::contact(const QContactLocalId& contactId, const QtMobility::QContactFetchHint& hint, QContactManager::Error* error) const |
152 { |
146 { |
153 // TODO: implementation for definitionRestrictions! |
147 // TODO: implementation for definitionRestrictions! |
154 Q_UNUSED(definitionRestrictions); |
148 Q_UNUSED(hint); |
155 QContact ret; |
149 QContact ret; |
156 |
150 |
157 // id == 0 gives a bad argument error from POOM, so don't even try it |
151 // id == 0 gives a bad argument error from POOM, so don't even try it |
158 if (contactId != 0) { |
152 if (contactId != 0) { |
159 // Fetch! |
153 // Fetch! |
160 SimpleComPointer<IItem> item = 0; |
154 SimpleComPointer<IItem> item = 0; |
161 HRESULT hr = d->m_app->GetItemFromOidEx(contactId, 0, &item); |
155 HRESULT hr = d->m_app->GetItemFromOidEx(contactId, 0, &item); |
162 if (SUCCEEDED(hr)) { |
156 if (SUCCEEDED(hr)) { |
163 if (item) { |
157 if (item) { |
164 error = QContactManager::NoError; |
158 *error = QContactManager::NoError; |
165 ret = convertToQContact(item); |
159 ret = convertToQContact(item); |
166 } else { |
160 } else { |
167 error = QContactManager::DoesNotExistError; |
161 *error = QContactManager::DoesNotExistError; |
168 } |
162 } |
169 } else { |
163 } else { |
170 if (HRESULT_CODE(hr) == ERROR_NOT_FOUND) { |
164 if (HRESULT_CODE(hr) == ERROR_NOT_FOUND) { |
171 error = QContactManager::DoesNotExistError; |
165 *error = QContactManager::DoesNotExistError; |
172 } else { |
166 } else { |
173 qWarning() << "Failed to retrieve contact:" << HRESULT_CODE(hr); |
167 qWarning() << "Failed to retrieve contact:" << HRESULT_CODE(hr); |
174 error = QContactManager::UnspecifiedError; |
168 *error = QContactManager::UnspecifiedError; |
175 } |
169 } |
176 } |
170 } |
177 } else { |
171 } else { |
178 error = QContactManager::DoesNotExistError; |
172 *error = QContactManager::DoesNotExistError; |
179 } |
173 } |
180 return ret; |
174 return ret; |
181 } |
175 } |
182 |
176 |
183 bool QContactWinCEEngine::saveContact(QContact* contact, QContactManager::Error& error) |
177 bool QContactWinCEEngine::saveContact(QContact* contact, QContactManager::Error* error) |
184 { |
178 { |
185 if (contact == 0) { |
179 if (contact == 0) { |
186 error = QContactManager::BadArgumentError; |
180 *error = QContactManager::BadArgumentError; |
187 return false; |
181 return false; |
188 } |
182 } |
189 |
183 |
190 QContactChangeSet cs; |
184 QContactChangeSet cs; |
191 |
185 |
192 // ensure that the contact's details conform to their definitions |
186 // ensure that the contact's details conform to their definitions |
193 if (!validateContact(*contact, error)) { |
187 if (!validateContact(*contact, error)) { |
194 error = QContactManager::InvalidDetailError; |
188 *error = QContactManager::InvalidDetailError; |
195 return false; |
189 return false; |
196 } |
190 } |
197 |
191 |
198 SimpleComPointer<IItem> icontact; |
192 SimpleComPointer<IItem> icontact; |
199 bool wasOld = false; |
193 bool wasOld = false; |
204 if (SUCCEEDED(hr)) { |
198 if (SUCCEEDED(hr)) { |
205 wasOld = true; |
199 wasOld = true; |
206 } else { |
200 } else { |
207 if (HRESULT_CODE(hr) == ERROR_NOT_FOUND) { |
201 if (HRESULT_CODE(hr) == ERROR_NOT_FOUND) { |
208 // Well, doesn't exist any more |
202 // Well, doesn't exist any more |
209 error = QContactManager::DoesNotExistError; |
203 *error = QContactManager::DoesNotExistError; |
210 d->m_ids.removeAll(contact->localId()); |
204 d->m_ids.removeAll(contact->localId()); |
211 } else { |
205 } else { |
212 qWarning() << "Didn't get old contact" << HRESULT_CODE(hr); |
206 qWarning() << "Didn't get old contact" << HRESULT_CODE(hr); |
213 error = QContactManager::UnspecifiedError; |
207 *error = QContactManager::UnspecifiedError; |
214 } |
208 } |
215 } |
209 } |
216 } else if (contact->localId() == 0) { |
210 } else if (contact->localId() == 0) { |
217 // new contact! |
211 // new contact! |
218 SimpleComPointer<IDispatch> idisp = 0; |
212 SimpleComPointer<IDispatch> idisp = 0; |
222 hr = idisp->QueryInterface<IItem>(&icontact); |
216 hr = idisp->QueryInterface<IItem>(&icontact); |
223 |
217 |
224 if (SUCCEEDED(hr)) { |
218 if (SUCCEEDED(hr)) { |
225 } else { |
219 } else { |
226 qWarning() << "Failed to query interface" << HRESULT_CODE(hr); |
220 qWarning() << "Failed to query interface" << HRESULT_CODE(hr); |
227 error = QContactManager::UnspecifiedError; |
221 *error = QContactManager::UnspecifiedError; |
228 } |
222 } |
229 } else { |
223 } else { |
230 qWarning() << "Failed to create contact: "<< HRESULT_CODE(hr); |
224 qWarning() << "Failed to create contact: "<< HRESULT_CODE(hr); |
231 error = QContactManager::OutOfMemoryError; |
225 *error = QContactManager::OutOfMemoryError; |
232 } |
226 } |
233 } else { |
227 } else { |
234 // Saving a contact with a non zero id, but that doesn't exist |
228 // Saving a contact with a non zero id, but that doesn't exist |
235 error = QContactManager::DoesNotExistError; |
229 *error = QContactManager::DoesNotExistError; |
236 } |
230 } |
237 |
231 |
238 if (icontact) { |
232 if (icontact) { |
239 // Convert our QContact to the Icontact (via setProps) |
233 // Convert our QContact to the Icontact (via setProps) |
240 if (convertFromQContact(*contact, icontact, error)) { |
234 if (convertFromQContact(*contact, icontact, *error)) { |
241 HRESULT hr = icontact->Save(); |
235 HRESULT hr = icontact->Save(); |
242 if (SUCCEEDED(hr)) { |
236 if (SUCCEEDED(hr)) { |
243 // yay! we also need to set the new contact id |
237 // yay! we also need to set the new contact id |
244 long oid = 0; |
238 long oid = 0; |
245 hr = icontact->get_Oid(&oid); |
239 hr = icontact->get_Oid(&oid); |
246 if (SUCCEEDED(hr)) { |
240 if (SUCCEEDED(hr)) { |
247 error = QContactManager::NoError; |
241 *error = QContactManager::NoError; |
248 QContact c = this->contact((QContactLocalId)oid, QStringList(), error); |
242 QContact c = this->contact((QContactLocalId)oid, QContactFetchHint(), error); |
249 |
243 |
250 if (error == QContactManager::NoError) { |
244 if (*error == QContactManager::NoError) { |
251 *contact = c; |
245 *contact = c; |
252 if (wasOld) { |
246 if (wasOld) { |
253 cs.changedContacts().insert(contact->localId()); |
247 cs.insertChangedContact(contact->localId()); |
254 } else { |
248 } else { |
255 cs.addedContacts().insert(contact->localId()); |
249 cs.insertAddedContact(contact->localId()); |
256 d->m_ids.append(contact->localId()); |
250 d->m_ids.append(contact->localId()); |
257 } |
251 } |
258 } |
252 } |
259 |
253 |
260 cs.emitSignals(this); |
254 cs.emitSignals(this); |
261 return true; |
255 return true; |
262 } |
256 } |
263 qWarning() << "Saved contact, but couldn't retrieve id again??" << HRESULT_CODE(hr); |
257 qWarning() << "Saved contact, but couldn't retrieve id again??" << HRESULT_CODE(hr); |
264 // Blargh. |
258 // Blargh. |
265 error = QContactManager::UnspecifiedError; |
259 *error = QContactManager::UnspecifiedError; |
266 } else { |
260 } else { |
267 qWarning() << "Failed to save contact" << HRESULT_CODE(hr); |
261 qWarning() << "Failed to save contact" << HRESULT_CODE(hr); |
268 } |
262 } |
269 } else { |
263 } else { |
270 qWarning() << "Failed to convert contact"; |
264 qWarning() << "Failed to convert contact"; |
273 |
267 |
274 // error should have been set. |
268 // error should have been set. |
275 return false; |
269 return false; |
276 } |
270 } |
277 |
271 |
278 bool QContactWinCEEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error& error) |
272 bool QContactWinCEEngine::removeContact(const QContactLocalId& contactId, QContactManager::Error* error) |
279 { |
273 { |
280 // Fetch an IItem* for this |
274 // Fetch an IItem* for this |
281 if (contactId != 0) { |
275 if (contactId != 0) { |
282 SimpleComPointer<IItem> item ; |
276 SimpleComPointer<IItem> item ; |
283 QContactChangeSet cs; |
277 QContactChangeSet cs; |
284 |
278 |
285 HRESULT hr = d->m_app->GetItemFromOidEx(contactId, 0, &item); |
279 HRESULT hr = d->m_app->GetItemFromOidEx(contactId, 0, &item); |
286 if (SUCCEEDED(hr)) { |
280 if (SUCCEEDED(hr)) { |
287 hr = item->Delete(); |
281 hr = item->Delete(); |
288 if (SUCCEEDED(hr)) { |
282 if (SUCCEEDED(hr)) { |
289 error = QContactManager::NoError; |
283 *error = QContactManager::NoError; |
290 d->m_ids.removeAll(contactId); |
284 d->m_ids.removeAll(contactId); |
291 cs.removedContacts().insert(contactId); |
285 cs.insertRemovedContact(contactId); |
292 cs.emitSignals(this); |
286 cs.emitSignals(this); |
293 return true; |
287 return true; |
294 } |
288 } |
295 qWarning() << "Failed to delete:" << HRESULT_CODE(hr); |
289 qWarning() << "Failed to delete:" << HRESULT_CODE(hr); |
296 error = QContactManager::UnspecifiedError; |
290 *error = QContactManager::UnspecifiedError; |
297 } else { |
291 } else { |
298 if (HRESULT_CODE(hr) == ERROR_NOT_FOUND) { |
292 if (HRESULT_CODE(hr) == ERROR_NOT_FOUND) { |
299 error = QContactManager::DoesNotExistError; |
293 *error = QContactManager::DoesNotExistError; |
300 } else { |
294 } else { |
301 qWarning() << "Failed to retrieve item pointer in delete" << HRESULT_CODE(hr); |
295 qWarning() << "Failed to retrieve item pointer in delete" << HRESULT_CODE(hr); |
302 error = QContactManager::UnspecifiedError; |
296 *error = QContactManager::UnspecifiedError; |
303 } |
297 } |
304 } |
298 } |
305 } else { |
299 } else { |
306 // Id 0 does not exist |
300 // Id 0 does not exist |
307 error = QContactManager::DoesNotExistError; |
301 *error = QContactManager::DoesNotExistError; |
308 } |
302 } |
309 return false; |
303 return false; |
310 } |
304 } |
311 |
305 |
312 QMap<QString, QContactDetailDefinition> QContactWinCEEngine::detailDefinitions(const QString& contactType, QContactManager::Error& error) const |
306 QMap<QString, QContactDetailDefinition> QContactWinCEEngine::detailDefinitions(const QString& contactType, QContactManager::Error* error) const |
313 { |
307 { |
314 error = QContactManager::NoError; |
308 *error = QContactManager::NoError; |
315 QMap<QString, QMap<QString, QContactDetailDefinition> > defns = QContactManagerEngine::schemaDefinitions(); |
309 QMap<QString, QMap<QString, QContactDetailDefinition> > defns = QContactManagerEngine::schemaDefinitions(); |
316 |
310 |
317 // Remove the details we don't support |
311 // Remove the details we don't support |
318 defns[contactType].remove(QContactSyncTarget::DefinitionName); |
312 defns[contactType].remove(QContactSyncTarget::DefinitionName); |
319 defns[contactType].remove(QContactGeoLocation::DefinitionName); |
313 defns[contactType].remove(QContactGeoLocation::DefinitionName); |
328 fields.remove(QContactAnniversary::FieldSubType); |
322 fields.remove(QContactAnniversary::FieldSubType); |
329 defns[contactType][QContactAnniversary::DefinitionName].setFields(fields); |
323 defns[contactType][QContactAnniversary::DefinitionName].setFields(fields); |
330 |
324 |
331 // No logo for organisation |
325 // No logo for organisation |
332 fields = defns[contactType][QContactOrganization::DefinitionName].fields(); |
326 fields = defns[contactType][QContactOrganization::DefinitionName].fields(); |
333 fields.remove(QContactOrganization::FieldLogo); |
327 fields.remove(QContactOrganization::FieldLogoUrl); |
334 defns[contactType][QContactOrganization::DefinitionName].setFields(fields); |
328 defns[contactType][QContactOrganization::DefinitionName].setFields(fields); |
335 |
329 |
336 // No subtypes for these details |
330 // No subtypes for these details |
337 fields = defns[contactType][QContactUrl::DefinitionName].fields(); |
331 fields = defns[contactType][QContactUrl::DefinitionName].fields(); |
338 fields.remove(QContactUrl::FieldSubType); |
332 fields.remove(QContactUrl::FieldSubType); |
390 { |
384 { |
391 return d->m_requestWorker.waitRequest(req, msecs) && req->isFinished(); |
385 return d->m_requestWorker.waitRequest(req, msecs) && req->isFinished(); |
392 } |
386 } |
393 |
387 |
394 /*! \reimp */ |
388 /*! \reimp */ |
395 bool QContactWinCEEngine::hasFeature(QContactManager::ManagerFeature feature) const |
389 bool QContactWinCEEngine::hasFeature(QContactManager::ManagerFeature feature, const QString& contactType) const |
396 { |
390 { |
|
391 Q_UNUSED(contactType); |
397 // The Windows CE backend is an "isolated" backend |
392 // The Windows CE backend is an "isolated" backend |
398 if (feature == QContactManager::Anonymous) |
393 if (feature == QContactManager::Anonymous) |
399 return true; |
394 return true; |
400 |
395 |
401 // Windows CE backend does not support Mutable Definitions, Relationships or Action Preferences |
396 // Windows CE backend does not support Mutable Definitions, Relationships or Action Preferences |
402 return false; |
397 return false; |
403 } |
398 } |
404 |
399 |
405 /* Synthesise the display label of a contact */ |
400 /* Synthesise the display label of a contact */ |
406 QString QContactWinCEEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error& error) const |
401 QString QContactWinCEEngine::synthesizedDisplayLabel(const QContact& contact, QContactManager::Error* error) const |
407 { |
402 { |
408 Q_UNUSED(error) |
403 Q_UNUSED(error) |
409 // The POOM API (well, lack thereof) makes this a bit strange. |
404 // The POOM API (well, lack thereof) makes this a bit strange. |
410 // It's basically just "Last, First" or "Company", if "FileAs" is not set. |
405 // It's basically just "Last, First" or "Company", if "FileAs" is not set. |
411 QContactName name = contact.detail<QContactName>(); |
406 QContactName name = contact.detail<QContactName>(); |
472 case QContactFilter::UnionFilter: |
467 case QContactFilter::UnionFilter: |
473 return true; |
468 return true; |
474 } |
469 } |
475 return false; |
470 return false; |
476 } |
471 } |
|
472 |
|
473 /*! \reimp */ |
|
474 QMap<QString, QString> QContactWinCEEngine::managerParameters() const |
|
475 { |
|
476 return QMap<QString, QString>(); |
|
477 } |
|
478 |
|
479 /*! \reimp */ |
|
480 int QContactWinCEEngine::managerVersion() const |
|
481 { |
|
482 return QTCONTACTS_VERSION; |
|
483 } |
|
484 |
|
485 /*! \reimp */ |
|
486 QList<QContact> QContactWinCEEngine::contacts(const QContactFilter& filter, const QList<QContactSortOrder>& sortOrders, const QContactFetchHint& fetchHint, QContactManager::Error* error) const |
|
487 { |
|
488 QList<QContactLocalId> ids = contactIds(filter, sortOrders, error); |
|
489 QList<QContact> cs; |
|
490 if (*error == QContactManager::NoError) { |
|
491 foreach (const QContactLocalId& id, ids) { |
|
492 cs << contact(id, fetchHint, error); |
|
493 } |
|
494 } |
|
495 return cs; |
|
496 } |
|
497 |
|
498 /*! \reimp */ |
|
499 bool QContactWinCEEngine::saveRelationship(QContactRelationship* relationship, QContactManager::Error* error) |
|
500 { |
|
501 Q_UNUSED(relationship); |
|
502 *error = QContactManager::NotSupportedError; |
|
503 return false; |
|
504 } |
|
505 |
|
506 /*! \reimp */ |
|
507 bool QContactWinCEEngine::removeRelationship(const QContactRelationship& relationship, QContactManager::Error* error) |
|
508 { |
|
509 Q_UNUSED(relationship); |
|
510 *error = QContactManager::NotSupportedError; |
|
511 return false; |
|
512 } |
|
513 |
|
514 /*! \reimp */ |
|
515 bool QContactWinCEEngine::saveContacts(QList<QContact>* contacts, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
516 { |
|
517 bool ret = true; |
|
518 |
|
519 for (int j = 0; j < contacts->size(); j++) { |
|
520 if (!saveContact(&((*contacts)[j]), error)) { |
|
521 ret = false; |
|
522 } |
|
523 if (*error != QContactManager::NoError) { |
|
524 errorMap->insert(j, *error); |
|
525 } |
|
526 } |
|
527 return ret; |
|
528 } |
|
529 |
|
530 /*! \reimp */ |
|
531 bool QContactWinCEEngine::removeContacts(const QList<QContactLocalId>& contactIds, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
532 { |
|
533 bool ret = true; |
|
534 |
|
535 for (int j = 0; j < contactIds.size(); j++) { |
|
536 if (!removeContact(contactIds[j], error)) { |
|
537 ret = false; |
|
538 } |
|
539 |
|
540 if (*error != QContactManager::NoError) { |
|
541 errorMap->insert(j, *error); |
|
542 } |
|
543 } |
|
544 return ret; |
|
545 } |
|
546 |
|
547 /*! \reimp */ |
|
548 bool QContactWinCEEngine::setSelfContactId(const QContactLocalId& contactId, QContactManager::Error* error) |
|
549 { |
|
550 Q_UNUSED(contactId); |
|
551 *error = QContactManager::NotSupportedError; |
|
552 return false; |
|
553 } |
|
554 |
|
555 /*! \reimp */ |
|
556 QContactLocalId QContactWinCEEngine::selfContactId(QContactManager::Error* error) const |
|
557 { |
|
558 *error = QContactManager::NotSupportedError; |
|
559 return QContactLocalId(); |
|
560 } |
|
561 |
|
562 /*! \reimp */ |
|
563 QList<QContactRelationship> QContactWinCEEngine::relationships(const QString& relationshipType, const QContactId& participantId, QContactRelationship::Role role, QContactManager::Error* error) const |
|
564 { |
|
565 Q_UNUSED(relationshipType); |
|
566 Q_UNUSED(participantId); |
|
567 Q_UNUSED(role); |
|
568 *error = QContactManager::NotSupportedError; |
|
569 return QList<QContactRelationship>(); |
|
570 } |
|
571 |
|
572 /*! \reimp */ |
|
573 bool QContactWinCEEngine::saveRelationships(QList<QContactRelationship>* relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
574 { |
|
575 Q_UNUSED(relationships); |
|
576 Q_UNUSED(errorMap); |
|
577 *error = QContactManager::NotSupportedError; |
|
578 return false; |
|
579 } |
|
580 |
|
581 /*! \reimp */ |
|
582 bool QContactWinCEEngine::removeRelationships(const QList<QContactRelationship>& relationships, QMap<int, QContactManager::Error>* errorMap, QContactManager::Error* error) |
|
583 { |
|
584 Q_UNUSED(relationships); |
|
585 Q_UNUSED(errorMap); |
|
586 *error = QContactManager::NotSupportedError; |
|
587 return false; |
|
588 } |
|
589 |
|
590 /*! \reimp */ |
|
591 bool QContactWinCEEngine::saveDetailDefinition(const QContactDetailDefinition& def, const QString& contactType, QContactManager::Error* error) |
|
592 { |
|
593 Q_UNUSED(def); |
|
594 Q_UNUSED(contactType); |
|
595 *error = QContactManager::NotSupportedError; |
|
596 return false; |
|
597 } |
|
598 |
|
599 /*! \reimp */ |
|
600 bool QContactWinCEEngine::removeDetailDefinition(const QString& definitionId, const QString& contactType, QContactManager::Error* error) |
|
601 { |
|
602 Q_UNUSED(definitionId); |
|
603 Q_UNUSED(contactType); |
|
604 *error = QContactManager::NotSupportedError; |
|
605 return false; |
|
606 } |
|
607 |
477 /*! |
608 /*! |
478 * Returns the list of data types supported by the WinCE engine |
609 * Returns the list of data types supported by the WinCE engine |
479 */ |
610 */ |
480 QList<QVariant::Type> QContactWinCEEngine::supportedDataTypes() const |
611 QList<QVariant::Type> QContactWinCEEngine::supportedDataTypes() const |
481 { |
612 { |