diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/UIControls/src/CPbk2AddressSelect.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/UIControls/src/CPbk2AddressSelect.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,962 @@ +/* +* Copyright (c) 2005-2007 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: Phonebook 2 address selection. +* +*/ + + +#include + +// Phonebook 2 +#include "CPbk2SelectFieldDlg.h" +#include "MPbk2ControlKeyObserver.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Virtual Phonebook +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include + +//SpSettings +#include +#include +#include + +/// Unnamed namespace for local definitions +namespace { + +#ifdef _DEBUG +enum TPanicCode + { + EPanicPostCond_Constructor = 1, + EPanicPreCond_ExecuteLD + }; + +static void Panic(TPanicCode aReason) + { + _LIT(KPanicText, "CPbk2AddressSelect"); + User::Panic(KPanicText, aReason); + } +#endif // _DEBUG + +#define KOneVOIPServiceAvailable 1 + +const TInt KFirstField = 0; +const TInt KDefaultTitleFormat = MPbk2ContactNameFormatter::EUseSeparator; + +/** + * Returns index of given field in store contact field collection. + * + * @param aCollection Store contact field collection. + * @param aField Store contact field to search for. + * @return Index of the given field. + */ +inline TInt IndexOfField( + const MVPbkStoreContactFieldCollection& aCollection, + const MVPbkStoreContactField& aField ) + { + TInt ret = KErrNotFound; + const TInt count = aCollection.FieldCount(); + + for ( TInt i = 0; i < count; ++i ) + { + MVPbkStoreContactField* field = aCollection.FieldAtLC( i ); + if ( aField.IsSame( *field ) ) + { + ret = i; + CleanupStack::PopAndDestroy(); // field + break; + } + CleanupStack::PopAndDestroy(); // field + } + + return ret; + } + +} /// namespace + +// MODULE DATA STRUCTURES + +/** + * Special field selection dialog class for CPbk2AddressSelect. + * The main purpose of this class is to + * get #include of MPbk2ControlKeyObserver + * away from public header CPbk2AddressSelect.h. + */ +NONSHARABLE_CLASS(CPbk2AddressSelect::CSelectFieldDlg) : + public CPbk2SelectFieldDlg, + private MPbk2ControlKeyObserver + { + public: // Construction + + /** + * Constructor. + * + * @param aParent Parent. + */ + CSelectFieldDlg( CPbk2AddressSelect& aParent ) : + iParent( aParent ) + { + SetObserver( this ); + } + + private: // From MPbk2ControlKeyObserver + TKeyResponse Pbk2ControlKeyEventL + ( const TKeyEvent& aKeyEvent, TEventCode aType ); + + private: // Data + /// Ref: Parent + CPbk2AddressSelect& iParent; + }; + + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::CSelectFieldDlg::Pbk2ControlKeyEventL +// -------------------------------------------------------------------------- +// +TKeyResponse CPbk2AddressSelect::CSelectFieldDlg::Pbk2ControlKeyEventL + ( const TKeyEvent& aKeyEvent, TEventCode aType ) + { + // Forward call to virtual function in CPbk2AddressSelect interface + return iParent.Pbk2ControlKeyEventL( aKeyEvent,aType ); + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::CPbk2AddressSelect +// -------------------------------------------------------------------------- +// +CPbk2AddressSelect::CPbk2AddressSelect( + TPbk2AddressSelectParams& aParams, + const TArray* aStoreContactsArray, + const TArray* aPresenceIconsArray ): + iParams( aParams ), + iStoreContactsArray( aStoreContactsArray ), + iPresenceIconsArray( aPresenceIconsArray ) + { + __ASSERT_DEBUG + ( !iFieldDlg && !iDestroyedPtr, + Panic( EPanicPostCond_Constructor ) ); + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::~CPbk2AddressSelect +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2AddressSelect::~CPbk2AddressSelect() + { + // Tell ExecuteLD this object is already destroyed + if (iDestroyedPtr) + { + *iDestroyedPtr = ETrue; + } + + // Set eliminator pointer to NULL + if ( iSelfPtr ) + { + *iSelfPtr = NULL; + } + + delete iFieldDlg; + delete iFieldFilter; + delete iFieldTypeSelector; + iFieldFilterArray.ResetAndDestroy(); + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2AddressSelect* CPbk2AddressSelect::NewL + ( TPbk2AddressSelectParams& aParams ) + { + CPbk2AddressSelect* self = new ( ELeave ) CPbk2AddressSelect( + aParams, NULL, NULL ); + CleanupStack::PushL( self ); + self->ConstructL( NULL ); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2AddressSelect* CPbk2AddressSelect::NewL + ( TPbk2AddressSelectParams& aParams, + CVPbkFieldTypeSelector& aFieldTypeSelector, + const TArray* aStoreContactsArray, + const TArray* aPresenceIconsArray ) + { + CPbk2AddressSelect* self = new ( ELeave ) CPbk2AddressSelect( aParams, + aStoreContactsArray, aPresenceIconsArray ); + CleanupStack::PushL( self ); + self->ConstructL( &aFieldTypeSelector ); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::ConstructL +// -------------------------------------------------------------------------- +// +void CPbk2AddressSelect::ConstructL( + CVPbkFieldTypeSelector* aFieldTypeSelector ) + { + // Read the resource referenced in address select resource struct + const TInt fieldTypeSelectorRes = iParams.iResReader.ReadInt32(); + TResourceReader selectorReader; + CCoeEnv::Static()->CreateResourceReaderLC + ( selectorReader, fieldTypeSelectorRes ); + if ( aFieldTypeSelector == NULL ) + { + // Give that resource reader to the field type selector + iFieldTypeSelector = CVPbkFieldTypeSelector::NewL + ( selectorReader, iParams.iContactManager.FieldTypes() ); + } + else + { + iFieldTypeSelector = CVPbkFieldTypeSelector::NewL( + *aFieldTypeSelector ); + } + CleanupStack::PopAndDestroy(); // selectorReader + + iNoAddressesForNamePromptResource = iParams.iResReader.ReadInt32(); + iNoAddressesPromptResource = iParams.iResReader.ReadInt32(); + iSoftKeyResource = iParams.iResReader.ReadInt32(); + + const CVPbkFieldFilter::TConfig config + ( const_cast + ( iParams.iContact.Fields() ), + iFieldTypeSelector, NULL ); + + iFieldFilter = CVPbkFieldFilter::NewL( config ); + + if ( iStoreContactsArray != NULL && iStoreContactsArray->Count() != 0 ) + { + TInt count = iStoreContactsArray->Count(); + for ( TInt i = 0; i < count; i++ ) + { + const CVPbkFieldFilter::TConfig conf + ( const_cast + ( iStoreContactsArray->operator[](i)->Fields() ), + iFieldTypeSelector, NULL ); + CVPbkFieldFilter* fieldFilter = CVPbkFieldFilter::NewL( conf ); + CleanupStack::PushL( fieldFilter ); + iFieldFilterArray.AppendL( fieldFilter ); + CleanupStack::Pop(); //fieldfilter + } + } + + CPbk2ApplicationServices* appServices = + CPbk2ApplicationServices::InstanceLC(); + iAttributeManager = + &appServices->ContactManager().ContactAttributeManagerL(); + CleanupStack::PopAndDestroy(); // appServices + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::ExecuteLD +// -------------------------------------------------------------------------- +// +EXPORT_C MVPbkStoreContactField* CPbk2AddressSelect::ExecuteLD() + { + __ASSERT_DEBUG( !iFieldDlg, Panic( EPanicPreCond_ExecuteLD ) ); + + // "D" function semantics + CleanupStack::PushL( this ); + TBool thisDestroyed = EFalse; + // Ensure that thisDestroyed will be ETrue if this object is destroyed. + // See in destructor how this is done. + iDestroyedPtr = &thisDestroyed; + + SelectFieldL(); + + MVPbkStoreContactField* returnedField = NULL; + if ( iSelectedField ) + { + // We cannot return iSelectedField directly since if its NULL, + // it's value changes to 0xdedede before it is returned. + // Therefore we must test iSelectedField before assigning it + // to returnedField. + returnedField = iSelectedField; + } + + if ( thisDestroyed ) + { + // This object has already been destroyed + CleanupStack::Pop( this ); + returnedField = NULL; + } + else + { + CleanupStack::PopAndDestroy( this ); + } + + return returnedField; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::AttemptExitL +// -------------------------------------------------------------------------- +// +EXPORT_C void CPbk2AddressSelect::AttemptExitL( TBool aAccept ) + { + if ( iFieldDlg ) + { + iFieldDlg->AttemptExitL( aAccept ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::Pbk2ControlKeyEventL +// -------------------------------------------------------------------------- +// +EXPORT_C TKeyResponse CPbk2AddressSelect::Pbk2ControlKeyEventL + ( const TKeyEvent& aKeyEvent, TEventCode aType ) + { + TKeyResponse ret = EKeyWasNotConsumed; + + if ( aType == EEventKey && aKeyEvent.iCode == EKeyPhoneSend ) + { + // Event is Send key, tell field selection dialog to accept + // current selection + AttemptExitL( ETrue ); + ret = EKeyWasConsumed; + } + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::SetCba +// -------------------------------------------------------------------------- +// +EXPORT_C void CPbk2AddressSelect::SetCba( TInt aCbaResourceId ) + { + iSoftKeyResource = aCbaResourceId; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::RequestExitL +// -------------------------------------------------------------------------- +// +void CPbk2AddressSelect::RequestExitL( TInt aCommandId ) + { + if ( aCommandId == EEikBidCancel ) + { + AttemptExitL( EFalse ); + } + else if ( aCommandId == EEikBidOk ) + { + AttemptExitL( ETrue ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::ForceExit +// -------------------------------------------------------------------------- +// +void CPbk2AddressSelect::ForceExit() + { + TRAPD( err, AttemptExitL( EFalse ) ); + if ( err != KErrNone ) + { + // If not nicely then use the force + delete this; + } + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::ResetWhenDestroyed +// -------------------------------------------------------------------------- +// +void CPbk2AddressSelect::ResetWhenDestroyed( + MPbk2DialogEliminator** aSelfPtr ) + { + iSelfPtr = aSelfPtr; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::AddressField +// Returns true if aField is an applicable address field. +// -------------------------------------------------------------------------- +// +TBool CPbk2AddressSelect::AddressField + ( const MVPbkStoreContactField& aField ) const + { + TBool ret = EFalse; + + // Return true if field belongs to the selector + ret = ( iFieldFilter->FindField( aField ) == + KErrNotFound ) ? EFalse : ETrue; + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::NoAddressesL +// Called if there are no applicable address fields in a contact passed +// to ExecuteLD. +// -------------------------------------------------------------------------- +// +void CPbk2AddressSelect::NoAddressesL + ( TPbk2AddressSelectParams aParams ) const + { + if ( !aParams.iSuppressWarnings ) + { + HBufC* prompt = NULL; + HBufC* name = aParams.iNameFormatter.GetContactTitleOrNullL + ( iParams.iContact.Fields(), KDefaultTitleFormat ); + + if ( name ) + { + CleanupStack::PushL(name); + prompt = StringLoader::LoadL + ( iNoAddressesForNamePromptResource, *name ); + CleanupStack::PopAndDestroy(); // name + } + else + { + prompt = StringLoader::LoadL( iNoAddressesPromptResource ); + } + + if ( prompt ) + { + CleanupStack::PushL( prompt ); + // This is a waiting dialog because the address select might be + // used from the application server and the information note will + // disappear if the application server closes before the + // note timeout has expired, thus causing blinking + CAknInformationNote* noteDlg = + new ( ELeave ) CAknInformationNote( ETrue ); + noteDlg->ExecuteLD( *prompt ); + CleanupStack::PopAndDestroy(); // prompt + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::SelectFieldL +// -------------------------------------------------------------------------- +// +inline void CPbk2AddressSelect::SelectFieldL() + { + // If currently focused field is an applicable field + if ( iParams.iFocusedField && AddressField( *iParams.iFocusedField ) ) + { + // Applicable field was focused -> return field + SetSelectedFieldL( iParams.iFocusedField ); + } + else + { + TBool found = EFalse; + // Focus is in on some other field, first check default field + if ( iParams.iDefaultPriorities && + iParams.iUseDefaultDirectly && + iParams.iDefaultPriorities->Count() > 0 ) + { + found = SelectFromDefaultFieldsL(); + } + + if ( !found ) + { + // No direct call to focused or default number, we have to + // select from applicable fields + SelectFromApplicableFieldsL(); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::SelectFromApplicableFieldsL +// -------------------------------------------------------------------------- +// +inline void CPbk2AddressSelect::SelectFromApplicableFieldsL() + { + TInt indexOfDefault = IndexOfDefaultFieldL(); + TInt fieldCount = iFieldFilter->FieldCount(); + + // check also addiotnal contacts + if ( iFieldFilterArray.Count() > 0 ) + { + TInt count = iFieldFilterArray.Count(); + for ( TInt i = 0; i < count; i++ ) + { + fieldCount += iFieldFilterArray[i]->FieldCount(); + } + } + + // Different actions for different number of applicable fields found + if ( fieldCount == 0 ) + { + // No applicable addresses found + NoAddressesL( iParams ); + } + else if ( fieldCount == 1 && !iParams.iQueryAlways ) + { + // Exactly one applicable address found, just return it + if ( iFieldFilter->FieldCount() != 0 ) + { + SetSelectedFieldL( &iFieldFilter->FieldAt( KFirstField ) ); + } + else + { + SetSelectedFieldL( &iFieldFilterArray[0]->FieldAt( KFirstField ) ); + } + } + else if (fieldCount > 1 || iParams.iQueryAlways ) + { + HBufC* title = LoadDialogTitleL(); + + // Run the address selection dialog + CleanupStack::PushL( title ); + iFieldDlg = new ( ELeave ) CSelectFieldDlg( *this ); + iFieldDlg->ResetWhenDestroyed( &iFieldDlg ); + const MVPbkStoreContactField* field = NULL; + field = iFieldDlg->ExecuteLCD + ( *iFieldFilter, + iFieldFilterArray, + iPresenceIconsArray, + iParams.iContactManager, + iParams.iFieldPropertyArray, + iSoftKeyResource, + iParams.iCommMethod, + *title, + indexOfDefault ); + + SetSelectedFieldL( field ); + + CleanupStack::PopAndDestroy( 2 ); // field, title + } + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::IndexOfDefaultFieldL +// -------------------------------------------------------------------------- +// +inline TInt CPbk2AddressSelect::IndexOfDefaultFieldL() + { + TInt ret = KErrNotFound; + + const MVPbkStoreContactField* field = FindDefaultFieldLC(); + if ( field ) + { + ret = iFieldFilter->FindField( *field ); + } + CleanupStack::PopAndDestroy(); // field + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::SelectFromDefaultFieldsL +// -------------------------------------------------------------------------- +// +inline TBool CPbk2AddressSelect::SelectFromDefaultFieldsL() + { + TBool found = EFalse; + + const MVPbkStoreContactField* field = FindDefaultFieldLC(); + if ( field ) + { + SetSelectedFieldL( field ); + found = ETrue; + } + CleanupStack::PopAndDestroy(); // field + + return found; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::FindDefaultFieldLC +// -------------------------------------------------------------------------- +// +MVPbkStoreContactField* CPbk2AddressSelect::FindDefaultFieldLC() + { + MVPbkStoreContactField* ret = NULL; + + // Go through the default priorities array, and + // check does a specific default exist + if ( iParams.iDefaultPriorities ) + { + const TInt defaultCount = iParams.iDefaultPriorities->Count(); + + for (TInt i=0; iAt(i); + + // Create an attribute prototype out of the attribute identifier + CVPbkDefaultAttribute* attr = + CVPbkDefaultAttribute::NewL( defaultType ); + CleanupStack::PushL( attr ); + + if ( iAttributeManager->HasContactAttributeL + ( *attr, iParams.iContact ) ) + { + const MVPbkStoreContactFieldCollection& fields = + iParams.iContact.Fields(); + + // Get the field with attribute + const TInt fieldCount = fields.FieldCount(); + for ( TInt j = 0; j < fieldCount; ++j ) + { + if ( iAttributeManager->HasFieldAttributeL + ( *attr, fields.FieldAt( j ) ) ) + { + ret = fields.FieldAtLC( j ); + CleanupStack::Pop(); // ret + break; + } + } + } + + CleanupStack::PopAndDestroy( attr ); + } + } + + CleanupDeletePushL( ret ); + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::SetSelectedFieldL +// -------------------------------------------------------------------------- +// +inline void CPbk2AddressSelect::SetSelectedFieldL + ( const MVPbkStoreContactField* aField ) + { + if ( aField ) + { + const MVPbkStoreContactFieldCollection& fields = + iParams.iContact.Fields(); + TInt index = IndexOfField( fields, *aField ); + if ( index >= 0 ) + { + // field from main contact + iSelectedField = fields.FieldAtLC( index ); + CleanupStack::Pop(); + } + else if ( iStoreContactsArray != NULL && + iStoreContactsArray->Count() > 0 ) + { + // field from additional contact + TInt count = iStoreContactsArray->Count(); + for( TInt i = 0; i < count; i++ ) + { + const MVPbkStoreContactFieldCollection& xspFields = + iStoreContactsArray->operator[](i)->Fields(); + index = IndexOfField( xspFields, *aField ); + if ( index >= 0 ) + { + iSelectedField = xspFields.FieldAtLC( index ); + CleanupStack::Pop(); + break; + } + } + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::LoadDialogTitleL +// -------------------------------------------------------------------------- +// +inline HBufC* CPbk2AddressSelect::LoadDialogTitleL() + { + HBufC* title = NULL; + switch( iParams.iCommMethod ) + { + case VPbkFieldTypeSelectorFactory::EVoiceCallSelector: + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_CALL ); + break; + } + case VPbkFieldTypeSelectorFactory::EUniEditorSelector: + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_MESSAGE ); + break; + } + case VPbkFieldTypeSelectorFactory::EEmailEditorSelector: + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_EMAIL ); + break; + } + case VPbkFieldTypeSelectorFactory::EInstantMessagingSelector: + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_CHAT ); + break; + } + case VPbkFieldTypeSelectorFactory::EVOIPCallSelector: + { + title = GetVOIPDialogTitleL(); + break; + } + case VPbkFieldTypeSelectorFactory::EURLSelector: + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_URL ); + break; + } + case VPbkFieldTypeSelectorFactory::EVideoCallSelector: + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_VIDEO_CALL ); + break; + } + case VPbkFieldTypeSelectorFactory::EFindOnMapSelector: + { + if ( AreGeoFieldsForAddressesL() ) + { + title = StringLoader::LoadL( R_QTN_CCA_POPUP_SHOW_ON_MAP ); + } + else + { + title = StringLoader::LoadL( R_QTN_CCA_POPUP_FIND_ON_MAP ); + } + break; + } + case VPbkFieldTypeSelectorFactory::EAssignFromMapSelector: + { + title = StringLoader::LoadL( R_QTN_CCA_POPUP_ASSIGN_FROM_MAP ); + break; + } + case VPbkFieldTypeSelectorFactory::EPocSelector: + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_PUSH_TO_TALK ); + break; + } + default: + { + HBufC* entryTitle = iParams.iNameFormatter.GetContactTitleL + ( iParams.iContact.Fields(), KDefaultTitleFormat ); + CleanupStack::PushL( entryTitle ); + + if ( iParams.iTitleResId ) + { + if ( iParams.iIncludeContactNameInPrompt ) + { + title = StringLoader::LoadL + ( iParams.iTitleResId, *entryTitle ); + } + else + { + title = StringLoader::LoadL + ( iParams.iTitleResId ); + } + CleanupStack::PopAndDestroy( entryTitle ); + } + else + { + title = entryTitle; // takes ownership of entryTitle + CleanupStack::Pop( entryTitle ); + entryTitle = NULL; + } + break; + } + } + + return title; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::AreGeoFieldsForAddressesL +// -------------------------------------------------------------------------- +// +TBool CPbk2AddressSelect::AreGeoFieldsForAddressesL() + { + TBool result = EFalse; + TBool generalAddress = ETrue; + TBool homeAddress = ETrue; + TBool workAddress = ETrue; + TInt startIndex = 0; + + TPbk2StoreContactAnalyzer analyzer( iParams.iContactManager, NULL ); + + TInt countFields = iParams.iContact.Fields().FieldCount(); + for ( TInt i = 0; i < countFields; i++ ) + { + const MVPbkStoreContactField& field = + iParams.iContact.Fields().FieldAt( i ); + TInt countProps = + field.BestMatchingFieldType()->VersitProperties().Count(); + TArray props = + field.BestMatchingFieldType()->VersitProperties(); + for ( TInt ii = 0; ii < countProps; ii++ ) + { + if ( props[ ii ].Name() == EVPbkVersitNameADR ) + { + if ( props[ ii ].Parameters().Contains( + EVPbkVersitParamHOME ) ) + { + homeAddress = EFalse; + } + else if ( props[ ii ].Parameters().Contains( + EVPbkVersitParamWORK ) ) + { + workAddress = EFalse; + } + else + { + generalAddress = EFalse; + } + } + } + } + + if ( !homeAddress ) + { + if ( analyzer.HasFieldL( R_PHONEBOOK2_HOME_GEO_SELECTOR, + startIndex, &iParams.iContact ) != KErrNotFound ) + { + homeAddress = ETrue; + } + } + if ( !workAddress ) + { + if ( analyzer.HasFieldL( R_PHONEBOOK2_WORK_GEO_SELECTOR, + startIndex, &iParams.iContact ) != KErrNotFound ) + { + workAddress = ETrue; + } + } + if ( !generalAddress ) + { + if ( analyzer.HasFieldL( R_PHONEBOOK2_GENERAL_GEO_SELECTOR, + startIndex, &iParams.iContact ) != KErrNotFound ) + { + generalAddress = ETrue; + } + } + + if ( generalAddress && homeAddress && workAddress ) + { + result = ETrue; + } + else + { + result = EFalse; + } + + return result; + } + +// -------------------------------------------------------------------------- +// CPbk2AddressSelect::GetVOIPDialogTitleL +// -------------------------------------------------------------------------- +// +inline HBufC* CPbk2AddressSelect::GetVOIPDialogTitleL() + { + //Usecase : If we have only one voip service, the voip(Internet Call) + //dialog title must be "ServiceName" appended with "call:". + //eg : If we have a service named SKYPE installed in the Phone + //and if SKYPE supports VOIP, dialog title should be + //"SKYPE call:". + //If we have more than one voip service, then the VOIP dialog title must be + //should be R_QTN_PHOB_TITLE_POPUP_VOIP_CALL + //as defined in the rss + + //Check whether we have more than one voip service configured + //in the Phone + HBufC* title (NULL); + TPtrC tempTitle; + RIdArray idArray; + CleanupClosePushL(idArray); + CSPSettings* settings = CSPSettings::NewLC(); + TInt numServSupportInternetCall (0); //Num of Service that support InternetCall + TServiceId serviceId (0); //Stores the last found Service Id of VOIP Service + TInt findResult = settings->FindServiceIdsL(idArray); + if ( findResult == KErrNone ) + { + for (TInt i = 0; i < idArray.Count(); ++i) + { + TBool supported( EFalse ); + CSPEntry* entry = CSPEntry::NewLC(); + TServiceId id = idArray[i]; + User::LeaveIfError( settings->FindEntryL(id, *entry) ); + const CSPProperty* property = NULL; + + //Mandatory Settings for VOIP + if (entry->GetProperty(property, EPropertyServiceAttributeMask) == KErrNone) + { + TInt value = 0; + property->GetValue(value); + if ( value & ESupportsInternetCall ) + { + serviceId = id; + numServSupportInternetCall++; + } + } + CleanupStack::PopAndDestroy(); // entry + } + CleanupStack::PopAndDestroy(2); // settings, idArray + + if ( KOneVOIPServiceAvailable == numServSupportInternetCall ) + { + // get the XSP ServiceName + // CPbk2ServiceManager stores all the brandinfo + // related to the services configured to the phone + // use this to show uniform icon & name throughout PhoneBook + MPbk2ApplicationServices2* servicesExtension = + reinterpret_cast + ( Phonebook2::Pbk2AppUi()->ApplicationServices(). + MPbk2ApplicationServicesExtension( + KMPbk2ApplicationServicesExtension2Uid ) ); + CPbk2ServiceManager& servMan = servicesExtension->ServiceManager(); + const CPbk2ServiceManager::RServicesArray& services = servMan.Services(); + for ( TInt i = 0; i < services.Count(); i++ ) + { + const CPbk2ServiceManager::TService& service = services[i]; + //Found the appropriate service info + if ( service.iServiceId == serviceId ) + { + tempTitle.Set( service.iDisplayName ); + break; + } + } + } + } + if ( tempTitle.Length() ) + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_VOIP_CALL_SINGLE_SERVICE, + tempTitle); + } + else + { + title = StringLoader::LoadL( R_QTN_PHOB_TITLE_POPUP_VOIP_CALL ); + } + + return title; + } + +// End of File