diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook/View/src/CPbkContactInfoControl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook/View/src/CPbkContactInfoControl.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,923 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Provides methods for UI control of phonebook "Contact Info View". +* +*/ + + +// INCLUDE FILES +#include "CPbkContactInfoControl.h" // Class declarations + +#include // TResourceReader +#include // CAknTitlePane +#include // CAknDoubleGraphicStyleListBox +#include +#include +#include // KEikDynamicLayoutVariantSwitch +#include + +#include +#include // View resources +#include +#include "CPbkViewState.h" +#include "CPbkThumbnailPopup.h" +#include "CPbkFieldListBoxModel.h" +#include + +#include +#include + +// PbkEng.dll +#include +#include +#include + + +/// Unnamed namespace for local definitions +namespace { + +// LOCAL CONSTANTS AND MACROS +enum TPanicCode + { + EPanicPreCond_CurrentField = 1, + EPanicLogic_CurrentField, + EPanicPostCond_Constructor, + EPanicPreCond_ConstructFromResourceL, + EPanicPostCond_ConstructFromResourceL, + EPanicInvalidListBoxType, + EPanicPreCond_ContactItem, + EPanicPreCond_CurrentFieldIndex, + EPanicPostCond_CurrentFieldIndex, + EPanicPreCond_FieldPos, // 10 + EPanicPreCond_UpdateL, + EPanicPostCond_UpdateL, + EPanicPreCond_OfferKeyEventL, + EPanicPreCond_SizeChanged, + EPanicPreCond_CountComponentControls, + EPanicPreCond_ComponentControl, + EPanicPreCond_FieldCount, + EPanicPreCond_ListBox + }; + +void Panic(TInt aReason) + { + _LIT(KPanicText, "CPbkContactInfoControl"); + User::Panic(KPanicText, aReason); + } + +} // namespace + +// MODULE DATA STRUCTURES + +/** + * listbox item drawer for CPbkContactInfoControl. + */ +NONSHARABLE_CLASS(CPbkContactInfoControl::CItemDrawer) : + public CFormattedCellListBoxItemDrawer + { + public: // interface + /** + * Constructor. + */ + inline CItemDrawer(MTextListBoxModel* aTextListBoxModel, + const CFont* aFont, + CFormattedCellListBoxData* aFormattedCellData); + + /** + * Sets iFields to aFields. + */ + inline void SetFields(const CPbkFieldArray& aFields); + + private: // from CListItemDrawer + TListItemProperties Properties(TInt aItemIndex) const; + + private: // data members + /// Ref: array of fields. + const CPbkFieldArray* iFields; + }; + +/** + * Listbox for CPbkContactInfoControl + */ +NONSHARABLE_CLASS(CPbkContactInfoControl::CListBox) : + public CAknFormDoubleGraphicStyleListBox + { + public: // constructor + inline CListBox(); + inline CItemDrawer* ItemDrawer() const; + inline void SetIconArray(CPbkIconArray* aIconArray); + inline CPbkIconArray* IconArray(); + public: // from CEikFormattedCellListBox + void CreateItemDrawerL(); + + }; + +/** + * Data holding helper class for CPbkContactInfoControl::UpdateL(). + */ +NONSHARABLE_CLASS(CPbkContactInfoControl::CUpdateData) : + public CBase + { + public: // Interface + // Compiler-generated default constructor is ok for this class + ~CUpdateData(); + + /** + * Saves data into this object which restores aListBox's state (model, + * top and current item index) in this objects destructor. + */ + void StoreListBoxState(CEikTextListBox& aListBox); + + /** + * Resets any data set with StoreListBoxState(). + */ + inline void ResetListBoxState(); + + public: // Data + CPbkFieldArray* iFieldArray; + HBufC* iTitlePaneText; + CPbkThumbnailPopup* iThumbnailHandler; + MDesCArray* iListBoxModel; + + private: // Data + CEikTextListBox* iListBox; + MDesCArray* iItemTextArray; + TInt iRestoreTopItem; + TInt iRestoreCurrentItem; + }; + + +/** + * Helper class for UpdateL module test. + */ +NONSHARABLE_CLASS(CPbkContactInfoControl::CUpdateTestData) : + public CBase + { + public: // Interface + void ConstructL(CPbkContactInfoControl& aControl); + ~CUpdateTestData(); + TBool Compare(CPbkContactInfoControl& aControl) const; + + private: // Data + CPbkContactItem* iContactItem; + TInt iTopIndex; + TInt iCurrentIndex; + CAknTitlePane* iTitlePane; + HBufC* iTitlePaneText; + CPbkFieldArray* iFieldArray; + CPbkThumbnailPopup* iThumbnailHandler; + }; + +// ==================== LOCAL FUNCTIONS ==================== + +template +inline void Swap(Type& aObj1, Type& aObj2) + { + Type tmp = aObj1; + aObj1 = aObj2; + aObj2 = tmp; + } + + +// ================= MEMBER FUNCTIONS ======================= +inline +CPbkContactInfoControl::CItemDrawer::CItemDrawer + (MTextListBoxModel* aTextListBoxModel, + const CFont* aFont, + CFormattedCellListBoxData* aFormattedCellData) : + CFormattedCellListBoxItemDrawer( + aTextListBoxModel, + aFont, + aFormattedCellData) + { + } + +inline +void CPbkContactInfoControl::CItemDrawer::SetFields + (const CPbkFieldArray& aFields) + { + iFields = &aFields; + } + +TListItemProperties CPbkContactInfoControl::CItemDrawer::Properties + (TInt aItemIndex) const + { + TListItemProperties result = + CFormattedCellListBoxItemDrawer::Properties(aItemIndex); + + // TODO: aItemIndexCount() and aItemIndex>=0 restrictions below + // because class' internal data is corrupted, + // probably in CPbkContactInfoControl::UpdateL + if (iFields && aItemIndex>=0 && aItemIndexCount() && + (*iFields)[aItemIndex].DefaultPhoneNumberField()) + { + // default phonenumber field prompt is underlined + result.SetUnderlined(ETrue); + } + return result; + } + +inline +CPbkContactInfoControl::CListBox::CListBox() + { + } + +inline +CPbkContactInfoControl::CItemDrawer* CPbkContactInfoControl::CListBox::ItemDrawer + ( ) const + { + return static_cast(CAknDoubleGraphicStyleListBox::ItemDrawer()); + } + +inline +void CPbkContactInfoControl::CListBox::SetIconArray(CPbkIconArray* aIconArray) + { + ItemDrawer()->ColumnData()->SetIconArray(aIconArray); + } + +inline +CPbkIconArray* CPbkContactInfoControl::CListBox::IconArray() + { + return static_cast(ItemDrawer()->ColumnData()->IconArray()); + } + +void CPbkContactInfoControl::CListBox::CreateItemDrawerL() + { + CFormattedCellListBoxData* formattedData = CFormattedCellListBoxData::NewL(); + CleanupStack::PushL(formattedData); + iItemDrawer = new(ELeave) CPbkContactInfoControl::CItemDrawer(Model(), iEikonEnv->NormalFont(), formattedData); + CleanupStack::Pop(); + } + +CPbkContactInfoControl::CUpdateData::~CUpdateData() + { + if (iListBox) + { + iListBox->Model()->SetItemTextArray(iItemTextArray); + if (iRestoreTopItem >= 0) iListBox->SetTopItemIndex(iRestoreTopItem); + if (iRestoreCurrentItem >= 0) iListBox->SetCurrentItemIndex(iRestoreCurrentItem); + } + delete iThumbnailHandler; + delete iTitlePaneText; + delete iListBoxModel; + delete iFieldArray; + } + +void CPbkContactInfoControl::CUpdateData::StoreListBoxState + (CEikTextListBox& aListBox) + { + iListBox = &aListBox; + iItemTextArray = iListBox->Model()->ItemTextArray(); + iRestoreTopItem = iListBox->TopItemIndex(); + iRestoreCurrentItem = iListBox->CurrentItemIndex(); + } + +inline void CPbkContactInfoControl::CUpdateData::ResetListBoxState() + { + iListBox = NULL; + } + +EXPORT_C CPbkContactInfoControl* CPbkContactInfoControl::NewL + (TInt aResId, + const CCoeControl& aParent, + CPbkContactItem* aContact, + CPbkContactEngine* aEngine) + { + CPbkContactInfoControl* self = new(ELeave) CPbkContactInfoControl; + CleanupStack::PushL(self); + + self->iContactEngine = aEngine; + self->SetContainerWindowL(aParent); + + TResourceReader reader; + self->iCoeEnv->CreateResourceReaderLC(reader, aResId); + self->ConstructFromResourceL(reader); + CleanupStack::PopAndDestroy(); // reader + + self->UpdateL(aContact); + CleanupStack::Pop(); // self + return self; + } + +CPbkContactInfoControl::CPbkContactInfoControl() + { + iShowThumbnail = ETrue; + // new(ELeave) will reset member data + __ASSERT_DEBUG( + !iListBox && iFlags==0 && !iFields && !iContactItem && !iThumbnailHandler, + Panic(EPanicPostCond_Constructor)); + } + +void CPbkContactInfoControl::ConstructFromResourceL(TResourceReader& aReader) + { + __ASSERT_DEBUG( + !iListBox && !iListBoxModel && iFlags==0 && !iFields && !iContactItem && !iThumbnailHandler, + Panic(EPanicPreCond_ConstructFromResourceL)); + + TPtrC emptyText = aReader.ReadTPtrC(); + iFlags = aReader.ReadUint32(); + const TInt listBoxType = aReader.ReadInt16(); + // It is no more possible to specify the listbox type from resource file + __ASSERT_ALWAYS(listBoxType == EAknCtDoubleGraphicListBox, + Panic(EPanicInvalidListBoxType)); + + iListBox = new(ELeave) CListBox; + iListBox->SetContainerWindowL(*this); + iListBox->ConstructFromResourceL(aReader); + iListBox->View()->SetListEmptyTextL(emptyText); + + // Load list box icons + TInt iconArrayRes = aReader.ReadInt32(); + // Use granularity of 4 + CPbkIconArray* iconArray = new(ELeave) CPbkIconArray(4); + CleanupStack::PushL(iconArray); + iconArray->ConstructFromResourceL(iconArrayRes); + + // get extension factory for setting extension icons + CPbkExtGlobals* extGlobal = CPbkExtGlobals::InstanceL(); + extGlobal->PushL(); + MPbkExtensionFactory& factory = extGlobal->FactoryL(); + factory.AddPbkFieldIconsL(NULL, iconArray); + CleanupStack::PopAndDestroy(extGlobal); + + CleanupStack::Pop(); // iconArray + iListBox->SetIconArray(iconArray); + + iDefaultIconId = static_cast(aReader.ReadInt32()); + + // Set up the listbox + iListBox->CreateScrollBarFrameL(ETrue); + iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto); + // Take ownership of default listbox model + iListBoxModel = iListBox->Model()->ItemTextArray(); + iListBox->Model()->SetOwnershipType(ELbmDoesNotOwnItemArray); + + __ASSERT_DEBUG( + iListBox && iListBoxModel && !iFields && !iContactItem && !iThumbnailHandler, + Panic(EPanicPostCond_ConstructFromResourceL)); + } + +CPbkContactInfoControl::~CPbkContactInfoControl() + { + delete iMarkedItemsArray; + delete iThumbnailHandler; + delete iListBox; + delete iListBoxModel; + delete iFields; + } + +void CPbkContactInfoControl::UpdateL(CPbkContactItem* aContact) + { + // PreCond: + __ASSERT_DEBUG(aContact && iListBox, Panic(EPanicPreCond_UpdateL)); + + iVoiceTagField = NULL; + iVoiceTagFetchCompleted = EFalse; + + CUpdateData* updateData = new(ELeave) CUpdateData; + CleanupStack::PushL(updateData); + updateData->iFieldArray = new(ELeave) CPbkFieldArray(8); // granularity of 8 + + CheckRingToneFieldL( aContact ); + + const TInt fieldCount = aContact->CardFields().Count(); + for (TInt i = 0; i < fieldCount; ++i) + { + TPbkContactItemField& field = aContact->CardFields()[i]; + if (!field.IsHidden() && // Don't show hidden fields + !field.IsEmptyOrAllSpaces() && // Don't show empty fields + // Don't show name fields unless specfied by flags + ((iFlags & KPbkContactInfoControlShowNameFields) || !field.FieldInfo().NameField()) && + // Don't show image fields unless specfied by flags + ((iFlags & KPbkContactInfoControlShowImageFields) || !field.FieldInfo().IsImageField())) + { + updateData->iFieldArray->AppendL(field); + } + } + + CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane(); + CAknTitlePane* titlePane = NULL; + if (statusPane && (iFlags & KPbkContactInfoControlUpdateStatusPane)) + { + if ((iFlags & KPbkContactInfoControlUpdateTitlePane) && + statusPane->PaneCapabilities(TUid::Uid(EEikStatusPaneUidTitle)).IsPresent()) + { + titlePane = static_cast(statusPane->ControlL(TUid::Uid(EEikStatusPaneUidTitle))); + updateData->iTitlePaneText = aContact->GetContactTitleOrNullL(); + if (!updateData->iTitlePaneText) + { + updateData->iTitlePaneText = iCoeEnv->AllocReadResourceL(R_QTN_PHOB_UNNAMED); + } + } + if ( (iFlags & KPbkContactInfoControlUpdateContextPane) && iShowThumbnail ) + { + updateData->iThumbnailHandler = CPbkThumbnailPopup::NewL(*iContactEngine); + updateData->iThumbnailHandler->Load(*aContact, iListBox ); + } + } + + // Contact must be set before setting listbox + iContactItem = aContact; + + // Update list box + HBufC* timeFormat = iCoeEnv->AllocReadResourceLC(R_QTN_DATE_USUAL); + + CPbkFieldListBoxModel::TParams params( + *updateData->iFieldArray, + *timeFormat, + *iListBox->IconArray()); + params.iDefaultIconId = iDefaultIconId; + params.iFieldAnalyzer = this; + + CPbkFieldListBoxModel* listBoxModel = CPbkFieldListBoxModel::NewL(params); + CleanupStack::PopAndDestroy(); // timeFormat + listBoxModel->SetClipper(*this); + updateData->iListBoxModel = listBoxModel; + updateData->StoreListBoxState(*iListBox); + iListBox->Model()->SetItemTextArray(updateData->iListBoxModel); + iListBox->Reset(); + iListBox->UpdateScrollBarsL(); + + // All code that might leave has been executed succesfully + // -> Change state and redraw. + updateData->ResetListBoxState(); + Swap(iFields, updateData->iFieldArray); + Swap(iListBoxModel, updateData->iListBoxModel); + iListBox->ItemDrawer()->SetFields(*iFields); + iContactItem = aContact; + if (titlePane && updateData->iTitlePaneText) + { + titlePane->SetText(updateData->iTitlePaneText); + updateData->iTitlePaneText = NULL; + } + Swap(iThumbnailHandler, updateData->iThumbnailHandler); + + // Cleanup + CleanupStack::PopAndDestroy(); // updateData + + __ASSERT_DEBUG(iListBox && iContactItem && iFields && iListBoxModel, Panic(EPanicPostCond_UpdateL)); + __ASSERT_DEBUG(iContactItem->CardFields().Count() >= iFields->Count(), Panic(EPanicPostCond_UpdateL)); + __ASSERT_DEBUG(&static_cast(iListBoxModel)->Array() == iFields, Panic(EPanicPostCond_UpdateL)); + __ASSERT_DEBUG(iListBox->Model()->ItemTextArray() == iListBoxModel, Panic(EPanicPostCond_UpdateL)); + __ASSERT_DEBUG(iListBox->Model()->NumberOfItems() == iFields->Count(), Panic(EPanicPostCond_UpdateL)); + } + +CPbkContactItem& CPbkContactInfoControl::ContactItem() + { + __ASSERT_DEBUG(iContactItem, Panic(EPanicPreCond_ContactItem)); + return *iContactItem; + } + +TPbkContactItemField* CPbkContactInfoControl::CurrentField() const + { + // PreCond: + __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_CurrentField)); + + const TInt index = iListBox->CurrentItemIndex(); + // CPbkFieldArray will check index + if (index >= 0) + { + __ASSERT_DEBUG(index < iFields->Count(), Panic(EPanicLogic_CurrentField)); + return &(*iFields)[index]; + } + else + { + return NULL; + } + } + +EXPORT_C TInt CPbkContactInfoControl::CurrentFieldIndex + ( ) const + { + // PreCond: + __ASSERT_DEBUG(iFields, Panic(EPanicPreCond_CurrentFieldIndex)); + + const TPbkContactItemField* currentField = CurrentField(); + // Initialize the index to surely errornous value + TInt index = -1; + if (currentField) + { + // Search the field in the stored fields array + index = iContactItem->FindFieldIndex(*currentField); + // Field must be found + __ASSERT_DEBUG(index >= 0, Panic(EPanicPostCond_CurrentFieldIndex)); + } + return index; + } + +EXPORT_C TInt CPbkContactInfoControl::FieldPos(const TPbkContactItemField& aField) + { + // PreCond: + __ASSERT_DEBUG(iFields, Panic(EPanicPreCond_FieldPos)); + + for (TInt i = 0; i < iFields->Count(); ++i) + { + if ((*iFields)[i].IsSame(aField)) + { + // aField found + return i; + } + } + + // aField not found + return -1; + } + +EXPORT_C TInt CPbkContactInfoControl::FieldCount() const + { + // PreCond: + __ASSERT_DEBUG(iFields, Panic(EPanicPreCond_FieldCount)); + + return iFields->Count(); + } + +EXPORT_C CPbkViewState* CPbkContactInfoControl::GetStateL() const + { + CPbkViewState* state = GetStateLC(); + CleanupStack::Pop(); // state + return state; + } + +EXPORT_C CPbkViewState* CPbkContactInfoControl::GetStateLC() const + { + CPbkViewState* state = CPbkViewState::NewLC(); + state->SetFocusedContactId(iContactItem->Id()); + if (iListBox->Model()->NumberOfItems() > 0) + { + state->SetFocusedFieldIndex(CurrentFieldIndex()); + const TInt topIndex = iListBox->TopItemIndex(); + if (topIndex >= 0) + { + const TPbkContactItemField& topField = (*iFields)[topIndex]; + state->SetTopFieldIndex(iContactItem->FindFieldIndex(topField)); + } + } + return state; + } + +EXPORT_C void CPbkContactInfoControl::RestoreStateL(const CPbkViewState* aState) + { + const TInt numItems = iListBox->Model()->NumberOfItems(); + if (aState && numItems > 0) + { + TInt focusIndex = 0; + TInt topIndex = 0; + const TInt height = iListBox->View()->NumberOfItemsThatFitInRect(iListBox->View()->ViewRect()); + + // The index of field to-be-focused depends on whether the shown + // contact is the latest contact that has been shown in ContactInfo. + // For re-opened contacts the focus is same as before the ContactInfo + // was closed. For new contact the first POC field should be focused. + if (aState->FocusedFieldIndex() == -1) + { + // "New" contact. Set focus to first POC field + for (TInt i = 0; i < iFields->Count(); i++) + { + if ((*iFields)[i].FieldInfo().IsPocField()) + { + focusIndex = i; + break; + } + } + // Set top index so that focused field is bottom-most visible field + topIndex = Max(focusIndex - height + 1, 0); + } + else + { + // "Old" contact. Set focus to previously selected field + // Set top item + if (aState->TopFieldIndex() >= 0 && aState->TopFieldIndex() < iContactItem->CardFields().Count()) + { + topIndex = Max(FieldPos(iContactItem->CardFields()[aState->TopFieldIndex()]), 0); + } + + // Set listIndex so that maximum number of items are visible + if (topIndex + height > numItems) + { + topIndex += numItems - (height + topIndex); + if (topIndex < 0) topIndex = 0; + } + + // Set focus + if (aState->FocusedFieldIndex() >= 0) + { + if (aState->FocusedFieldIndex() < iContactItem->CardFields().Count()) + { + focusIndex = Max(FieldPos(iContactItem->CardFields()[aState->FocusedFieldIndex()]), 0); + } + else + { + focusIndex = iContactItem->CardFields().Count() - 1; + } + } + } + iListBox->SetTopItemIndex(topIndex); + + // TODO: focusIndex may be invalid e.g. after contact ringing tone + // removal/addition. + if (focusIndex<0) + { + focusIndex=0; + } + else if (focusIndex>=numItems ) + { + focusIndex=numItems-1; + } + iListBox->SetCurrentItemIndex(focusIndex); + } + else + { + iListBox->Reset(); + } + iListBox->UpdateScrollBarsL(); + } + +EXPORT_C CEikListBox& CPbkContactInfoControl::ListBox() + { + __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_ListBox)); + return *iListBox; + } + +void CPbkContactInfoControl::HideThumbnail() + { + iShowThumbnail = EFalse; + if (iThumbnailHandler) + { + iThumbnailHandler->CancelLoading(); + } + } + +void CPbkContactInfoControl::ShowThumbnailL() + { + iShowThumbnail = ETrue; + if (iFlags & KPbkContactInfoControlUpdateContextPane) + { + if (iContactItem) + { + if (!iThumbnailHandler) + { + iThumbnailHandler = CPbkThumbnailPopup::NewL(*iContactEngine); + } + iThumbnailHandler->Load(*iContactItem, iListBox); + } + } + } + +TKeyResponse CPbkContactInfoControl::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) + { + __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_OfferKeyEventL)); + + if ( iThumbnailHandler && + (aKeyEvent.iScanCode == EStdKeyUpArrow || aKeyEvent.iScanCode == EStdKeyDownArrow )) + { + iThumbnailHandler->Refresh(); + } + // Forward all key events to the list box + return iListBox->OfferKeyEventL(aKeyEvent,aType); + } + +TInt CPbkContactInfoControl::NumberOfItems() const + { + // This control displays only one item + return 1; + } + +TBool CPbkContactInfoControl::ItemsMarked() const + { + // No items can be marked in this control + return EFalse; + } + +const CContactIdArray& CPbkContactInfoControl::MarkedItemsL() const + { + if (!iMarkedItemsArray) + { + iMarkedItemsArray = CContactIdArray::NewL(); + } + + // Remove old contents of array + // (use Remove instead of Reset to keep the array buffer) + iMarkedItemsArray->Remove(0,iMarkedItemsArray->Count()); + iMarkedItemsArray->AddL(FocusedContactIdL()); + + return *iMarkedItemsArray; + } + +TContactItemId CPbkContactInfoControl::FocusedContactIdL() const + { + return iContactItem->Id(); + } + +const TPbkContactItemField* CPbkContactInfoControl::FocusedField() const + { + return CurrentField(); + } + +MObjectProvider* CPbkContactInfoControl::ObjectProvider() + { + return this; + } + +TInt CPbkContactInfoControl::FocusedFieldIndex() const + { + return CurrentFieldIndex(); + } + +TBool CPbkContactInfoControl::ClipFromBeginning(TDes& aBuffer, TInt aItemIndex, TInt aSubCellNumber) + { + return AknTextUtils::ClipToFit(aBuffer, AknTextUtils::EClipFromBeginning, + this->iListBox, aItemIndex, aSubCellNumber); + } + +TBool CPbkContactInfoControl::HasVoiceTagL(const TPbkContactItemField& aField) const + { + if (!iVoiceTagFetchCompleted) + { + iVoiceTagField = iContactItem->VoiceTagField(); + iVoiceTagFetchCompleted = ETrue; + } + if (iVoiceTagFetchCompleted && iVoiceTagField) + { + return (!iVoiceTagField->IsEmptyOrAllSpaces() && iVoiceTagField->IsSame(aField)); + } + else + { + return EFalse; + } + } + +TBool CPbkContactInfoControl::HasSpeedDialL(const TPbkContactItemField& aField) const + { + if (!iContactEngine) + { + return EFalse; + } + + const TInt fieldIndex = iContactItem->FindFieldIndex(aField); + + // If there is no such a field, KErrNotFound is returned as a + // field index. + if ( fieldIndex != KErrNotFound ) + { + return (iContactEngine->IsSpeedDialAssigned(*iContactItem, fieldIndex)); + } + else + { + return EFalse; + } + } + +void CPbkContactInfoControl::SizeChanged() + { + __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_SizeChanged)); + // Listbox occupies whole area of this control + iListBox->SetRect(Rect()); + } + +TInt CPbkContactInfoControl::CountComponentControls() const + { + __ASSERT_DEBUG(iListBox, Panic(EPanicPreCond_CountComponentControls)); + // Always only one child control: the list box. + return 1; + } + +CCoeControl* CPbkContactInfoControl::ComponentControl(TInt PBK_DEBUG_ONLY(aIndex)) const + { + __ASSERT_DEBUG(iListBox && aIndex==0, Panic(EPanicPreCond_ComponentControl)); + // Return the one and only child control + return iListBox; + } + +void CPbkContactInfoControl::HandleResourceChange(TInt aType) + { + CPbkContactDetailsBaseControl::HandleResourceChange(aType); + TRAP_IGNORE(DoHandleResourceChangeL(aType)); + } + +void CPbkContactInfoControl::DoHandleResourceChangeL(TInt aType) + { + if (aType == KAknsMessageSkinChange || aType == KEikDynamicLayoutVariantSwitch) + { + CPbkIconArray* iconArray = iListBox->IconArray(); + if (iconArray) + { + iconArray->RefreshL(R_PBK_ICON_INFO_ARRAY); + } + const TBool isNonFocusing( IsNonFocusing() ); + if ( iContactItem ) + { + if ( !isNonFocusing ) + { + if (IsFocused()) + { + iThumbnailHandler->Load(*iContactItem, iListBox); + } + } + } + if (aType == KEikDynamicLayoutVariantSwitch) + { + SizeChanged(); + if ( !isNonFocusing ) + { + if (IsFocused()) + { + // cause also refreshing of thumbnail + ShowThumbnailL(); + } + } + } + } + } + + +void CPbkContactInfoControl::FocusChanged( TDrawNow aDrawNow ) + { + CCoeControl::FocusChanged( aDrawNow ); + const TBool focused( IsFocused() ); + + if (focused) + { + // No big deal if thumbnail is not shown + TRAP_IGNORE( ShowThumbnailL() ); + } + else + { + HideThumbnail(); + } + + if( iListBox ) + { + iListBox->SetFocus( IsFocused(), aDrawNow ); + } + } + +void CPbkContactInfoControl::CheckRingToneFieldL( CPbkContactItem* aContact ) + { + // Check is there ringtone field and if there is, check that file is still + // available. If not, hide the field. + TPbkContactItemField* ringtoneField = + aContact->FindField( EPbkFieldIdPersonalRingingToneIndication ); + if ( ringtoneField ) + { + if ( ringtoneField->StorageType()==KStorageTypeText ) + { + if ( !BaflUtils::FileExists( + iContactEngine->FsSession(), + ringtoneField->Text()) ) + { + ringtoneField->SetHidden( ETrue ); + } + } + } + } + +// CPbkContactInfoControl::CUpdateTestData implementation +#ifdef __TEST_UpdateL__ +void CPbkContactInfoControl::CUpdateTestData::ConstructL(CPbkContactInfoControl& aControl) + { + iContactItem = aControl.iContactItem; + iTopIndex = aControl.iListBox->TopItemIndex(); + iCurrentIndex = aControl.iListBox->CurrentItemIndex(); + + CEikStatusPane* statusPane = static_cast(aControl.iCoeEnv)->AppUiFactory()->StatusPane(); + if (statusPane && statusPane->PaneCapabilities(TUid::Uid(EEikStatusPaneUidTitle)).IsPresent()) + { + iTitlePane = static_cast(statusPane->ControlL(TUid::Uid(EEikStatusPaneUidTitle))); + iTitlePaneText = iTitlePane->Text()->AllocL(); + } + + iFieldArray = aControl.iFields; + iThumbnailHandler = aControl.iThumbnailHandler; + } + +CPbkContactInfoControl::CUpdateTestData::~CUpdateTestData() + { + delete iTitlePaneText; + } + +TBool CPbkContactInfoControl::CUpdateTestData::Compare(CPbkContactInfoControl& aControl) const + { + return + iContactItem == aControl.iContactItem && + (iTopIndex < 0 || iTopIndex == aControl.iListBox->TopItemIndex()) && + (iCurrentIndex < 0 || iCurrentIndex == aControl.iListBox->CurrentItemIndex()) && + iTitlePaneText->Compare(*iTitlePane->Text())==0 && + iFieldArray == aControl.iFields && + (!iFieldArray || iFieldArray == &static_cast(aControl.iListBoxModel)->Array()) && + iThumbnailHandler == aControl.iThumbnailHandler; + } +#endif + +// End of File