--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2ContactInfoControl.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1379 @@
+/*
+* 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 contact info view control.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <CPbk2ContactInfoControl.h>
+
+// Phonebook 2
+#include "CPbk2ContactInfoListBox.h"
+#include "CPbk2ContactInfoDataSwapper.h"
+#include "CPbk2ContactFieldDynamicProperties.h"
+#include "CPbk2ThumbnailLoader.h"
+#include "Pbk2TitlePanePictureFactory.h"
+#include <Pbk2UIControls.rsg>
+#include <Pbk2UIControls.hrh>
+#include <CPbk2IconArray.h>
+#include <MPbk2ContactNameFormatter.h>
+#include <CPbk2ViewState.h>
+#include <MPbk2ControlObserver.h>
+#include <CPbk2PresentationContact.h>
+#include <CPbk2PresentationContactField.h>
+#include <CPbk2PresentationContactFieldCollection.h>
+#include <CPbk2FieldPropertyArray.h>
+#include <Pbk2MenuFilteringFlags.hrh>
+#include <MPbk2ContactNavigation.h>
+#include <CPbk2StorePropertyArray.h>
+#include <CPbk2StoreSpecificFieldPropertyArray.h>
+#include <MPbk2Command.h>
+#include <Pbk2Profile.h>
+
+// Virtual Phonebook
+#include <MVPbkContactOperationBase.h>
+#include <CVPbkContactManager.h>
+#include <MVPbkContactLink.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkStoreContactField.h>
+#include <MVPbkStoreContactFieldCollection.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactFieldSelector.h>
+#include <MVPbkFieldType.h>
+#include <CVPbkFieldTypeSelector.h>
+#include <CVPbkContactStoreUriArray.h>
+#include <MVPbkContactFieldTextData.h>
+#include <VPbkEng.rsg>
+
+// System includes
+#include <akntitle.h>
+#include <AknsConstants.h>
+#include <avkon.hrh>
+#include <barsread.h>
+#include <bautils.h>
+
+// Debugging headers
+#include <Pbk2Debug.h>
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+
+const TInt KNumberOfControls = 1;
+const TInt KNoContacts = 0;
+const TInt KNumberOfContacts = 1;
+const TInt KDefaultTitleFormat = MPbk2ContactNameFormatter::EUseSeparator;
+
+#ifdef _DEBUG
+enum TPanicCode
+ {
+ EPanicPreCond_FocusedField = 1,
+ EPanicLogic_FocusedField,
+ EPanicPreCond_FocusedFieldIndex,
+ EPanicPostCond_FocusedFieldIndex,
+ EPanicPreCond_FieldPos,
+ EPanicPreCond_OfferKeyEventL,
+ EPanicPreCond_SizeChanged,
+ EPanicPreCond_CountComponentControls,
+ EPanicPreCond_ComponentControl
+ };
+
+void Panic(TInt aReason)
+ {
+ _LIT(KPanicText, "CPbk2ContactInfoControl");
+ User::Panic(KPanicText, aReason);
+ }
+#endif // _DEBUG
+
+} /// namespace
+
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::CPbk2ContactInfoControl
+// --------------------------------------------------------------------------
+//
+CPbk2ContactInfoControl::CPbk2ContactInfoControl(
+ CVPbkContactManager& aManager,
+ MPbk2ContactNameFormatter& aNameFormatter,
+ MPbk2FieldPropertyArray& aFieldProperties,
+ CPbk2StorePropertyArray& aStoreProperties,
+ MPbk2ContactNavigation* aNavigator ) :
+ iContactManager( aManager ),
+ iNameFormatter( aNameFormatter ),
+ iNavigator( aNavigator ),
+ iFieldProperties( aFieldProperties ),
+ iStoreProperties( aStoreProperties ),
+ iFocusedFieldIndex( KErrNotFound )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::~CPbk2ContactInfoControl
+// --------------------------------------------------------------------------
+//
+CPbk2ContactInfoControl::~CPbk2ContactInfoControl()
+ {
+ if( iTitlePane )
+ {
+ iTitlePane->SetSmallPicture( NULL, NULL, EFalse );
+ }
+ if (iCommand)
+ {
+ // inform the command that the control is deleted
+ iCommand->ResetUiControl(*this);
+ }
+ iObservers.Reset();
+ delete iThumbnailLoader;
+ delete iListBox;
+ delete iContact;
+ delete iStoreContact;
+ delete iRetriever;
+ delete iContactLink;
+ delete iSpecificFieldProperties;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ConstructL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2ContactInfoControl::ConstructL(
+ const CCoeControl* aContainer)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2ContactInfoControl::ConstructL begin"));
+
+ SetContainerWindowL(*aContainer);
+
+ // Create the listbox
+ iListBox = CPbk2ContactInfoListBox::NewL(
+ *this, R_PBK2_CONTACT_INFO_CONTROL, iContactManager);
+ iListBox->SetObserver(this);
+ iListBox->SetScrollEventObserver( this );
+ iListBox->SetListBoxObserver( this );
+
+ // Get flags from listbox
+ iFlags = iListBox->Flags();
+
+ // Create thumbnail loader
+ iThumbnailLoader = CPbk2ThumbnailLoader::NewL( iContactManager );
+
+ CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane();
+ if( statusPane && statusPane->
+ PaneCapabilities( TUid::Uid( EEikStatusPaneUidTitle ) ).IsPresent() )
+ {
+ iTitlePane = static_cast<CAknTitlePane*>(
+ statusPane->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) );
+ }
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2ContactInfoControl::ConstructL end"));
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::NewL
+// --------------------------------------------------------------------------
+//
+EXPORT_C CPbk2ContactInfoControl* CPbk2ContactInfoControl::NewL
+ ( const CCoeControl* aContainer,
+ CVPbkContactManager& aManager,
+ MPbk2ContactNameFormatter& aNameFormatter,
+ MPbk2FieldPropertyArray& aFieldProperties,
+ CPbk2StorePropertyArray& aStoreProperties,
+ MPbk2ContactNavigation* aNavigator )
+ {
+ CPbk2ContactInfoControl* self = new ( ELeave ) CPbk2ContactInfoControl
+ ( aManager, aNameFormatter, aFieldProperties, aStoreProperties,
+ aNavigator );
+ CleanupStack::PushL( self );
+ self->ConstructL( aContainer );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::AddObserverL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CPbk2ContactInfoControl::AddObserverL
+ (MPbk2ControlObserver& aObserver)
+ {
+ User::LeaveIfError(iObservers.Append(&aObserver));
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::RemoveObserver
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CPbk2ContactInfoControl::RemoveObserver
+ (MPbk2ControlObserver& aObserver)
+ {
+ const TInt index = iObservers.Find(&aObserver);
+ if (index >= 0)
+ {
+ iObservers.Remove(index);
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ParentControl
+// --------------------------------------------------------------------------
+//
+MPbk2ContactUiControl* CPbk2ContactInfoControl::ParentControl() const
+ {
+ // Contact info control has no parent control
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::NumberOfContacts
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::NumberOfContacts() const
+ {
+ return KNumberOfContacts;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusedContactL
+// --------------------------------------------------------------------------
+//
+const MVPbkBaseContact* CPbk2ContactInfoControl::FocusedContactL() const
+ {
+ return iContact;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusedViewContactL
+// --------------------------------------------------------------------------
+//
+const MVPbkViewContact* CPbk2ContactInfoControl::FocusedViewContactL() const
+ {
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusedStoreContact
+// --------------------------------------------------------------------------
+//
+const MVPbkStoreContact* CPbk2ContactInfoControl::FocusedStoreContact() const
+ {
+ return iStoreContact;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetFocusedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetFocusedContactL(
+ const MVPbkBaseContact& aContact)
+ {
+ // Load the new contact
+ delete iContactLink;
+ iContactLink = NULL;
+ iContactLink = aContact.CreateLinkLC();
+ CleanupStack::Pop(); // iContactLink
+
+ RetrieveContactL( *iContactLink );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetFocusedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetFocusedContactL(
+ const MVPbkContactBookmark& /*aContactBookmark*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetFocusedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetFocusedContactL(
+ const MVPbkContactLink& aContactLink )
+ {
+ // Load the new contact
+ delete iContactLink;
+ iContactLink = NULL;
+ iContactLink = aContactLink.CloneLC();
+ CleanupStack::Pop(); // iContactLink
+
+ RetrieveContactL( *iContactLink );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusedContactIndex
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::FocusedContactIndex() const
+ {
+ return KErrNotSupported;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetFocusedContactIndexL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetFocusedContactIndexL( TInt /*aIndex*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::NumberOfContactFields
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::NumberOfContactFields() const
+ {
+ return iContact->Fields().FieldCount();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusedField
+// --------------------------------------------------------------------------
+//
+const MVPbkBaseContactField* CPbk2ContactInfoControl::FocusedField() const
+ {
+ // PreCond:
+ __ASSERT_DEBUG(iListBox && iFields, Panic(EPanicPreCond_FocusedField));
+
+ const MVPbkBaseContactField* ret = NULL;
+ const TInt fieldsCount = iFields->FieldCount();
+ const TInt index = iListBox->CurrentItemIndex();
+ TInt numberOfVisibleFields = 0;
+ if (index >= 0)
+ {
+ __ASSERT_DEBUG(index < iFields->FieldCount(),
+ Panic(EPanicLogic_FocusedField));
+
+ // Field collection may have hidden fields, so find visible field
+ // corresponding to the focused field in the listbox.
+ for ( TInt i = 0; i < fieldsCount && ret == NULL; i++ )
+ {
+ if ( iFields->At( i ).IsVisibleInDetailsView() &&
+ iFields->At( i ).DynamicVisibility() )
+ {
+ numberOfVisibleFields++;
+ }
+ if ( numberOfVisibleFields - 1 == index )
+ {
+ ret = &iFields->FieldAt( i );
+ }
+ }
+ }
+
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusedFieldIndex
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::FocusedFieldIndex() const
+ {
+ // PreCond:
+ __ASSERT_DEBUG(iContact, Panic(EPanicPreCond_FocusedFieldIndex));
+
+ return iListBox->CurrentItemIndex();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetFocusedFieldIndex
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetFocusedFieldIndex(
+ TInt aIndex )
+ {
+ iFocusedFieldIndex = aIndex;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ContactsMarked
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactInfoControl::ContactsMarked() const
+ {
+ // This control does not support contacts marking
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SelectedContactsL
+// --------------------------------------------------------------------------
+//
+MVPbkContactLinkArray* CPbk2ContactInfoControl::SelectedContactsL() const
+ {
+ // No selection support in contact info control
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SelectedContactsOrFocusedContactL
+// --------------------------------------------------------------------------
+//
+MVPbkContactLinkArray*
+ CPbk2ContactInfoControl::SelectedContactsOrFocusedContactL() const
+ {
+ CVPbkContactLinkArray* array = CVPbkContactLinkArray::NewLC();
+ const MVPbkBaseContact* focusedContact = FocusedContactL();
+ if ( focusedContact )
+ {
+ MVPbkContactLink* link = focusedContact->CreateLinkLC();
+ CleanupStack::Pop(); // link
+ array->AppendL( link );
+ }
+ CleanupStack::Pop(); // array
+
+ return array;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SelectedContactsIteratorL
+// --------------------------------------------------------------------------
+//
+MPbk2ContactLinkIterator*
+ CPbk2ContactInfoControl::SelectedContactsIteratorL() const
+ {
+ // No selection support in contact info control
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SelectedContactStoresL
+// --------------------------------------------------------------------------
+//
+CArrayPtr<MVPbkContactStore>*
+ CPbk2ContactInfoControl::SelectedContactStoresL() const
+ {
+ // This is not a contact store control
+ return NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ClearMarks
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::ClearMarks()
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetSelectedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetSelectedContactL(
+ TInt /*aIndex*/,
+ TBool /*aSelected*/)
+ {
+ // Not supported in Contact Info
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetSelectedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetSelectedContactL(
+ const MVPbkContactBookmark& /*aContactBookmark*/,
+ TBool /*aSelected*/ )
+ {
+ // Not supported
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetSelectedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetSelectedContactL(
+ const MVPbkContactLink& /*aContactLink*/,
+ TBool /*aSelected*/ )
+ {
+ // Not supported
+ }
+
+TInt CPbk2ContactInfoControl::CommandItemCount() const
+ {
+ return 0; // No command items.
+ }
+
+const MPbk2UiControlCmdItem& CPbk2ContactInfoControl::CommandItemAt(
+ TInt /*aIndex*/ ) const
+ {
+ // There are no command items in this control
+ __ASSERT_ALWAYS( EFalse, User::Panic( _L("Pbk2"), 4)); //TODO
+ MPbk2UiControlCmdItem* item = NULL; // For compiler only
+ return *item; // For compiler only
+ }
+
+const MPbk2UiControlCmdItem* CPbk2ContactInfoControl::FocusedCommandItem() const
+ {
+ return NULL;
+ }
+
+void CPbk2ContactInfoControl::DeleteCommandItemL( TInt /*aIndex*/ )
+ {
+ // Do nothing
+ }
+
+void CPbk2ContactInfoControl::AddCommandItemL(MPbk2UiControlCmdItem* /*aCommand*/, TInt /*aIndex*/)
+ {
+ //Do nothing, since there shouldn't be any command items in this state.
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::DynInitMenuPaneL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::DynInitMenuPaneL(
+ TInt /*aResourceId*/,
+ CEikMenuPane* /*aMenuPane*/) const
+ {
+ // Nothing to do
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ProcessCommandL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::ProcessCommandL(
+ TInt /*aCommandId*/) const
+ {
+ // Nothing to do
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::UpdateAfterCommandExecution
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::UpdateAfterCommandExecution()
+ {
+ if( iCommand )
+ {
+ /// Reset command pointer, command has completed
+ iCommand->ResetUiControl(*this);
+ iCommand = NULL;
+ }
+ iListBox->DrawDeferred();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::GetMenuFilteringFlagsL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::GetMenuFilteringFlagsL() const
+ {
+ TInt ret = KPbk2MenuFilteringFlagsNone;
+
+ const TInt fieldCount = FieldCount();
+ User::LeaveIfError( fieldCount );
+ if ( fieldCount > KNoContacts )
+ {
+ ret |= KPbk2ListContainsItems;
+ }
+
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ControlStateL
+// --------------------------------------------------------------------------
+//
+CPbk2ViewState* CPbk2ContactInfoControl::ControlStateL() const
+ {
+ CPbk2ViewState* state = CPbk2ViewState::NewLC();
+ const MVPbkBaseContact* contact = FocusedContactL();
+
+ if ( contact )
+ {
+ MVPbkContactLink* link = contact->CreateLinkLC();
+ state->SetFocusedContact(link);
+ CleanupStack::Pop(); // link
+ link = NULL; // state has the ownership
+
+ if ( iListBox->Model()->NumberOfItems() > 0 )
+ {
+ state->SetFocusedFieldIndex( FocusedFieldIndex() );
+ const TInt topIndex = iListBox->TopItemIndex();
+ if ( topIndex >= 0 )
+ {
+ const MVPbkStoreContactField& topField =
+ iFields->FieldAt( topIndex );
+ state->SetTopFieldIndex( iContact->PresentationFields().
+ FindFieldIndex( topField ) );
+ }
+ }
+ }
+
+ CleanupStack::Pop(); // state
+ return state;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::RestoreControlStateL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::RestoreControlStateL(
+ CPbk2ViewState* aState )
+ {
+ const TInt numItems = iListBox->Model()->NumberOfItems();
+ const TInt currentItemIndex = iListBox->CurrentItemIndex();
+
+ TInt topFieldIndex( KErrNotFound );
+ if ( aState )
+ {
+ if ( iFocusedFieldIndex == KErrNotFound )
+ {
+ iFocusedFieldIndex = aState->FocusedFieldIndex();
+ topFieldIndex = aState->TopFieldIndex();
+ }
+ }
+
+ if ( iFocusedFieldIndex >= 0 &&
+ iFocusedFieldIndex < numItems )
+ {
+ iListBox->SetCurrentItemIndex(iFocusedFieldIndex);
+ if ( topFieldIndex >= 0 )
+ {
+ iListBox->SetTopItemIndex( topFieldIndex );
+ }
+ iListBox->UpdateScrollBarsL();
+ }
+ else
+ {
+ iListBox->Reset();
+
+ // Get the field type
+ TResourceReader resReader;
+ CCoeEnv::Static()->CreateResourceReaderLC
+ (resReader, R_PHONEBOOK2_SIP_MSISDN_SELECTOR );
+
+ CVPbkFieldTypeSelector* selector =
+ CVPbkFieldTypeSelector::NewL(resReader, iContactManager.FieldTypes());
+ CleanupStack::PopAndDestroy(); // resReader
+ CleanupStack::PushL( selector );
+
+ const TInt count( iFields->FieldCount() );
+ for ( TInt i( 0 ); i < count; ++i )
+ {
+ const MVPbkFieldType* field = iFields->At( i ).BestMatchingFieldType();
+ if ( selector->IsFieldTypeIncluded( *field ) )
+ {
+ iListBox->SetCurrentItemIndex( i );
+ iFocusedFieldIndex = i;
+ iListBox->UpdateScrollBarsL();
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy( selector );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FindTextL
+// --------------------------------------------------------------------------
+//
+const TDesC& CPbk2ContactInfoControl::FindTextL()
+ {
+ // No find box in this control
+ return KNullDesC;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ResetFindL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::ResetFindL()
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ShowThumbnail
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::ShowThumbnail()
+ {
+ if (iThumbnailLoader && IsFocused() )
+ {
+ iThumbnailLoader->LoadThumbnail
+ ( iStoreContact, iListBox, ELocationUpDown );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::HideThumbnail
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::HideThumbnail()
+ {
+ if (iThumbnailLoader)
+ {
+ iThumbnailLoader->HideThumbnail();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetBlank
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetBlank(TBool /*aBlank*/)
+ {
+ // This control does not support blanking
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::RegisterCommand
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::RegisterCommand(
+ MPbk2Command* aCommand)
+ {
+ iCommand = aCommand;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SetTextL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SetTextL( const TDesC& aText )
+ {
+ iListBox->View()->SetListEmptyTextL( aText );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ContactUiControlExtension
+// --------------------------------------------------------------------------
+//
+TAny* CPbk2ContactInfoControl::ContactUiControlExtension(TUid aExtensionUid )
+ {
+ if( aExtensionUid == KMPbk2ContactUiControlExtension2Uid )
+ {
+ return static_cast<MPbk2ContactUiControl2*>( this );
+ }
+
+ return NULL;
+ }
+
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::UpdateL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::UpdateL(
+ MVPbkStoreContact* aContact)
+ {
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateL);
+
+ // Update specific field properties first
+ delete iSpecificFieldProperties;
+ iSpecificFieldProperties = NULL;
+
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLCreateStoreSpecificFieldProps);
+ iSpecificFieldProperties = CPbk2StoreSpecificFieldPropertyArray::NewL(
+ iFieldProperties,
+ iStoreProperties,
+ iContactManager.FieldTypes(),
+ aContact->ParentStore());
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLCreateStoreSpecificFieldProps);
+
+ // Create an presentation contact from the store contact
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLCreatePresentationContact);
+ CPbk2PresentationContact* presentation =
+ CPbk2PresentationContact::NewL(*aContact, *iSpecificFieldProperties);
+ CleanupStack::PushL(presentation);
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLCreatePresentationContact);
+
+ // Create title pane picture
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLCreateTitlePanePicture);
+ CEikImage* image = Pbk2TitlePanePictureFactory::
+ CreateTitlePanePictureLC( aContact, iStoreProperties );
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLCreateTitlePanePicture);
+
+ // Instantiate a helper object
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLCreateSwapper);
+ CPbk2ContactInfoDataSwapper* swapper =
+ new(ELeave) CPbk2ContactInfoDataSwapper;
+ CleanupStack::PushL(swapper);
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLCreateSwapper);
+
+ // Store the members which are to be swapped
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLStorePanes);
+ StorePanesL(*swapper, presentation);
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLStorePanes);
+
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLCreateDynamicFieldProperties);
+ CPbk2ContactFieldDynamicProperties* filter =
+ CreateDynamicFieldPropertiesLC( *presentation );
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLCreateDynamicFieldProperties);
+
+ // Prepare listbox for state transitition
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLPrepareForUpdate);
+ iListBox->PrepareForUpdateL
+ ( *swapper, presentation->PresentationFields(),
+ *iSpecificFieldProperties, filter );
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLPrepareForUpdate);
+
+ CleanupStack::Pop(); // filter
+
+ // All code that might leave has been executed succesfully, change state
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLSetTitlePane);
+ if( iTitlePane )
+ {
+ // Set title pane text
+ if( swapper->iTitlePaneText )
+ {
+ iTitlePane->SetText(swapper->iTitlePaneText);
+ swapper->iTitlePaneText = NULL;
+ }
+ // Set title pane picture
+ // picture ownership is transfered to title pane
+ image->SetPictureOwnedExternally( ETrue );
+ iTitlePane->SetSmallPicture(
+ image->Bitmap(), image->Mask(), image->Bitmap() != NULL );
+ }
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLSetTitlePane);
+
+ // Update listbox
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLUpdateListbox);
+ TRAPD(err, iListBox->DoUpdateL(*swapper, *aContact));
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLUpdateListbox);
+
+ // Cleanup and change state
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLCleanupState);
+ CleanupStack::PopAndDestroy(swapper);
+ // bitmap and mask from image were transfered to title pane,
+ // so image can be destroyed now
+ CleanupStack::PopAndDestroy( image );
+ CleanupStack::Pop(presentation);
+ delete iContact;
+ iContact = presentation;
+ iFields = &presentation->PresentationFields();
+ User::LeaveIfError(err);
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLCleanupState);
+
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLSetIndex);
+ if ( iFocusedFieldIndex >= 0 &&
+ iFocusedFieldIndex < iListBox->Model()->NumberOfItems() )
+ {
+ iListBox->SetCurrentItemIndex(iFocusedFieldIndex);
+ }
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLSetIndex);
+
+ // Update navigators
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLUpdateNavigators);
+ if ( iNavigator )
+ {
+ MVPbkContactLink* contactLink = aContact->CreateLinkLC();
+ if ( contactLink )
+ {
+ iNavigator->UpdateNaviIndicatorsL(*contactLink);
+ }
+ CleanupStack::PopAndDestroy(); // contactLink
+ }
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLUpdateNavigators);
+
+ DrawDeferred();
+
+ // To avoid double deletion, the store contact ownership
+ // is transferred after everything that can leave has been
+ // executed
+ delete iStoreContact;
+ iStoreContact = aContact;
+
+ // Notify control readiness
+ PBK2_PROFILE_START(Pbk2Profile::EContactInfoControlUpdateLSendEvents);
+ TRAPD( error, SendEventToObserversL( TPbk2ControlEvent::EReady ) );
+ if ( error != KErrNone )
+ {
+ // When function leaves the aContact will be
+ // deleted through CleanupStack by calling function.
+ iStoreContact = NULL;
+ User::Leave( error );
+ }
+
+ SetFocus( ETrue );
+
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateLSendEvents);
+ PBK2_PROFILE_END(Pbk2Profile::EContactInfoControlUpdateL);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FieldCount
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::FieldCount() const
+ {
+ TInt ret = KErrNotReady;
+ if ( iFields )
+ {
+ ret = iFields->FieldCount();
+ }
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FieldPos
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::FieldPos(
+ const MVPbkStoreContactField& aField) const
+ {
+ // PreCond:
+ __ASSERT_DEBUG(iListBox && iFields, Panic(EPanicPreCond_FieldPos));
+
+ TInt ret = KErrNotFound;
+ const TInt count(iFields->FieldCount());
+ for (TInt i = 0; i < count; ++i)
+ {
+ if (iFields->At(i).IsSame(aField))
+ {
+ ret = i;
+ break;
+ }
+ }
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::VPbkSingleContactOperationComplete
+// --------------------------------------------------------------------------
+//
+
+void CPbk2ContactInfoControl::VPbkSingleContactOperationComplete(
+ MVPbkContactOperationBase& aOperation,
+ MVPbkStoreContact* aContact)
+ {
+ if (aContact && &aOperation == iRetriever)
+ {
+ // contact loading completed, update control data
+ TRAPD(err, UpdateL(aContact));
+ if (err != KErrNone)
+ {
+ delete aContact;
+ CCoeEnv::Static()->HandleError(err);
+ }
+
+ delete iRetriever;
+ iRetriever = NULL;
+ delete iContactLink;
+ iContactLink = NULL;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::VPbkSingleContactOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::VPbkSingleContactOperationFailed(
+ MVPbkContactOperationBase& /*aOperation*/,
+ TInt aError)
+ {
+ CCoeEnv::Static()->HandleError(aError);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusedItemPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactInfoControl::FocusedItemPointed()
+ {
+ return iListBox->FocusedItemPointed();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusableItemPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactInfoControl::FocusableItemPointed()
+ {
+ return iListBox->FocusableItemPointed();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SearchFieldPointed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactInfoControl::SearchFieldPointed()
+ {
+ return iListBox->SearchFieldPointed();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::OfferKeyEventL
+// --------------------------------------------------------------------------
+//
+TKeyResponse CPbk2ContactInfoControl::OfferKeyEventL(
+ const TKeyEvent& aKeyEvent,
+ TEventCode aType)
+ {
+ __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_OfferKeyEventL));
+
+ if ( aType == EEventKey )
+ {
+ // Reset iFocusedFieldIndex
+ // UpdateL method called after editor is closed and correct field
+ // is focused. Focus jump, if user same time than UpdateL method is
+ // called, scrolling fields. That's why this iFocusedFieldIndex
+ // reseting.
+ iFocusedFieldIndex = KErrNotFound;
+ }
+
+ // Forward all key events to the list box
+ TKeyResponse response = iListBox->OfferKeyEventL(aKeyEvent,aType);
+
+ // Ignore Send Key up and down events to prevent Dialer appearance
+ // on top of Phonebook application.
+ if ( response == EKeyWasNotConsumed && IsFocused() )
+ {
+ if ( ( aType == EEventKeyDown || aType == EEventKeyUp )
+ && aKeyEvent.iScanCode == EStdKeyYes )
+ {
+ response = EKeyWasConsumed;
+ }
+ }
+
+/*
+HandleControlEventL does this already...no need for double update...plus the HandleControlEventL works also for touch...
+ // Let the listbox first handle the key event before drawing the
+ // thumbnail.
+ if ( iThumbnailLoader && aType == EEventKey &&
+ (aKeyEvent.iScanCode == EStdKeyUpArrow ||
+ aKeyEvent.iScanCode == EStdKeyDownArrow ))
+ {
+ RDebug::Print( _L("### info view: OfferKeyEventL!") );
+ iThumbnailLoader->Refresh();
+ }
+*/
+ return response;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SizeChanged
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SizeChanged()
+ {
+ __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_SizeChanged));
+ // Listbox occupies whole area of this control
+ iListBox->SetRect(Rect());
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::CountComponentControls
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactInfoControl::CountComponentControls() const
+ {
+ __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_CountComponentControls));
+
+ // Always only one child control: the list box.
+ return KNumberOfControls;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::ComponentControl
+// --------------------------------------------------------------------------
+//
+CCoeControl* CPbk2ContactInfoControl::ComponentControl(
+ TInt PBK2_DEBUG_ONLY(aIndex)) const
+ {
+ __ASSERT_DEBUG(iListBox && aIndex==0,
+ Panic(EPanicPreCond_ComponentControl));
+
+ // Return the one and only child control
+ return iListBox;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::FocusChanged
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::FocusChanged(
+ TDrawNow aDrawNow )
+ {
+ if ( iListBox )
+ {
+ iListBox->SetFocus( IsFocused(), aDrawNow );
+ }
+
+ if ( IsFocused() )
+ {
+ ShowThumbnail();
+ }
+ else
+ {
+ HideThumbnail();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::HandleResourceChange
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::HandleResourceChange(
+ TInt aType)
+ {
+ CCoeControl::HandleResourceChange(aType);
+ TRAP_IGNORE(DoHandleResourceChangeL(aType));
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::HandlePointerEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::HandlePointerEventL(
+ const TPointerEvent& aPointerEvent )
+ {
+ CCoeControl::HandlePointerEventL( aPointerEvent );
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ switch( aPointerEvent.iType )
+ {
+ case TPointerEvent::EButton1Up:
+ {
+ if ( iListBox != NULL && iListBox->Rect().Contains(
+ aPointerEvent.iPosition ) )
+ {
+ iFocusedFieldIndex = iListBox->CurrentItemIndex();
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ };
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::HandleControlEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::HandleControlEventL(
+ CCoeControl* aControl,
+ TCoeEvent aEventType)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2ContactInfoControl::HandleControlEventL(0x%x,0x%x,%d)"),
+ this, aControl, aEventType);
+ if ( iThumbnailLoader && (aControl == iListBox) && IsFocused() )
+ {
+ iThumbnailLoader->Refresh();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::StorePanesL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2ContactInfoControl::StorePanesL(
+ CPbk2ContactInfoDataSwapper& aSwapper,
+ const CPbk2PresentationContact* aContact)
+ {
+ if( iFlags & KPbk2ContactInfoControlUpdateStatusPane )
+ {
+ if( (iFlags & KPbk2ContactInfoControlUpdateTitlePane) && iTitlePane )
+ {
+ // Store title pane text
+ if (aContact)
+ {
+ aSwapper.iTitlePaneText = iNameFormatter.GetContactTitleL(
+ aContact->Fields(), KDefaultTitleFormat);
+ }
+ }
+ if( iFlags & KPbk2ContactInfoControlUpdateContextPane )
+ {
+ if (aContact)
+ {
+ iThumbnailLoader->LoadThumbnail(&aContact->StoreContact(),
+ iListBox,
+ ELocationUpDown);
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::SendEventToObserversL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::SendEventToObserversL(
+ const TPbk2ControlEvent& aEvent)
+ {
+ // Loop backwards in case some observer destroys itself in the
+ // event handler
+ for (TInt i = iObservers.Count()-1; i >= 0; --i)
+ {
+ iObservers[i]->HandleControlEventL(*this, aEvent);
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::CreateDynamicFieldPropertiesLC
+// --------------------------------------------------------------------------
+//
+CPbk2ContactFieldDynamicProperties*
+ CPbk2ContactInfoControl::CreateDynamicFieldPropertiesLC(
+ CPbk2PresentationContact& aContact )
+ {
+ CPbk2ContactFieldDynamicProperties* filter =
+ CPbk2ContactFieldDynamicProperties::NewLC();
+ // Check is there ringtone field and if there is, check that file is still
+ // available. If not, hide the field.
+ TInt fieldCount( aContact.Fields().FieldCount() );
+ for ( TInt i = 0; i < fieldCount; ++i )
+ {
+ const MVPbkStoreContactField& field = aContact.Fields().FieldAt( i );
+ TInt resId( field.BestMatchingFieldType()->FieldTypeResId() );
+ if ( resId == R_VPBK_FIELD_TYPE_RINGTONE )
+ {
+ TPtrC filename =
+ MVPbkContactFieldTextData::Cast( field.FieldData() ).Text();
+ if ( !BaflUtils::FileExists(
+ CCoeEnv::Static()->FsSession(),
+ filename ) )
+ {
+ filter->AddHiddenFieldResourceId( resId );
+ aContact.PresentationFields().At( i ).
+ SetDynamicVisibility( EFalse );
+ break;
+ }
+ }
+ }
+
+ return filter;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::DoHandleResourceChangeL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::DoHandleResourceChangeL(
+ TInt aType)
+ {
+ if (iListBox)
+ {
+ iListBox->DoHandleResourceChangeL(aType);
+ }
+/* This is useless...no need to show or hide thumbnail on layout/skin change...thumbnail will handle it's own resouce change event
+ if ( aType == KEikDynamicLayoutVariantSwitch ||
+ aType == KAknsMessageSkinChange )
+ {
+ if ( IsFocused() )
+ {
+ RDebug::Print( _L("### InfoControl::HandleResourceChangeL - show") );
+ ShowThumbnail();
+ }
+ else
+ {
+ RDebug::Print( _L("### InfoControl::HandleResourceChangeL - hide") );
+ HideThumbnail();
+ }
+ }*/
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::RetrieveContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::RetrieveContactL(
+ const MVPbkContactLink& aContactLink )
+ {
+ delete iRetriever;
+ iRetriever = NULL;
+ iRetriever = iContactManager.RetrieveContactL( aContactLink, *this );
+ }
+
+// --------------------------------------------------------------------------
+//
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::HandleScrollEventL(CEikScrollBar* /*aScrollBar*/, TEikScrollEvent aEventType)
+ {
+
+
+ switch( aEventType )
+ {
+ // drag events -> hide thumbnail
+ // AL: this isn't very efficient way of doing this...
+ // ...thumbnail loader interface should be extended to
+ // enable thumbnail window to be hidden/shown without
+ // destroying and reloading the bitmaps...
+ case EEikScrollThumbDragHoriz:
+ case EEikScrollThumbDragVert:
+ {
+ iDidMove = ETrue;
+ HideThumbnail();
+ break;
+ }
+
+ // release events
+ case EEikScrollThumbReleaseHoriz:
+ case EEikScrollThumbReleaseVert:
+ {
+ // AL: this isn't very efficient way of doing this...
+ // ...thumbnail loader interface should be extended to
+ // enable thumbnail window to be hidden/shown without
+ // destroying and reloading the bitmaps...
+ if( iDidMove )
+ {
+ ShowThumbnail();
+ iDidMove = EFalse;
+ }
+ break;
+ }
+
+ default:
+ {
+ iDidMove= EFalse;
+ if( iThumbnailLoader )
+ {
+ iThumbnailLoader->Refresh();
+ }
+ }
+ }
+ }
+// --------------------------------------------------------------------------
+// CPbk2ContactInfoControl::HandleListBoxEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactInfoControl::HandleListBoxEventL(
+ CEikListBox* /*aListBox*/, TListBoxEvent aEventType )
+ {
+ switch ( aEventType )
+ {
+ case EEventItemDoubleClicked:
+ SendEventToObserversL( TPbk2ControlEvent::EContactDoubleTapped );
+ break;
+ case EEventItemSingleClicked:
+ SendEventToObserversL( TPbk2ControlEvent::EContactTapped );
+ break;
+ case EEventEnterKeyPressed:
+ SendEventToObserversL( TPbk2ControlEvent::EControlEnterKeyPressed );
+ break;
+ default:
+ ;
+ }
+ }
+
+
+// End of File