diff -r 5b6f26637ad3 -r f4a778e096c2 phonebookui/Phonebook2/Commands/src/CPbk2CommandHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/Commands/src/CPbk2CommandHandler.cpp Wed Sep 01 12:29:52 2010 +0100 @@ -0,0 +1,1130 @@ +/* +* 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 command handler. +* +*/ + + +// INCLUDE FILES +#include "CPbk2CommandHandler.h" + +// Phonebook 2 +#include "CPbk2CommandFactory.h" +#include "CPbk2CommandStore.h" +#include "CPbk2AiwInterestArray.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Virtual Phonebook +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include +#include +#include +#include + + +/// Unnamed namespace for local definitions +namespace { + +#ifdef _DEBUG +enum TPanicCode + { + EPanicPreCond_CmdOpenMeViewsL = 1, + EPanicPreCond_CmdOpenSettingsViewL, + EPanicPreCond_CmdOpenPreviousViewL, + EPanicPreCond_CmdOpenHelpL, + EPanicLogic_FocusedFieldMatchesFieldTypeL, + EPanicLogic_FocusedContactHasFieldTypeL + }; + +void Panic(TPanicCode aReason) + { + _LIT(KPanicText, "CPbk2CommandHandler"); + User::Panic(KPanicText, aReason); + } +#endif //_DEBUG + +/** + * Checks if focused field is of given field type. + * + * @param aUiControl UI control. + * @param aSelectorResId Selector resource id. + * @param aContactManager Virtual Phonebook contact manager. + * @return ETrue if field type matches with given types. + */ +TBool FocusedFieldMatchesFieldTypeL( + MPbk2ContactUiControl& aUiControl, + TInt aSelectorResId, + CVPbkContactManager& aContactManager ) + { + const MVPbkStoreContact* contact = aUiControl.FocusedStoreContact(); + __ASSERT_DEBUG(contact, Panic + ( EPanicLogic_FocusedFieldMatchesFieldTypeL ) ); + + TPbk2StoreContactAnalyzer analyzer( aContactManager, NULL ); + const MVPbkBaseContactField* field = aUiControl.FocusedField(); + return field && + analyzer.IsFieldTypeIncludedL( *field, aSelectorResId ); + } + +/** + * Checks if the focused contact have a given field type. + * + * @param aUiControl UI control + * @param aSelectorResId Selector resource id. + * @param aContactManager Virtual Phonebook contact manager. + * @return Index of the field having the type, KErrNotFound if + * the contact does not have the field type. + */ + TInt FocusedContactHasFieldTypeL( + MPbk2ContactUiControl& aUiControl, + TInt aSelectorResId, + CVPbkContactManager& aContactManager ) + { + TInt ret = KErrNotFound; + const MVPbkStoreContact* contact = aUiControl.FocusedStoreContact(); + __ASSERT_DEBUG( contact, + Panic( EPanicLogic_FocusedContactHasFieldTypeL ) ); + + TPbk2StoreContactAnalyzer analyzer( aContactManager, contact ); + ret = analyzer.HasFieldL( aSelectorResId ); + return ret; + } + +/** + * Checks if command is 'exit' command. + * + * @param aCommandId The command to check. + * @return ETrue if command is an exit command, EFalse otherwise. + */ +TBool IsExitCommand( TInt aCommandId ) + { + TBool ret = EFalse; + + if ( EEikCmdExit == aCommandId || EAknSoftkeyExit == aCommandId || + EAknCmdExit == aCommandId || EPbk2CmdExit == aCommandId ) + { + ret = ETrue; + } + + return ret; + } + +} /// namespace + + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::CPbk2CommandHandler +// -------------------------------------------------------------------------- +// +inline CPbk2CommandHandler::CPbk2CommandHandler() + { + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::~CPbk2CommandHandler +// -------------------------------------------------------------------------- +// +CPbk2CommandHandler::~CPbk2CommandHandler() + { + delete iAiwInterestArray; + delete iCommandStore; + delete iCommandFactory; + delete iContactRelocator; + Release(iExtensionManager); + Release(iAppServices); + FeatureManager::UnInitializeLib(); + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2CommandHandler* CPbk2CommandHandler::NewL() + { + CPbk2CommandHandler* self = new(ELeave) CPbk2CommandHandler(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::ConstructL +// -------------------------------------------------------------------------- +// +inline void CPbk2CommandHandler::ConstructL() + { + iCommandFactory = CPbk2CommandFactory::NewL(); + iCommandStore = CPbk2CommandStore::NewL(); + iAiwInterestArray = CPbk2AiwInterestArray::NewL(); + iExtensionManager = CPbk2UIExtensionManager::InstanceL(); + iContactRelocator = CPbk2ContactRelocator::NewL(); + iAppServices = CPbk2ApplicationServices::InstanceL(); + + // Initialize feature manager + FeatureManager::InitializeLibL(); + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::HandleCommandL +// -------------------------------------------------------------------------- +// +TBool CPbk2CommandHandler::HandleCommandL + ( const TInt aCommandId, MPbk2ContactUiControl& aControl, + const CPbk2AppViewBase* aAppView ) + { + TBool ret = ETrue; + + // Exit commands are forwarded right away to appui + // Otherwise there is possibility that + // 'exit' command is not handled in low memory situations + if ( IsExitCommand( aCommandId ) ) + { + ret = EFalse; + } + + // Offer the command to AIW unless it is exit command + if ( ret && !iAiwInterestArray->HandleCommandL + ( aCommandId, aControl, KNullHandle ) ) + { + // Try generic command, this can also be a command from an extension + ret = CmdGenericCommandL( TPbk2CommandId( aCommandId ), aControl ); + if ( !ret ) + { + ret = ETrue; + switch ( aCommandId ) + { + case EAknSoftkeyBack: // FALLTHROUGH + case EPbk2CmdOpenPreviousView: + { + CmdOpenPreviousViewL( aControl, aAppView ); + break; + } + case EPbk2CmdSettings: + { + CmdOpenSettingsViewL( aControl, aAppView, + Phonebook2::KPbk2SettingsViewUid ); + break; + } + case EAknCmdHelp: + { + CmdOpenHelpL( aControl, aAppView ); + break; + } + default: + { + ret = EFalse; + break; + } + } + } + } + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::DynInitMenuPaneL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::DynInitMenuPaneL( + TInt aResourceId, + CEikMenuPane* aMenuPane, + CPbk2AppViewBase& aViewBase, + MPbk2ContactUiControl& aControl ) + { + // First, delegate to AIW interests. + // If the menu initialization is handled there, + // there's no need to continue here + if ( !iAiwInterestArray->DynInitMenuPaneL + ( aResourceId, *aMenuPane, aControl ) ) + { + // Then call extensions + iExtensionManager->DynInitMenuPaneL( aResourceId, aMenuPane, + aViewBase, aControl ); + + // First perform standard menu filtering + PerformStandardMenuFilteringL( aResourceId, aMenuPane, aControl ); + + // Then perform field type based filtering + PerformFieldTypeBasedFilteringL( aResourceId, aMenuPane, aControl ); + + // Finally perform store specific filtering + PerformStoreSpecificFilteringL( aResourceId, aMenuPane, aControl ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::RegisterAiwInterestL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::RegisterAiwInterestL( + const TInt aInterestId, + const TInt aMenuResourceId, + const TInt aInterestResourceId, + const TBool aAttachBaseService) + { + iAiwInterestArray->QueueInterestL(aInterestId, + aMenuResourceId, aInterestResourceId, aAttachBaseService); + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::ServiceCmdByMenuCmd +// -------------------------------------------------------------------------- +// +TInt CPbk2CommandHandler::ServiceCmdByMenuCmd( + TInt aMenuCmdId ) const + { + return iAiwInterestArray->ServiceCmdByMenuCmd( aMenuCmdId ); + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::AddAndExecuteCommandL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::AddAndExecuteCommandL( + MPbk2Command* aCommand) + { + iCommandStore->AddAndExecuteCommandL(aCommand); + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::AddMenuCommandObserver +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::AddMenuCommandObserver( + MPbk2MenuCommandObserver& aObserver) + { + iCommandStore->AddMenuCommandObserver(aObserver); + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::RemoveMenuCommandObserver +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::RemoveMenuCommandObserver( + MPbk2MenuCommandObserver& aObserver) + { + iCommandStore->RemoveMenuCommandObserver(aObserver); + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::DynInitToolbarL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::DynInitToolbarL + ( TInt aResourceId, CAknToolbar* aToolbar, + const CPbk2AppViewBase& /*aAppView*/, + MPbk2ContactUiControl& aControl ) + { + switch ( aResourceId ) + { + case R_PBK2_NAMESLIST_TOOLBAR: + { + if ( aControl.FocusedContactIndex() == KErrNotFound ) + { + // If there is not focused contact (empty list or otherwise no + // focus) then disable calling and message writing + aToolbar->SetItemDimmed( EPbk2CmdCall, ETrue, ETrue ); + aToolbar->SetItemDimmed( EPbk2CmdWriteNoQuery, ETrue, ETrue ); + } + else if ( aControl.ContactsMarked() ) + { + // Disable calling to many contacts + aToolbar->SetItemDimmed( EPbk2CmdCall, ETrue, ETrue ); + } + break; + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::OfferToolbarEventL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::OfferToolbarEventL + ( TInt aCommand, MPbk2ContactUiControl& aControl, + const CPbk2AppViewBase* aAppView ) + { + if ( aAppView ) + { + HandleCommandL( aCommand, aControl, aAppView ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::CmdOpenSettingsViewL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::CmdOpenSettingsViewL + ( MPbk2ContactUiControl& aControl, + const CPbk2AppViewBase* aAppView, TUid aViewId ) + { + if (aAppView) + { + // Phonebook 2 view explorer for view switching + MPbk2ViewExplorer* viewExplorer = Phonebook2::Pbk2AppUi()->Pbk2ViewExplorer(); + + __ASSERT_DEBUG( viewExplorer, + Panic( EPanicPreCond_CmdOpenSettingsViewL ) ); + + CPbk2ViewState* state = aAppView->ViewStateLC(); + viewExplorer->ActivatePhonebook2ViewL + ( aViewId, state ); + CleanupStack::PopAndDestroy( state ); + aControl.UpdateAfterCommandExecution(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::CmdOpenPreviousViewL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::CmdOpenPreviousViewL + ( MPbk2ContactUiControl& /*aControl*/, + const CPbk2AppViewBase* aAppView ) + { + if (aAppView) + { + // Phonebook 2 view explorer for view switching + MPbk2ViewExplorer* viewExplorer = Phonebook2::Pbk2AppUi()->Pbk2ViewExplorer(); + + CPbk2ViewState* state = aAppView->ViewStateLC(); + viewExplorer->ActivatePreviousViewL( state ); + CleanupStack::PopAndDestroy( state ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::CmdOpenHelpL +// -------------------------------------------------------------------------- +// +void CPbk2CommandHandler::CmdOpenHelpL + ( MPbk2ContactUiControl& aControl, + const CPbk2AppViewBase* aAppView ) + { + if ( aAppView ) + { + TCoeHelpContext helpContext; + if ( iExtensionManager->GetHelpContextL + ( helpContext, *aAppView, aControl) ) + { + CArrayFix* helpContextArray = + new (ELeave) CArrayFixFlat( 1 ); + CleanupStack::PushL( helpContextArray ); + helpContextArray->AppendL( helpContext ); + + // HlpLauncher destroys the help context array + CleanupStack::Pop( helpContextArray ); + HlpLauncher::LaunchHelpApplicationL + ( CCoeEnv::Static()->WsSession(), helpContextArray ); + } + else + { + HlpLauncher::LaunchHelpApplicationL + ( CCoeEnv::Static()->WsSession(), + CEikonEnv::Static()->EikAppUi()->AppHelpContextL() ); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::CmdGenericCommandL +// -------------------------------------------------------------------------- +// +TBool CPbk2CommandHandler::CmdGenericCommandL( + TPbk2CommandId aCommandId, + MPbk2ContactUiControl& aControl) + { + // Create the command object + TBool result = EFalse; + MPbk2Command* cmd = iCommandFactory->CreateCommandForIdL( + aCommandId, aControl); + if (cmd) + { + // If command factory was able to create the command, + // add it to the command store and execute it + iCommandStore->AddAndExecuteCommandL(cmd); + result = ETrue; + } + return result; + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::PerformStandardMenuFilteringL +// -------------------------------------------------------------------------- +// +inline void CPbk2CommandHandler::PerformStandardMenuFilteringL( + TInt aResourceId, + CEikMenuPane* aMenuPane, + MPbk2ContactUiControl& aControl ) + { + switch (aResourceId) + { + case R_PHONEBOOK2_NAMESLIST_DELETE_MENU: + { + if ( aControl.NumberOfContacts() == 0 ) + { + aMenuPane->SetItemDimmed( EPbk2CmdDeleteMe, ETrue ); + } + break; + } + + case R_PHONEBOOK2_NAMELIST_CALL_CONTACT_MENU: + { + // Weed out commands not meant to be used with marked items + if ( aControl.ContactsMarked() ) + { + aMenuPane->SetItemDimmed( EPbk2CmdCall, ETrue ); + } + break; + } + + case R_PHONEBOOK2_NAMESLIST_CREATE_MENU: + { + // Weed out commands not meant to be used with marked items + if ( aControl.ContactsMarked() ) + { + aMenuPane->SetItemDimmed( EPbk2CmdCreateNew, ETrue ); + } + break; + } + + case R_PHONEBOOK2_NAMESLIST_SEND_URL_MENU: + { + // Weed out commands not meant to be used with empty list + if ( aControl.NumberOfContacts() == 0 ) + { + aMenuPane->SetItemDimmed( EPbk2CmdGoToURL, ETrue ); + } + + if ( aControl.ContactsMarked() ) + { + aMenuPane->SetItemDimmed( EPbk2CmdGoToURL, ETrue ); + } + break; + } + + case R_PHONEBOOK2_NAMESLIST_COPY_MENU: // FALLTHROUGH + case R_PHONEBOOK2_NAMESLIST_COPY_CONTEXT_MENU: + { + // The copy menu is not shown if there are no contacts + TBool itemSpecCommEnabled = Phonebook2::Pbk2AppUi()->ActiveView()->MenuBar()->ItemSpecificCommandsEnabled(); + if ( aControl.NumberOfContacts() == 0 || + ( !aControl.ContactsMarked() && !itemSpecCommEnabled ) || + ( !aControl.FocusedContactL() && itemSpecCommEnabled && + !aControl.ContactsMarked() ) ) + { + aMenuPane->SetItemDimmed( EPbk2CmdCopy, ETrue ); + } + break; + } + + case R_PHONEBOOK2_CONTACTINFO_EDIT_MENU: + { + // Weed out commands not meant to be used with empty contact + if ( aControl.NumberOfContactFields() == 0 ) + { + aMenuPane->SetItemDimmed( EPbk2CmdWrite, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdGoToURL, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdDefaultSettings, ETrue ); + } + break; + } + + case R_PHONEBOOK2_CONTACTINFO_EXTENDED_MENU: + { + CVPbkContactManager& manager = iAppServices->ContactManager(); + + // Always dim thumbnail if image/text supported or vice versa + if ( FeatureManager::FeatureSupported + ( KFeatureIdCallImagetext ) ) + { + aMenuPane->SetItemDimmed( EPbk2CmdFetchThumbnail, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdRemoveThumbnail, ETrue ); + } + else + { + aMenuPane->SetItemDimmed( EPbk2CmdAddImage, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdImage, ETrue ); + } + + // Weed out commands not meant to be used with empty contact + if ( aControl.NumberOfContactFields() == 0 ) + { + aMenuPane->SetItemDimmed( EPbk2CmdSend, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdAssignSpeedDial, ETrue); + aMenuPane->SetItemDimmed( EPbk2CmdRemoveSpeedDial, ETrue ); + aMenuPane->SetItemDimmed + ( EPbk2CmdPersonalRingingTone, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdCopy, ETrue ); + + if ( !FeatureManager::FeatureSupported + ( KFeatureIdCallImagetext ) ) + { + aMenuPane->SetItemDimmed + ( EPbk2CmdFetchThumbnail, ETrue ); + aMenuPane->SetItemDimmed + ( EPbk2CmdRemoveThumbnail, ETrue ); + } + else + { + aMenuPane->SetItemDimmed( EPbk2CmdAddImage, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdImage, ETrue ); + } + } + else + { + // Utilise attribute manager to find out if + // the contact have a speed dial defined + TBool hasSpeedDial = HasSpeedDialL( aControl ); + + // Filtering is based on the speed dial existence + if ( !hasSpeedDial ) + { + aMenuPane->SetItemDimmed + ( EPbk2CmdRemoveSpeedDial, ETrue ); + } + else + { + aMenuPane->SetItemDimmed + ( EPbk2CmdAssignSpeedDial, ETrue ); + } + } + break; + } + + case R_PHONEBOOK2_CONTACTINFO_CONTEXT_MENU: + { + // Weed out commands not meant to be used with empty contact + if ( aControl.NumberOfContactFields() == 0 ) + { + aMenuPane->SetItemDimmed( EPbk2CmdWrite, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdGoToURL, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdPersonalRingingTone, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdUseNumber, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdImage, ETrue ); + } + break; + } + + case R_PHONEBOOK2_INFO_MENU: + { + // Filter memory info items when list box is empty + // or items are marked + if ( aControl.NumberOfContacts() == 0 || + aControl.ContactsMarked() ) + { + aMenuPane->SetItemDimmed( EPbk2CmdPhonebook2Info, ETrue ); + } + break; + } + + case R_PHONEBOOK2_SYSTEM_MENU: + { + if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + // Remove non-supported help from menu + aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue ); + } + break; + } + case R_PHONEBOOK2_MERGE_CONTACTS: + { + TBool supported = FeatureManager::FeatureSupported( KFeatureIdFfContactsMerge ); + + if ( !supported || aControl.ContactsMarked() ) + { + aMenuPane->SetItemDimmed( EPbk2CmdMergeContacts, ETrue ); + } + break; + } + default: + { + // Do nothing + break; + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::PerformStoreSpecificFiltering +// -------------------------------------------------------------------------- +// +inline void CPbk2CommandHandler::PerformStoreSpecificFilteringL( + TInt aResourceId, + CEikMenuPane* aMenuPane, + MPbk2ContactUiControl& aControl ) + { + switch (aResourceId) + { + case R_PHONEBOOK2_NAMESLIST_CONTEXT_MENU_MARKED_ITEMS: // FALLTHROUGH + case R_PHONEBOOK2_NAMESLIST_DELETE_MENU: + { + // Weed out commands not meant to be used with read only stores + if (AreSelectedContactsFromReadOnlyStoreL( aControl )) + { + aMenuPane->SetItemDimmed(EPbk2CmdDeleteMe, ETrue); + } + break; + } + + case R_PHONEBOOK2_CONTACTINFO_EDIT_MENU: + { + TBool phoneMemoryInConfiguration = + iContactRelocator->IsPhoneMemoryInConfigurationL(); + + // Weed out commands not meant to be used with read only stores + if (AreSelectedContactsFromReadOnlyStoreL( aControl )) + { + aMenuPane->SetItemDimmed(EPbk2CmdDeleteMe, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdEditMe, ETrue); + } + + // Weed out phone memory specific commands, if there is no + // phone memory in configuration + if (!phoneMemoryInConfiguration) + { + aMenuPane->SetItemDimmed(EPbk2CmdDefaultSettings, ETrue); + } + break; + } + + case R_PHONEBOOK2_CONTACTINFO_EXTENDED_MENU: + { + TBool phoneMemoryInConfiguration = + iContactRelocator->IsPhoneMemoryInConfigurationL(); + + // Weed out phone memory specific commands, if there is no + // phone memory in configuration + if (!phoneMemoryInConfiguration) + { + aMenuPane->SetItemDimmed(EPbk2CmdAssignSpeedDial, ETrue); + if (!FeatureManager::FeatureSupported(KFeatureIdCallImagetext)) + { + aMenuPane->SetItemDimmed(EPbk2CmdFetchThumbnail, ETrue); + } + else + { + aMenuPane->SetItemDimmed(EPbk2CmdAddImage, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdImage, ETrue); + } + aMenuPane->SetItemDimmed(EPbk2CmdPersonalRingingTone, ETrue); + } + + break; + } + + case R_PHONEBOOK2_CONTACTINFO_CONTEXT_MENU: + { + // Weed out commands not meant to be used with read only stores + if (AreSelectedContactsFromReadOnlyStoreL( aControl )) + { + aMenuPane->SetItemDimmed(EPbk2CmdEditMe, ETrue); + } + break; + } + case R_PHONEBOOK2_MERGE_CONTACTS: + { + TBool phoneMemoryInConfiguration = + iContactRelocator->IsPhoneMemoryInConfigurationL(); + + if( !phoneMemoryInConfiguration ) + { + aMenuPane->SetItemDimmed( EPbk2CmdMergeContacts, ETrue ); + } + break; + } + default: + { + // Do nothing + break; + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::PerformFieldTypeBasedFilteringL +// -------------------------------------------------------------------------- +// +inline void CPbk2CommandHandler::PerformFieldTypeBasedFilteringL( + TInt aResourceId, + CEikMenuPane* aMenuPane, + MPbk2ContactUiControl& aControl ) + { + CVPbkContactManager& manager = iAppServices->ContactManager(); + + switch (aResourceId) + { + case R_PHONEBOOK2_CONTACTINFO_EDIT_MENU: + { + // Weed out commands which are not shown if currently focused field is + // not phone number + if (!FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_PHONENUMBER_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue); + } + + // If the contact does not have URL field, there is no + // "Go To URL" option available + if (FocusedContactHasFieldTypeL(aControl, + R_PHONEBOOK2_URL_SELECTOR, manager) < 0) + { + aMenuPane->SetItemDimmed(EPbk2CmdGoToURL, ETrue); + } + break; + } + + case R_PHONEBOOK2_CONTACTINFO_EXTENDED_MENU: + { + // Speed dial menus are variated based on VoIP support + if( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) ) + { + // Weed out commands which are not shown if currently focused field is + // neither phone number nor VoIP field + if( !FocusedFieldMatchesFieldTypeL( aControl, + R_PHONEBOOK2_SIP_MSISDN_SELECTOR, manager ) ) + { + aMenuPane->SetItemDimmed( EPbk2CmdAssignSpeedDial, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdRemoveSpeedDial, ETrue ); + } + } + else + { + // Weed out commands which are not shown if currently focused field is + // not phone number + if( !FocusedFieldMatchesFieldTypeL( aControl, + R_PHONEBOOK2_PHONENUMBER_SELECTOR, manager ) ) + { + aMenuPane->SetItemDimmed( EPbk2CmdAssignSpeedDial, ETrue ); + aMenuPane->SetItemDimmed( EPbk2CmdRemoveSpeedDial, ETrue ); + } + } + + // Alternate Thumbnail/Call object menus based on whether data + // has been added or not + if (!FeatureManager::FeatureSupported(KFeatureIdCallImagetext)) + { + // Weed out command Remove Thumbnail if contact does not have one + if (FocusedContactHasFieldTypeL(aControl, + R_PHONEBOOK2_THUMBNAIL_SELECTOR, manager) < 0) + { + aMenuPane->SetItemDimmed(EPbk2CmdRemoveThumbnail, ETrue); + } + } + else + { + if ((FocusedContactHasFieldTypeL(aControl, + R_PHONEBOOK2_IMAGE_SELECTOR, manager) < 0) && + (FocusedContactHasFieldTypeL(aControl, + R_PHONEBOOK2_THUMBNAIL_SELECTOR, manager) < 0)) + { + // Weed out Image submenu if contact does not have image + aMenuPane->SetItemDimmed(EPbk2CmdImage, ETrue); + } + else + { + // Weed out command Add Image if contact already has one + aMenuPane->SetItemDimmed(EPbk2CmdAddImage, ETrue); + } + } + break; + } + + case R_PHONEBOOK2_CONTACTINFO_CONTEXT_MENU: + { + TBool filtered = EFalse; + + // Telephone field + if (FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_PHONENUMBER_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdGoToURL, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdPersonalRingingTone, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdImage, ETrue); + filtered = ETrue; + + // Further filtering of phone number fields + // Pager field + // Pager returns a match for R_PHONEBOOK2_PHONENUMBER_SELECTOR + // too, but it requires further filtering, which is handled here + if (FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_PAGER_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdWrite, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue ); + } + + // VoIP + // VoIP returns a match for R_PHONEBOOK2_PHONENUMBER_SELECTOR + // too, but it requires further filtering, which is handled here + if (FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_VOIP_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdWrite, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue ); + } + } // further filtering + + // Email field + if (FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_EMAIL_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdGoToURL, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue ); + aMenuPane->SetItemDimmed(EPbk2CmdPersonalRingingTone, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdImage, ETrue); + filtered = ETrue; + } + + // URL field + if (FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_URL_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdWrite, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue ); + aMenuPane->SetItemDimmed(EPbk2CmdPersonalRingingTone, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdImage, ETrue); + filtered = ETrue; + } + + // Ringing tone field + if (FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_RINGTONE_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdWrite, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdGoToURL, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdEditMe, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue ); + aMenuPane->SetItemDimmed(EPbk2CmdImage, ETrue); + filtered = ETrue; + } + + // Image/text context submenus + if( FocusedFieldMatchesFieldTypeL(aControl, + R_PHONEBOOK2_IMAGE_SELECTOR, manager)) + { + aMenuPane->SetItemDimmed(EPbk2CmdWrite, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdGoToURL, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue ); + aMenuPane->SetItemDimmed(EPbk2CmdPersonalRingingTone, ETrue); + filtered = ETrue; + } + + if (!filtered) + { + // Default filtering leaves only edit option in the menu + aMenuPane->SetItemDimmed(EPbk2CmdWrite, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdGoToURL, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdUseNumber, ETrue ); + aMenuPane->SetItemDimmed(EPbk2CmdPersonalRingingTone, ETrue); + aMenuPane->SetItemDimmed(EPbk2CmdImage, ETrue); + } + break; + } + + case R_PHONEBOOK2_IMAGE_SUBMENU: + { + if (FeatureManager::FeatureSupported(KFeatureIdCallImagetext)) + { + if (FocusedContactHasFieldTypeL(aControl, + R_PHONEBOOK2_IMAGE_SELECTOR, manager) < 0) + { + // Weed out Image View command if contact has no image + // (it might have thumbnail from e.g. business card and + // and thus other image submenu options) + aMenuPane->SetItemDimmed(EPbk2CmdViewImage, ETrue); + } + } + break; + } + + default: + { + // AIW provider menus are filtered in the corresponding + // interest item, for example R_PHONEBOOK2_CALL_CONTEXT_MENU + // is filtered in CPbk2AiwInterestItemCall + break; + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::AreSelectedContactsFromReadOnlyStoreL +// Returns ETrue if all selected contacts are read-only. +// -------------------------------------------------------------------------- +// +inline TBool CPbk2CommandHandler::AreSelectedContactsFromReadOnlyStoreL( + MPbk2ContactUiControl& aControl) + { + // Default behavior is that selection is read-only, e.g + // a link can not be created for folding contact in which case + // the folding contact cannot be destroyed + TBool ret = ETrue; + + MPbk2ContactLinkIterator* iterator = + aControl.SelectedContactsIteratorL(); + if ( iterator ) + { + CleanupDeletePushL( iterator ); + + while( iterator->HasNext() && ret ) + { + MVPbkContactLink* link = iterator->NextL(); + + if ( link && !IsFromReadOnlyStore( *link ) ) + { + ret = EFalse; + } + + delete link; + link = NULL; + } + + CleanupStack::PopAndDestroy(); // iterator + } + else + { + // There was no iterator so there are no selected contacts, + // this means we are operating with the focused contact + const MVPbkBaseContact* focusedContact = + aControl.FocusedContactL(); + if ( focusedContact ) + { + MVPbkContactLink* link = focusedContact->CreateLinkLC(); + if ( link && !IsFromReadOnlyStore( *link ) ) + { + ret = EFalse; + } + CleanupStack::PopAndDestroy(); // link + } + } + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::IsFromReadOnlyStore +// -------------------------------------------------------------------------- +// +TBool CPbk2CommandHandler::IsFromReadOnlyStore( + const MVPbkContactLink& aContactLink ) const + { + TBool ret = EFalse; + + const MVPbkContactStore& store = aContactLink.ContactStore(); + if ( store.StoreProperties().ReadOnly() ) + { + ret = ETrue; + } + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::HasSpeedDialL +// -------------------------------------------------------------------------- +// +TBool CPbk2CommandHandler::HasSpeedDialL( + MPbk2ContactUiControl& aControl ) + { + TBool hasAttribute(EFalse); + + const MVPbkStoreContact* storeContact = + aControl.FocusedStoreContact(); + + // Convert presentation index to store index. + TInt index( ToStoreFieldIndexL( + aControl.FocusedFieldIndex(), + storeContact ) ); + + if ( index != KErrNotFound ) + { + const MVPbkStoreContactField& field = + storeContact->Fields().FieldAt( index ); + + + hasAttribute = + iAppServices->ContactManager().ContactAttributeManagerL(). + HasFieldAttributeL( + CVPbkSpeedDialAttribute::Uid(), + field ); + } + return hasAttribute; + } + +// -------------------------------------------------------------------------- +// CPbk2CommandHandler::ToStoreFieldIndexL +// -------------------------------------------------------------------------- +// +TInt CPbk2CommandHandler::ToStoreFieldIndexL( + TInt aPresIndex, + const MVPbkStoreContact* aStoreContact ) + { + // It is ok to remove const, we don't make any changes + MVPbkStoreContact* storeContact = + const_cast( aStoreContact ); + + TInt index( KErrNotFound ); + if ( aPresIndex >= 0 ) + { + CPbk2PresentationContact* presentationContact = + CPbk2PresentationContact::NewL( + *storeContact, + iAppServices->FieldProperties() ); + CleanupStack::PushL( presentationContact ); + + index = presentationContact->PresentationFields(). + StoreIndexOfField( aPresIndex ); + + CleanupStack::PopAndDestroy( presentationContact ); + } + return index; + } + +// End of File