phonebookui/pbkcommonui/src/cntimportsview.cpp
changeset 31 2a11b5b00470
child 37 fd64c38c277d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/pbkcommonui/src/cntimportsview.cpp	Fri May 14 15:42:23 2010 +0300
@@ -0,0 +1,632 @@
+/*
+* 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 "cntimportsview.h"
+#include "qtpbkglobal.h"
+#include <hbpushbutton.h>
+#include <hbaction.h>
+#include <hbview.h>
+#include <hbmenu.h>
+#include <hbframebackground.h>
+#include <QStandardItemModel>
+#include <hbmainwindow.h>
+#include <hblabel.h>
+#include <hblistview.h>
+#include <hbgroupbox.h>
+#include <QTimer.h>
+#include <hbnotificationdialog.h>
+#include <hbmessagebox.h>
+#include <hbprogressbar.h>
+#include <QGraphicsLinearLayout>
+#include <hbframebackground.h>
+#include <hbabstractviewitem.h>
+
+const char *CNT_IMPORT_UI_XML = ":/xml/contacts_sim.docml";
+const int KTimerValue = 1; // used as 1 msec timer for saving ADN contacts from SIM   
+
+CntImportsView::CntImportsView() : mContactSimManagerADN(0),
+    mContactSimManagerSDN(0),    
+    mFetchRequestADN(0),
+    mFetchRequestSDN(0),
+    mListView(0),
+    mSimUtility(0),
+    mAdnEntriesPresent(0),
+    mImportSimPopup(0),
+    mSaveCount(0),
+    mFetchIsDone(0),
+    mTimerId(0),
+    mAdnStorePresent(0),
+    mSdnStorePresent(0),
+    mSimPresent(0),
+    mAdnStoreEntries(0),
+    mSimError(0),
+    mWaitingForAdnCache(0)
+{
+    bool ok = false;
+    mDocumentLoader.load(CNT_IMPORT_UI_XML, &ok);
+
+    if (ok)
+    {
+        mView = static_cast<HbView*>(mDocumentLoader.findWidget(QString("view")));
+    }
+    else
+    {
+        qFatal("Unable to read :/xml/contacts_sim.docml");
+    }
+
+    //back button
+    mSoftkey = new HbAction(Hb::BackNaviAction, mView);
+    connect(mSoftkey, SIGNAL(triggered()), this, SLOT(showPreviousView()));
+      
+}
+
+void CntImportsView::deactivate()
+{
+}
+
+   
+CntImportsView::~CntImportsView()
+{
+    mView->deleteLater();
+    delete mFetchRequestADN;
+    delete mFetchRequestSDN;
+    delete mModel;
+    delete mSimUtility;
+}
+
+/*!
+Activates a previous view
+*/
+void CntImportsView::showPreviousView()
+{
+  CntViewParameters args;
+  mViewManager->back(args);
+}
+
+/*
+Activates a default view
+*/
+void CntImportsView::activate(CntAbstractViewManager* aMgr, const CntViewParameters aArgs)
+{
+    Q_UNUSED(aArgs);
+    //back button
+    HbMainWindow* window = mView->mainWindow();
+    if (mView->navigationAction() != mSoftkey)
+    {
+        mView->setNavigationAction(mSoftkey);
+    }
+            
+    mViewManager = aMgr;  
+    mContactSymbianManager = mViewManager->contactManager(SYMBIAN_BACKEND);
+   
+    // Sim Utility info fetch
+    int getSimInfoError(0);
+    int storesError(0);
+    
+    int error = -1;
+    mSimUtility = new SimUtility(SimUtility::AdnStore, error);
+    if (error != 0) 
+    {
+        delete mSimUtility; 
+        mSimUtility = 0;
+        mSimError = true;
+    }
+    else
+    {
+        // check what stores are there
+        SimUtility::AvailableStores stores = mSimUtility->getAvailableStores(storesError);
+        if(!storesError)
+        {
+            mSimPresent = stores.SimPresent;
+            mAdnStorePresent = stores.AdnStorePresent; 
+            mSdnStorePresent = stores.SdnStorePresent;
+        }
+        
+        //check there are ADN contacts 
+        if (mAdnStorePresent)
+        {
+            SimUtility::SimInfo simInfo = mSimUtility->getSimInfo(getSimInfoError);
+            if (!getSimInfoError)
+            {
+                // 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(mSimUtility, SIGNAL(adnCacheStatusReady(SimUtility::CacheStatus&, int)), this, SLOT(adnCacheStatusReady(SimUtility::CacheStatus&, int)));
+                    if (!mSimUtility->notifyAdnCacheStatus()) {
+                        mAdnStorePresent = false;
+                        mAdnEntriesPresent = false;
+                        mWaitingForAdnCache = false;
+                    }
+                }
+                else
+                {
+                    simInfoErrorMessage(getSimInfoError);
+                }
+            }
+        }
+    }
+        
+    mListView = static_cast<HbListView*>(mDocumentLoader.findWidget(QString("listView")));
+    
+    HbFrameBackground frame;
+    frame.setFrameGraphicsName("qtg_fr_list_normal");
+    frame.setFrameType(HbFrameDrawer::NinePieces);
+    mListView->itemPrototypes().first()->setDefaultFrame(frame);
+    
+    mListView->setUniformItemSizes(true);
+    
+    connect(mListView, SIGNAL(activated (const QModelIndex&)),
+                                      this,  SLOT(onListViewActivated(const QModelIndex&)));
+       
+    mModel = new QStandardItemModel();
+    
+    QStandardItem *importSimItem = new QStandardItem();
+    QStringList simList;
+    
+    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 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 ;        
+    }
+    importSimItem->setData(simList, Qt::DisplayRole);
+    importSimItem->setData(HbIcon("qtg_large_sim"), Qt::DecorationRole);   
+     
+    mModel->insertRow(0,importSimItem);
+    
+    QStandardItem *importDeviceItem = new QStandardItem();
+    QStringList deviceList;
+    QString deviceImport(hbTrId("txt_phob_dblist_import_from_device"));
+    deviceList << deviceImport;
+    importDeviceItem->setData(deviceList, Qt::DisplayRole);
+    importDeviceItem->setData(HbIcon("qtg_large_data_import"), Qt::DecorationRole);
+    importDeviceItem->setEnabled(false);
+       
+    mModel->insertRow(1,importDeviceItem);
+    
+    mListView->setModel(mModel);
+    mListView->setSelectionMode(HbAbstractItemView::NoSelection);
+}
+
+void CntImportsView::simInfoErrorMessage(int infoError)
+{
+    Q_UNUSED(infoError);
+    QString errorMessage;
+    errorMessage.append(hbTrId("sim_card_not_accessable"));
+    HbNotificationDialog::launchDialog(errorMessage);
+    mSimError = true;
+}
+
+void CntImportsView::onListViewActivated(const QModelIndex &index)
+{
+    int row = index.row();
+    if ( row == 0 ) // row 0 has "Imports from SIM" 
+    {
+       if (!startSimImport())
+       {
+           //show error note
+           simInfoErrorMessage(KErrAccessDenied);
+       }
+       else
+       {
+           //start popup and progress
+           showWaitNote();
+       }
+    }        
+}
+
+
+bool CntImportsView::startSimImport()
+{
+    bool started = false;
+
+    delete mFetchRequestADN;
+    mFetchRequestADN = 0;
+    delete mFetchRequestSDN;
+    mFetchRequestSDN = 0;
+        
+    if (mWaitingForAdnCache)
+    {
+        //show progress dialog and wait when ADN cache is ready
+        started = true;
+    }
+    else
+    {
+        if(mAdnStorePresent)
+        {
+            mContactSimManagerADN = mViewManager->contactManager(SIM_BACKEND_ADN);
+            mFetchRequestADN = new QContactFetchRequest;
+            mFetchRequestADN->setManager(mContactSimManagerADN);
+            connect(mFetchRequestADN, SIGNAL(resultsAvailable()), this, SLOT(importFetchResultReceivedADN()));
+        }
+      
+        if(mSdnStorePresent)
+        {
+            mContactSimManagerSDN = mViewManager->contactManager(SIM_BACKEND_SDN);
+            // SDN store fetch request
+            mFetchRequestSDN = new QContactFetchRequest;
+            mFetchRequestSDN->setManager(mContactSimManagerSDN);
+            connect(mFetchRequestSDN, SIGNAL(resultsAvailable()), this, SLOT(importFetchResultReceivedSDN()));
+        }
+        
+        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;
+        }
+    }
+    return started;
+}  
+
+void CntImportsView::stopSimImport()
+{
+    mImportSimPopup->close();
+    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();
+    }
+    
+}
+
+void CntImportsView::importFetchResultReceivedADN()
+{
+    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);
+               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;    
+        }
+    
+    }
+}
+
+void CntImportsView::timerEvent(QTimerEvent *event)
+{
+    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();
+    }
+}
+
+void CntImportsView::showWaitNote()
+{
+    mImportSimPopup = new HbDialog();    
+    mImportSimPopup->setDismissPolicy(HbDialog::NoDismiss);
+    mImportSimPopup->setTimeout(0);
+    mImportSimPopup->setBackgroundFaded(true);
+    mImportSimPopup->setAttribute(Qt::WA_DeleteOnClose, true);
+    
+    HbGroupBox *groupBox = new HbGroupBox;
+    groupBox->setHeading(hbTrId("txt_phob_title_import_contacts")); 
+    mImportSimPopup->setHeadingWidget(groupBox);
+    
+    QGraphicsLinearLayout *containerLayout = new QGraphicsLinearLayout(Qt::Vertical);
+    containerLayout->setContentsMargins(0, 0, 0, 0);
+    containerLayout->setSpacing(10);
+    
+    HbLabel *icon = new HbLabel();
+    icon->setIcon(HbIcon("qtg_large_sim"));  
+    
+    HbLabel *simText= new HbLabel();
+    simText->setPlainText(hbTrId("txt_phob_info_importing_contacts_from_sim")); 
+    simText->setTextWrapping(Hb::TextWordWrap);
+    simText->setElideMode(Qt::ElideNone);
+    
+    HbProgressBar *progressBar = new HbProgressBar;
+    progressBar->setRange(0,0); 
+    
+    HbPushButton *stopButton = new HbPushButton;
+    stopButton->setText(hbTrId("txt_phob_button_cancel"));
+    connect(stopButton, SIGNAL(clicked()), this, SLOT(stopSimImport()));
+    
+    QGraphicsLinearLayout *containerLayout1 = new QGraphicsLinearLayout(Qt::Horizontal);
+    containerLayout1->addItem(icon);
+    containerLayout1->addItem(simText);
+    
+    QGraphicsWidget *containerWidget = new QGraphicsWidget;    
+    containerLayout->addItem(containerLayout1);
+    containerLayout->addItem(progressBar);
+    containerLayout->addItem(stopButton);  
+    containerWidget->setLayout(containerLayout);
+    mImportSimPopup->setContentWidget(containerWidget);
+    mSaveCount = 0;
+    mImportSimPopup->open();
+}
+
+void CntImportsView::showSimImportResults() const
+{
+    QString results;
+    results.append(hbTrId("txt_phob_dpophead_ln_contacts_imported", mSaveCount));
+    HbNotificationDialog::launchDialog(results);
+}
+
+void CntImportsView::fetchSDNContacts()
+{
+   if (mSdnStorePresent && mContactSimManagerSDN->error() == QContactManager::NoError)
+    {
+        mFetchRequestSDN->start();
+    }
+    else
+    {
+        // no SDN contacts to fetch
+        showSimImportResults();
+        mImportSimPopup->close();
+        // Importing finished, go back to NamesView
+        showPreviousView();
+    }
+}
+
+void CntImportsView::importFetchResultReceivedSDN()
+{
+    QList<QContact> simContactsListSDN = mFetchRequestSDN->contacts();
+    if (simContactsListSDN.isEmpty())
+    {
+        //No sdn contacts present
+        showSimImportResults();
+        mSaveSimContactsListSDN.clear(); 
+        mImportSimPopup->close();
+        // Importing finished, go back to NamesView
+        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);
+               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(); 
+        mImportSimPopup->close();
+        // Importing finished, go back to NamesView
+        showPreviousView();
+    }   
+}
+
+void CntImportsView::adnCacheStatusReady(SimUtility::CacheStatus& cacheStatus, int error)
+{
+    mWaitingForAdnCache = false;
+    //update ADN store info...
+    if (error != 0 || cacheStatus == SimUtility::ECacheFailed)
+    {
+        mAdnStorePresent = false;
+        mAdnEntriesPresent = false;
+    }
+    else
+    {
+        //check if there are ADN contacts
+        mAdnStorePresent = true;
+        mAdnEntriesPresent = false;
+        int getSimInfoError = -1;
+        SimUtility::SimInfo simInfo = mSimUtility->getSimInfo(getSimInfoError);
+        if (!getSimInfoError)
+        {
+            // sim entries are present
+            mAdnStoreEntries = simInfo.usedEntries;
+            if (mAdnStoreEntries > 0) 
+            { 
+                mAdnEntriesPresent = true;
+            }
+        }
+    }
+    
+    //and start SIM contacts import, if user tapped "SIM import"
+    if(mImportSimPopup != NULL && mImportSimPopup->isActive())
+    {
+        if (!startSimImport())
+        {
+            //dismiss wait note
+            mImportSimPopup->close();
+            //and show error note
+            simInfoErrorMessage(KErrAccessDenied);
+        }
+    }
+}
+
+// EOF