--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/Commands/src/CPbk2CommandHandler.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1138 @@
+/*
+* 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 <MPbk2ViewExplorer.h>
+#include <CPbk2AppViewBase.h>
+#include <CPbk2AppUiBase.h>
+#include <CPbk2UIExtensionManager.h>
+#include <MPbk2Command.h>
+#include <Pbk2Commands.rsg>
+#include <Pbk2UIControls.rsg>
+#include <CPbk2ViewState.h>
+#include <CPbk2PhonebookInfoDlg.h>
+#include <TPbk2StoreContactAnalyzer.h>
+#include <MPbk2ContactNameFormatter.h>
+#include <CPbk2StoreProperty.h>
+#include <CPbk2StorePropertyArray.h>
+#include <CPbk2ContactRelocator.h>
+#include <MPbk2ContactLinkIterator.h>
+#include <CPbk2PresentationContact.h>
+#include <CPbk2PresentationContactFieldCollection.h>
+#include <CPbk2FieldPropertyArray.h>
+#include <cpbk2commandactivator.h>
+#include <CPbk2ApplicationServices.h>
+#include <MPbk2AppUi.h>
+
+// Virtual Phonebook
+#include <CVPbkContactManager.h>
+#include <MVPbkStoreContactField.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactAttributeManager.h>
+#include <MVPbkContactLinkArray.h>
+#include <MVPbkContactLink.h>
+#include <CVPbkSpeedDialAttribute.h>
+#include <MVPbkStoreContact.h>
+#include <VPbkContactStoreUris.h>
+
+// System includes
+#include <avkon.hrh>
+#include <eikmenup.h>
+#include <featmgr.h>
+#include <hlplch.h>
+#include <akntoolbar.h>
+#include <eikmenub.h>
+
+
+/// 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<TCoeHelpContext>* helpContextArray =
+ new (ELeave) CArrayFixFlat<TCoeHelpContext>( 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 );
+ }
+ if ( aControl.ContactsMarked() )
+ {
+ aMenuPane->SetItemSpecific( EPbk2CmdDeleteMe, EFalse );
+ }
+ 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( EPbk2CmdSend, ETrue );
+ 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 )
+ {
+ // ETrue if all selected contacts are read-only
+ TBool readOnly = AreSelectedContactsFromReadOnlyStoreL( 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 (readOnly)
+ {
+ 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 (readOnly)
+ {
+ 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 (readOnly)
+ {
+ 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<MVPbkStoreContact*>( 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