qtmobility/plugins/contacts/symbiansim/src/cntsymbiansimengine.cpp
changeset 14 6fbed849b4f4
parent 5 453da2cfceef
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    51 
    51 
    52 #include <QEventLoop>
    52 #include <QEventLoop>
    53 #include <QTimer>
    53 #include <QTimer>
    54 #include <QDebug>
    54 #include <QDebug>
    55 
    55 
    56 const int KRequestTimeout = 30000; // in ms
    56 #include <centralrepository.h>
       
    57 
       
    58 // Telephony Configuration API
       
    59 // Keys under this category are used in defining telephony configuration.
       
    60 const TUid KCRUidTelConfiguration = {0x102828B8};
       
    61 // Amount of digits to be used in contact matching.
       
    62 // This allows a customer to variate the amount of digits to be matched.
       
    63 const TUint32 KTelMatchDigits                               = 0x00000001;
       
    64 // Default match length
       
    65 const TInt KDefaultMatchLength(7);
       
    66 
    57 
    67 
    58 CntSymbianSimEngineData::CntSymbianSimEngineData()
    68 CntSymbianSimEngineData::CntSymbianSimEngineData()
    59     :m_simStore(0)
    69     :m_simStore(0)
    60 {
    70 {
    61     
    71     
    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)
   161 
   175 
   162     QContactName name = contact.detail(QContactName::DefinitionName);
   176     QContactName name = contact.detail(QContactName::DefinitionName);
   163     if(!name.customLabel().isEmpty()) {
   177     if(!name.customLabel().isEmpty()) {
   164         return name.customLabel();
   178         return name.customLabel();
   165     } else {
   179     } else {
   166         // TODO: localize unnamed
   180         return QString("");
   167         return QString("Unnamed");
       
   168     }
   181     }
   169 }
   182 }
   170 
   183 
   171 /*!
   184 /*!
   172  * Saves the contacts to the Etel store. Only part of the contact's details
   185  * Saves the contacts to the Etel store. Only part of the contact's details
   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);