--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/App/src/CPbkNamesListAppView.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1187 @@
+/*
+* Copyright (c) 2002 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:
+* Provides phonebook Names List View controller methods
+*
+*/
+
+
+// INCLUDE FILES
+// This class' declaration
+#include "CPbkNamesListAppView.h"
+
+#include <apgcli.h>
+#include <eikmenup.h>
+#include <StringLoader.h> // StringLoader
+#include <Phonebook.hrh>
+#include <SharedDataClient.h>
+
+// Send UI
+#include <sendui.h> // Send UI API
+#include <sendnorm.rsg> // for Send UI functionality
+#include <SenduiMtmUids.h> // Send UI MTM uid's
+
+// Phonebook.app include files
+#include <Phonebook.rsg> // Phonebook resources
+#include "CPbkAppUi.h" // Phonebook application UI class
+#include "CPbkDeleteContactsCmd.h"
+#include "CPbkAssignToGroupCmd.h"
+#include "CPbkDocument.h"
+#include "CPbkAppGlobals.h"
+#include "CPbkMenuFiltering.h"
+#include "PbkUid.h"
+#include "PbkApplicationLauncherFactory.h"
+#include "MPbkApplicationLauncher.h"
+#include "CPbkDbRecoveryUi.h"
+
+// Phonebook engine include files
+#include <CPbkContactEngine.h> // Phonebook engine
+#include <CPbkFieldsInfo.h>
+#include <CPbkContactItem.h>
+#include <PbkCommandHandler.h>
+#include <CPbkConstants.h>
+#include <CPbkAiwInterestArray.h>
+
+// Phonebook view include files
+#include <PbkView.rsg> // PbkView dll resources
+#include <CPbkViewState.h> // Phonebook view state object
+#include <CPbkContactViewListControl.h>
+#include <CPbkAddToGroup.h>
+#include <CPbkContactEditorDlg.h>
+#include <CPbkDeleteContactQuery.h>
+#include <CPbkPhonebookInfoDlg.h>
+#include <CPbkFFSCheck.h>
+
+// From PbkUI
+#include <CPbkControlContainer.h> // Control container
+#include <MPbkCommand.h>
+#include <MPbkCommandFactory.h>
+#include <MenuFilteringFlags.h>
+
+// PbkExtension classes
+#include <CPbkExtGlobals.h>
+#include <MPbkExtensionFactory.h>
+#include <MPbkViewExtension.h>
+#include <cshelp/phob.hlp.hrh>
+
+// Debugging headers
+#include <pbkdebug.h>
+#include "PbkProfiling.h"
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+
+// Sufficient amount of memory for contact database modification
+const TInt KFreeSpaceForDbCompress = 128*1024; // 128kb
+
+#ifdef _DEBUG
+enum TPanicCode
+ {
+ EPanicPreCond_HandleCommandL=1,
+ EPanicPostCond_DoActivateL,
+ EPanicPreCond_ConstructL,
+ EPanicPostCond_ConstructL,
+ EPanicPreCond_CmdCreateNewL,
+ EPanicPreCond_CmdEditMeL,
+ EPanicPreCond_CmdAddToGroupL,
+ EPanicPreCond_CmdDuplicateMeL,
+ EPanicPreCond_DynInitMenuPaneL,
+ EPanicPreCond_CmdDeleteMeL,
+ EPanicPreCond_HandleContactViewListControlEventL
+ };
+#endif // _DEBUG
+
+
+// ==================== LOCAL FUNCTIONS ====================
+
+#ifdef _DEBUG
+void Panic(TPanicCode aReason)
+ {
+ _LIT(KPanicText, "CPbkNamesListAppView");
+ User::Panic(KPanicText, aReason);
+ }
+#endif // _DEBUG
+
+
+} // namespace
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+inline CPbkNamesListAppView::CPbkNamesListAppView()
+ : iContactToFocus(KNullContactId)
+ {
+ }
+
+inline void CPbkNamesListAppView::ConstructL()
+ {
+ // PreCond
+ __ASSERT_DEBUG(!iContainer, Panic(EPanicPreCond_ConstructL));
+
+ // Init base class
+ __PBK_PROFILE_START(PbkProfiling::EViewBaseConstruct);
+ BaseConstructL(R_PHONEBOOK_NAMESLIST_APPVIEW);
+ __PBK_PROFILE_END(PbkProfiling::EViewBaseConstruct);
+
+ iExtGlobal = CPbkExtGlobals::InstanceL();
+
+ // Do not create the container control here: defer creation to first
+ // activation of the view (first DoActivateL call). This saves a lot
+ // of memory and application starting time, because all the application
+ // views (classes like this) must be created at startup. Controls will
+ // be created on-demand as the views are accessed.
+
+ // Create recovery UI here instead AppUI so that if recovery
+ // fails and we need exit we can set this view container not focusing
+ // to prevent focus change event
+ iDbRecoveryUi = CPbkDbRecoveryUi::NewL( *Engine(), *this );
+
+ // PostCond
+ __ASSERT_DEBUG(!iContainer, Panic(EPanicPostCond_ConstructL));
+ }
+
+CPbkNamesListAppView* CPbkNamesListAppView::NewL()
+ {
+ CPbkNamesListAppView* self = new(ELeave) CPbkNamesListAppView();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ return self;
+ }
+
+CPbkNamesListAppView::~CPbkNamesListAppView()
+ {
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING
+ ("CPbkNamesListAppView(%x)::~CPbkNamesListAppView()"), this);
+
+ if (iContainer)
+ {
+ AppUi()->RemoveFromStack(iContainer);
+ delete iContainer;
+ }
+ if (iAllContactsView)
+ {
+ iAllContactsView->Close(*this);
+ }
+ delete iDbRecoveryUi;
+ delete iControlState;
+ delete iParamState;
+ Release(iViewExtension);
+ Release(iExtGlobal);
+ delete iPbkFFSCheck;
+ if (iSharedDataClient)
+ {
+ iSharedDataClient->Close();
+ delete iSharedDataClient;
+ }
+ }
+
+void CPbkNamesListAppView::CmdCreateNewL()
+ {
+ __ASSERT_DEBUG(iContainer && iContainer->Control(),
+ Panic(EPanicPreCond_CmdCreateNewL));
+ CPbkContactViewListControl& control = *iContainer->Control();
+
+ // Create a new contact
+ CPbkContactItem* newContact = Engine()->CreateEmptyContactL();
+ CleanupStack::PushL(newContact);
+
+ TInt fieldToFocus = -1;
+ TBool edited = EFalse;
+
+ // If there is text in the find box, put it in the contact as last name
+ const TDesC& findText = control.FindTextL();
+ if (findText.Length() > 0)
+ {
+ TPbkContactItemField* lastNameField = newContact->AddOrReturnUnusedFieldL
+ (*Engine()->FieldsInfo().Find(EPbkFieldIdLastName));
+ if (lastNameField)
+ {
+ lastNameField->TextStorage()->SetTextL(findText);
+ fieldToFocus = newContact->FindFieldIndex(*lastNameField);
+ edited = ETrue;
+ }
+ }
+
+ // blank control to prevent name list thumbnail update
+ // during editing
+ control.SetBlank( ETrue );
+ control.HideThumbnail();
+ iContainer->SetFocusing(EFalse);
+ iContainer->Control()->SetFocusing( EFalse );
+
+ // Trap this, so that the thumbnail doesnt get hidden in case of leave
+ TRAPD(err, DoOpenContactEditorDlgL(control, *newContact,
+ ETrue, fieldToFocus, edited));
+
+ iContainer->Control()->SetFocusing( ETrue );
+ iContainer->SetFocusing(ETrue);
+ control.SetBlank( EFalse );
+ control.ShowThumbnailL();
+
+ User::LeaveIfError( err );
+
+ CleanupStack::PopAndDestroy(); // newContact
+ }
+
+void CPbkNamesListAppView::DoOpenContactEditorDlgL
+ (CPbkContactViewListControl& aControl,
+ CPbkContactItem& aNewContact, TBool aIsNewContact,
+ TInt aFieldToFocus/*=-1*/, TBool aEdited /*=EFalse*/)
+ {
+ // Run the editor dialog
+ CPbkContactEditorDlg* editorDlg = CPbkContactEditorDlg::NewL
+ (*Engine(), aNewContact, aIsNewContact, aFieldToFocus, aEdited);
+ editorDlg->SetExitCommandId(EPbkCmdExit);
+ const TContactItemId newContactId = editorDlg->ExecuteLD();
+
+ // Clear Find box contents and markings, because at the UI spec level
+ // a view switch occured above from Names List view to New Memory Entry
+ // view.
+ aControl.ResetFindL();
+ aControl.HandleMarkableListUpdateAfterCommandExecution();
+
+ if (newContactId != KNullContactId)
+ {
+ // Move focus to the newly created contact in contact view event handler
+ iContactToFocus = newContactId;
+ }
+ }
+
+void CPbkNamesListAppView::CmdDeleteMeL()
+ {
+ CPbkContactViewListControl& control = *iContainer->Control();
+ __ASSERT_DEBUG(iContainer && control.NumberOfItems() > 0,
+ Panic(EPanicPreCond_CmdDeleteMeL));
+
+ if (control.ItemsMarked())
+ {
+ // Items marked
+ const CContactIdArray& markedItems = control.MarkedItemsL();
+
+ if (markedItems.Count() == 1)
+ {
+ // One item marked
+ DoDeleteContactL(markedItems[0]);
+ }
+ else if (markedItems.Count() > 1)
+ {
+ // Multiple items marked
+ DoDeleteMarkedContactsL(markedItems);
+ }
+ }
+ else
+ {
+ // No marked items -> delete focused contact
+ DoDeleteContactL(control.FocusedContactIdL());
+ }
+ }
+
+void CPbkNamesListAppView::CmdEditMeL()
+ {
+ __ASSERT_DEBUG(
+ iContainer &&
+ iContainer->Control()->NumberOfItems() > 0 &&
+ iContainer->Control()->CurrentItemIndex() >= 0 &&
+ !iContainer->Control()->ItemsMarked(),
+ Panic(EPanicPreCond_CmdEditMeL));
+
+ // Get focused contact's ID
+ const TContactItemId focusId = iContainer->Control()->FocusedContactIdL();
+
+ // Open editor for the focused contact
+ iContainer->Control()->SetFocusing( EFalse );
+ TRAPD( err , DoEditL(focusId) );
+ iContainer->Control()->SetFocusing( ETrue );
+ User::LeaveIfError( err );
+ }
+
+void CPbkNamesListAppView::CmdAddToGroupL()
+ {
+ __ASSERT_DEBUG(
+ iContainer &&
+ iContainer->Control()->NumberOfItems() > 0 &&
+ Engine()->Database().GroupCount() > 0,
+ Panic(EPanicPreCond_CmdAddToGroupL));
+
+ CPbkContactViewListControl& control = *iContainer->Control();
+
+ // create parameters
+ CContactIdArray* idArray = NULL;
+ if (control.ItemsMarked())
+ {
+ const CContactIdArray& markedIdArray = control.MarkedItemsL();
+ idArray = CContactIdArray::NewLC(&markedIdArray);
+ }
+ else
+ {
+ const TContactItemId focusedContactId = control.FocusedContactIdL();
+ idArray = CContactIdArray::NewLC();
+ idArray->AddL(focusedContactId);
+ }
+
+ CPbkAddToGroup* addToGroup = CPbkAddToGroup::NewL();
+ TContactItemId groupId = addToGroup->ExecuteLD(*Engine());
+ if (groupId != KNullContactId)
+ {
+ CPbkAssignToGroupCmd* cmd = CPbkAssignToGroupCmd::NewL
+ (*Engine(), *idArray, *iContainer->Control(), groupId);
+ PbkAppUi()->AddAndExecuteCommandL(cmd);
+ }
+
+ CleanupStack::PopAndDestroy(idArray);
+ }
+
+void CPbkNamesListAppView::CmdDuplicateMeL()
+ {
+ __ASSERT_DEBUG(
+ iContainer &&
+ iContainer->Control()->NumberOfItems() > 0 &&
+ !iContainer->Control()->ItemsMarked(),
+ Panic(EPanicPreCond_CmdDuplicateMeL));
+
+ const TContactItemId newContactId = Engine()->DuplicateContactL
+ (iContainer->Control()->FocusedContactIdL(), ETrue);
+
+ iContainer->Control()->SetFocusing( EFalse );
+ TRAPD( err , DoEditL(newContactId) );
+ iContainer->Control()->SetFocusing( ETrue );
+ User::LeaveIfError( err );
+ }
+
+inline void CPbkNamesListAppView::CmdContextMenuL()
+ {
+ if (iContainer->Control()->ItemsMarked())
+ {
+ LaunchPopupMenuL(R_PBK_NAMESLIST_CONTEXT_MENUBAR_ITEMS_MARKED);
+ }
+ else
+ {
+ LaunchPopupMenuL(R_PBK_NAMESLIST_CONTEXT_MENUBAR);
+ }
+ }
+
+inline void CPbkNamesListAppView::CmdOpenSettingsL()
+ {
+ // Hide the control
+ iContainer->Control()->MakeVisible(EFalse);
+ iContainer->SetFocusing(EFalse);
+
+ // Trap this, so that the thumbnail doesnt get hidden in case of leave
+ TRAPD(err, DoOpenSettingsDlgL());
+
+ iContainer->SetFocusing(ETrue);
+ // Restore control
+ iContainer->Control()->MakeVisible(ETrue);
+
+ // In case of an error, leave
+ if (err != KErrNone)
+ {
+ User::Leave(err);
+ }
+ }
+
+inline void CPbkNamesListAppView::DoOpenSettingsDlgL()
+ {
+ // Create the settings command object
+ MPbkCommand* cmd = CPbkAppGlobalsBase::InstanceL()->
+ CommandFactory().CreateSettingsCmdL(*Engine(), *this);
+ // Execute the command
+ cmd->ExecuteLD();
+
+ // Clear Find box contents and markings
+ CPbkContactViewListControl& control = *iContainer->Control();
+ control.ResetFindL();
+ control.HandleMarkableListUpdateAfterCommandExecution();
+ }
+
+/**
+ * Command handler: go to URL command.
+ */
+void CPbkNamesListAppView::CmdGoToURLL()
+ {
+ // Get the focused contact item
+ const TContactItemId focusId = iContainer->Control()->FocusedContactIdL();
+ CPbkContactItem* focusItem = Engine()->ReadContactLC(focusId);
+
+ // Create the go to URL command object
+ MPbkCommand* cmd = CPbkAppGlobalsBase::InstanceL()->
+ CommandFactory().CreateGoToURLCmdL(*focusItem, NULL);
+ // Execute the command
+ cmd->ExecuteLD();
+
+ CleanupStack::PopAndDestroy(); // focusItem
+ }
+
+void CPbkNamesListAppView::CmdOpenOneTouchL()
+ {
+ MPbkApplicationLauncher* appLauncher =
+ PbkApplicationLauncherFactory::CreateLC();
+ appLauncher->LaunchApplicationL(TUid::Uid(KSpeedDialUid));
+ CleanupStack::PopAndDestroy(); // appLauncher
+ }
+
+inline void CPbkNamesListAppView::CmdPhonebookInfoL()
+ {
+ CPbkContactViewListControl& control = *iContainer->Control();
+
+ // Hide thumbnail
+ control.HideThumbnail();
+ iContainer->SetFocusing(EFalse);
+ iContainer->CoeControl()->SetFocusing(EFalse);
+
+ // Trap this, so that the thumbnail doesnt get hidden in case of leave
+ TRAPD(err, DoShowPhonebookInfoL());
+
+ // Restore
+ iContainer->SetFocusing(ETrue);
+ iContainer->CoeControl()->SetFocusing(ETrue);
+ control.ShowThumbnailL();
+
+ // In case of an error, leave
+ if (err != KErrNone)
+ {
+ User::Leave(err);
+ }
+ }
+
+inline void CPbkNamesListAppView::DoShowPhonebookInfoL()
+ {
+ CPbkPhonebookInfoDlg* infoPopup =
+ CPbkPhonebookInfoDlg::NewL(*Engine());
+ infoPopup->ExecuteLD();
+ }
+
+inline TBool CPbkNamesListAppView::NoOpenOneTouch() const
+ {
+ TBool ret = ETrue;
+ if(Engine()->Constants()->
+ LocallyVariatedFeatureEnabled(EPbkLVAllowOpen1Touch))
+ {
+ ret = EFalse;
+ }
+ return ret;
+ }
+
+CPbkContactViewListControl& CPbkNamesListAppView::Control()
+ {
+ return *(iContainer->Control());
+ }
+
+void CPbkNamesListAppView::DeleteFocusedEntryL()
+ {
+ CmdDeleteMeL();
+ }
+
+CPbkViewState* CPbkNamesListAppView::GetViewStateLC() const
+ {
+ return iContainer ? iContainer->Control()->GetStateLC() : NULL;
+ }
+
+void CPbkNamesListAppView::HandleCommandL(TInt aCommandId)
+ {
+ // PreCond:
+ __ASSERT_DEBUG(iContainer && iViewExtension,
+ Panic(EPanicPreCond_HandleCommandL));
+
+ if (iViewExtension->HandleCommandL(aCommandId, *this))
+ {
+ return;
+ }
+
+ // Process view-specific commands
+ switch (aCommandId)
+ {
+ case EPbkCmdCreateNew:
+ {
+ PbkAppUi()->FFSClCheckL(PbkCommandHandler(this,
+ &CPbkNamesListAppView::CmdCreateNewL));
+ break;
+ }
+
+ case EPbkCmdDeleteMe:
+ {
+ CmdDeleteMeL();
+ break;
+ }
+
+ case EPbkCmdEditMe:
+ {
+ PbkAppUi()->FFSClCheckL(PbkCommandHandler(this,
+ &CPbkNamesListAppView::CmdEditMeL));
+ break;
+ }
+
+ case EPbkCmdAddToGroup:
+ {
+ PbkAppUi()->FFSClCheckL(PbkCommandHandler(this,
+ &CPbkNamesListAppView::CmdAddToGroupL));
+ break;
+ }
+
+ case EPbkCmdDuplicateMe:
+ {
+ PbkAppUi()->FFSClCheckL(PbkCommandHandler(this,
+ &CPbkNamesListAppView::CmdDuplicateMeL));
+ break;
+ }
+
+ case EPbkCmdGoToURL:
+ {
+ CmdGoToURLL();
+ break;
+ }
+
+ case EPbkCmdSettings:
+ {
+ CmdOpenSettingsL();
+ break;
+ }
+
+ case EPbkCmdOpenOneTouch:
+ {
+ CmdOpenOneTouchL();
+ break;
+ }
+
+ case EPbkCmdContextMenu:
+ {
+ CmdContextMenuL();
+ break;
+ }
+
+ case EPbkCmdPhonebookInfo:
+ {
+ CmdPhonebookInfoL();
+ break;
+ }
+ case EPbkCmdSendUICommand:
+ {
+ // Set up flags depending on current UI state
+ TUint flags = 0;
+ if (iContainer->Control()->ItemsMarked())
+ {
+ flags |= KPbkItemsMarked;
+ }
+ HandleSendContactsL( flags );
+ break;
+ }
+ case EPbkCmdExit:
+ {
+ // make sure that the visible control is not set blank
+ Control().SetBlank(EFalse);
+ // fall through
+ }
+ default:
+ {
+ // Command not handled here, forward it to base class
+ CPbkContactListAppView::HandleCommandL(aCommandId);
+ break;
+ }
+ }
+ }
+
+TUid CPbkNamesListAppView::Id() const
+ {
+ return CPbkAppUi::KPbkNamesListViewUid;
+ }
+
+void CPbkNamesListAppView::HandleStatusPaneSizeChange()
+ {
+ // Resize the container to fill the client rectangle
+ if (iContainer)
+ {
+ iContainer->SetRect(ClientRect());
+ }
+ }
+
+void CPbkNamesListAppView::DoActivateL
+ (const TVwsViewId& aPrevViewId,
+ TUid aCustomMessageId,
+ const TDesC8& aCustomMessage)
+ {
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkNamesListAppView(%x)::DoActivateL()"),
+ this);
+
+ // Load the view status bar title
+ HBufC* title = StringLoader::LoadLC(R_QTN_PHOB_TITLE);
+
+ // Update application-wide state leave-safely
+ CPbkAppUi::CViewActivationTransaction* viewActivationTransaction =
+ PbkAppUi()->HandleViewActivationLC (Id(), aPrevViewId, title, NULL);
+
+ // Check activation parameters
+ delete iParamState;
+ iParamState = NULL;
+ if (aCustomMessageId == CPbkViewState::Uid())
+ {
+ iParamState = CPbkViewState::NewL(aCustomMessage);
+ }
+
+ if (!iAllContactsView)
+ {
+ iAllContactsView = &Engine()->AllContactsView();
+ iAllContactsView->OpenL(*this);
+ }
+
+ if (!iContainer)
+ {
+ // Create the container and control
+ CContainer* container = CContainer::NewLC(this, *this);
+
+ container->SetHelpContext
+ (TCoeHelpContext(ApplicationUid(), KPHOB_HLP_NAME_LIST));
+
+ if (!iViewExtension)
+ {
+ iViewExtension = iExtGlobal->FactoryL().
+ CreatePbkViewExtensionL
+ (Id(), *PbkAppUi()->PbkDocument()->Engine(), *this);
+ }
+
+ // Create the view-side UI control and connect it to the container
+ CPbkContactViewListControl* control = CPbkContactViewListControl::NewL(
+ *Engine(), *iAllContactsView, R_PBK_NAMES_LIST_CONTROL, container);
+
+ container->SetControl(control, ClientRect());
+ control->AddObserverL(*this);
+ iViewExtension->SetContactUiControl(control);
+
+ AppUi()->AddToStackL(*this,container);
+ CleanupStack::Pop(container);
+ iContainer = container;
+ }
+
+ // Activate control
+ iContainer->ActivateL();
+
+ // Commit application-wide state changes
+ viewActivationTransaction->Commit();
+ CleanupStack::PopAndDestroy(2); // viewActivationTransaction, title
+ __PBK_PROFILE_END(PbkProfiling::ENamesListViewActivateControl);
+ if (iParamState && iContainer->Control()->IsReady())
+ {
+ iContainer->Control()->RestoreStateL(iParamState);
+ }
+
+ // The application is set here to background if application exit occurs
+ if (iParamState && iParamState->Flags() & CPbkViewState::ESendToBackground)
+ {
+ PbkAppUi()->SendAppToBackgroundL();
+ iContainer->Control()->DeleteThumbnail();
+ }
+
+ __PBK_PROFILE_END(PbkProfiling::ENamesListViewDoActivateL);
+
+ __PBK_PROFILE_START(PbkProfiling::ENamesListContactViewOpen);
+
+ // PostCond:
+ __ASSERT_DEBUG(iContainer && iContainer->Control(),
+ Panic(EPanicPostCond_DoActivateL));
+ }
+
+void CPbkNamesListAppView::DoDeactivate()
+ {
+ PBK_DEBUG_PRINT(
+ PBK_DEBUG_STRING("CPbkNamesListAppView(%x)::DoDeactivate()"), this);
+
+ delete iParamState;
+ iParamState = NULL;
+ delete iControlState;
+ iControlState = NULL;
+
+ if (iContainer)
+ {
+ AppUi()->RemoveFromStack(iContainer);
+ TRAP_IGNORE(iControlState = iContainer->Control()->GetStateL(EFalse));
+ delete iContainer;
+ iContainer = NULL;
+ }
+
+ if (iViewExtension)
+ {
+ iViewExtension->SetContactUiControl(NULL);
+ }
+ }
+
+void CPbkNamesListAppView::DynInitMenuPaneL
+ (TInt aResourceId,
+ CEikMenuPane* aMenuPane)
+ {
+ __ASSERT_DEBUG(iContainer && iViewExtension,
+ Panic(EPanicPreCond_DynInitMenuPaneL));
+
+ // Set up flags depending on current UI state
+ TUint flags = 0;
+ if (iContainer->Control()->NumberOfItems() == 0)
+ {
+ flags |= KPbkControlEmpty;
+ }
+ if (iContainer->Control()->ItemsMarked())
+ {
+ flags |= KPbkItemsMarked;
+ }
+ if (Engine()->Database().GroupCount() == 0)
+ {
+ flags |= KPbkNoGroups;
+ }
+ if (NoOpenOneTouch())
+ {
+ flags |= KPbkNoOpenOneTouch;
+ }
+
+ // Offer the menu to AIW first
+ if (iAiwInterestArray->InitMenuPaneL(aResourceId, *aMenuPane, flags))
+ {
+ // No need to continue
+ return;
+ }
+
+ // Then to the extensions
+ iViewExtension->DynInitMenuPaneL(aResourceId, aMenuPane);
+
+ switch (aResourceId)
+ {
+ case R_PHONEBOOK_NAMESLIST_MENU:
+ {
+ if ( !Engine()->Constants()->
+ LocallyVariatedFeatureEnabled( EPbkLVGroupManagementSend ) )
+ {
+ flags |= KPbkNoGroupSend;
+ }
+ NamesListPaneMenuFilteringL(*aMenuPane, flags);
+ break;
+ }
+ case R_PHONEBOOK_INFO_MENU_PANE:
+ {
+ PhonebookInfoPaneMenuFilteringL(*aMenuPane, flags);
+ break;
+ }
+ case R_PBK_NAMESLIST_CONTEXTMENU_MARKED_ITEMS:
+ {
+ ContextMarkedItemsPaneMenuFilteringL(*aMenuPane, flags);
+ break;
+ }
+ case R_PHONEBOOK_SETTINGS_MENU:
+ {
+ SettingsPaneMenuFilteringL(*aMenuPane, flags);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ CPbkContactListAppView::DynInitMenuPaneL(aResourceId, aMenuPane);
+ }
+
+
+void CPbkNamesListAppView::HandleForegroundEventL(TBool aForeground)
+ {
+ CPbkContactListAppView::HandleForegroundEventL(aForeground);
+
+ // If this view is gaining foreground, then make sure that thumbnail
+ // gets drawn
+ if (aForeground && iContainer && iContainer->Control())
+ {
+ iContainer->Control()->ShowThumbnailL();
+ }
+ }
+
+
+void CPbkNamesListAppView::NamesListPaneMenuFilteringL
+ (CEikMenuPane& aMenuPane, TUint aFlags)
+ {
+ if ((aFlags & KPbkControlEmpty) || (aFlags & KPbkItemsMarked))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdOpenMeViews, ETrue);
+ aMenuPane.SetItemDimmed(EPbkCmdEditMe, ETrue);
+ aMenuPane.SetItemDimmed(EPbkCmdDuplicateMe, ETrue);
+ }
+
+ if ((aFlags & KPbkControlEmpty) ||
+ ((aFlags & KPbkItemsMarked) && (aFlags & KPbkNoGroupSend)))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdWrite, ETrue);
+ }
+
+ if ((aFlags & KPbkControlEmpty) || (aFlags & KPbkNoGroups))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdAddToGroup, ETrue);
+ }
+
+ if ((aFlags & KPbkControlEmpty) || (aFlags & KPbkItemsMarked) ||
+ (aFlags & KPbkNoGroups))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdBelongsToGroups, ETrue);
+ }
+
+ if ((aFlags & KPbkItemsMarked))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdCreateNew, ETrue);
+ }
+
+ if ((aFlags & KPbkControlEmpty))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdDeleteMe, ETrue);
+ }
+
+ if (aFlags & KPbkNoOpenOneTouch)
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdOpenOneTouch, ETrue);
+ }
+ }
+
+void CPbkNamesListAppView::PhonebookInfoPaneMenuFilteringL
+ (CEikMenuPane& aMenuPane, TUint aFlags)
+ {
+ CPbkAppGlobals* globals = // does not take ownership
+ CPbkAppGlobals::InstanceL();
+
+ // By default disable filtering of send contact menu,
+ // when there are marked items
+ TBool markedItemsFiltering = EFalse;
+
+ // Check is multiple vCard sending via BT/IR supported
+ if (!Engine()->Constants()->LocallyVariatedFeatureEnabled
+ (EPbkLVMultipleVCardOverBTAndIR))
+ {
+ // It is not supported. Marked items filtering is
+ // now needed if there is no mailbox set up
+ markedItemsFiltering = !globals->SendUiL()->ValidateServiceL
+ (KSenduiMtmSmtpUid, TSendingCapabilities(0,0,0));
+ }
+
+ // if names list is empty, no options menu items
+ if ((aFlags & KPbkControlEmpty)
+ || ((aFlags & KPbkItemsMarked) && markedItemsFiltering))
+ {
+ // Hide "Send contact" menu
+ aMenuPane.SetItemDimmed(EPbkCmdSendUICommand, ETrue);
+ }
+ else
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdSendUICommand, EFalse);
+ }
+
+ if ((aFlags & KPbkControlEmpty) || (aFlags & KPbkItemsMarked))
+ {
+ aMenuPane.SetItemDimmed(EPbkPhonebookInfoSubMenu, ETrue);
+ }
+
+ // Go To URL filtering
+ if ((aFlags & KPbkControlEmpty) || (aFlags & KPbkItemsMarked))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdGoToURL, ETrue);
+ }
+ else
+ {
+ TBool hasURL(EFalse);
+
+ // Get the focused contact item
+ const TContactItemId focusId =
+ iContainer->Control()->FocusedContactIdL();
+ CPbkContactItem* focusItem = Engine()->ReadContactLC(focusId);
+
+ // Check does the contact has URL addresses
+ if (focusItem->FindField(EPbkFieldIdURL))
+ {
+ hasURL = ETrue;
+ }
+
+ aMenuPane.SetItemDimmed(EPbkCmdGoToURL, !hasURL);
+ CleanupStack::PopAndDestroy(); // focusItem
+ }
+
+ }
+
+void CPbkNamesListAppView::SettingsPaneMenuFilteringL
+ (CEikMenuPane& aMenuPane, TUint aFlags)
+ {
+ CPbkMenuFiltering::SettingsPaneMenuFilteringL
+ (aMenuPane, aFlags);
+ }
+
+
+void CPbkNamesListAppView::ContextMarkedItemsPaneMenuFilteringL
+ (CEikMenuPane& aMenuPane, TUint aFlags)
+ {
+ if ((aFlags & KPbkNoGroups))
+ {
+ aMenuPane.SetItemDimmed(EPbkCmdAddToGroup, ETrue);
+ }
+ }
+
+void CPbkNamesListAppView::HandleContactViewListControlEventL
+ (CPbkContactViewListControl& aControl,
+ const TPbkContactViewListControlEvent& aEvent)
+ {
+ __ASSERT_DEBUG(&aControl == iContainer->Control(),
+ Panic(EPanicPreCond_HandleContactViewListControlEventL));
+
+ // Suppress unreferenced parameter warning
+ (void) aControl;
+
+ switch (aEvent.iEventType)
+ {
+ case TPbkContactViewListControlEvent::EReady:
+ {
+ Cba()->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_EXIT);
+ Cba()->DrawDeferred();
+ RestoreControlStateL();
+
+ // This profile is started in the NewApplication() entry point of
+ // this application
+ __PBK_PROFILE_END(PbkProfiling::EFullStartup);
+ // Log the profiling results
+#ifdef PBK_ENABLE_PROFILE
+ for (TInt bin = 1; bin < PbkProfiling::KEndProfileBins; ++bin)
+ {
+ __PBK_PROFILE_DISPLAY(bin);
+ }
+#endif // PBK_ENABLE_PROFILE
+ break;
+ }
+
+ case TPbkContactViewListControlEvent::EItemAdded:
+ {
+ if (!PbkAppUi()->IsRunningForeground())
+ {
+ iContainer->Control()->SetCurrentItemIndex(0);
+ }
+ else if (iContactToFocus == aEvent.iContactId)
+ {
+ CPbkContactViewListControl& control = *iContainer->Control();
+ const TInt index = control.FindContactIdL(aEvent.iContactId);
+ control.SetCurrentItemIndexAndDraw(index);
+ iContactToFocus = KNullContactId;
+ control.ShowThumbnailL();
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+inline void CPbkNamesListAppView::HandleRemoveFocusedEventL
+ (TInt aIndex)
+ {
+ TInt index = aIndex;
+ if (index >= 0)
+ {
+ const TInt lastIndex = iAllContactsView->CountL()-1;
+ if (index > lastIndex)
+ {
+ index = lastIndex;
+ }
+ if (index >= 0)
+ {
+ iControlState->SetFocusedContactId(iAllContactsView->AtL(index));
+ }
+ }
+ }
+
+inline void CPbkNamesListAppView::HandleRemoveEvent
+ (const TContactViewEvent& aEvent)
+ {
+ if (iControlState && iControlState->FocusedContactId()==aEvent.iContactId)
+ {
+ TRAP_IGNORE(HandleRemoveFocusedEventL(aEvent.iInt));
+ }
+ }
+
+void CPbkNamesListAppView::HandleContactViewEvent
+ (const CContactViewBase& aView, const TContactViewEvent& aEvent)
+ {
+ if (!iContainer && &aView==iAllContactsView)
+ {
+ switch (aEvent.iEventType)
+ {
+ case TContactViewEvent::EItemRemoved:
+ {
+ HandleRemoveEvent(aEvent);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+void CPbkNamesListAppView::PreCommandExecutionL()
+ {
+ iContainer->Control()->HideThumbnail();
+ iContainer->SetFocusing(EFalse);
+ }
+
+void CPbkNamesListAppView::PostCommandExecutionL
+ (TPbkCommandStatus aStatus)
+ {
+ // Following data member check is needed, because e.g. PEC may call
+ // this function after asynchronous command and in that case iContainer may
+ // not exist anymore.
+ if (iContainer)
+ {
+ if (aStatus == EPbkCommandExecuted)
+ {
+ iContainer->Control()->HandleMarkableListUpdateAfterCommandExecution();
+ iContainer->Control()->DrawNow();
+ }
+ iContainer->SetFocusing(ETrue);
+ iContainer->Control()->ShowThumbnailL();
+ }
+ }
+
+/**
+ * Open contact editor dialog for aContactId.
+ */
+void CPbkNamesListAppView::DoEditL(TContactItemId aContactId)
+ {
+ CPbkContactViewListControl& control = *iContainer->Control();
+
+ // Open the contact for editing (leaves 2 objects to cleanup stack)
+ CPbkContactItem* ci = Engine()->OpenContactLCX(aContactId);
+
+ // Make control invisible to save an extra redraw
+ control.HideThumbnail();
+ iContainer->SetFocusing(EFalse);
+
+ // Trap this, so that the thumbnail doesnt get hidden in case of leave
+ TRAPD(err, DoOpenContactEditorDlgL(control, *ci, EFalse));
+
+ iContainer->SetFocusing(ETrue);
+ // Restore thumbnail
+ control.ShowThumbnailL();
+
+ // In case of an error, leave
+ if (err != KErrNone)
+ {
+ User::Leave(err);
+ }
+
+ CleanupStack::PopAndDestroy(2); // ci, lock
+ }
+
+inline TBool CPbkNamesListAppView::DoDeleteContactQueryL(
+ TContactItemId aContactId)
+ {
+ CPbkDeleteContactQuery* dlg = CPbkDeleteContactQuery::NewLC();
+ return (dlg->RunLD(*Engine(),aContactId) != 0);
+ }
+
+void CPbkNamesListAppView::DoDeleteContactL(TContactItemId aContactId)
+ {
+ if (DoDeleteContactQueryL(aContactId))
+ {
+ // Compress contact database in low disk space situation.
+ // This compress guarantees that contact db size decreases
+ // when phone user deletes single contact manually several times.
+ // Compression is done before delete because compression may release
+ // disk space. This extra space may be needed for successful delete
+ // operation.
+ TRAPD(err,FFSCheckL());
+ if (KErrDiskFull == err)
+ {
+ //Db comppression does not cancel delete operation.
+ TRAP_IGNORE(DbCompactL());
+ err = KErrNone;
+ }
+ User::LeaveIfError(err);
+
+ TRAP(err, Engine()->DeleteContactL(aContactId, ETrue));
+ if ( KErrNotFound == err )
+ {
+ // Ignore KErrNotFound which means that somebody got
+ // the contact first
+ err = KErrNone;
+ }
+ User::LeaveIfError(err);
+ iContainer->Control()->HandleMarkableListUpdateAfterCommandExecution();
+ }
+ }
+
+inline TBool CPbkNamesListAppView::DoDeleteMarkedContactsQueryL
+ (const CContactIdArray& aMarkedItems)
+ {
+ CPbkDeleteContactQuery* dlg = CPbkDeleteContactQuery::NewLC();
+ return (dlg->RunLD(*Engine(), aMarkedItems) != 0);
+ }
+
+void CPbkNamesListAppView::DoDeleteMarkedContactsL
+ (const CContactIdArray& aMarkedItems)
+ {
+ if (DoDeleteMarkedContactsQueryL(aMarkedItems))
+ {
+ CPbkDeleteContactsCmd* cmd = CPbkDeleteContactsCmd::NewL
+ (*Engine(), aMarkedItems, *iContainer->Control());
+ PbkAppUi()->AddAndExecuteCommandL(cmd);
+ }
+ }
+
+void CPbkNamesListAppView::RestoreControlStateL()
+ {
+ CPbkContactViewListControl& control = *iContainer->Control();
+ control.RestoreStateL(iControlState);
+ // parameter state overrides stored state
+ control.RestoreStateL(iParamState);
+ delete iControlState;
+ iControlState = NULL;
+ delete iParamState;
+ iParamState = NULL;
+ }
+
+inline void CPbkNamesListAppView::FFSCheckL()
+ {
+ if (!iPbkFFSCheck)
+ {
+ iPbkFFSCheck = CPbkFFSCheck::NewL();
+ }
+ // Leaves with KErrDiskFull if free disk space is below critical level.
+ iPbkFFSCheck->FFSClCheckL();
+ }
+
+inline void CPbkNamesListAppView::RequestFreeDiskSpaceLC()
+ {
+ if (!iSharedDataClient)
+ {
+ iSharedDataClient = new (ELeave) RSharedDataClient();
+ User::LeaveIfError(iSharedDataClient->Connect());
+ }
+ iSharedDataClient->RequestFreeDiskSpaceLC(KFreeSpaceForDbCompress);
+ }
+
+inline void CPbkNamesListAppView::DbCompactL()
+ {
+ RequestFreeDiskSpaceLC();
+ Engine()->Database().CompactL();
+ CleanupStack::PopAndDestroy();// RequestFreeDiskSpaceLC
+ }
+
+void CPbkNamesListAppView::DisableController()
+ {
+ if (iContainer)
+ {
+ AppUi()->RemoveFromStack(iContainer);
+ delete iContainer;
+ iContainer = NULL;
+ }
+ }
+
+// End of File