phonebookui/cntcommonui/common/cntsimengine.cpp
changeset 72 6abfb1094884
child 81 640d30f4fb64
--- /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 <QString.h>
+
+#include "cntglobal.h"
+#include "CntSimEngine.h"
+#include "cntimportviewcallback.h"
+#include "cntdebug.h"
+
+#include <hbview.h>
+#include <QCoreApplication>
+#include <QStandardItemModel>
+#include <hbextendedlocale.h>
+#include <hbstringutil.h>
+#include <hbparameterlengthlimiter.h>
+#include <hbdialog.h>
+#include <hbnotificationdialog.h>
+#include <hbdevicenotificationdialog.h>
+
+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<QContact> 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<QContactId> contactId(new QContactId());
+               contactId->setLocalId(0);
+               contactId->setManagerUri(QString());
+               contact.setId(*contactId);
+    
+               // custom label contains name information, save it to the first name 
+               QList<QContactDetail> names = contact.details(QContactName::DefinitionName);
+               if (names.count() > 0) 
+               {
+                   QContactName name = static_cast<QContactName>(names.at(0));
+                   name.setFirstName(name.customLabel());
+                   name.setCustomLabel(QString());
+                   contact.saveDetail(&name);
+               }
+                 
+               //update phone numbers to contain default subtype
+               QList<QContactDetail> numbers = contact.details(QContactPhoneNumber::DefinitionName);
+               for (int i = 0; i < numbers.count(); i++) 
+               {
+                   QContactPhoneNumber number = static_cast<QContactPhoneNumber>(numbers.at(i));
+                   number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+                   contact.saveDetail(&number);
+               }
+               
+               //remove sync target details, it's read-only. 
+                QList<QContactDetail> syncTargets = contact.details(QContactSyncTarget::DefinitionName);
+                for (int j = 0; j < syncTargets.count(); j++) 
+                {
+                    QContactSyncTarget syncTarget = static_cast<QContactSyncTarget>(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<QContact> 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<QContactId> contactId(new QContactId());
+               contactId->setLocalId(0);
+               contactId->setManagerUri(QString());
+               contact.setId(*contactId);
+    
+               //custom label contains name information, save it to the first name 
+              QList<QContactDetail> names = contact.details(QContactName::DefinitionName);
+              if (names.count() > 0) 
+              {
+                  QContactName name = static_cast<QContactName>(names.at(0));
+                  name.setFirstName(name.customLabel());
+                  name.setCustomLabel(QString());
+                  contact.saveDetail(&name);
+              }
+                
+              //update phone numbers to contain default subtype
+              QList<QContactDetail> numbers = contact.details(QContactPhoneNumber::DefinitionName);
+              for (int i = 0; i < numbers.count(); i++) 
+              {
+                  QContactPhoneNumber number = static_cast<QContactPhoneNumber>(numbers.at(i));
+                  number.setSubTypes(QContactPhoneNumber::SubTypeMobile);
+                  contact.saveDetail(&number);
+              }
+              
+              //remove sync target details, it's read-only. 
+              QList<QContactDetail> syncTargets = contact.details(QContactSyncTarget::DefinitionName);
+              for (int j = 0; j < syncTargets.count(); j++) 
+              {
+                  QContactSyncTarget syncTarget = static_cast<QContactSyncTarget>(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<int, QContactManager::Error> 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<QContactPhoneNumber> numberList( aContact.details<QContactPhoneNumber>() );
+    //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<QContactEmailAddress> emailList( aContact.details<QContactEmailAddress>() );
+    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;
+}
+
+
+
+