--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2NamesListReadyState.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,2473 @@
+/*
+* 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 names list ready state.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbk2NamesListReadyState.h"
+
+// Phonebook 2
+#include "CPbk2AdaptiveSearchGridFiller.h"
+#include "CPbk2ThumbnailLoader.h"
+#include "CPbk2ContactViewListBox.h"
+#include "CPbk2ContactViewIterator.h"
+#include "MPbk2UiControlEventSender.h"
+#include "CPbk2FindDelay.h"
+#include "CPbk2NamesListControl.h"
+#include "CPbk2FindStringSplitter.h"
+#include <CPbk2ViewState.h>
+#include <MPbk2ControlObserver.h>
+#include <Pbk2MenuFilteringFlags.hrh>
+#include <MPbk2ApplicationServices.h>
+#include <MPbk2AppUi.h>
+#include "TPbk2FindTextUtil.h"
+#include <CPbk2AppViewBase.h>
+
+#include "PmuCommands.hrh" // For accessing EPmuCmdCascadingBackup
+#include "Pbk2USimUI.hrh" // For accessing EPsu2CmdCascadingSimMemory
+#include <Pbk2InternalUID.h>
+#include <pbk2doublelistboxcmditemextension.h>
+
+// Virtual Phonebook
+#include <MVPbkContactViewBase.h>
+#include <MVPbkViewContact.h>
+#include <MVPbkContactLink.h>
+#include <MVPbkContactBookmark.h>
+#include <CVPbkContactLinkArray.h>
+#include <CVPbkContactFindPolicy.h>
+#include <CVPbkContactManager.h>
+
+// System includes
+#include <akntoolbar.h>
+#include <AknsDrawUtils.h>
+#include <barsread.h>
+#include <aknsfld.h>
+#include <badesca.h>
+#include <aknViewAppUi.h>
+#include <aknappui.h>
+#include <eikmenub.h>
+#include <eikdialg.h>
+
+// Debugging headers
+#include <Pbk2Debug.h>
+#include "CPbk2PredictiveSearchFilter.h"
+#include "cpbk2predictiveviewstack.h"
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+const TInt KNumberOfControls = 2; // listbox and findbox
+const TInt KFindDelayTime = 700000; // microseconds
+const TInt KFindDelayThresholdContacts = 1000; // amount of contacts to
+ // activate find delay
+
+#ifdef _DEBUG
+enum TPanicCode
+ {
+ EPanicLogic_ComponentControl = 1,
+ EPanicLogic_FindTextL,
+ EPanicLogic_PreConds_SetCurrentItemIndexAndDraw,
+ EPanicLogic_Command_index_out_of_bounds
+ };
+
+void Panic(TPanicCode aReason)
+ {
+ _LIT(KPanicText, "CPbk2NamesListReadyState");
+ User::Panic(KPanicText, aReason);
+ }
+#endif // _DEBUG
+
+
+NONSHARABLE_CLASS(TCleanupEnableListBoxViewRedraw)
+ {
+ public: // Interface
+
+ /**
+ * Constructor.
+ *
+ * @param aListBoxView The list box view
+ */
+ inline TCleanupEnableListBoxViewRedraw( CListBoxView& aListBoxView )
+ : iCleanupItem( CleanupOp, &aListBoxView )
+ {
+ }
+
+ /**
+ * Returns the cleanup item.
+ */
+ inline operator TCleanupItem() const
+ {
+ return iCleanupItem;
+ }
+
+ private: // Implementation
+ static void CleanupOp(
+ TAny* aPtr );
+
+ private: // Data
+ /// Own: Cleanup item
+ TCleanupItem iCleanupItem;
+ };
+
+// --------------------------------------------------------------------------
+// TCleanupEnableListBoxViewRedraw::CleanupOp
+// --------------------------------------------------------------------------
+//
+void TCleanupEnableListBoxViewRedraw::CleanupOp( TAny* aPtr )
+ {
+ static_cast<CListBoxView*>(aPtr)->SetDisableRedraw(EFalse);
+ }
+
+
+/**
+ * Resolves the next index of the listbox according the key event.
+ * If key event is UP, the index is decreased from current index.
+ * If key event is DOWN, the index is increased from current index.
+ * If current index is last & event is DOWN, the new index is set to first.
+ * If current index is first & event is UP, the new index is set to last.
+ *
+ * @param aKeyEvent Key event.
+ * @param aListBox List box.
+ * @return Next index of the list item.
+ */
+TInt NextFocusIndex
+ ( const TKeyEvent& aKeyEvent, CEikListBox& aListBox )
+ {
+ TInt result( KErrNotFound );
+ const TInt KFirstItemIndex( 0 );
+ TInt itemCount( aListBox.Model()->NumberOfItems() );
+ const TInt KLastItemIndex( itemCount - 1 );
+ TInt currentItemIndex( aListBox.CurrentItemIndex() );
+ if ( aKeyEvent.iCode == EKeyDownArrow )
+ {
+ result = currentItemIndex + 1;
+ if ( result > KLastItemIndex )
+ {
+ // Set to first
+ result = KFirstItemIndex;
+ }
+ }
+ else if ( aKeyEvent.iCode == EKeyUpArrow )
+ {
+ result = currentItemIndex - 1;
+ if ( result < KFirstItemIndex )
+ {
+ // Set to last
+ result = KLastItemIndex;
+ }
+ }
+ else
+ {
+ result = currentItemIndex;
+ }
+ return result;
+ }
+
+} /// namespace
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::CPbk2NamesListReadyState
+// --------------------------------------------------------------------------
+//
+inline CPbk2NamesListReadyState::CPbk2NamesListReadyState(
+ const CCoeControl& aParent,
+ CPbk2ContactViewListBox& aListBox,
+ MPbk2FilteredViewStack& aViewStack,
+ CAknSearchField* aFindBox,
+ CPbk2ThumbnailLoader& aThumbnailLoader,
+ MPbk2UiControlEventSender& aEventSender,
+ MPbk2ContactNameFormatter& aNameFormatter,
+ RPointerArray<MPbk2UiControlCmdItem>& aCommandItems,
+ CPbk2PredictiveSearchFilter& aSearchFilter ) :
+ iParent( aParent ),
+ iListBox( aListBox ),
+ iViewStack( aViewStack ),
+ iFindBox( aFindBox ),
+ iThumbnailLoader( aThumbnailLoader ),
+ iEventSender( aEventSender ),
+ iNameFormatter( aNameFormatter ),
+ iCommandItems( aCommandItems ),
+ iSearchFilter(aSearchFilter)
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::~CPbk2NamesListReadyState
+// --------------------------------------------------------------------------
+//
+CPbk2NamesListReadyState::~CPbk2NamesListReadyState()
+ {
+ UnsubscribeCmdItemsVisibility();
+ iListBox.SetListCommands( NULL );
+
+ delete iAdaptiveSearchGridFiller;
+ delete iFindPolicy;
+ delete iFindDelay;
+ delete iFindTextBuf;
+ iSelectedItems.Close();
+ delete iStringArray;
+ delete iStringSplitter;
+ iIteratorIndexes.Close();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2NamesListReadyState* CPbk2NamesListReadyState::NewLC
+ ( const CCoeControl* aParent, CPbk2ContactViewListBox& aListBox,
+ MPbk2FilteredViewStack& aViewStack, CAknSearchField* aFindBox,
+ CPbk2ThumbnailLoader& aThumbnailLoader,
+ MPbk2UiControlEventSender& aEventSender,
+ MPbk2ContactNameFormatter& aNameFormatter,
+ RPointerArray<MPbk2UiControlCmdItem>& aCommandItems,
+ CPbk2PredictiveSearchFilter& aSearchFilter )
+ {
+ CPbk2NamesListReadyState* self = new (ELeave) CPbk2NamesListReadyState(
+ *aParent, aListBox, aViewStack, aFindBox, aThumbnailLoader,
+ aEventSender, aNameFormatter, aCommandItems, aSearchFilter );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ConstructL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2NamesListReadyState::ConstructL()
+ {
+ if ( iFindBox )
+ {
+ if (!iFindBox->IsFocused() && iParent.IsFocused() )
+ {
+ iFindBox->SetFocus(ETrue);
+ }
+ iFindBox->ResetL();
+ }
+
+ iFindDelay = CPbk2FindDelay::NewL( *this );
+
+ // Create contact find policy
+ CVPbkContactManager& manager =
+ Phonebook2::Pbk2AppUi()->ApplicationServices().ContactManager();
+ CVPbkContactFindPolicy::TParam param =
+ CVPbkContactFindPolicy::TParam(
+ manager.FieldTypes(),
+ manager.FsSession() );
+ iFindPolicy = CVPbkContactFindPolicy::NewL( param );
+
+ if( iFindBox )
+ {
+ iFindBox->AddAdaptiveSearchTextObserverL( this );
+ iAdaptiveSearchGridFiller = CPbk2AdaptiveSearchGridFiller::NewL( *iFindBox, iNameFormatter );
+ }
+ }
+
+void CPbk2NamesListReadyState::UnsubscribeCmdItemsVisibility() const
+ {
+ for ( TInt i = 0; i < iCommandItems.Count(); ++i )
+ {
+ iCommandItems[i]->SetVisibilityObserver( NULL );
+ }
+ }
+
+void CPbk2NamesListReadyState::SubscribeCmdItemsVisibility()
+ {
+ for ( TInt i = 0; i < iCommandItems.Count(); ++i )
+ {
+ iCommandItems[i]->SetVisibilityObserver( this );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ActivateStateL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ActivateStateL()
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::ActivateStateL(0x%x)"), this );
+
+ AllowCommandsToShowThemselves( ETrue );
+ UpdateAdaptiveSearchGridL( EFalse );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::DeactivateState
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::DeactivateState()
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::DeactivateState(0x%x)"), this );
+
+ AllowCommandsToShowThemselves( EFalse );
+ HideThumbnail();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::CountComponentControls
+// --------------------------------------------------------------------------
+//
+TInt CPbk2NamesListReadyState::CountComponentControls() const
+ {
+ TInt numberOfControls( KNumberOfControls );
+ if ( !iFindBox )
+ {
+ --numberOfControls;
+ }
+ return numberOfControls;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ComponentControl
+// --------------------------------------------------------------------------
+//
+CCoeControl* CPbk2NamesListReadyState::ComponentControl(TInt aIndex) const
+ {
+ switch (aIndex)
+ {
+ case 0:
+ {
+ return &iListBox;
+ }
+ case 1:
+ {
+ return iFindBox;
+ }
+ default:
+ {
+ // Illegal state
+ __ASSERT_DEBUG(EFalse, Panic(EPanicLogic_ComponentControl));
+ return NULL;
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SizeChanged
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SizeChanged()
+ {
+ const TRect rect(iParent.Rect());
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::SizeChanged(0x%x), rect=(%d,%d,%d,%d)"),
+ this, rect.iTl.iX, rect.iTl.iY, rect.iBr.iX, rect.iBr.iY);
+
+ if ( iFindBox )
+ {
+ AknLayoutUtils::LayoutControl(&iListBox, rect,
+ AKN_LAYOUT_WINDOW_list_gen_pane(1));
+
+ AknLayoutUtils::LayoutControl( iFindBox, rect,
+ AKN_LAYOUT_WINDOW_find_pane );
+ if (iFindBox->IsVisible() && iListBox.IsVisible())
+ {
+ iFindBox->SetLinePos(EABColumn);
+ }
+ }
+ else
+ {
+ AknLayoutUtils::LayoutControl(&iListBox, rect,
+ AKN_LAYOUT_WINDOW_list_gen_pane(0));
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::MakeComponentsVisible
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::MakeComponentsVisible(TBool aVisible)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::MakeComponentsVisible(0x%x,%d)"),
+ this, aVisible);
+
+ iListBox.MakeVisible(aVisible);
+
+ CEikScrollBar *scrollBar = iListBox.ScrollBarFrame()->GetScrollBarHandle
+ (CEikScrollBar::EVertical);
+ if ( scrollBar )
+ {
+ scrollBar->MakeVisible(aVisible);
+ }
+
+ if ( iFindBox )
+ {
+ if ( (iFindBox->IsVisible()&&!aVisible) || (!iFindBox->IsVisible()&&aVisible) )
+ {
+ iFindBox->MakeVisible(aVisible);
+ }
+ }
+
+ // Have to call to make sure that scrollbar is updated when state of
+ // control is changing.
+ TRAP_IGNORE( iListBox.UpdateScrollBarsL() );
+
+ // Change visible state
+ iVisible = aVisible;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ActivateL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ActivateL()
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::ActivateL(0x%x)"), this );
+
+ if ( iFindBox )
+ {
+ // Adjust find box cursor
+ CEikEdwin& findEditor = iFindBox->Editor();
+ findEditor.SetCursorPosL(findEditor.TextLength(), EFalse);
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::Draw
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::Draw
+ ( const TRect& aRect, CWindowGc& aGc ) const
+ {
+ PBK2_DEBUG_PRINT( PBK2_DEBUG_STRING(
+ "CPbk2NamesListReadyState::Draw(0x%x, TRect(%d,%d,%d,%d))" ),
+ this, aRect.iTl.iX, aRect.iTl.iY, aRect.iBr.iX, aRect.iBr.iY );
+
+ if ( !iVisible )
+ {
+ // If control is not visible (blanked) draw a blank background
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ MAknsControlContext* cc =
+ AknsDrawUtils::ControlContext( &iListBox );
+
+ if ( !AknsDrawUtils::Background( skin, cc, &iListBox, aGc, aRect ) )
+ {
+ // Blank background if no skin present
+ aGc.SetPenStyle( CGraphicsContext::ENullPen );
+ aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+ aGc.DrawRect( aRect );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::DialogMenuBar
+// --------------------------------------------------------------------------
+//
+CEikMenuBar* CPbk2NamesListReadyState::DialogMenuBar(CAknAppUi* aAppUi)
+ {
+ CEikMenuBar* menuBar = NULL;
+
+ // Check for an active dialog and fetch its menu bar
+ if (aAppUi->IsDisplayingMenuOrDialog())
+ {
+ CCoeControl* ctrl = aAppUi->TopFocusedControl();
+ if (ctrl)
+ {
+ CEikDialog* dialog = ctrl->MopGetObjectNoChaining(dialog);
+ if (dialog)
+ {
+ dialog->MopGetObject(menuBar);
+ }
+ }
+ }
+ return menuBar;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ViewMenuBar
+// --------------------------------------------------------------------------
+//
+CEikMenuBar* CPbk2NamesListReadyState::ViewMenuBar(CAknAppUi* aAppUi)
+ {
+ CEikMenuBar* menuBar = NULL;
+
+ // Check for an active view
+ TVwsViewId uid;
+ if (aAppUi->GetActiveViewId(uid) == KErrNone)
+ {
+ if ( uid.iAppUid != uid.iViewUid )
+ {
+ CAknView* view =
+ static_cast<CAknViewAppUi*> (aAppUi)->View(uid.iViewUid);
+ if ( view )
+ {
+ menuBar = view->MenuBar();
+ }
+ }
+ }
+ return menuBar;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::MenuBar
+// --------------------------------------------------------------------------
+//
+CEikMenuBar* CPbk2NamesListReadyState::MenuBar(CAknAppUi* aAppUi)
+ {
+ // Try fetching a menu bar from currently displayed dialog
+ CEikMenuBar* menuBar = DialogMenuBar( aAppUi );
+
+ if ( !menuBar ) // Menu bar was not dialog based
+ {
+ // Try fetching a menu bar from an active view
+ menuBar = ViewMenuBar(aAppUi);
+ }
+
+ if ( !menuBar ) // Menu bar was not view based
+ {
+ // Finally, try fetching a menu bar from AppUi
+ menuBar = CEikonEnv::Static()->AppUiFactory()->MenuBar();
+ }
+ return menuBar;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::OfferKeyEventL
+// --------------------------------------------------------------------------
+//
+TKeyResponse CPbk2NamesListReadyState::OfferKeyEventL
+ (const TKeyEvent& aKeyEvent, TEventCode aType)
+ {
+ // Remember current index and selection before
+ // listbox has handled the event.
+ TInt oldItemIndex( iListBox.CurrentItemIndex() );
+ TBool oldItemMarkedBefore
+ ( iListBox.View()->ItemIsSelected( oldItemIndex ) );
+
+ // Remember next index based on key event (UP, DOWN)
+ // and selection before listbox has handled the event.
+ TInt newItemIndex( NextFocusIndex( aKeyEvent, iListBox ) );
+ TBool newItemMarkedBefore
+ ( iListBox.View()->ItemIsSelected( newItemIndex ) );
+
+ TKeyResponse result( EKeyWasNotConsumed );
+ if ( iFindBox )
+ {
+ //If the FindBox is locked then dont offer the event to the findbox
+ if (!iSearchFilter.IsLocked())
+ {
+ // use the "C" key to delete the Adaptive search character must
+ // change the focus to Adaptive search pane
+ if ( aKeyEvent.iCode == EKeyBackspace && iAdaptiveSearchGridFiller )
+ {
+ iAdaptiveSearchGridFiller->SetFocusToAdaptiveSearchGrid();
+ }
+
+ // Offer the key event first to findbox
+ result = iFindBox->OfferKeyEventL( aKeyEvent, aType );
+
+ CPbk2PredictiveViewStack& predictiveViewStack = static_cast<CPbk2PredictiveViewStack&>( iViewStack );
+
+ TInt contactItemIndex = newItemIndex - CommandItemCount();
+
+ if ( contactItemIndex >= 0 && oldItemIndex != newItemIndex && iSearchFilter.IsPredictiveActivated() && iViewStack.Level() &&
+ !predictiveViewStack.IsNonMatchingMarkedContact( contactItemIndex ) )
+ {
+ iSearchFilter.CommitFindPaneTextL( iViewStack, iNameFormatter, contactItemIndex );
+ }
+
+ }
+ else
+ {
+ //If FindPane is locked, then forward only the backspace key.
+ if ( aKeyEvent.iCode == EKeyBackspace )
+ {
+ // Offer the key event first to findbox
+ result = iFindBox->OfferKeyEventL( aKeyEvent, aType );
+ }
+ }
+ }
+
+ // And then offer the event to listbox if necessary
+ if ( result == EKeyWasNotConsumed )
+ {
+ // Use hash key to mark and unmark list item
+ if ( (aKeyEvent.iScanCode == EStdKeyHash)
+ && MenuBar( iAvkonAppUi )->ItemSpecificCommandsEnabled() )
+ {
+ if ( aType == EEventKeyUp )
+ {
+ if ( newItemMarkedBefore )
+ {
+ iListBox.View()->DeselectItem( newItemIndex );
+ }
+ else
+ {
+ iListBox.View()->SelectItemL( newItemIndex );
+ }
+ }
+ result = EKeyWasConsumed;
+ }
+ else
+ {
+ result = iListBox.OfferKeyEventL( aKeyEvent, aType );
+ }
+ }
+ else
+ {
+ // Find box consumed the key event, abort abort
+ return result;
+ }
+
+ // If listbox handles the event, test if the selections have changed.
+ if ( result == EKeyWasConsumed )
+ {
+ // If newItemIndex is found (it is not KErrNotFound) and
+ // if newItemIndex is not the same as oldItemIndex
+ if ( newItemIndex != KErrNotFound
+ && newItemIndex != oldItemIndex )
+ {
+ // Check if the new item index has marked afterwards.
+ TBool newItemMarkedAfter
+ ( iListBox.View()->ItemIsSelected( newItemIndex ) );
+
+ // If new item selection has changed, send event.
+ if ( newItemMarkedBefore != newItemMarkedAfter )
+ {
+ // Send event about changed state
+ TPbk2ControlEvent
+ event( TPbk2ControlEvent::EContactSelected );
+ event.iInt = newItemIndex;
+ if ( !newItemMarkedAfter )
+ {
+ event.iEventType =
+ TPbk2ControlEvent::EContactUnselected;
+ }
+ iEventSender.SendEventToObserversL( event );
+
+ //if commands marked, unmark it back
+ if ( !IsContactAtListboxIndex( newItemIndex ) && newItemMarkedAfter )
+ {
+ UnmarkCommands();
+ event.iEventType = TPbk2ControlEvent::EContactUnselected;
+ iEventSender.SendEventToObserversL( event );
+ }
+ }
+ }
+
+ // Check if old item's selection has changed and send event.
+ TBool oldItemMarkedAfter
+ ( iListBox.View()->ItemIsSelected( oldItemIndex ) );
+ if ( oldItemMarkedBefore != oldItemMarkedAfter )
+ {
+ // Send event about changed state
+ TPbk2ControlEvent
+ event( TPbk2ControlEvent::EContactSelected );
+ event.iInt = oldItemIndex;
+ if ( !oldItemMarkedAfter )
+ {
+ event.iEventType =
+ TPbk2ControlEvent::EContactUnselected;
+ }
+ iEventSender.SendEventToObserversL( event );
+
+ //if commands marked, unmark it back
+ if ( !IsContactAtListboxIndex( oldItemIndex ) && oldItemMarkedAfter )
+ {
+ UnmarkCommands();
+ event.iEventType = TPbk2ControlEvent::EContactUnselected;
+ iEventSender.SendEventToObserversL( event );
+ }
+ }
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HandlePointerEventL
+// Event sending differs from OfferKeyEventL's solution on purpose.
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::HandlePointerEventL
+ ( const TPointerEvent& aPointerEvent )
+ {
+ iSearchFieldPointed = EFalse;
+ if ( iFindBox )
+ {
+ if ( iFindBox->Rect().Contains( aPointerEvent.iPosition ) )
+ {
+ iFindBox->HandlePointerEventL( aPointerEvent );
+ iSearchFieldPointed = ETrue;
+ }
+ }
+
+ TInt previousItemIndex = iListBox.CurrentItemIndex();
+ iListBox.HandlePointerEventL( aPointerEvent );
+
+ // Handle focus change when dragging
+ if ( previousItemIndex != iListBox.CurrentItemIndex() &&
+ aPointerEvent.iType == TPointerEvent::EDrag )
+ {
+ HandleFocusChangeL();
+ }
+
+ if ( !iSearchFieldPointed && FocusableItemPointed() &&
+ aPointerEvent.iType == TPointerEvent::EButton1Up )
+ {
+ // Send selection events based on marking
+ TInt focusIndex = iListBox.CurrentItemIndex();
+ const TBool markedAfter = iListBox.View()->ItemIsSelected( focusIndex );
+
+ TPbk2ControlEvent event( TPbk2ControlEvent::EContactSelected );
+ event.iInt = focusIndex;
+ if ( !markedAfter )
+ {
+ event.iEventType = TPbk2ControlEvent::EContactUnselected;
+ }
+ iEventSender.SendEventToObserversL( event );
+
+ }
+
+ TInt currentIndex = iListBox.CurrentItemIndex();
+ CPbk2PredictiveViewStack& predictiveViewStack = static_cast<CPbk2PredictiveViewStack&>( iViewStack );
+
+ TInt contactItemIndex = currentIndex - CommandItemCount();
+ if ( contactItemIndex >= 0 && iFindBox && iSearchFilter.IsPredictiveActivated() && iViewStack.Level() &&
+ !predictiveViewStack.IsNonMatchingMarkedContact( contactItemIndex ) )
+ {
+ iSearchFilter.CommitFindPaneTextL( iViewStack, iNameFormatter, contactItemIndex );
+ }
+
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::NamesListState
+// --------------------------------------------------------------------------
+//
+TInt CPbk2NamesListReadyState::NamesListState() const
+ {
+ return CPbk2NamesListControl::EStateReady;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HandleContactViewEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::HandleContactViewEventL
+ (TInt aEvent, TInt aIndex)
+ {
+ // need to calculate list index from contact
+ // view index
+ TInt listIndex = CommandItemCount() + aIndex;
+ HandleListboxEventL(aEvent, listIndex, EFalse );
+
+ TInt currentFocusIndex = iListBox.CurrentItemIndex();
+ TBool marked = iListBox.View()->ItemIsSelected( currentFocusIndex );
+
+ //update findpane according to the new focused contact after delete operation.
+ //Do nothing if the next focused contact is marked because it would not be found.
+ if ( aEvent == MPbk2NamesListState::EItemRemoved
+ && iSearchFilter.IsPredictiveActivated()
+ && iViewStack.Level()
+ && iFindBox
+ && iFindBox->TextLength() != 0
+ && !marked)
+ {
+ iSearchFilter.CommitFindPaneTextL( iViewStack, iNameFormatter, currentFocusIndex );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HandleCommandEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::HandleCommandEventL
+ (TInt aEvent, TInt /* aCommandIndex*/ )
+ {
+ HandleListboxEventL(aEvent, 0, ETrue );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HandleListboxEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::HandleListboxEventL
+ (TInt aEvent, TInt aListboxIndex, TBool aMantainFocus )
+ {
+ switch (aEvent)
+ {
+ case EItemAdded:
+ {
+ //contact added, grid might not have all necessary characters.
+ //this could be optimized, we could just check the added contact and
+ //update map if the performance is not enough
+ UpdateAdaptiveSearchGridL( ETrue );
+
+ // Inform find box and list box
+ UpdateFindBoxL();
+
+ TInt topIndex = iListBox.TopItemIndex();
+ iListBox.HandleEventL(aEvent, aListboxIndex);
+
+ // Maintain focus
+ // TODO: similar focus handling code in case item delete in iListBox.HandleEventL
+ // to consider to move this focus code there as well
+ if (aListboxIndex >= 0 && aListboxIndex < iListBox.NumberOfItems() )
+ {
+ if ( aMantainFocus )
+ {
+ //keep focused item and top item if its not 0
+ if ( aListboxIndex <= iListBox.CurrentItemIndex() &&
+ ( iListBox.CurrentItemIndex() + 1 ) < iListBox.NumberOfItems() )
+ {
+ iListBox.SetCurrentItemIndex(
+ iListBox.CurrentItemIndex() + 1 );
+ if ( topIndex > 0 && ( topIndex + 1 ) < iListBox.NumberOfItems() )
+ {
+ iListBox.SetTopItemIndex( topIndex + 1 );
+ }
+ }
+ }
+ else
+ {
+ //change focus to the added item
+ if ( aListboxIndex != iListBox.CurrentItemIndex() )
+ {
+ iListBox.SetCurrentItemIndex( aListboxIndex );
+ }
+ }
+ }
+
+ iParent.DrawDeferred();
+ HandleFocusChangeL();
+ break;
+ }
+ case EItemRemoved:
+ {
+ //contact removed, grids might have unecessary characters
+ UpdateAdaptiveSearchGridL( ETrue );
+
+ // Inform find box and list box
+ UpdateFindBoxL();
+ iListBox.HandleEventL(aEvent, aListboxIndex);
+
+ // Maintain focus
+ if (aListboxIndex >= 0 && aListboxIndex < iListBox.NumberOfItems() )
+ {
+ if ( aMantainFocus )
+ {
+ //no op
+ }
+ else
+ {
+ //change focus
+ if ( aListboxIndex != iListBox.CurrentItemIndex() )
+ {
+ iListBox.SetCurrentItemIndex( aListboxIndex );
+ }
+ }
+ }
+
+ iParent.DrawDeferred();
+ HandleFocusChangeL();
+ break;
+ }
+ case EContactViewUpdated:
+ {
+ UpdateAdaptiveSearchGridL( ETrue );
+ break;
+ }
+ default:
+ {
+ // Do nothing
+ break;
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::CoeControl
+// --------------------------------------------------------------------------
+//
+CCoeControl& CPbk2NamesListReadyState::CoeControl()
+ {
+ CCoeControl* tmp = NULL;
+ return *static_cast<CCoeControl*>(tmp);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HandleControlEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::HandleControlEventL( CCoeControl* aControl,
+ MCoeControlObserver::TCoeEvent aEventType, TInt aParam )
+ {
+ if ( aEventType == MCoeControlObserver::EEventStateChanged )
+ {
+ // Find box
+ if ( aControl == iFindBox )
+ {
+ if( aParam )
+ {
+ //means the search came from adaptive search grid
+ if( iAdaptiveSearchGridFiller )
+ {
+ iAdaptiveSearchGridFiller->InvalidateAdaptiveSearchGrid();
+ }
+ }
+ //if aParam is ETrue, it means that event came from adaptive search, which means
+ //we do not want to delay filtering
+ if ( ( !aParam ) &&
+ ( iFindDelay ) &&
+ ( NumberOfContacts() >= KFindDelayThresholdContacts ) )
+ {
+ if ( iFindDelay->IsActive() )
+ {
+ iFindDelay->Cancel();
+ }
+ iFindDelay->After( TTimeIntervalMicroSeconds32( KFindDelayTime ) );
+ }
+ else
+ {
+ UpdateFindResultL();
+ }
+ }
+ // List
+ else if ( aControl == &iListBox )
+ {
+ HandleFocusChangeL();
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::TopContactL
+// --------------------------------------------------------------------------
+//
+const MVPbkViewContact* CPbk2NamesListReadyState::TopContactL()
+ {
+ const MVPbkViewContact* contact = NULL;
+
+ // There is an offset between listbox indexes and view indexes.
+ const TInt topListboxIndex = iListBox.TopItemIndex();
+ const TInt enabledCommandCount = CommandItemCount();
+ // Check whether the index is valid. Also check whether the top
+ // really is a contact.
+ if ( topListboxIndex >= 0 && topListboxIndex >= enabledCommandCount )
+ {
+ // Map from listbox index to view index
+ contact = &iViewStack.ContactAtL(
+ topListboxIndex - enabledCommandCount );
+ }
+ return contact;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ParentControl
+// --------------------------------------------------------------------------
+//
+MPbk2ContactUiControl* CPbk2NamesListReadyState::ParentControl() const
+ {
+ // Names list control does not have a parent control
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::NumberOfContacts
+// --------------------------------------------------------------------------
+//
+TInt CPbk2NamesListReadyState::NumberOfContacts() const
+ {
+ // The listbox can also have command items.
+ TInt result = iListBox.NumberOfItems() - CommandItemCount();
+ if ( result < 0 )
+ {
+ result = 0; // No contacts
+ }
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusedContactL
+// --------------------------------------------------------------------------
+//
+const MVPbkBaseContact* CPbk2NamesListReadyState::FocusedContactL() const
+ {
+ return FocusedViewContactL();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusedViewContactL
+// --------------------------------------------------------------------------
+//
+const MVPbkViewContact* CPbk2NamesListReadyState::FocusedViewContactL() const
+ {
+ const MVPbkViewContact* contact = NULL;
+
+ // There is an offset between listbox indexes and view indexes.
+ const TInt focusListboxIndex = iListBox.CurrentItemIndex();
+ const TInt enabledCommandCount = CommandItemCount();
+ // Is the focus on a contact. Check...
+ if (focusListboxIndex >= 0 && focusListboxIndex >= enabledCommandCount )
+ {
+ // Yes, the focus is on a contact.
+ // Map from listbox index to view index
+ contact = &iViewStack.ContactAtL(
+ focusListboxIndex - enabledCommandCount );
+ }
+ return contact;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusedStoreContact
+// --------------------------------------------------------------------------
+//
+const MVPbkStoreContact* CPbk2NamesListReadyState::FocusedStoreContact() const
+ {
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetFocusedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetFocusedContactL
+ ( const MVPbkBaseContact& aContact )
+ {
+ SetFocusedContactL( KErrNotSupported, &aContact );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetFocusedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetFocusedContactL
+ ( const MVPbkContactBookmark& aContactBookmark )
+ {
+ TInt viewIndex = iViewStack.IndexOfBookmarkL( aContactBookmark );
+ SetFocusedContactL( viewIndex, NULL );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetFocusedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetFocusedContactL
+ ( const MVPbkContactLink& aContactLink )
+ {
+ TInt viewIndex = iViewStack.IndexOfLinkL( aContactLink );
+ SetFocusedContactL( viewIndex, NULL );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusedContactIndex
+// --------------------------------------------------------------------------
+//
+TInt CPbk2NamesListReadyState::FocusedContactIndex() const
+ {
+ // The result is a view index. There is an offset between listbox indexes
+ // and view indexes.
+
+ TInt viewIndex = KErrNotFound;
+ const TInt currentListboxIndex = iListBox.CurrentItemIndex();
+ const TInt commandCount = CommandItemCount();
+ // Is the focus on a contact or on a command item? Check:
+ if ( currentListboxIndex >= commandCount )
+ {
+ // Yes, the focus is on a contact.
+ // Need to map from listbox indexes to view indexes.
+ viewIndex = currentListboxIndex - commandCount;
+ }
+ return viewIndex;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetFocusedContactIndex
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetFocusedContactIndexL( TInt aIndex )
+ {
+ // The aIndex is a view index. There is an offset between listbox indexes
+ // and view indexes.
+
+ if ( aIndex < 0 )
+ {
+ aIndex = 0;
+ }
+ const TInt enabledCommandCount = CommandItemCount();
+ if ( aIndex > iListBox.BottomItemIndex() - enabledCommandCount )
+ {
+ aIndex = iListBox.BottomItemIndex() - enabledCommandCount;
+ }
+
+ SetFocusedContactL( aIndex, NULL );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::NumberOfContactFields
+// --------------------------------------------------------------------------
+//
+TInt CPbk2NamesListReadyState::NumberOfContactFields() const
+ {
+ return KErrNotSupported;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusedField
+// --------------------------------------------------------------------------
+//
+const MVPbkBaseContactField* CPbk2NamesListReadyState::FocusedField() const
+ {
+ // There is no field level focus
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusedFieldIndex
+// --------------------------------------------------------------------------
+//
+TInt CPbk2NamesListReadyState::FocusedFieldIndex() const
+ {
+ // There is no field level focus
+ return KErrNotFound;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetFocusedFieldIndex
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetFocusedFieldIndex( TInt /*aIndex*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ContactsMarked
+// --------------------------------------------------------------------------
+//
+TBool CPbk2NamesListReadyState::ContactsMarked() const
+ {
+ return iListBox.ContactsMarked();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SelectedContactsL
+// --------------------------------------------------------------------------
+//
+MVPbkContactLinkArray*
+ CPbk2NamesListReadyState::SelectedContactsL() const
+ {
+ // Get listbox selection indexes, a reference only
+ const CListBoxView::CSelectionIndexArray* selArray =
+ iListBox.SelectionIndexes();
+
+
+ TInt count = 1; // initialize to one, because if there are
+ // no selections we operate with one focused contact
+ if (selArray)
+ {
+ count = selArray->Count();
+ }
+
+ CVPbkContactLinkArray* linkArray = NULL;
+
+ if (count > 0)
+ {
+ linkArray = CVPbkContactLinkArray::NewLC();
+
+ // Loop through the selections and construct a link for
+ // each of the contacts
+ const TInt commandItemCount = CommandItemCount();
+ for (TInt i=0; i<count; ++i)
+ {
+ const TInt singleSelection = selArray->At(i);
+ if ( IsContactAtListboxIndex( singleSelection ) )
+ {
+ // Take the view contact from the view, the ownership
+ // stays at the view
+ const MVPbkViewContact* contact =
+ &iViewStack.ContactAtL( singleSelection - commandItemCount );
+ MVPbkContactLink* link = contact->CreateLinkLC();
+ if (link)
+ {
+ linkArray->AppendL(link);
+ CleanupStack::Pop(); // the array takes ownership of the link
+ }
+ }
+ }
+
+ CleanupStack::Pop(linkArray);
+ }
+
+ return linkArray;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SelectedContactsOrFocusedContactL
+// --------------------------------------------------------------------------
+//
+MVPbkContactLinkArray*
+ CPbk2NamesListReadyState::SelectedContactsOrFocusedContactL() const
+ {
+ MVPbkContactLinkArray* result = NULL;
+ result = SelectedContactsL();
+
+ if ( !result )
+ {
+ CVPbkContactLinkArray* array = CVPbkContactLinkArray::NewLC();
+ const MVPbkBaseContact* focusedContact = FocusedContactL();
+ if ( focusedContact )
+ {
+ MVPbkContactLink* link = focusedContact->CreateLinkLC();
+ CleanupStack::Pop(); // link
+ array->AppendL( link );
+ }
+ else
+ {
+ // there was no focused contact, check if this is the my card
+ AppendMyCardLinkIfExistL( *array );
+ }
+ CleanupStack::Pop(); // array
+ result = array;
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::AppendMyCardLinkIfExistL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::AppendMyCardLinkIfExistL( CVPbkContactLinkArray& aArray ) const
+ {
+ TInt currentItem = iListBox.CurrentItemIndex();
+ // if focused index is command item
+ if( currentItem < CommandItemCount() )
+ {
+ // check if the command is my card ( this search is copied from CommandItemAt - function to avoid const cast)
+ // Some of the commands might be disabled. Skip those.
+ TInt enabledCount = 0;
+ TInt indexOfResult = KErrNotFound;
+ for ( TInt n = 0; n < iCommandItems.Count() && indexOfResult == KErrNotFound; ++n )
+ {
+ if ( iCommandItems[ n ]->IsEnabled() )
+ {
+ enabledCount++;
+ if ( enabledCount-1 == currentItem )
+ {
+ indexOfResult = n;
+ }
+ }
+ }
+ MPbk2UiControlCmdItem* item = iCommandItems[ indexOfResult ];
+ // check if the command item was a my card
+ if( item->CommandId() == EPbk2CmdOpenMyCard )
+ {
+ // get extension point and my card link
+ TAny* object = item->ControlCmdItemExtension( TUid::Uid( KPbk2ControlCmdItemExtensionUID ) );
+ if( object )
+ {
+ MPbk2DoubleListboxCmdItemExtension* extension =
+ static_cast<MPbk2DoubleListboxCmdItemExtension*>( object );
+ // if extension exists
+ if( extension )
+ {
+ const MVPbkContactLink* link = extension->Link();
+ // if link exists, add it to the array
+ if( link )
+ {
+ aArray.AppendL( link->CloneLC() );
+ CleanupStack::Pop();
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SelectedContactsIteratorL
+// --------------------------------------------------------------------------
+//
+MPbk2ContactLinkIterator*
+ CPbk2NamesListReadyState::SelectedContactsIteratorL() const
+ {
+ // Get listbox selection indexes, a reference only
+ const CListBoxView::CSelectionIndexArray* selArray =
+ iListBox.SelectionIndexes();
+
+ TInt count = 0;
+ if ( selArray )
+ {
+ count = selArray->Count();
+ }
+
+ MPbk2ContactLinkIterator* iterator = NULL;
+
+ if ( count > 0 )
+ {
+ // Need to map the listbox indexes to view indexes.
+ // Also need to filter out cmd items.
+ iIteratorIndexes.Reset();
+ const TInt commandItemCount = CommandItemCount();
+ const TInt selectionCount = selArray->Count();
+ for ( TInt n = 0; n < selectionCount; ++n )
+ {
+ const TInt listboxIndex = selArray->At( n );
+ if ( listboxIndex >= commandItemCount)
+ {
+ // It is a contact.
+ // Do a mapping from listbox index to view index
+ iIteratorIndexes.AppendL( listboxIndex - commandItemCount );
+ }
+ }
+ iterator = CPbk2ContactViewIterator::NewLC
+ ( iViewStack, iIteratorIndexes.Array() );
+ CleanupStack::Pop(); // iterator
+ }
+
+ return iterator;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SelectedContactStoresL
+// --------------------------------------------------------------------------
+//
+CArrayPtr<MVPbkContactStore>*
+ CPbk2NamesListReadyState::SelectedContactStoresL() const
+ {
+ // This is not a state of the contact store control
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ClearMarks
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ClearMarks()
+ {
+ iListBox.View()->ClearSelection();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetSelectedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetSelectedContactL
+ ( TInt aIndex, TBool aSelected )
+ {
+ if ( aSelected )
+ {
+ iListBox.View()->SelectItemL( aIndex );
+ }
+ else
+ {
+ iListBox.View()->DeselectItem( aIndex );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetSelectedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetSelectedContactL(
+ const MVPbkContactBookmark& aContactBookmark,
+ TBool aSelected )
+ {
+ TInt index = iViewStack.IndexOfBookmarkL( aContactBookmark );
+ if ( index != KErrNotFound )
+ {
+ SetSelectedContactL( index, aSelected );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetSelectedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetSelectedContactL(
+ const MVPbkContactLink& aContactLink,
+ TBool aSelected )
+ {
+ TInt index = iViewStack.IndexOfLinkL( aContactLink );
+ if ( index != KErrNotFound )
+ {
+ SetSelectedContactL( index, aSelected );
+ }
+ }
+
+
+TInt CPbk2NamesListReadyState::CommandItemCount() const
+ {
+ // Some of the commands might be disabled. Don't count those.
+ TInt enabledCommandCount = 0;
+ for ( TInt n = 0; n < iCommandItems.Count(); ++n )
+ {
+ if ( iCommandItems[ n ]->IsEnabled() )
+ {
+ enabledCommandCount++;
+ }
+ }
+ return enabledCommandCount;
+ }
+
+const MPbk2UiControlCmdItem&
+CPbk2NamesListReadyState::CommandItemAt( TInt aIndex ) const
+ {
+ // Some of the commands might be disabled. Skip those.
+ TInt enabledCount = 0;
+ TInt indexOfResult = KErrNotFound;
+
+ for ( TInt n = 0; n < iCommandItems.Count()&& indexOfResult == KErrNotFound; ++n )
+ {
+ if ( iCommandItems[ n ]->IsEnabled() )
+ {
+ enabledCount++;
+ if ( enabledCount-1 == aIndex )
+ {
+ indexOfResult = n;
+ }
+ }
+ }
+
+ return *iCommandItems[ indexOfResult ];
+ }
+
+const MPbk2UiControlCmdItem*
+CPbk2NamesListReadyState::FocusedCommandItem() const
+ {
+ const MPbk2UiControlCmdItem* cmdItem = NULL;
+ // Is the focus on a command item:
+ TInt focusListIndex = iListBox.CurrentItemIndex();
+ const TInt commandItemCount = CommandItemCount();
+ if ( focusListIndex != KErrNotFound && focusListIndex < commandItemCount )
+ {
+ // Yes it's a command item.
+ cmdItem = &CommandItemAt(focusListIndex);
+ }
+ return cmdItem;
+ }
+
+void CPbk2NamesListReadyState::DeleteCommandItemL( TInt /*aIndex*/ )
+ {
+ // ownership & management of iCommandItems is wasted in names list
+ // control. Do nothing here
+ }
+
+void CPbk2NamesListReadyState::AddCommandItemL(MPbk2UiControlCmdItem* /*aCommand*/, TInt /*aIndex*/)
+ {
+ // ownership & management of iCommandItems is wasted in names list
+ // control. Do nothing here
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::DynInitMenuPaneL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::DynInitMenuPaneL(
+ TInt aResourceId, CEikMenuPane* aMenuPane) const
+ {
+ AknSelectionService::HandleMarkableListDynInitMenuPane
+ (aResourceId, aMenuPane, &iListBox);
+
+ TInt focusedItem = iListBox.View()->CurrentItemIndex();
+ TBool markHidden = iListBox.View()->ItemIsSelected( focusedItem );
+ TBool unmarkHidden = !iListBox.View()->ItemIsSelected( focusedItem );
+ TBool markAllHidden = ( iListBox.Model()->NumberOfItems() == 0 ) ||
+ ( iListBox.SelectionIndexes()->Count() == iListBox.Model()->NumberOfItems() );
+ TBool unmarkAllHidden = ( iListBox.Model()->NumberOfItems() == 0 ) ||
+ ( iListBox.SelectionIndexes()->Count() == 0 );
+
+ TInt position;
+ if (aMenuPane->MenuItemExists(EAknCmdMark, position))
+ {
+ aMenuPane->SetItemDimmed(EAknCmdMark, markHidden);
+ }
+ if (aMenuPane->MenuItemExists(EAknCmdUnmark, position))
+ {
+ aMenuPane->SetItemDimmed(EAknCmdUnmark, unmarkHidden);
+ }
+ if (aMenuPane->MenuItemExists(EAknMarkAll, position))
+ {
+ aMenuPane->SetItemDimmed(EAknMarkAll, markAllHidden);
+ }
+ if (aMenuPane->MenuItemExists(EAknUnmarkAll, position))
+ {
+ aMenuPane->SetItemDimmed(EAknUnmarkAll, unmarkAllHidden);
+ }
+
+ // When all contacts are marked in the listbox, the command items are not marked.
+ // This code snippet dims out the Mark All menu item which is shown since the
+ // list box cannot differentiate a command and a contact item
+
+ TInt commandItemCount = CommandItemCount();
+
+
+ if ((iListBox.SelectionIndexes()->Count() + commandItemCount ) == iListBox.Model()->NumberOfItems())
+ {
+ TInt i; // Stores the position of the searched menu item.
+ // This position is not needed or used anywhere
+ if (aMenuPane->MenuItemExists(EAknMarkAll, i))
+ {
+ aMenuPane->SetItemDimmed(EAknMarkAll, ETrue);
+ }
+ }
+
+ // If there's any, command items are always placed at the top of the list box.
+ // By comparing the list box current item index with the command item count, we are trying to find out
+ // if the current focused item is command item or not.
+
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ProcessCommandL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ProcessCommandL
+ (TInt aCommandId) const
+ {
+ AknSelectionService::HandleMarkableListProcessCommandL
+ (aCommandId, &iListBox);
+
+ // Send event
+ TPbk2ControlEvent event( TPbk2ControlEvent::EContactSelected );
+ event.iInt = iListBox.CurrentItemIndex();
+
+ switch( aCommandId )
+ {
+ case EAknCmdMark:
+ case EAknMarkAll:
+ {
+ // Send event about changed state
+ iEventSender.SendEventToObserversL( event );
+ // commands should stay unmarked
+ UnmarkCommands();
+ break;
+ }
+
+ case EAknCmdUnmark:
+ {
+ event.iEventType = TPbk2ControlEvent::EContactUnselected;
+ iEventSender.SendEventToObserversL( event );
+ break;
+ }
+
+ case EAknUnmarkAll:
+ {
+ // Send event about changed state
+ event.iEventType = TPbk2ControlEvent::EContactUnselectedAll;
+ iEventSender.SendEventToObserversL( event );
+ break;
+ }
+
+ default:;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::UpdateAfterCommandExecution
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::UpdateAfterCommandExecution()
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::GetMenuFilteringFlagsL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2NamesListReadyState::GetMenuFilteringFlagsL() const
+ {
+ TInt ret = KPbk2ListContainsItems;
+ if (ContactsMarked())
+ {
+ ret |= KPbk2ListContainsMarkedItems;
+ }
+ else
+ {
+ ret |= KPbk2ListContainsNoMarkedItems;
+ }
+
+ TInt focusIndex = iListBox.CurrentItemIndex();
+ // Non-contact items are not expandable.
+ const TInt commandItemCount = CommandItemCount();
+ if ( focusIndex < commandItemCount )
+ {
+ // It is not a contact.
+ focusIndex = KErrNotFound;
+ }
+
+ // There is an offset between view indexes and listbox indexes.
+ if (focusIndex >= 0 &&
+ iViewStack.ContactAtL(focusIndex - commandItemCount).Expandable())
+ {
+ ret |= KPbk2FocusedItemIsExpandable;
+ }
+
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ControlStateL
+// --------------------------------------------------------------------------
+//
+CPbk2ViewState* CPbk2NamesListReadyState::ControlStateL() const
+ {
+ // State objects do not handle control state changes
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetFocusedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetFocusedContactL( TInt aIndex,
+ const MVPbkBaseContact* aContact )
+ {
+ // The aIndex is a view index. There is an offset between listbox indexes
+ // and view indexes.
+
+ TInt viewIndex = KErrNotReady;
+
+ if ( aContact )
+ {
+ MVPbkContactBookmark* bookmark = aContact->CreateBookmarkLC();
+ TInt contactIndex = iViewStack.IndexOfBookmarkL( *bookmark );
+ CleanupStack::PopAndDestroy(); // bookmark
+
+ if ( contactIndex >= 0 &&
+ contactIndex < iViewStack.ContactCountL() )
+ {
+ viewIndex = contactIndex;
+ }
+ }
+
+ if ( viewIndex == KErrNotReady )
+ {
+ if ( aIndex >= 0 &&
+ aIndex < iViewStack.ContactCountL() )
+ {
+ viewIndex = aIndex;
+ }
+ }
+
+ // Need to map current listbox index to view indexes.
+ // But at the same time check whether the current item is a contact.
+ const TInt enabledCommandCount = CommandItemCount();
+ TInt currentContactAsViewIndex = KErrNotReady;
+ if ( iListBox.CurrentItemIndex() >= enabledCommandCount )
+ {
+ // Yes, the current item is a contact.
+ currentContactAsViewIndex =
+ iListBox.CurrentItemIndex() - enabledCommandCount;
+ }
+
+ // If index is valid, and not already the current one, then use it to set
+ // the current item.
+ if ( viewIndex != KErrNotReady && viewIndex != currentContactAsViewIndex )
+ {
+ iListBox.SetCurrentItemIndex( viewIndex + enabledCommandCount );
+ // Force hiding of thumbnail from previously focused contact
+ HideThumbnail();
+ HandleFocusChangeL();
+ }
+
+ // Should be drawn always to be sure that UI is updated
+ iParent.DrawDeferred();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::RestoreControlStateL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::RestoreControlStateL
+ (CPbk2ViewState* aState)
+ {
+ TBool redraw = EFalse;
+ if (aState->Flags() & CPbk2ViewState::EInitialized)
+ {
+ iListBox.Reset();
+ redraw = ETrue;
+ }
+ else
+ {
+ if (iViewStack.ContactCountL() > 0)
+ {
+ if (aState->Flags() & CPbk2ViewState::EFocusFirst)
+ {
+ iListBox.SetCurrentItemIndex(0);
+ }
+ else if (aState->Flags() & CPbk2ViewState::EFocusLast)
+ {
+ iListBox.SetCurrentItemIndex(iListBox.Model()->NumberOfItems()-1);
+ }
+ else
+ {
+ // Restore top contact
+ const MVPbkContactLink* topContact = aState->TopContact();
+ if (topContact)
+ {
+ const TInt viewIndex = iViewStack.IndexOfLinkL(*topContact);
+ if (viewIndex >= 0)
+ {
+ const TInt prevListboxIndex = iListBox.TopItemIndex();
+ // There is an offset between listbox indexes
+ // and view indexes.
+ const TInt listboxIndex = viewIndex + CommandItemCount();
+ iListBox.SetTopItemIndex(listboxIndex);
+ iListBox.FixTopItemIndex();
+ if (listboxIndex != prevListboxIndex)
+ {
+ redraw = ETrue;
+ }
+ }
+ }
+
+ const MVPbkContactLink* focusedContact = aState->FocusedContact();
+ if (focusedContact)
+ {
+ const TInt viewIndex =
+ iViewStack.IndexOfLinkL(*focusedContact);
+ if (viewIndex >= 0)
+ {
+ const TInt prevListboxIndex = iListBox.CurrentItemIndex();
+ // There is an offset between listbox indexes
+ // and view indexes.
+ const TInt listboxIndex = viewIndex + CommandItemCount();
+ iListBox.SetCurrentItemIndex(listboxIndex);
+ if (listboxIndex != prevListboxIndex)
+ {
+ redraw = ETrue;
+ }
+ }
+ }
+ }
+ // Restore selections
+ const MVPbkContactLinkArray* markedContacts =
+ aState->MarkedContacts();
+ if (RestoreMarkedContactsL(markedContacts))
+ {
+ redraw = ETrue;
+ }
+ }
+ }
+ if (redraw)
+ {
+ iParent.DrawDeferred();
+ iListBox.UpdateScrollBarsL();
+ HandleFocusChangeL();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FindTextL
+// --------------------------------------------------------------------------
+//
+const TDesC& CPbk2NamesListReadyState::FindTextL()
+ {
+ if ( iFindBox )
+ {
+ TPbk2FindTextUtil::EnsureFindTextBufSizeL(
+ *iFindBox,
+ &iFindTextBuf );
+ TPtr bufPtr = iFindTextBuf->Des();
+ iFindBox->GetSearchText(bufPtr);
+ return *iFindTextBuf;
+ }
+
+ return KNullDesC;
+ }
+
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ResetFindL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ResetFindL()
+ {
+ if ( iFindBox && iFindBox->TextLength() > 0 )
+ {
+ iSearchFilter.ResetL();
+ iFindBox->ResetL();
+ iViewStack.Reset();
+ iFindBox->DrawDeferred();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HideThumbnail
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::HideThumbnail()
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ShowThumbnail
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ShowThumbnail()
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetBlank
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetBlank(TBool aBlank)
+ {
+ if (!aBlank)
+ {
+ // Redraw
+ iParent.DrawDeferred();
+ TRAPD( error,
+ iListBox.UpdateScrollBarsL();
+ HandleFocusChangeL();
+ );
+ if ( error != KErrNone )
+ {
+ CCoeEnv::Static()->HandleError( error );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::RegisterCommand
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::RegisterCommand(
+ MPbk2Command* /*aCommand*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetTextL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetTextL( const TDesC& aText )
+ {
+ iListBox.View()->SetListEmptyTextL( aText );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ContactUiControlExtension
+// --------------------------------------------------------------------------
+//
+TAny* CPbk2NamesListReadyState::ContactUiControlExtension(TUid aExtensionUid )
+ {
+ if( aExtensionUid == KMPbk2ContactUiControlExtension2Uid )
+ {
+ return static_cast<MPbk2ContactUiControl2*>( this );
+ }
+
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusedItemPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2NamesListReadyState::FocusedItemPointed()
+ {
+ return iListBox.FocusedItemPointed();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FocusableItemPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2NamesListReadyState::FocusableItemPointed()
+ {
+ return iListBox.FocusableItemPointed();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SearchFieldPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2NamesListReadyState::SearchFieldPointed()
+ {
+ return iSearchFieldPointed;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::TopViewChangedL
+//
+// This is called when top view is changed. However this happens before .e.g
+// the view containing top contacts is ready and therefore in this point of
+// execution we don't know whether there will be e.g. "Add to favorites"
+// command item visible or not
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::TopViewChangedL(
+ MVPbkContactViewBase& aOldView )
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::TopViewChangedL begin") );
+
+ // Switch view
+ TInt countBefore = aOldView.ContactCountL();
+ TInt countAfter = iViewStack.ContactCountL();
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::TopViewChangedL:before=%d,now=%d"),
+ countBefore, countAfter );
+
+ // Markings must be checked before HandleItemAdditionL or
+ // HandleItemRemovalL because they reset markings
+ TBool marked = ContactsMarked();
+
+ // Handle list box changes
+ // Promotion item "Add to favourites" should not be visible if top view is
+ // not base view (iViewStack.Level() !== 0). Remote search may be shown when there
+ // is text entered in find box. MyCard enabled similarly as add favorites.
+ TBool addFavoOk = iViewStack.Level() == 0 && !(iFindBox && iFindBox->TextLength());
+ UpdateCommandEnabled( EPbk2CmdAddFavourites, addFavoOk );
+ UpdateCommandEnabled( EPbk2CmdRcl, !addFavoOk );
+ UpdateCommandEnabled( EPbk2CmdOpenMyCard, addFavoOk );
+
+ if ( countAfter > countBefore ) //count does not contain command items
+ {
+ iListBox.HandleItemAdditionL();
+ }
+ if ( countAfter < countBefore )
+ {
+ iListBox.HandleItemRemovalL();
+ }
+
+ UpdateAdaptiveSearchGridL( EFalse );
+
+ if ( marked )
+ {
+ // update markings to the new view
+ RestoreMarkedItemsL( iSelectedItems );
+ }
+
+ if ( iSearchFilter.IsPredictiveActivated() )
+ {
+ TInt indexOfMatchedItem = iSearchFilter.CommitFindPaneTextL( iViewStack, iNameFormatter );
+ if ( indexOfMatchedItem == KErrNotFound )
+ {
+ indexOfMatchedItem = 0;
+ }
+ iListBox.SetCurrentItemIndexAndDraw(indexOfMatchedItem);
+ }
+ else
+ {
+ SetCurrentItemIndexAndDrawL();
+ }
+
+ HandleFocusChangeL();
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::TopViewChangedL end") );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::TopViewUpdatedL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::TopViewUpdatedL()
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::TopViewUpdatedL begin") );
+
+ // Promotion item "Add to favourites" should not be visible if top view is
+ // not base view (iViewStack.Level() !== 0). Remote search may be shown when there
+ // is text entered in find box. MyCard enabled similarly as add favorites.
+ TBool addFavoOk = iViewStack.Level() == 0 && !(iFindBox && iFindBox->TextLength());
+
+ UpdateCommandEnabled( EPbk2CmdAddFavourites, addFavoOk );
+ UpdateCommandEnabled( EPbk2CmdRcl, !addFavoOk );
+ UpdateCommandEnabled( EPbk2CmdOpenMyCard, addFavoOk );
+ UpdateAdaptiveSearchGridL( ETrue );
+
+ if ( ContactsMarked() )
+ {
+ // The view didn't change so we have to restore the items that
+ // were saved last time the find box was updated.
+ RestoreMarkedItemsL( iSelectedItems );
+ SetCurrentItemIndexAndDrawL();
+ }
+ HandleFocusChangeL();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::BaseViewChangedL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::BaseViewChangedL()
+ {
+ HandleFocusChangeL();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ViewStackError
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ViewStackError( TInt /*aError*/ )
+ {
+ // CPbk2NameListControl is listening to view stack errors and handles
+ // them. This is UI control's internal design and the state can
+ // ignore the error
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::ContactAddedToBaseView
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::ContactAddedToBaseView(
+ MVPbkContactViewBase& /*aBaseView*/, TInt /*aIndex*/,
+ const MVPbkContactLink& /*aContactLink*/ )
+ {
+ // CPbk2NameListControl handles this.
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::FindDelayComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::FindDelayComplete()
+ {
+ TRAPD( error, UpdateFindResultL() );
+ if ( error != KErrNone )
+ {
+ CCoeEnv::Static()->HandleError( error );
+ iViewStack.Reset();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::AdaptiveSearchTextChanged
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::AdaptiveSearchTextChanged( CAknSearchField* aSearchField )
+ {
+ //Add this line to call CPbk2AdaptiveSearchGridFiller::InvalidateAdaptiveSearchGrid()
+ //to control GRID must be updated always after user has pressed a key, even if the keymap does not changed
+ HandleControlEventL( aSearchField, MCoeControlObserver::EEventStateChanged, ETrue );
+
+ //this callback method is only used to notice when language has changed and
+ //to update adaptive search grid.
+
+ if( aSearchField->LanguageChanged() )
+ {
+ UpdateAdaptiveSearchGridL( ETrue );
+ }
+ }
+
+
+void CPbk2NamesListReadyState::CmdItemVisibilityChanged( TInt aCmdItemId, TBool aVisible )
+ {
+ TInt cmdItemIndex = FindCommand(aCmdItemId);
+ TRAP_IGNORE( HandleCommandEventL(
+ (aVisible ? EItemAdded : EItemRemoved),
+ cmdItemIndex) );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::RestoreMarkedContactsL
+// Marks specified contacts in the listbox.
+//
+// @param aMarkedContacts Contacts to mark.
+// @return True if any contacts were marked in the list.
+// --------------------------------------------------------------------------
+//
+TBool CPbk2NamesListReadyState::RestoreMarkedContactsL
+ (const MVPbkContactLinkArray* aMarkedContacts)
+ {
+ TBool result = EFalse;
+ DisableRedrawEnablePushL();
+ iListBox.ClearSelection();
+ if (aMarkedContacts)
+ {
+ const TInt count = aMarkedContacts->Count();
+ for (TInt i=0; i < count; ++i)
+ {
+ const MVPbkContactLink& contact = aMarkedContacts->At(i);
+ const TInt viewIndex = iViewStack.IndexOfLinkL(contact);
+ if (viewIndex >= 0)
+ {
+ const TInt listboxIndex = viewIndex + CommandItemCount();
+ iListBox.View()->SelectItemL(listboxIndex);
+ result = ETrue;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(); // DisableRedrawEnablePushL
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::RestoreMarkedItemsL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::RestoreMarkedItemsL(
+ const MVPbkContactBookmarkCollection& aSelectedItems )
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::RestoreMarkedItemsL: %d items"),
+ aSelectedItems.Count() );
+
+ DisableRedrawEnablePushL();
+ iListBox.ClearSelection();
+ const TInt count = aSelectedItems.Count();
+ for ( TInt i = 0; i < count; ++i )
+ {
+ TInt index = iViewStack.IndexOfBookmarkL( aSelectedItems.At( i ) ) + CommandItemCount();
+ if ( index >= 0 )
+ {
+ iListBox.View()->SelectItemL( index );
+ }
+ }
+ CleanupStack::PopAndDestroy(); // DisableRedrawEnablePushL
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::DisableRedrawEnablePushL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::DisableRedrawEnablePushL()
+ {
+ CListBoxView& listBoxView = *iListBox.View();
+ listBoxView.SetDisableRedraw(ETrue);
+ CleanupStack::PushL(TCleanupEnableListBoxViewRedraw(listBoxView));
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HandleFocusChangeL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::HandleFocusChangeL()
+ {
+ iEventSender.SendEventToObserversL(
+ TPbk2ControlEvent::TPbk2ControlEvent::EControlFocusChanged );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::UpdateFindResultL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::UpdateFindResultL()
+ {
+ TBuf <KSearchFieldLength> findPaneTxt( FindTextL() );
+
+ if ( iSearchFilter.StartFindPaneInlineEditL( findPaneTxt ) )
+ {
+ TBool selectionChanged = HasSelectedItemsChangedL();
+
+ MVPbkContactBookmarkCollection* marked = NULL;
+ if ( ContactsMarked() )
+ {
+ marked = &SelectedItemsL( iViewStack );
+ }
+ else
+ {
+ // User has removed all the marks so update also bookmarks.
+ iSelectedItems.RemoveAndDeleteAll();
+ }
+
+ // Extract the find text into array
+ if ( !iStringSplitter )
+ {
+ iStringSplitter = CPbk2FindStringSplitter::NewL( iNameFormatter );
+ }
+ MDesCArray* temp = iStringSplitter->SplitTextIntoArrayL( findPaneTxt );
+ delete iStringArray;
+ iStringArray = temp;
+
+ iViewStack.UpdateFilterL( *iStringArray, marked, selectionChanged );
+
+ UpdateAdaptiveSearchGridL( EFalse );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::UpdateFindBoxL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::UpdateFindBoxL()
+ {
+ if ( iFindBox )
+ {
+ if ( iViewStack.ContactCountL() > 0 && iParent.IsFocused() )
+ {
+ iFindBox->SetFocusing( ETrue );
+ // If findbox is focusing, SetFocus would clear some flag of Fep,
+ // and it will cause 'b','c',''e',...could not be entered for the
+ // first character by V-ITUT.
+ if ( !iFindBox->IsFocused() )
+ {
+ iFindBox->SetFocus( ETrue, EDrawNow );
+ }
+ }
+ else
+ {
+ iFindBox->SetNonFocusing();
+ iFindBox->SetFocus( EFalse, EDrawNow );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SelectedItemsL
+// --------------------------------------------------------------------------
+//
+MVPbkContactBookmarkCollection& CPbk2NamesListReadyState::SelectedItemsL(
+ MVPbkContactViewBase& aCurrentView )
+ {
+ // Get listbox selection indexes, a reference only
+ const CListBoxView::CSelectionIndexArray* selArray =
+ iListBox.SelectionIndexes();
+
+ if ( selArray )
+ {
+ iSelectedItems.RemoveAndDeleteAll();
+ const TInt count = selArray->Count();
+ for ( TInt i = 0; i < count; ++i )
+ {
+
+ iSelectedItems.AppendL(
+ aCurrentView.CreateBookmarkLC( selArray->At(i) - CommandItemCount() ) );
+ CleanupStack::Pop();
+ }
+ }
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::SelectedItemsL:%d marked"),
+ iSelectedItems.Count() );
+
+ return iSelectedItems;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::HasSelectedItemsChangedL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2NamesListReadyState::HasSelectedItemsChangedL()
+ {
+ TBool result = EFalse;
+
+ // Get listbox selection indexes, a reference only
+ const CListBoxView::CSelectionIndexArray* selArray =
+ iListBox.SelectionIndexes();
+
+ if ( selArray )
+ {
+ TInt bookmarkCount = iSelectedItems.Count();
+ TInt markedCount = selArray->Count();
+ // Changed if number of items are different
+ result = bookmarkCount != markedCount;
+ if ( !result )
+ {
+ // There are equeal amount of items. Compare as long
+ // as the difference is found
+ for ( TInt i = 0; i < bookmarkCount && !result; ++i )
+ {
+ result = selArray->At(i) !=
+ iViewStack.IndexOfBookmarkL( iSelectedItems.At(i) );
+ }
+ }
+ }
+ else if ( iSelectedItems.Count() > 0 )
+ {
+ result = ETrue;
+ }
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NamesListReadyState::HasSelectedItemsChangedL: %d "),
+ result );
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2NamesListReadyState::SetCurrentItemIndexAndDrawL
+// --------------------------------------------------------------------------
+//
+void CPbk2NamesListReadyState::SetCurrentItemIndexAndDrawL()
+ {
+ __ASSERT_DEBUG( &iListBox && iFindPolicy,
+ Panic(EPanicLogic_PreConds_SetCurrentItemIndexAndDraw) );
+
+ if ( iStringArray && iStringArray->MdcaCount() > 0 )
+ {
+ TBool isCurrentItemSet( EFalse );
+ const TInt count( iViewStack.ContactCountL() );
+ for ( TInt i(0); i < count; ++i )
+ {
+ const MVPbkViewContact& contact = iViewStack.ContactAtL( i );
+ if ( iFindPolicy->MatchContactNameL( *iStringArray, contact ) )
+ {
+ isCurrentItemSet = ETrue;
+ iListBox.SetCurrentItemIndexAndDraw(i);
+ break;
+ }
+ }
+ if ( !isCurrentItemSet )
+ {
+ iListBox.SetCurrentItemIndexAndDraw(0);
+ }
+ }
+ else
+ {
+ iListBox.SetCurrentItemIndexAndDraw(0);
+ }
+ }
+
+void CPbk2NamesListReadyState::UpdateAdaptiveSearchGridL( TBool aClearCache )
+ {
+ if( ( !iAdaptiveSearchGridFiller ) || ( !iFindBox ) )
+ {
+ return;
+ }
+
+ CAknSearchField::TSearchFieldStyle searchStyle = iFindBox->SearchFieldStyle();
+
+ if ( searchStyle != CAknSearchField::EAdaptiveSearch )
+ {
+ delete iAdaptiveSearchGridFiller;
+ iAdaptiveSearchGridFiller = NULL;
+ return;
+ }
+
+ iAdaptiveSearchGridFiller->StopFilling();
+
+ if( aClearCache )
+ {
+ iAdaptiveSearchGridFiller->ClearCache();
+ }
+
+
+ iAdaptiveSearchGridFiller->StartFilling( iViewStack, FindTextL() );
+ }
+
+/**
+ * Tells whether the listbox line contains a contact or not.
+ * Does not check that the aListboxIndex is within range of listbox.
+ * @param aListboxIndex The position in the listbox to be checked.
+ */
+TBool CPbk2NamesListReadyState::IsContactAtListboxIndex( TInt aListboxIndex ) const
+ {
+ // There can be command items at the top of the list.
+ // The command items are not contacts.
+ const TInt enabledCommandCount = CommandItemCount();
+ return aListboxIndex >= enabledCommandCount;
+ }
+
+void CPbk2NamesListReadyState::AllowCommandsToShowThemselves( TBool aVisible )
+ {
+ if ( aVisible )
+ {
+ // ownership not transferred
+ iListBox.SetListCommands( &iCommandItems );
+ SubscribeCmdItemsVisibility();
+ UpdateCommandEnabled( EPbk2CmdAddFavourites, ETrue ); //By default add favorites may be shown
+ UpdateCommandEnabled( EPbk2CmdOpenMyCard, ETrue );
+ }
+ else
+ {
+ UpdateCommandEnabled( EPbk2CmdRcl, EFalse );
+ UpdateCommandEnabled( EPbk2CmdAddFavourites, EFalse );
+ UpdateCommandEnabled( EPbk2CmdOpenMyCard, EFalse );
+ UnsubscribeCmdItemsVisibility();
+ iListBox.SetListCommands( NULL );
+ }
+ }
+
+void CPbk2NamesListReadyState::UpdateCommandEnabled( TInt aCommandId, TBool aEnabled )
+ {
+ for ( TInt i = 0; i < iCommandItems.Count(); i++ )
+ {
+ if ( iCommandItems[i]->CommandId() == aCommandId )
+ {
+ iCommandItems[i]->SetEnabled( aEnabled );
+ break;
+ }
+ }
+ }
+
+TBool CPbk2NamesListReadyState::IsCommandEnabled(TInt aCommandId) const
+ {
+ TBool res = EFalse;
+ for ( TInt i = 0; i < iCommandItems.Count(); i++ )
+ {
+ if ( iCommandItems[i]->CommandId() == aCommandId )
+ {
+ res = iCommandItems[i]->IsEnabled();
+ break;
+ }
+ }
+ return res;
+ }
+
+//
+// Search for a command in iCommandItems and returns its index
+//
+TInt CPbk2NamesListReadyState::FindCommand(TInt aCommandId) const
+ {
+ TInt result = KErrNotFound;
+ for ( TInt i = 0; i < iCommandItems.Count(); ++i )
+ {
+ if ( iCommandItems[i]->CommandId() == aCommandId )
+ {
+ result = i;
+ break;
+ }
+
+ }
+ return result;
+ }
+
+TInt CPbk2NamesListReadyState::CalculateListboxIndex(TInt aCommandIndex) const
+ {
+ //TInt num = 0;
+ TInt num(KErrNotFound);
+ for ( TInt i = 0; i <= aCommandIndex; ++i )
+ {
+ if(iCommandItems[i]->IsEnabled())
+ {
+ ++num;
+ }
+ }
+ return num;
+ }
+
+
+void CPbk2NamesListReadyState::UnmarkCommands() const
+ {
+ for ( TInt i = 0; i < CommandItemCount(); i++ )
+ {
+ iListBox.View()->DeselectItem( i );
+ }
+ }
+
+TInt CPbk2NamesListReadyState::EnabledCommandCount() const
+ {
+ TInt result = 0;
+ for ( TInt i = 0; i < iCommandItems.Count(); ++i )
+ {
+ if(iCommandItems[i]->IsEnabled())
+ {
+ result++;
+ }
+ }
+ return result;
+ }
+
+// End of File