83 d->m_simStore = new CntSimStore(this, parameters.value(KParameterKeySimStoreName), error); |
93 d->m_simStore = new CntSimStore(this, parameters.value(KParameterKeySimStoreName), error); |
84 if (*error != QContactManager::NoError) { |
94 if (*error != QContactManager::NoError) { |
85 //qDebug() << "Failed to open SIM store" << error; |
95 //qDebug() << "Failed to open SIM store" << error; |
86 return; |
96 return; |
87 } |
97 } |
88 |
98 |
89 if(d->m_simStore->storeName() == KParameterValueSimStoreNameSdn) { |
99 // Get phone number match length from cenrep |
|
100 d->m_phoneNumberMatchLen = KDefaultMatchLength; |
|
101 TRAP_IGNORE(getMatchLengthL(d->m_phoneNumberMatchLen)); // ignore error and use default value |
|
102 |
|
103 if(d->m_simStore->storeInfo().m_storeName == KParameterValueSimStoreNameSdn) { |
90 // In case of SDN store we need to check if any SDN contacts exist to |
104 // In case of SDN store we need to check if any SDN contacts exist to |
91 // determine if the store is supported or not |
105 // determine if the store is supported or not |
92 if(d->m_simStore->storeInfo().iUsedEntries == 0) |
106 if(d->m_simStore->storeInfo().m_usedEntries == 0) |
93 *error = QContactManager::NotSupportedError; |
107 *error = QContactManager::NotSupportedError; |
94 } |
108 } |
95 } |
109 } |
96 |
110 |
97 CntSymbianSimEngine::CntSymbianSimEngine(const CntSymbianSimEngine &other) |
111 CntSymbianSimEngine::CntSymbianSimEngine(const CntSymbianSimEngine &other) |
220 *error = QContactManager::NotSupportedError; |
233 *error = QContactManager::NotSupportedError; |
221 return QMap<QString, QContactDetailDefinition>(); |
234 return QMap<QString, QContactDetailDefinition>(); |
222 } |
235 } |
223 |
236 |
224 // Get store information |
237 // Get store information |
225 TSimStoreInfo storeInfo = d->m_simStore->storeInfo(); |
238 SimStoreInfo storeInfo = d->m_simStore->storeInfo(); |
226 |
239 |
227 // the map we will eventually return |
240 // the map we will eventually return |
228 QMap<QString, QContactDetailDefinition> retn; |
241 QMap<QString, QContactDetailDefinition> retn; |
229 |
242 |
230 // local variables for reuse |
243 // local variables for reuse |
283 def.setFields(fields); |
296 def.setFields(fields); |
284 def.setUnique(true); |
297 def.setUnique(true); |
285 retn.insert(def.name(), def); |
298 retn.insert(def.name(), def); |
286 |
299 |
287 // email support needs to be checked run-time, because it is SIM specific |
300 // email support needs to be checked run-time, because it is SIM specific |
288 #ifndef SYMBIANSIM_BACKEND_PHONEBOOKINFOV1 |
301 if (storeInfo.m_emailSupported) { |
289 if (storeInfo.iMaxEmailAddr > 0) { |
|
290 def.setName(QContactEmailAddress::DefinitionName); |
302 def.setName(QContactEmailAddress::DefinitionName); |
291 fields.clear(); |
303 fields.clear(); |
292 f.setDataType(QVariant::String); |
304 f.setDataType(QVariant::String); |
293 f.setAllowableValues(QVariantList()); |
305 f.setAllowableValues(QVariantList()); |
294 fields.insert(QContactEmailAddress::FieldEmailAddress, f); |
306 fields.insert(QContactEmailAddress::FieldEmailAddress, f); |
295 def.setFields(fields); |
307 def.setFields(fields); |
296 def.setUnique(true); |
308 def.setUnique(true); |
297 retn.insert(def.name(), def); |
309 retn.insert(def.name(), def); |
298 } |
310 } |
299 #endif |
|
300 |
311 |
301 // phone number |
312 // phone number |
302 def.setName(QContactPhoneNumber::DefinitionName); |
313 def.setName(QContactPhoneNumber::DefinitionName); |
303 fields.clear(); |
314 fields.clear(); |
304 f.setDataType(QVariant::String); |
315 f.setDataType(QVariant::String); |
305 f.setAllowableValues(QVariantList()); |
316 f.setAllowableValues(QVariantList()); |
306 fields.insert(QContactPhoneNumber::FieldNumber, f); |
317 fields.insert(QContactPhoneNumber::FieldNumber, f); |
307 // TODO: subtypes supported in case a sim contact can have multiple phone numbers? |
318 // TODO: subtypes supported in case a sim contact can have multiple phone numbers? |
308 def.setFields(fields); |
319 def.setFields(fields); |
309 #ifndef SYMBIANSIM_BACKEND_PHONEBOOKINFOV1 |
320 if (storeInfo.m_additionalNumberSupported) { |
310 if (storeInfo.iMaxAdditionalNumbers > 0) { |
|
311 // multiple numbers supported |
321 // multiple numbers supported |
312 def.setUnique(false); |
322 def.setUnique(false); |
313 } else { |
323 } else { |
314 // only one phone number allowed |
324 // only one phone number allowed |
315 def.setUnique(true); |
325 def.setUnique(true); |
316 } |
326 } |
317 #else |
|
318 // only one phone number allowed |
|
319 def.setUnique(true); |
|
320 #endif |
|
321 retn.insert(def.name(), def); |
327 retn.insert(def.name(), def); |
322 |
328 |
323 // nickname support needs to be checked run-time, because it is SIM specific |
329 // nickname support needs to be checked run-time, because it is SIM specific |
324 #ifndef SYMBIANSIM_BACKEND_PHONEBOOKINFOV1 |
330 if (storeInfo.m_secondNameSupported) { |
325 if (storeInfo.iMaxSecondNames > 0) { |
|
326 def.setName(QContactNickname::DefinitionName); |
331 def.setName(QContactNickname::DefinitionName); |
327 fields.clear(); |
332 fields.clear(); |
328 f.setDataType(QVariant::String); |
333 f.setDataType(QVariant::String); |
329 f.setAllowableValues(QVariantList()); |
334 f.setAllowableValues(QVariantList()); |
330 fields.insert(QContactNickname::FieldNickname, f); |
335 fields.insert(QContactNickname::FieldNickname, f); |
331 def.setFields(fields); |
336 def.setFields(fields); |
332 def.setUnique(true); |
337 def.setUnique(true); |
333 retn.insert(def.name(), def); |
338 retn.insert(def.name(), def); |
334 } |
339 } |
335 #endif |
|
336 |
340 |
337 // name |
341 // name |
338 def.setName(QContactName::DefinitionName); |
342 def.setName(QContactName::DefinitionName); |
339 fields.clear(); |
343 fields.clear(); |
340 f.setDataType(QVariant::String); |
344 f.setDataType(QVariant::String); |
467 // We don't support anything in the ManagerFeature |
471 // We don't support anything in the ManagerFeature |
468 return false; |
472 return false; |
469 } |
473 } |
470 |
474 |
471 /*! |
475 /*! |
|
476 Returns a whether the supplied \a filter can be implemented |
|
477 natively by this engine. If not, the base class implementation |
|
478 will emulate the functionality. |
|
479 */ |
|
480 bool CntSymbianSimEngine::isFilterSupported(const QContactFilter& filter) const |
|
481 { |
|
482 if (filter.type() == QContactFilter::ContactDetailFilter) { |
|
483 QContactDetailFilter f(filter); |
|
484 if (f.detailDefinitionName() == QContactPhoneNumber::DefinitionName && |
|
485 f.detailFieldName() == QContactPhoneNumber::FieldNumber && |
|
486 f.matchFlags() == QContactFilter::MatchPhoneNumber) |
|
487 return true; |
|
488 } |
|
489 return false; |
|
490 } |
|
491 |
|
492 /*! |
472 * Returns the list of data types supported by the manager |
493 * Returns the list of data types supported by the manager |
473 */ |
494 */ |
474 QStringList CntSymbianSimEngine::supportedContactTypes() const |
495 QStringList CntSymbianSimEngine::supportedContactTypes() const |
475 { |
496 { |
476 // TODO: groups supported by some USIM cards? |
497 // TODO: groups supported by some USIM cards? |
487 } |
508 } |
488 |
509 |
489 void CntSymbianSimEngine::setReadOnlyAccessConstraint(QContactDetail* detail) const |
510 void CntSymbianSimEngine::setReadOnlyAccessConstraint(QContactDetail* detail) const |
490 { |
511 { |
491 setDetailAccessConstraints(detail, QContactDetail::ReadOnly); |
512 setDetailAccessConstraints(detail, QContactDetail::ReadOnly); |
|
513 } |
|
514 |
|
515 |
|
516 /*! |
|
517 Returns true if the supplied contact \a contact matches the supplied filter \a filter. |
|
518 */ |
|
519 bool CntSymbianSimEngine::filter(const QContactFilter &filter, const QContact &contact) |
|
520 { |
|
521 // Special handling for phonenumber matching: |
|
522 // Matching is done from the right by using a configurable number of digits. |
|
523 // Default number of digits is 7. So for example if we filter with number |
|
524 // +358505555555 the filter should match to +358505555555 and 0505555555. |
|
525 if (filter.type() == QContactFilter::ContactDetailFilter) |
|
526 { |
|
527 QContactDetailFilter f(filter); |
|
528 if (f.detailDefinitionName() == QContactPhoneNumber::DefinitionName && |
|
529 f.detailFieldName() == QContactPhoneNumber::FieldNumber && |
|
530 f.matchFlags() == QContactFilter::MatchPhoneNumber) |
|
531 { |
|
532 QString matchNumber = f.value().toString().right(d->m_phoneNumberMatchLen); |
|
533 QList<QContactPhoneNumber> pns = contact.details<QContactPhoneNumber>(); |
|
534 foreach (QContactPhoneNumber pn, pns) { |
|
535 QString number = pn.number().right(d->m_phoneNumberMatchLen); |
|
536 if (number == matchNumber) |
|
537 return true; |
|
538 } |
|
539 return false; |
|
540 } |
|
541 } |
|
542 return QContactManagerEngine::testFilter(filter, contact); |
492 } |
543 } |
493 |
544 |
494 /*! |
545 /*! |
495 * Executes an asynchronous request so that it will appear synchronous. This is |
546 * Executes an asynchronous request so that it will appear synchronous. This is |
496 * used internally in all synchronous functions. This way we only need to |
547 * used internally in all synchronous functions. This way we only need to |
515 |
566 |
516 // Mimic the way how async requests are normally run |
567 // Mimic the way how async requests are normally run |
517 if (!engine.startRequest(req)) { |
568 if (!engine.startRequest(req)) { |
518 *qtError = QContactManager::LockedError; |
569 *qtError = QContactManager::LockedError; |
519 } else { |
570 } else { |
520 if (!engine.waitForRequestFinished(req, KRequestTimeout)) |
571 if (!engine.waitForRequestFinished(req, 0)) // no timeout |
521 *qtError = QContactManager::UnspecifiedError; // timeout occurred |
572 *qtError = QContactManager::UnspecifiedError; |
522 } |
573 } |
523 engine.requestDestroyed(req); |
574 engine.requestDestroyed(req); |
524 |
575 |
525 if (req->error()) |
576 if (req->error()) |
526 *qtError = req->error(); |
577 *qtError = req->error(); |
527 |
578 |
528 return (*qtError == QContactManager::NoError); |
579 return (*qtError == QContactManager::NoError); |
|
580 } |
|
581 |
|
582 /* |
|
583 * Get the match length setting used in MatchPhoneNumber type filtering. |
|
584 * \a matchLength Phone number digits to be used in matching (counted from |
|
585 * right). |
|
586 */ |
|
587 void CntSymbianSimEngine::getMatchLengthL(int &matchLength) |
|
588 { |
|
589 //Get number of digits used to match |
|
590 CRepository* repository = CRepository::NewL(KCRUidTelConfiguration); |
|
591 CleanupStack::PushL(repository); |
|
592 User::LeaveIfError(repository->Get(KTelMatchDigits, matchLength)); |
|
593 CleanupStack::PopAndDestroy(repository); |
529 } |
594 } |
530 |
595 |
531 QContactManagerEngine* CntSymbianSimFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error* error) |
596 QContactManagerEngine* CntSymbianSimFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error* error) |
532 { |
597 { |
533 CntSymbianSimEngine *engine = new CntSymbianSimEngine(parameters, error); |
598 CntSymbianSimEngine *engine = new CntSymbianSimEngine(parameters, error); |