--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/smartmessaging/vcardbc/src/vcardvpbutil.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,776 @@
+/*
+* Copyright (c) 2006-2006 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: VirtualPhonebook support for importing VCard messages
+*
+*/
+
+
+
+// system includes
+#include <AknQueryDialog.h> // CAknTextQueryDialog
+#include <vcardbc.rsg> // resource definitions
+
+//Phonebook 2 API
+#include <CPbk2StoreConfiguration.h>
+#include <VPbkContactStoreUris.h>
+#include <CVPbkContactStoreUriArray.h>
+#include <MVPbkContactStoreList.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactOperationBase.h>
+#include <CVPbkVCardEng.h>
+#include <CVPbkContactManager.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkFieldType.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactStoreInfo.h>
+#include <CPbk2SortOrderManager.h>
+#include <MPbk2ContactNameFormatter.h>
+#include <Pbk2ContactNameFormatterFactory.h>
+#include <MVPbkContactFieldData.h>
+#include <MVPbkContactFieldTextData.h>
+#include <Pbk2UIControls.rsg>
+#include <VPbkSyncConstants.h>
+#include <TVPbkFieldVersitProperty.h>
+#include <TVPbkContactStoreUriPtr.h>
+#include <MVPbkContactFieldDateTimeData.h>
+#include <CVPbkFieldTypeSelector.h>
+#include <CVPbkContactStoreUri.h>
+#include <stringloader.h> // StringLoader
+#include <AknNoteWrappers.h>
+#include <pbk2commonui.rsg>
+#include "VCardLog.h"
+#include <s32file.h> // for RFileReadStream
+#include <barsread.h> // for ResourceReader
+
+// user includes
+#include "vcardvpbutil.h"
+
+// local constants & enumerations
+_LIT(KClassName, "CVCardVpbUtil");
+_LIT(KUnnamedText, "Unnamed");
+_LIT(KDEFAULT_CNTDB_URI, "cntdb://c:contacts.cdb");
+
+enum TPanicCode
+ {
+ ENoContactImported,
+ EInvalidIndex,
+ EPanicPostCond_ReallocBufferL
+ };
+
+/// Unnamed namespace for this-file-only helper funtions
+namespace {
+
+// Initial size for the conversion buffer
+const TInt KBufferLength = 128;
+_LIT8(KWvAddressVersitExtensionName, "X-WV-ID");
+
+/**
+ * Searches Versit property aArray for field aName.
+ */
+TBool ContainsFieldType(
+ TArray<TVPbkFieldVersitProperty> aArray,
+ TVPbkFieldTypeName aName)
+ {
+ TBool ret = EFalse;
+ const TInt size = aArray.Count();
+ for (TInt i=0; i<size; ++i)
+ {
+ if (aArray[i].Name() == aName)
+ {
+ ret = ETrue;
+ break;
+ }
+ }
+ return ret;
+ }
+
+/**
+ * Searches Versit property array for a field aName
+ * which has aExtensionName.
+ */
+TBool ContainsFieldTypeAndExtensionName(
+ TArray<TVPbkFieldVersitProperty> aArray,
+ TVPbkFieldTypeName aName,
+ const TDesC8& aExtensionName)
+ {
+ TBool ret = EFalse;
+ const TInt size = aArray.Count();
+ for (TInt i=0; i<size; ++i)
+ {
+ if (aArray[i].Name() == aName &&
+ aArray[i].ExtensionName().CompareF(aExtensionName) == 0)
+ {
+ ret = ETrue;
+ break;
+ }
+ }
+ return ret;
+ }
+
+
+/**
+ * Inspects is number conversion allowed. It is not allowed
+ * for certain fields, like for email field.
+ */
+inline TBool IsNumberConversionAllowed(const MVPbkFieldType& aFieldType)
+ {
+ TBool ret = ETrue;
+
+ // Perform number conversion if allowed
+ if (ContainsFieldType(aFieldType.VersitProperties(), EVPbkVersitNameURL))
+ {
+ ret = EFalse;
+ }
+ else if (ContainsFieldType(aFieldType.VersitProperties(), EVPbkVersitNameEMAIL))
+ {
+ ret = EFalse;
+ }
+ // search for the X-WV-ID field
+ else if (ContainsFieldTypeAndExtensionName(
+ aFieldType.VersitProperties(), EVPbkVersitNameX, KWvAddressVersitExtensionName))
+ {
+ ret = EFalse;
+ }
+
+ return ret;
+ }
+
+
+} // namespace
+
+
+// ======== MEMBER FUNCTIONS ========
+
+CVCardVpbUtil* CVCardVpbUtil::NewL()
+ {
+ CVCardVpbUtil* self = new( ELeave ) CVCardVpbUtil();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CVCardVpbUtil::~CVCardVpbUtil()
+ {
+ delete iAvailableUris;
+
+ iContactsToShow.ResetAndDestroy();
+
+ iContactsToStore.ResetAndDestroy();
+
+ if ( iDefaultContactStore )
+ {
+ iDefaultContactStore->Close( *this );
+ }
+
+ if ( iShowContactStore )
+ {
+ iShowContactStore->Close( *this );
+ }
+
+ if(iStoreList)
+ {
+ iStoreList->CloseAll( *this );
+ }
+
+ delete iContactManager;
+ delete iVCardEngine;
+ delete iBuffer;
+ }
+
+void CVCardVpbUtil::ImportVCardL( TVCardBCBusinessCardType aVCardType, RFile aFileHandle )
+ {
+ RFileReadStream stream;
+ stream.Attach( aFileHandle );
+ CleanupClosePushL( stream );
+ iVCardType = aVCardType;
+
+ //import is done to both store at this point as the fileHandle is not
+ //accessible later
+ VCardToPhoneStoreL( stream );
+ VCardToDefaultStoreL( stream );
+ CleanupStack::Pop(); //stream
+
+ //were done with stream as the data has been imported
+ //this will also close the fileHandle
+ stream.Release();
+ stream.Close();
+ }
+
+TBool CVCardVpbUtil::CommitVCardToStoreL()
+ {
+ MVPbkContactOperationBase* ope( NULL );
+ if( DefaultStoreSupportsAllFieldsL()&& !StoreFullL() )
+ {
+ ope =
+ iContactManager->CommitContactsL( iContactsToStore.Array(), *this );
+ }
+ else
+ {
+ //dialog to ask user if contact data is to be stored to phone memory
+ //this is the case if the contact data can not be fitted to the
+ //default saving store ie. SIM store
+ CAknQueryDialog* qDlg = CAknQueryDialog::NewL();
+ if ( qDlg->ExecuteLD( R_VCARD_STORE_QUERY ) )
+ {
+ ope =
+ iContactManager->CommitContactsL( iContactsToShow.Array(), *this );
+ }
+ }
+ if( ope )
+ {
+ CleanupDeletePushL( ope );
+
+ //the active scheduler needs two iterations
+ for ( TInt i = 0; i < 2; ++i )
+ {
+ StartSchedulerAndDecideToLeaveL();
+ }
+ CleanupStack::PopAndDestroy();
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+MVPbkStoreContact* CVCardVpbUtil::ContactData() const
+ {
+ __ASSERT_DEBUG( iContactsToShow.Count() > 0, Panic( ENoContactImported ) );
+ return iContactsToShow[0];
+ }
+
+TBool CVCardVpbUtil::IsContactItemEmpty()
+ {
+ const MVPbkStoreContactFieldCollection& fields = ContactData()->Fields();
+ TInt count = fields.FieldCount();
+
+ TBool ret( ETrue );
+ while( count )
+ {
+ __ASSERT_DEBUG( count <= fields.FieldCount() && count > 0,
+ Panic( EInvalidIndex ) );
+
+ const MVPbkStoreContactField& field = fields.FieldAt( count - 1 );
+
+ if( !field.FieldData().IsEmpty() )
+ {
+ ret = EFalse;
+ break;
+ }
+ count--;
+ }
+ return ret;
+ }
+
+void CVCardVpbUtil::OpenComplete()
+ {
+ //nothing to do
+ }
+
+void CVCardVpbUtil::StoreReady( MVPbkContactStore& /*aContactStore*/ )
+ {
+ if( iRespondToObserverEvent )
+ {
+ iLastError = KErrNone;
+ CActiveScheduler::Stop();
+ }
+ }
+
+void CVCardVpbUtil::StoreUnavailable(
+ MVPbkContactStore& aContactStore,
+ TInt /*aReason*/ )
+ {
+ // Remove the store from the available uri list. This is the case e.g. in when SIM card
+ // is set to be default saving memory and SIM card is not inserted to phone.
+ TVPbkContactStoreUriPtr uri = aContactStore.StoreProperties().Uri();
+ iAvailableUris->Remove( uri );
+ if( iRespondToObserverEvent )
+ {
+ //we do not consider an unavailable store as leaving error situation
+ iLastError = KErrNone;
+ CActiveScheduler::Stop();
+ }
+ }
+
+void CVCardVpbUtil::HandleStoreEventL(
+ MVPbkContactStore& /*aContactStore*/,
+ TVPbkContactStoreEvent /*aStoreEvent*/ )
+ {
+ if( iRespondToObserverEvent )
+ {
+ CActiveScheduler::Stop();
+ }
+ }
+
+void CVCardVpbUtil::VPbkSingleContactOperationComplete(
+ MVPbkContactOperationBase& /*aOperation*/,
+ MVPbkStoreContact* /*aContact*/ )
+ {
+ if( iRespondToObserverEvent )
+ {
+ CActiveScheduler::Stop();
+ }
+ }
+
+void CVCardVpbUtil::VPbkSingleContactOperationFailed(
+ MVPbkContactOperationBase& /*aOperation*/,
+ TInt aError )
+ {
+ if( iRespondToObserverEvent )
+ {
+ iLastError = aError;
+ CActiveScheduler::Stop();
+ }
+ }
+
+void CVCardVpbUtil::StepComplete(
+ MVPbkContactOperationBase& /*aOperation*/,
+ TInt /*aStepSize*/ )
+ {
+ if( iRespondToObserverEvent )
+ {
+ iLastError = KErrNone;
+ }
+ }
+
+
+TBool CVCardVpbUtil::StepFailed(
+ MVPbkContactOperationBase& /*aOperation*/,
+ TInt /*aStepSize*/,
+ TInt aError )
+ {
+ if( iRespondToObserverEvent )
+ {
+ iLastError = aError;
+ CActiveScheduler::Stop();
+
+ //since we trigger a leave we can also cancel the
+ //ongoing operation
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+void CVCardVpbUtil::OperationComplete(
+ MVPbkContactOperationBase& /*aOperation*/ )
+ {
+ if( iRespondToObserverEvent )
+ {
+ iLastError = KErrNone;
+ CActiveScheduler::Stop();
+ }
+ }
+
+CVCardVpbUtil::CVCardVpbUtil()
+ {
+ }
+
+void CVCardVpbUtil::ConstructL()
+ {
+ CPbk2StoreConfiguration* storeConfiguration = CPbk2StoreConfiguration::NewL();
+ CleanupStack::PushL( storeConfiguration );
+ iAvailableUris = storeConfiguration->CurrentConfigurationL();
+
+ //if default contact store is not included in uriarray we will add it manually
+ //this happens if the store is not enabled in phonebook settings
+ TVPbkContactStoreUriPtr defaultCntDbUriPtr( VPbkContactStoreUris::DefaultCntDbUri() );
+ if ( !iAvailableUris->IsIncluded( defaultCntDbUriPtr ) )
+ {
+ iAvailableUris->AppendL( defaultCntDbUriPtr );
+ }
+
+ iContactManager = CVPbkContactManager::NewL( *iAvailableUris );
+ iStoreList = &iContactManager->ContactStoresL();
+ TInt storeCount ( iStoreList->Count() );
+ iStoreList->OpenAllL( *this );
+
+ // Every store sends EStoreReady or EOpenError event
+ for ( TInt i = 0; i < storeCount; ++i )
+ {
+ StartSchedulerAndDecideToLeaveL();
+ }
+
+ iVCardEngine = CVPbkVCardEng::NewL( *iContactManager );
+
+ if ( iAvailableUris->Count() > 0 )
+ {
+ // It is assumed that phone memory store is always succesfully opened.
+
+ // Default saving memory might not be available. E.g. if it set to SIM and SIM is
+ // not inserted to phone.
+ TVPbkContactStoreUriPtr defaultsavingstore = storeConfiguration->DefaultSavingStoreL();
+ if ( iAvailableUris->IsIncluded( defaultsavingstore ) )
+ {
+ iDefaultContactStore =
+ iContactManager->ContactStoresL().Find( defaultsavingstore );
+ }
+ else
+ {
+ iDefaultContactStore =
+ iContactManager->ContactStoresL().Find( defaultCntDbUriPtr );
+ }
+
+ iShowContactStore =
+ iContactManager->ContactStoresL().Find( defaultCntDbUriPtr );
+ }
+ else
+ {
+ // Even the phone memory store could not be opened. We can leave, since it is impossible
+ // to open vCard.
+ User::Leave( KErrCouldNotConnect );
+ }
+
+ iBuffer = HBufC::NewL(KBufferLength);
+ CleanupStack::PopAndDestroy( storeConfiguration );
+ }
+
+TBool CVCardVpbUtil::DefaultStoreSupportsAllFieldsL()
+ {
+ TBool retVal( ETrue );
+ TInt shownCount = iContactsToShow[0]->Fields().FieldCount();
+ TInt storedCount = iContactsToStore[0]->Fields().FieldCount();
+
+ CPbk2SortOrderManager* sortOrderManager = CPbk2SortOrderManager::NewL( iContactManager->FieldTypes() );
+ CleanupStack::PushL( sortOrderManager );
+
+ MPbk2ContactNameFormatter* nameFormatter = Pbk2ContactNameFormatterFactory::CreateL(
+ KUnnamedText, iContactManager->FieldTypes(),
+ *sortOrderManager );
+ CleanupStack::PushL( nameFormatter );
+
+ TInt shownTitleFields( 0 );
+ for( TInt counter = 0; counter < shownCount; counter++ )
+ {
+ const MVPbkBaseContactField& srcField = iContactsToShow[0]->Fields().FieldAt( counter );
+ const MVPbkFieldType* fieldType = srcField.BestMatchingFieldType();
+ if( nameFormatter->IsTitleFieldType( *fieldType ) )
+ shownTitleFields++;
+ }
+
+ TInt storedTitleFields( 0 );
+ for( TInt counter = 0; counter < storedCount; counter++ )
+ {
+ const MVPbkBaseContactField& srcField = iContactsToStore[0]->Fields().FieldAt( counter );
+ const MVPbkFieldType* fieldType = srcField.BestMatchingFieldType();
+ if( nameFormatter->IsTitleFieldType( *fieldType ) )
+ storedTitleFields++;
+ }
+
+ CleanupStack::Pop( 2 );
+ delete nameFormatter;
+ delete sortOrderManager;
+
+ //check if any of the dropped fields was title field
+ if( shownCount - shownTitleFields > storedCount - storedTitleFields )
+ retVal = EFalse;
+
+ return retVal;
+ }
+
+
+void CVCardVpbUtil::VCardToPhoneStoreL( RFileReadStream& aStream )
+ {
+ if( iContactsToShow.Count() > 0 )
+ {
+ iContactsToShow.ResetAndDestroy();
+ iContactsToShow.Close();
+ }
+
+ //always ensure that the read stream is in the beginning
+ //of the file
+ aStream.Source()->SeekL( MStreamBuf::ERead, EStreamBeginning, 0 );
+ MVPbkContactOperationBase* op;
+ if( iVCardType == EVCard )
+ {
+ op = iVCardEngine->ImportVCardL(
+ iContactsToShow,
+ *iShowContactStore,
+ aStream,
+ *this);
+ }
+ else
+ {
+ op =
+ iVCardEngine->ImportCompactBusinessCardL(
+ iContactsToShow,
+ *iShowContactStore,
+ aStream,
+ *this);
+ }
+ CleanupDeletePushL( op );
+ StartSchedulerAndDecideToLeaveL();
+ CleanupStack::PopAndDestroy();
+
+ }
+
+void CVCardVpbUtil::VCardToDefaultStoreL( RFileReadStream& aStream )
+ {
+ if( iContactsToStore.Count() > 0 )
+ {
+ iContactsToStore.ResetAndDestroy();
+ iContactsToStore.Close();
+ }
+
+ //always ensure that the read stream is in the beginning
+ //of the file
+ aStream.Source()->SeekL( MStreamBuf::ERead, EStreamBeginning, 0 );
+ MVPbkContactOperationBase* op;
+ if( iVCardType == EVCard )
+ {
+ op =
+ iVCardEngine->ImportVCardL(
+ iContactsToStore,
+ *iDefaultContactStore,
+ aStream,
+ *this);
+ }
+ else
+ {
+ op =
+ iVCardEngine->ImportCompactBusinessCardL(
+ iContactsToStore,
+ *iDefaultContactStore,
+ aStream,
+ *this);
+ }
+ CleanupDeletePushL( op );
+ StartSchedulerAndDecideToLeaveL();
+ CleanupStack::PopAndDestroy();
+
+ }
+
+void CVCardVpbUtil::StartSchedulerAndDecideToLeaveL()
+ {
+ //we want to control the responding to observable events to only happen
+ //to requests made from this module
+ iRespondToObserverEvent = ETrue;
+ CActiveScheduler::Start();
+ User::LeaveIfError( iLastError );
+ iRespondToObserverEvent = EFalse;
+ }
+
+TPtrC CVCardVpbUtil::FormatFieldContentL
+ (const MVPbkBaseContactField& aField)
+ {
+ const MVPbkFieldType* aFieldType = aField.BestMatchingFieldType();
+ TPtr text(iBuffer->Des());
+
+ switch (aField.FieldData().DataType())
+ {
+ case EVPbkFieldStorageTypeText:
+ {
+ const MVPbkContactFieldTextData* fieldData =
+ &MVPbkContactFieldTextData::Cast(aField.FieldData());
+ TPtrC fieldText(fieldData->Text());
+
+ if (IsFieldTypeL(*aFieldType, R_MESSAGING_PHONENUMBER_SELECTOR))
+ {
+ // telephony field
+
+ // convert number according to active number setting
+ if ( fieldText.Length() <= KBufferLength )
+ {
+ HBufC* formattedPhoneNumber = fieldText.AllocLC();
+ TPtr formatterNumber = formattedPhoneNumber->Des();
+
+ AknTextUtils::DisplayTextLanguageSpecificNumberConversion(
+ formatterNumber );
+ text.Set(ReallocBufferL(formatterNumber.Length()+4));
+ _LIT( Kstr, " " );
+ TDesC16 tmp = Kstr;
+ text.Copy(tmp);
+ text.Append(0x202A);
+ text.Append(formatterNumber);
+ text.Append(0x202C);
+ CleanupStack::PopAndDestroy(formattedPhoneNumber);
+ }
+ else
+ {
+ return fieldData->Text();
+ }
+ }
+ else if (IsFieldTypeL(*aFieldType, R_MESSAGING_SYNCRONIZATION_SELECTOR))
+ {
+ // syncronization field
+ if (!fieldText.CompareF(KVPbkContactSyncPublic))
+ {
+ HBufC* textBuffer = CCoeEnv::Static()->AllocReadResourceLC(
+ R_QTN_CALE_CONFIDENT_PUBLIC);
+ TPtr localizedSyncText = textBuffer->Des();
+ text.Set(ReallocBufferL(localizedSyncText.Length()));
+ text.Copy(localizedSyncText);
+ CleanupStack::PopAndDestroy(textBuffer);
+ }
+ else if (!fieldText.CompareF(KVPbkContactSyncNoSync))
+ {
+ HBufC* textBuffer = CCoeEnv::Static()->AllocReadResourceLC(
+ R_QTN_CALE_CONFIDENT_NONE);
+ TPtr localizedSyncText = textBuffer->Des();
+ text.Set(ReallocBufferL(localizedSyncText.Length()));
+ text.Copy(localizedSyncText);
+ CleanupStack::PopAndDestroy(textBuffer);
+ }
+ else
+ {
+ // otherwise sync setting is the default value - private
+ HBufC* textBuffer = CCoeEnv::Static()->AllocReadResourceLC(
+ R_QTN_CALE_CONFIDENT_PRIVATE);
+ TPtr localizedSyncText = textBuffer->Des();
+ text.Set(ReallocBufferL(localizedSyncText.Length()));
+ text.Copy(localizedSyncText);
+ CleanupStack::PopAndDestroy(textBuffer);
+ }
+ }
+ else
+ {
+ text.Set(ReallocBufferL(fieldText.Length()));
+ text.Copy(fieldText);
+
+ // Check is there need to display the digits in the
+ // text with foreign characters
+ // Perform number conversion if allowed
+ if (IsNumberConversionAllowed(*aFieldType))
+ {
+ AknTextUtils::DisplayTextLanguageSpecificNumberConversion(
+ text);
+ }
+ }
+ break;
+ }
+ case EVPbkFieldStorageTypeDateTime:
+ {
+ TInt error = KErrNone;
+ do
+ {
+ HBufC* timeFormat = CCoeEnv::Static()->AllocReadResourceLC(R_QTN_DATE_USUAL);
+ const MVPbkContactFieldDateTimeData* fieldData =
+ &MVPbkContactFieldDateTimeData::Cast(aField.FieldData());
+ TRAPD(error, fieldData->DateTime().FormatL(text, *timeFormat));
+ AknTextUtils::DisplayTextLanguageSpecificNumberConversion(text);
+ CleanupStack::PopAndDestroy(timeFormat); // timeFormat
+ if (error == KErrOverflow)
+ {
+ // allocate bigger buffer for formatting text
+ text.Set(ReallocBufferL(2*text.MaxLength()));
+ }
+ else if (error)
+ {
+ // rethrow other errors
+ User::Leave(error);
+ }
+ } while (error == KErrOverflow);
+ break;
+ }
+ default:
+ {
+ text.Zero();
+ break;
+ }
+ }
+
+ return text;
+ }
+
+/**
+ * Checks the field type.
+ */
+TBool CVCardVpbUtil::IsFieldTypeL(
+ const MVPbkFieldType& aFieldType,
+ TInt aResourceId) const
+ {
+ TResourceReader reader;
+ CCoeEnv::Static()->CreateResourceReaderLC(reader, aResourceId);
+
+ CVPbkFieldTypeSelector* selector = CVPbkFieldTypeSelector::NewL(
+ reader, iContactManager->FieldTypes());
+ // Check if the field type is the one needed
+ TBool ret = selector->IsFieldTypeIncluded(aFieldType);
+ CleanupStack::PopAndDestroy(); // resource buffer
+ delete selector;
+ return ret;
+ }
+
+TPtr CVCardVpbUtil::ReallocBufferL
+ (TInt aNewSize)
+ {
+ const TInt currMaxLength = iBuffer->Des().MaxLength();
+ if (aNewSize > currMaxLength)
+ {
+ iBuffer = iBuffer->ReAllocL(aNewSize);
+ }
+
+ //PostCond:
+ __ASSERT_DEBUG(iBuffer->Des().MaxLength() >= aNewSize,
+ Panic(EPanicPostCond_ReallocBufferL));
+
+ return iBuffer->Des();
+ }
+
+void CVCardVpbUtil::Panic( TInt aReason )
+ {
+ User::Panic( KClassName, aReason );
+ }
+/**
+ * Check whether default store is Full or Not.
+ */
+TBool CVCardVpbUtil::StoreFullL()
+{
+ LOG("CVCardVpbUtil::StoreFullL");
+ TBool ret( EFalse );
+ const MVPbkContactStore* iTargetStore;
+ HBufC* textBuffer;
+ CPbk2StoreConfiguration* storeConfiguration = CPbk2StoreConfiguration::NewL();
+ CleanupStack::PushL( storeConfiguration );
+ TVPbkContactStoreUriPtr defaultsavingstore = storeConfiguration->DefaultSavingStoreL();
+ iTargetStore = iContactManager->ContactStoresL().Find(defaultsavingstore );
+ const MVPbkContactStoreInfo& storeInfo = iTargetStore->StoreInfo();
+ if ( storeInfo.MaxNumberOfContactsL() != KVPbkStoreInfoUnlimitedNumber &&
+ storeInfo.MaxNumberOfContactsL() <= storeInfo.NumberOfContactsL() )
+ {
+ CVPbkContactStoreUri* uri = CVPbkContactStoreUri::NewL( defaultsavingstore );
+ CleanupStack::PushL( uri );
+ if(uri->Uri().UriDes().CompareC(KDEFAULT_CNTDB_URI) == 0 )
+ {
+ LOG("CVCardVpbUtil::StoreFullL, Phone memory full");
+ textBuffer = StringLoader::LoadLC( R_QTN_PHOB_PB_INFO_MEMORY_PHONE );
+ }
+ else
+ {
+ LOG("CVCardVpbUtil::StoreFullL, SIM memory full");
+ textBuffer = StringLoader::LoadLC( R_QTN_PHOB_PB_INFO_MEMORY_SIM );
+ }
+ ShowNoteL( R_QTN_PHOB_NOTE_STORE_FULL, textBuffer->Des() );
+ CleanupStack::PopAndDestroy(textBuffer);
+ CleanupStack::PopAndDestroy();//destroy uri
+ ret = ETrue;
+ }
+ CleanupStack::PopAndDestroy( storeConfiguration );
+ return ret;
+}
+
+/**
+ * Shows popup Note.
+ */
+void CVCardVpbUtil::ShowNoteL( TInt aResourceId, const TDesC& aString )
+{
+ LOG("CVCardVpbUtil::ShowNoteL");
+ HBufC* prompt = NULL;
+ if( aString.Length() )
+ prompt = StringLoader::LoadLC( aResourceId, aString );
+ else
+ prompt = StringLoader::LoadLC( aResourceId );
+ CAknInformationNote* dlg = new(ELeave) CAknInformationNote(ETrue);
+ dlg->ExecuteLD(*prompt);
+ CleanupStack::PopAndDestroy(); // prompt
+}
+