diff -r de1630741fbe -r 2a11b5b00470 phonebookui/pbkcommonui/src/cntimportsview.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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(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(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 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); + 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 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 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); + 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(); + 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