diff -r 59984e68247d -r 6abfb1094884 phonebookui/cntcommonui/common/cntsimengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/cntcommonui/common/cntsimengine.cpp Tue Sep 21 17:07:25 2010 +0300 @@ -0,0 +1,700 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include + +#include "cntglobal.h" +#include "CntSimEngine.h" +#include "cntimportviewcallback.h" +#include "cntdebug.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const int KTimerValue = 1; // used as 1 msec timer for saving ADN contacts from SIM + +CntSimEngine::CntSimEngine(CntImportViewCallback& aImportViewCallback, HbView& aView) +: mImportViewCallback(aImportViewCallback), + mView(aView), + mAdnSimUtility(0), + mSdnSimUtility(0), + mContactSimManagerADN(0), + mContactSimManagerSDN(0), + mFetchRequestADN(0), + mFetchRequestSDN(0), + mTimer(0), + mAbsEngine(0), + mTimerId(0), + mSaveCount(0), + mAdnStoreEntries(0), + mSdnStoreEntries(0), + mAdnEntriesPresent(false), + mFetchIsDone(false), + mAdnStorePresent(false), + mSdnStorePresent(false), + mSimPresent(false), + mSimError(false), + mWaitingForAdnCache(false), + mImportInProgress(false) +{ + +} + +CntSimEngine::~CntSimEngine() +{ + CNT_ENTRY + delete mFetchRequestADN; + delete mFetchRequestSDN; + delete mAdnSimUtility; + delete mSdnSimUtility; + CNT_EXIT +} + +void CntSimEngine::init(CntAbstractEngine& aAbsEngine) +{ + CNT_ENTRY + mAbsEngine = &aAbsEngine; + mContactSymbianManager = &mAbsEngine->contactManager(SYMBIAN_BACKEND); + + // Sim Utility info fetch + int getSimInfoError(0); + int storesError(0); + int getSdnSimInfoError(0); + + + //ADN store + int error = -1; + mAdnSimUtility = new CntSimUtility(CntSimUtility::AdnStore, error); + + if (error != 0) + { + delete mAdnSimUtility; + mAdnSimUtility = 0; + mSimError = true; + //mSimError = true; + } + else + { + // check what stores are there + CntSimUtility::AvailableStores stores = mAdnSimUtility->getAvailableStores(storesError); + if(!storesError) + { + mSimPresent = stores.SimPresent; + mAdnStorePresent = stores.AdnStorePresent; + mSdnStorePresent = stores.SdnStorePresent; + } + + //check there are ADN contacts + if (mAdnStorePresent) + { + CntSimUtility::SimInfo simInfo = mAdnSimUtility->getSimInfo(getSimInfoError); + if (getSimInfoError == KErrNone) + { + // sim entries are present + mAdnStoreEntries = simInfo.usedEntries; + if (mAdnStoreEntries > 0) + { + mAdnEntriesPresent = true; + } + } + else + { + if (getSimInfoError == KErrNotReady) + { + //ADN store is not accessible, e.g. because of active FDN + //Or ADN cache is not ready yet, so wait for this + + mAdnStorePresent = true; + mAdnEntriesPresent = true; + mWaitingForAdnCache = true; + connect(mAdnSimUtility, SIGNAL(getSimInfoAndUpdateUI(CntSimUtility::CacheStatus&, int)), this, SLOT(getSimInfoAndUpdateUI(CntSimUtility::CacheStatus&, int))); + if (!mAdnSimUtility->notifyAdnCacheStatus()) { + mAdnStorePresent = false; + mAdnEntriesPresent = false; + mWaitingForAdnCache = false; + } + } + else + { + simInfoErrorMessage(getSimInfoError); + } + } + } + } + + //SDN store + if (mSdnStorePresent && !mWaitingForAdnCache) + { + int sdnError = -1; + mSdnStorePresent = false; + if (!mSdnSimUtility) + { + mSdnSimUtility = new CntSimUtility(CntSimUtility::SdnStore, sdnError); + if (sdnError != 0) + { + delete mSdnSimUtility; + mSdnSimUtility = 0; + } + } + if (mSdnSimUtility) + { + //get number of SDN contacts + CntSimUtility::SimInfo sdnSimInfo = mSdnSimUtility->getSimInfo(getSdnSimInfoError); + if (!getSdnSimInfoError) + { + // sim entries are present + mSdnStoreEntries = sdnSimInfo.usedEntries; + if (mSdnStoreEntries > 0) + { + mSdnStorePresent = true; + } + } + } + } + CNT_EXIT + // end SDN store +} + +void CntSimEngine::checkEntries(QStringList& simList, QStandardItem& importSimItem) +{ + CNT_ENTRY + QString simImport(hbTrId("txt_phob_dblist_import_from_sim")); + QString simNoContacts(hbTrId("txt_phob_dblist_import_from_1_val_no_sim_contacts")); + QString simNoCard(hbTrId("txt_phob_dblist_import_from_ovi_val_no_sim_card")); + + // check if SIM card is NOT there + if (mSimError) + { + simList << simImport; + importSimItem.setEnabled(false); + } + else if (!(mAdnStorePresent || mSdnStorePresent)) + { + // Both stores are not present + // disable the QStandardItem + if (!mSimPresent) + { + simList << simImport << simNoCard; + } + else + { + simList << simImport << simNoContacts; + } + importSimItem.setEnabled(false); + } + else if (!(mAdnEntriesPresent || mSdnStorePresent)) + { + // Sim card is present + // No ADN entries are there + // no SDN entries are there + simList << simImport << simNoContacts; + importSimItem.setEnabled(false); + } + else + { + // SIM card is present + //ADN entries or SDN entries are there + simList << simImport; + int error = 0; + QDateTime date = mAdnSimUtility->getLastImportTime(error); + if (error == 0) { + HbExtendedLocale locale = HbExtendedLocale::system(); + QString dateStr = locale.format(date.date(), r_qtn_date_usual); + QString dateStrLocaleDigits = HbStringUtil::convertDigits(dateStr); + QString dateStrFull = + HbParameterLengthLimiter(hbTrId("txt_phob_dblist_import_from_1_val_updated_1")).arg(dateStrLocaleDigits); + simList << dateStrFull; + } + } + CNT_EXIT +} + +bool CntSimEngine::startSimImport() +{ + CNT_ENTRY + bool started = false; + mImportInProgress = true; + mSaveCount = 0; + + delete mFetchRequestADN; + mContactSimManagerADN = &mAbsEngine->contactManager(SIM_BACKEND_ADN); + mFetchRequestADN = new QContactFetchRequest; + mFetchRequestADN->setManager(mContactSimManagerADN); + + delete mFetchRequestSDN; + mContactSimManagerSDN = &mAbsEngine->contactManager(SIM_BACKEND_SDN); + mFetchRequestSDN = new QContactFetchRequest; + mFetchRequestSDN->setManager(mContactSimManagerSDN); + + if (mWaitingForAdnCache) + { + //show progress dialog and wait when ADN cache is ready + started = true; + } + else + { + if(mAdnStorePresent) + { + connect(mFetchRequestADN, SIGNAL(resultsAvailable()), this, SLOT(importADNFetchResults())); + } + + if(mSdnStorePresent) + { + connect(mFetchRequestSDN, SIGNAL(resultsAvailable()), this, SLOT(importSDNFetchResults())); + } + + if(mAdnEntriesPresent > 0 && mContactSimManagerADN->error() == QContactManager::NoError) + { + // ADN contacts are there, start fetch + mFetchRequestADN->start(); + started = true; + } + else if (mSdnStorePresent && mContactSimManagerSDN->error() == QContactManager::NoError) + { + //start fetch of SDN contacts since ADN contacts are not there + mFetchRequestSDN->start(); + started = true; + } + } + CNT_EXIT + return started; +} + + +void CntSimEngine::stopSimImport() +{ + CNT_ENTRY + if(mImportInProgress) + { + emit closePopup(); + mImportInProgress = false; + if (mFetchIsDone) + { + // indicates that timer has been started + killTimer(mTimerId); + } + mSaveSimContactsList.clear(); + mSaveSimContactsListSDN.clear(); + + showSimImportResults(); + + if (mFetchRequestADN != NULL) + { + mFetchRequestADN->cancel(); + } + if (mFetchRequestSDN != NULL) + { + mFetchRequestSDN->cancel(); + } + + // save import time + int error = 0; + mAdnSimUtility->setLastImportTime(error); + + //update sim import row with last import time + if (error == 0) + { + QDateTime date = mAdnSimUtility->getLastImportTime(error); + if (error == 0) + { + QString simImport(hbTrId("txt_phob_dblist_import_from_sim")); + + HbExtendedLocale locale = HbExtendedLocale::system(); + QString dateStr = locale.format(date.date(), r_qtn_date_usual); + QString dateStrLocaleDigits = HbStringUtil::convertDigits(dateStr); + QString dateStrFull = + HbParameterLengthLimiter(hbTrId("txt_phob_dblist_import_from_1_val_updated_1")).arg(dateStrLocaleDigits); + //simList << dateStrFull; + + mImportViewCallback.setListBoxItemText(simImport, dateStrFull); + } + } + } + + CNT_EXIT +} + +void CntSimEngine::timerEvent(QTimerEvent *event) +{ + CNT_ENTRY + Q_UNUSED(event); + if (!(mSaveCount >= mSaveSimContactsList.count())) // while mSaveCount is less than or equal to mSaveSimContactsList.count() + { + QContact unSavedContact = mSaveSimContactsList.at(mSaveCount); + mContactSymbianManager->saveContact(&unSavedContact); + mSaveCount++; + //use another counter to check number of actual saved if saveContact() fails + } + else + { + // saving complete + killTimer(mTimerId); + mSaveSimContactsList.clear(); + + // ADN contacts fetching and saving is done + // Now start SDN fetching and save + fetchSDNContacts(); + } + CNT_EXIT +} + + +void CntSimEngine::importADNFetchResults() +{ + CNT_ENTRY + //save import time + int error = 0; + mAdnSimUtility->setLastImportTime(error); + + QList simContactsList = mFetchRequestADN->contacts(); + if (simContactsList.isEmpty()) + { + // No sim contacts, jump to fetching SDN contacts + fetchSDNContacts(); + } + else + { + // save ADN contacts + + int count = simContactsList.count(); + foreach(QContact contact, simContactsList) + { + if (contact.localId() > 0) + { + //delete local id before saving to different storage + QScopedPointer contactId(new QContactId()); + contactId->setLocalId(0); + contactId->setManagerUri(QString()); + contact.setId(*contactId); + + // custom label contains name information, save it to the first name + QList names = contact.details(QContactName::DefinitionName); + if (names.count() > 0) + { + QContactName name = static_cast(names.at(0)); + name.setFirstName(name.customLabel()); + name.setCustomLabel(QString()); + contact.saveDetail(&name); + } + + //update phone numbers to contain default subtype + QList numbers = contact.details(QContactPhoneNumber::DefinitionName); + for (int i = 0; i < numbers.count(); i++) + { + QContactPhoneNumber number = static_cast(numbers.at(i)); + number.setSubTypes(QContactPhoneNumber::SubTypeMobile); + contact.saveDetail(&number); + } + + //remove sync target details, it's read-only. + QList syncTargets = contact.details(QContactSyncTarget::DefinitionName); + for (int j = 0; j < syncTargets.count(); j++) + { + QContactSyncTarget syncTarget = static_cast(syncTargets.at(j)); + contact.removeDetail(&syncTarget); + } + + contact.setType(QContactType::TypeContact); + setPreferredDetails(contact); + mSaveSimContactsList.append(contact); + + } + } + // save the list synchronously because async cancelling of save request is + // not supported in symbian backend at the time of this implementation + + if (!(mSaveSimContactsList.isEmpty())) + { + // indicates that there is one or more sim contact that has been fetched + // create a timer and start saving synchronously one by one + // when cancel is pressed, kill the timer + + mTimerId = startTimer(KTimerValue); // starting a 1 msec timer + mFetchIsDone = true; + mSaveCount = 0; + } + } + CNT_EXIT +} + +void CntSimEngine::importSDNFetchResults() +{ + CNT_ENTRY + //save import time + int error = 0; + mAdnSimUtility->setLastImportTime(error); + + QList simContactsListSDN = mFetchRequestSDN->contacts(); + if (simContactsListSDN.isEmpty()) + { + //No sdn contacts present + showSimImportResults(); + mSaveSimContactsListSDN.clear(); + emit closePopup(); + mImportInProgress = false; + // Importing finished, go back to NamesView + emit showNamesView(); + //showPreviousView(); + } + else + { + // SAVE SDN CONTACTS + int count = simContactsListSDN.count(); + foreach(QContact contact, simContactsListSDN) + { + if (contact.localId() > 0) + { + //delete local id before saving to different storage + QScopedPointer contactId(new QContactId()); + contactId->setLocalId(0); + contactId->setManagerUri(QString()); + contact.setId(*contactId); + + //custom label contains name information, save it to the first name + QList names = contact.details(QContactName::DefinitionName); + if (names.count() > 0) + { + QContactName name = static_cast(names.at(0)); + name.setFirstName(name.customLabel()); + name.setCustomLabel(QString()); + contact.saveDetail(&name); + } + + //update phone numbers to contain default subtype + QList numbers = contact.details(QContactPhoneNumber::DefinitionName); + for (int i = 0; i < numbers.count(); i++) + { + QContactPhoneNumber number = static_cast(numbers.at(i)); + number.setSubTypes(QContactPhoneNumber::SubTypeMobile); + contact.saveDetail(&number); + } + + //remove sync target details, it's read-only. + QList syncTargets = contact.details(QContactSyncTarget::DefinitionName); + for (int j = 0; j < syncTargets.count(); j++) + { + QContactSyncTarget syncTarget = static_cast(syncTargets.at(j)); + contact.removeDetail(&syncTarget); + } + + contact.setType(QContactType::TypeContact); + setPreferredDetails(contact); + mSaveSimContactsListSDN.append(contact); + + } + } + // save the list synchronously because async cancelling of save request is + // not supported in symbian backend at the time of this implementation + + if (!(mSaveSimContactsListSDN.isEmpty())) + { + // indicates that there is one or more SDN sim contact that has been fetched + QMap errorMap; + mContactSymbianManager->saveContacts(&mSaveSimContactsListSDN,&errorMap); + // check number of contacts really saved + mSaveCount = mSaveCount + mSaveSimContactsListSDN.count(); + } + + // no more SDN contacts to fetch + showSimImportResults(); + mSaveSimContactsListSDN.clear(); + emit closePopup(); + mImportInProgress = false; + // Importing finished, go back to NamesView + emit showNamesView(); + //showPreviousView(); + } + CNT_EXIT +} + +void CntSimEngine::setPreferredDetails(QContact& aContact ) +{ + CNT_ENTRY + QList numberList( aContact.details() ); + //set preferred number for call if there is only one phone number + if ( aContact.preferredDetail("call").isEmpty() && numberList.count() == 1 ) + { + aContact.setPreferredDetail( "call", numberList.first() ); + } + //set preferred number for message if there is only one mobile phone number + if ( aContact.preferredDetail("message").isEmpty() && numberList.count() == 1 ) + { + aContact.setPreferredDetail( "message", numberList.first() ); + } + //set preferred number for message if there is only one email address + QList emailList( aContact.details() ); + if ( aContact.preferredDetail("email").isEmpty() && emailList.count() == 1 ) + { + aContact.setPreferredDetail( "email", emailList.first() ); + } + CNT_EXIT +} + +void CntSimEngine::showSimImportResults() const +{ + CNT_ENTRY + QString results = hbTrId("txt_phob_dpophead_ln_contacts_imported").arg(mSaveCount).arg(mAdnStoreEntries + mSdnStoreEntries); + HbNotificationDialog::launchDialog(results); + CNT_EXIT +} + +void CntSimEngine::fetchSDNContacts() +{ + CNT_ENTRY + if (mSdnStorePresent && mContactSimManagerSDN->error() == QContactManager::NoError) + { + mFetchRequestSDN->start(); + } + else + { + // no SDN contacts to fetch + showSimImportResults(); + emit closePopup(); + mImportInProgress = false; + // Importing finished, go back to NamesView + + //showPreviousView(); + emit showNamesView(); + } + CNT_EXIT +} + + +void CntSimEngine::getSimInfoAndUpdateUI(CntSimUtility::CacheStatus& cacheStatus, int error) +{ + CNT_ENTRY + mWaitingForAdnCache = false; + //update ADN store info... + if (error != KErrNone || cacheStatus == CntSimUtility::ECacheFailed) + { + mAdnStorePresent = false; + mAdnEntriesPresent = false; + mSdnStorePresent = false; + } + else + { + //check if there are ADN contacts + mAdnStorePresent = true; + mAdnEntriesPresent = false; + int getSimInfoError = -1; + CntSimUtility::SimInfo simInfo = mAdnSimUtility->getSimInfo(getSimInfoError); + if (!getSimInfoError) + { + // sim entries are present + mAdnStoreEntries = simInfo.usedEntries; + if (mAdnStoreEntries > 0) + { + mAdnEntriesPresent = true; + } + } + + //get number of SDN contacts + int sdnError = -1; + mSdnStorePresent = false; + if (!mSdnSimUtility) + { + mSdnSimUtility = new CntSimUtility(CntSimUtility::SdnStore, sdnError); + if (sdnError != 0) + { + delete mSdnSimUtility; + mSdnSimUtility = 0; + } + } + if (mSdnSimUtility) + { + int getSdnSimInfoError = 0; + CntSimUtility::SimInfo sdnSimInfo = mSdnSimUtility->getSimInfo(getSdnSimInfoError); + if (!getSdnSimInfoError) + { + mSdnStoreEntries = sdnSimInfo.usedEntries; + if (mSdnStoreEntries > 0) + { + mSdnStorePresent = true; + } + } + } + } + + //dismiss progress dialog, if there are no SIM contacts + if(!mAdnEntriesPresent && !mSdnStorePresent) + { + emit closePopup(); + showSimImportResults(); + } + + //disable sim import item, if there are no SIM contacts + if(!mAdnEntriesPresent && !mSdnStorePresent) + { + QString simImport(hbTrId("txt_phob_dblist_import_from_sim")); + QString simNoContacts(hbTrId("txt_phob_dblist_import_from_1_val_no_sim_contacts")); + + mImportViewCallback.setListBoxItemText(simImport, simNoContacts); + mImportViewCallback.setListBoxItemEnabled(false); + } + + //start SIM contacts import, if user tapped "SIM import" +// if(mImportSimPopup != NULL && mImportSimPopup->isActive()) +// { + if (!startSimImport()) + { + //dismiss wait note + emit closePopup(); + mImportInProgress = false; + //and show error note + simInfoErrorMessage(KErrAccessDenied); + } + // } + CNT_EXIT +} + +void CntSimEngine::simInfoErrorMessage(int infoError) +{ + CNT_ENTRY + Q_UNUSED(infoError); + QString errorMessage; + errorMessage.append(hbTrId("txt_phob_info_sim_card_error")); + HbNotificationDialog::launchDialog(errorMessage); + mSimError = true; + CNT_EXIT +} + +bool CntSimEngine::userCancelsImport(QString& aResults) +{ + CNT_ENTRY + aResults = ""; + + bool boolResult = mImportInProgress && !mSimError; + + if(boolResult) + { + aResults = hbTrId("txt_phob_dpophead_ln_contacts_imported").arg(mSaveCount).arg(mAdnStoreEntries + mSdnStoreEntries); + } + mImportInProgress = false; + CNT_EXIT + return boolResult; +} + + + +