diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/UIControls/src/CPbk2ContactViewListBoxModel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/UIControls/src/CPbk2ContactViewListBoxModel.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,597 @@ +/* +* 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 view list box model. +* +*/ + + +// INCLUDE FILES + +#include "CPbk2ContactViewListBoxModel.h" + +// Phonebook 2 +#include "CPbk2IconArray.h" +#include "MPbk2ClipListBoxText.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Pbk2NamesListExUID.h" +#include "cpbk2predictiveviewstack.h" + +// Virtual Phonebook +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include + +// Debugging headers +#include + +//from PCS engine +#include +#include + +/// Unnamed namespace for local definitions +namespace { + +// LOCAL CONSTANTS AND MACROS +const TText KSeparator = '\t'; +const TText KSpace = ' '; +const TInt KNameColumn = 1; + +const TInt KDefaultListFormatting = + MPbk2ContactNameFormatter::EUseSeparator | + MPbk2ContactNameFormatter::EPreserveLeadingSpaces; + +#ifdef _DEBUG +enum TPanicCode + { + EPanicPostCond_AppendIconIndex = 1, + EPanicPreCond_EmptyIconArray + }; + +void Panic(TPanicCode aReason) + { + _LIT(KPanicText, "CPbk2ContactViewListBoxModel"); + User::Panic(KPanicText, aReason); + } +#endif // _DEBUG + +/** + * Matches field type. + * + * @param aFieldTypeList The field type list to use. + * @param aField The field whose type to match. + * @return Matched field type. + */ +const MVPbkFieldType* MatchFieldType + ( const MVPbkFieldTypeList& aFieldTypeList, + const MVPbkBaseContactField& aField ) + { + const MVPbkFieldType* result = NULL; + + for (TInt matchPriority = 0; + matchPriority <= aFieldTypeList.MaxMatchPriority() && !result; + ++matchPriority) + { + result = aField.MatchFieldType(matchPriority); + } + + return result; + } + +/** + * Checks is the given field type included in + * the given selection. + * + * @param aResourceId Selector's resource id. + * @param aField The field whose type to check. + * @param aManager Contact manager. + * @return ETrue if field type is included. + */ +TBool IsFieldTypeIncludedL( + const MVPbkBaseContactField& aField, + const CVPbkContactManager& aManager, + const TInt aResourceId ) + { + // Get the field type + const MVPbkFieldType* fieldType = MatchFieldType + (aManager.FieldTypes(), aField); + + TResourceReader resReader; + CCoeEnv::Static()->CreateResourceReaderLC + (resReader, aResourceId); + + CVPbkFieldTypeSelector* selector = + CVPbkFieldTypeSelector::NewL(resReader, aManager.FieldTypes()); + CleanupStack::PopAndDestroy(); // resReader + + TBool ret = selector->IsFieldTypeIncluded(*fieldType); + delete selector; + return ret; + } + +} /// namespace + + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::CPbk2ContactViewListBoxModel +// -------------------------------------------------------------------------- +// +CPbk2ContactViewListBoxModel::CPbk2ContactViewListBoxModel + ( CPbk2ContactViewListBoxModel::TParams& aParams ) : + iContactManager( *aParams.iContactManager ), + iView( aParams.iView ), + iNameFormatter( *aParams.iNameFormatter ), + iBuffer( iFormattingBuffer ), + iIconArray( aParams.iIconArray ), + iEmptyIconId( aParams.iEmptyId ), + iDefaultIconId( aParams.iDefaultId ), + iPreviousCount( 0 ), + iClipListBoxText( aParams.iClipListBoxText ), + iIconsStartAtZero( !aParams.iMultiselection ), + iIconsOnlyOne( ETrue ) + { + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::~CPbk2ContactViewListBoxModel +// -------------------------------------------------------------------------- +// +CPbk2ContactViewListBoxModel::~CPbk2ContactViewListBoxModel() + { + delete iContactIcons; + if(iFeatureManagerInitilized) + { + FeatureManager::UnInitializeLib(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::NewL +// -------------------------------------------------------------------------- +// +CPbk2ContactViewListBoxModel* CPbk2ContactViewListBoxModel::NewL + ( CPbk2ContactViewListBoxModel::TParams& aParams ) + { + CPbk2ContactViewListBoxModel* self = + new ( ELeave ) CPbk2ContactViewListBoxModel( aParams ); + + CleanupStack::PushL(self); + self->ConstructL( aParams.iStoreProperties, aParams.iUiExtension ); + CleanupStack::Pop(); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::ConstructL +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::ConstructL( + CPbk2StorePropertyArray* aStoreProperties, + MPbk2ContactUiControlExtension* aUiExtension) + { + if ( aUiExtension ) + { + MPbk2ContactUiControlExtension2* ext = reinterpret_cast + ( aUiExtension-> + ContactUiControlExtensionExtension( + KMPbk2ContactUiControlExtensionExtension2Uid ) ); + if ( ext != NULL ) + { + CPbk2IconArray* extIconArray = const_cast( + iIconArray ); + ext->SetIconArray( *extIconArray ); + } + } + iContactIcons = CPbk2ContactIconsUtils::NewL( + *aStoreProperties, + aUiExtension ); + // Initialize feature manager + FeatureManager::InitializeLibL(); + iFeatureManagerInitilized = ETrue; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::MdcaCount +// -------------------------------------------------------------------------- +// +TInt CPbk2ContactViewListBoxModel::MdcaCount() const + { + TInt result = iPreviousCount; + TRAPD(err, result = iView->ContactCountL()); + if (err != KErrNone) + { + HandleError(err); + } + iPreviousCount = result; + return result; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::MdcaPoint +// -------------------------------------------------------------------------- +// +TPtrC CPbk2ContactViewListBoxModel::MdcaPoint( TInt aIndex ) const + { + TRAPD(err, FormatBufferL(aIndex)); + switch (err) + { + case KErrNone: + { + // OK + break; + } + + case KErrNotFound: // FALLTHROUGH + case KErrAccessDenied: + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::MdcaPoint(0x%x,%d), ignoring error %d"), + this, aIndex, err); + // Do not report these errors as they occur sometimes when + // the view is under a massive update + FormatEmptyBuffer(); + break; + } + + default: + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( + "CPbk2ContactViewListBoxModel::MdcaPoint(0x%x,%d), reporting error %d"), + this, aIndex, err); + FormatEmptyBuffer(); + // Report error + HandleError(err); + break; + } + } + return iBuffer; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::SetUnnamedText +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::SetUnnamedText( const TDesC* aText ) + { + iUnnamedText = aText; + } + +HBufC* CPbk2ContactViewListBoxModel::GetContactTitleLC( TInt aIndex ) const + { + const MVPbkViewContact& contact = iView->ContactAtL(aIndex); + HBufC* contactName = iNameFormatter.GetContactTitleL( contact.Fields(), KDefaultListFormatting ); + CleanupStack::PushL( contactName ); + return contactName; + } +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::FormatBufferL +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::FormatBufferL( const TInt aIndex ) const + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::FormatBufferL(0x%x,%d), begin"), + this); + const MVPbkViewContact& contact = iView->ContactAtL(aIndex); + FormatBufferForContactL(contact, aIndex ); + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::FormatBufferL(0x%x,%d), end"), + this); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::FormatEmptyBuffer +// Formats an empty listbox model text in case of an error. +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::FormatEmptyBuffer() const + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::FormatEmptyBuffer(0x%x), begin"), + this); + + TInt iconIndex = iIconArray->FindIcon(iEmptyIconId); + if (iconIndex < 0) + { + iconIndex = iIconArray->FindIcon(iDefaultIconId); + } + iBuffer.Num(iconIndex); + iBuffer.Append(KSeparator); + + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( + "CPbk2ContactViewListBoxModel::FormatEmptyBuffer(0x%x) formatted: %S"), + this, &iBuffer); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::FormatBufferForContactL +// Formats buffer to contain list box model text for a contact. +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::FormatBufferForContactL + ( const MVPbkViewContact& aViewContact, TInt aIndex ) const + { + RArray ids; + CleanupClosePushL( ids ); + // Format only name using aViewContact + iBuffer.Zero(); + + iContactIcons->GetIconIdsForContactL( aViewContact, ids ); + // ids shold contain at least one empty icon in any case + if ( ids.Count() == 0 ) + { + ids.Append( iEmptyIconId ); + } + + // Use temporary variables to avoid warnings in winscw build + const TInt KFirstIndex ( 0 ); + // If there are icons from extensions use them + if ( iIconsStartAtZero ) + { + // In array 1st icon is preceding icon and rest of + // the icons are added after the name as trailing icons + AppendIconIndex( ids[ KFirstIndex ] ); + } + else + { + //append default icon anyway, otherwise checkbox will not work + AppendIconIndex( iDefaultIconId ); + } + HBufC* name; + if( FeatureManager::FeatureSupported(KFeatureIdFfContactsCompanyNames)) + { + MPbk2ContactNameFormatter2* nameformatterExtension = + reinterpret_cast(iNameFormatter. + ContactNameFormatterExtension( MPbk2ContactNameFormatterExtension2Uid ) ); + name = nameformatterExtension->GetContactTitleWithCompanyNameL(aViewContact.Fields(), + KDefaultListFormatting); + } + else + { + // Append name + name = iNameFormatter.GetContactTitleL(aViewContact.Fields(), + KDefaultListFormatting); + } + + TPtr ptrName( name->Des() ); + + // Replace characters that can not be displayed correctly + Pbk2PresentationUtils::ReplaceNonGraphicCharacters + ( ptrName, KSpace ); + + if ( CutFromBeginningFieldL( aViewContact.Fields() ) && + iClipListBoxText ) + { + iClipListBoxText->ClipFromBeginning( + ptrName, aIndex, KNameColumn ); + } + AppendName( ptrName ); + delete name; + + if ( !iIconsStartAtZero ) + { + if ( iIconsOnlyOne ) + { + AppendTrailingIcon( ids[KFirstIndex] ); + } + else + { + AppendTrailingIcons( ids.Array(), KFirstIndex ); + } + } + else if ( !iIconsOnlyOne ) + { + AppendTrailingIcons( ids.Array(), KFirstIndex + 1 ); + } + + CleanupStack::PopAndDestroy(); //ids + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::AppendName +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::AppendName( const TDesC& aName ) const + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::AppendName(0x%x), begin"), + this); + + TPtrC text(aName); + if (text.Length()==0 && iUnnamedText) + { + text.Set(*iUnnamedText); + } + iBuffer.Append(text); + + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::AppendName(0x%x), end"), + this); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::AppendIconIndex +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::AppendIconIndex( + const TPbk2IconId& aIconId ) const + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::AppendIconIndex(0x%x), begin"), + this); + + TInt iconIndex = iIconArray->FindIcon( aIconId ); + if (iconIndex < 0) + { + iconIndex = iIconArray->FindIcon( iDefaultIconId ); + } + if (iconIndex < 0) + { + iconIndex = iIconArray->FindIcon( iEmptyIconId ); + } + + iBuffer.AppendNum( iconIndex ); + iBuffer.Append( KSeparator ); + + __ASSERT_DEBUG(iconIndex > KErrNotFound, + Panic(EPanicPostCond_AppendIconIndex)); + + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::AppendIconIndex(0x%x), end"), + this); + } + +void CPbk2ContactViewListBoxModel::AppendTrailingIcon( + const TPbk2IconId& aIconId ) const + { + TInt iconIndex = iIconArray->FindIcon( aIconId ); + if ( iconIndex >= 0 ) + { + iBuffer.Append( KSeparator ); + iBuffer.AppendNum( iconIndex ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::AppendTrailingIcons +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::AppendTrailingIcons + ( const TArray& aIds, TInt aStartIndex ) const + { + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::AppendTrailingIcons(0x%x), begin"), + this); + + const TInt count( aIds.Count() ); + // Start reading icon ids from index 1 + // In array 1st icon is preceding icon and rest of icons are added after + // the name as trailing icons. + for ( TInt i = aStartIndex; i < count; ++i ) + { + AppendTrailingIcon( aIds[i] ); + } + + PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING + ("CPbk2ContactViewListBoxModel::AppendTrailingIcons(0x%x), end"), + this); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::HandleError +// Handles any leave occuring in MdcaCount() or MdcaPoint(). +// @see CEikonEnv::NotifyIdleErrorWhileRedrawing( aError) +// -------------------------------------------------------------------------- +// +void CPbk2ContactViewListBoxModel::HandleError( TInt aError ) const + { + CEikonEnv::Static()->NotifyIdleErrorWhileRedrawing( aError ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::CutFromBeginningFieldL +// -------------------------------------------------------------------------- +// +TBool CPbk2ContactViewListBoxModel::CutFromBeginningFieldL + ( const MVPbkBaseContactFieldCollection& aContactFields ) const + { + TBool ret( ETrue ); + TInt fieldCount( aContactFields.FieldCount() ); + for ( TInt i(0); i < fieldCount && ret; ++i) + { + const MVPbkBaseContactField& field = aContactFields.FieldAt( i ); + if ( !field.FieldData().IsEmpty() ) + { + // Check are we dealing with a phone number field + if ( !IsFieldTypeIncludedL( field, iContactManager, + R_PHONEBOOK2_PHONENUMBER_SELECTOR)) + { + // If fields contains something else than number selection fields + ret = EFalse; + } + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::LastPCSQuery +// --------------------------------------------------------------------------- +const CPsQuery* CPbk2ContactViewListBoxModel::LastPCSQuery() const + { + + const CPbk2PredictiveViewStack* view = static_cast + ( iView ); + + if ( view ) + { + return view->LastPCSQuery(); + } + + return NULL; + } + +// --------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::GetMatchingPartsL +// --------------------------------------------------------------------------- +void CPbk2ContactViewListBoxModel::GetMatchingPartsL( const TDesC& aSearchData, + RArray& aMatchLocation) + { + const CPbk2PredictiveViewStack* view = static_cast + ( iView ); + + if ( view ) + { + view->GetMatchingPartsL(aSearchData, aMatchLocation); + } + } + +// --------------------------------------------------------------------------- +// CPbk2ContactViewListBoxModel::PSHandler +// --------------------------------------------------------------------------- +CPSRequestHandler* CPbk2ContactViewListBoxModel::PSHandler() const + { + const CPbk2PredictiveViewStack* view = static_cast + ( iView ); + + if ( view ) + { + return view->PSHandler(); + } + + return NULL; + } + +// End of File