diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/Presentation/src/CPbk2ContactNameFormatterBase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/Presentation/src/CPbk2ContactNameFormatterBase.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,440 @@ +/* +* 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: A base class for contact name formatters +* +*/ + + + +// INCLUDE FILES +#include "CPbk2ContactNameFormatterBase.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "CPbk2SortOrderManager.h" + +#include "Pbk2PresentationUtils.h" +#include "Pbk2DataCaging.hrh" + +namespace { + +// CONSTANTS +_LIT(KSpace, " "); +const TText KReplaceChar = ' '; + +// ============================= LOCAL FUNCTIONS =============================== + +void TrimNameAppend( TUint32 aFormattingFlags, const TDesC& aName, + TDes& aTitle ) + { + if ( aFormattingFlags & MPbk2ContactNameFormatter::EPreserveLeadingSpaces ) + { + // In lists, the leading spaces are not formatted, + // only the end of the string is + Pbk2PresentationUtils::TrimRightAppend( aName, aTitle ); + } + else if (aFormattingFlags & MPbk2ContactNameFormatter::EPreserveAllOriginalSpaces) + { + //Preserve original string with all spaces + aTitle.Append(aName); + } + else + { + // String is trimmed from beginning and end + Pbk2PresentationUtils::TrimAllAppend( aName, aTitle ); + } + + if ( aFormattingFlags & + MPbk2ContactNameFormatter::EReplaceNonGraphicChars ) + { + // Non-graphical characters are replaced with space + Pbk2PresentationUtils::ReplaceNonGraphicCharacters( aTitle, + KReplaceChar ); + } + } + +#ifdef _DEBUG +namespace { + + enum TPanic + { + EPanic_PreCond_UnnamedText = 1 + }; + + void Panic( TPanic aPanicCode ) + { + _LIT( KPanicCat, "CPbk2ContactNameFormatterBase" ); + User::Panic( KPanicCat, aPanicCode ); + } +} +#endif // _DEBUG + +} // namespace + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::CPbk2ContactNameFormatterBase +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPbk2ContactNameFormatterBase::CPbk2ContactNameFormatterBase( + const MVPbkFieldTypeList& aMasterFieldTypeList, + const CPbk2SortOrderManager& aSortOrderManager ) + : iMasterFieldTypeList( aMasterFieldTypeList ), + iSortOrderManager( aSortOrderManager ) + { + iFieldMapper.SetSortOrder( iSortOrderManager.SortOrder() ); + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase:BaseConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CPbk2ContactNameFormatterBase::BaseConstructL( const TDesC& aUnnamedText, + CVPbkFieldTypeSelector* aTitleFieldSelector ) + { + iUnnamedText = aUnnamedText.AllocL(); + iTitleFieldSelector = aTitleFieldSelector; + } + +// Destructor +CPbk2ContactNameFormatterBase::~CPbk2ContactNameFormatterBase() + { + delete iUnnamedText; + delete iTitleFieldSelector; + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::GetContactTitleOrNullL +// ----------------------------------------------------------------------------- +// +HBufC* CPbk2ContactNameFormatterBase::GetContactTitleOrNullL( + const MVPbkBaseContactFieldCollection& aContactFields, + TUint32 aFormattingFlags) + { + HBufC* result = HBufC::NewL + (MaxTitleLength(aContactFields, aFormattingFlags)); + TPtr resultPtr = result->Des(); + GetContactTitle(aContactFields, resultPtr, aFormattingFlags); + + if (resultPtr.Length() == 0) + { + delete result; + result = NULL; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::GetContactTitleL +// ----------------------------------------------------------------------------- +// +HBufC* CPbk2ContactNameFormatterBase::GetContactTitleL( + const MVPbkBaseContactFieldCollection& aContactFields, + TUint32 aFormattingFlags ) + { + HBufC* result = GetContactTitleOrNullL(aContactFields, aFormattingFlags); + if (!result) + { + result = UnnamedText().AllocL(); + } + return result; + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::UnnamedText +// ----------------------------------------------------------------------------- +// +const TDesC& CPbk2ContactNameFormatterBase::UnnamedText() const + { + __ASSERT_DEBUG( iUnnamedText, Panic( EPanic_PreCond_UnnamedText ) ); + return *iUnnamedText; + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::IsTitleField +// ----------------------------------------------------------------------------- +// +TBool CPbk2ContactNameFormatterBase::IsTitleField( + const MVPbkBaseContactField& aContactField ) const + { + const TInt maxMatchPriority = iMasterFieldTypeList.MaxMatchPriority(); + for (TInt matchPriority = 0; matchPriority + <= maxMatchPriority; ++matchPriority) + { + const MVPbkFieldType* fieldType = + aContactField.MatchFieldType(matchPriority); + if (fieldType) + { + return IsTitleFieldType(*fieldType); + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::IsTitleFieldType +// ----------------------------------------------------------------------------- +// +TBool CPbk2ContactNameFormatterBase::IsTitleFieldType( + const MVPbkFieldType& aFieldType) const + { + return iTitleFieldSelector->IsFieldTypeIncluded( aFieldType ); + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::SetFieldMapper +// ----------------------------------------------------------------------------- +// +void CPbk2ContactNameFormatterBase::SetFieldMapper( + const MVPbkBaseContactFieldCollection& aContactFields ) + { + iFieldMapper.SetSortOrder( iSortOrderManager.SortOrder() ); + iFieldMapper.SetContactFields( aContactFields ); + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::RequiresSeparatorBetweenNames +// ----------------------------------------------------------------------------- +// +TBool CPbk2ContactNameFormatterBase::RequiresSeparatorBetweenNames + (const TDesC& aLhs, const TDesC& aRhs) const + { + return (aLhs.Length() > 0 && aRhs.Length() > 0); + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::DoGetContactTitle +// ----------------------------------------------------------------------------- +// +void CPbk2ContactNameFormatterBase::DoGetContactTitle + (TDes& aTitle, TUint32 aFormattingFlags, + const TInt aStartingPosition, const TInt aEndingPosition) + { + // Find the fields in the sort order that have + // data to build the title + const TInt fieldCount = iFieldMapper.FieldCount(); + for (TInt i = aStartingPosition; i <= aEndingPosition && + i < fieldCount; ++i) + { + TakePartOfName(iFieldMapper.FieldAt(i), + aTitle, aFormattingFlags, ETrue); + } + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::DoCalculateMaxTitleLength +// ----------------------------------------------------------------------------- +// +TInt CPbk2ContactNameFormatterBase::DoCalculateMaxTitleLength + (const TUint32 aFormattingFlags, const TInt aStartingPosition, + const TInt aEndingPosition) + { + TInt result = 0; + + // Use all the fields in sort order to + // build the title (ie. the company name) + const TInt fieldCount = iFieldMapper.FieldCount(); + for (TInt i = aStartingPosition; i <= aEndingPosition && + i < fieldCount; ++i) + { + CalculatePartOfName(iFieldMapper.FieldAt(i), + result, aFormattingFlags, ETrue); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::DoAppendNonEmptyTitleFieldTypesL +// ----------------------------------------------------------------------------- +// +void CPbk2ContactNameFormatterBase::DoAppendNonEmptyTitleFieldTypesL( + CVPbkFieldTypeRefsList& aFieldTypeList, + const TInt aStartingPosition, + const TInt aEndingPosition ) + { + // Find the fields in the sort order that have + // data to build the title + for ( TInt i = aStartingPosition; i <= aEndingPosition; ++i ) + { + const MVPbkBaseContactField* field = iFieldMapper.FieldAt(i); + if ( field && IsTitleField( *field ) && !field->FieldData().IsEmpty() ) + { + // get the field type + const TInt maxMatchPriority = iMasterFieldTypeList.MaxMatchPriority(); + for ( TInt matchPriority = 0; matchPriority + <= maxMatchPriority; ++matchPriority ) + { + const MVPbkFieldType* fieldType = + field->MatchFieldType(matchPriority); + // Do not add duplicates to aFieldTypeList + if( fieldType && + !aFieldTypeList.ContainsSame( *fieldType ) ) + { + aFieldTypeList.AppendL( *fieldType ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::AreTitleFieldsEmpty +// ----------------------------------------------------------------------------- +// +TBool CPbk2ContactNameFormatterBase::AreTitleFieldsEmpty( + const TInt aStartingPosition, + const TInt aEndingPosition ) const + { + TBool result = ETrue; + + // Find the fields in the sort order that have + // data to build the title + const TInt fieldCount = iFieldMapper.FieldCount(); + for (TInt i = aStartingPosition; i <= aEndingPosition && + i < fieldCount; ++i) + { + const MVPbkBaseContactField* field = iFieldMapper.FieldAt(i); + + if ( field && IsTitleField(*field)) + { + const MVPbkContactFieldData& fieldData = field->FieldData(); + if (fieldData.DataType() == EVPbkFieldStorageTypeText) + { + const TDesC& fieldText = + MVPbkContactFieldTextData::Cast(fieldData).Text(); + TInt length = fieldText.Length(); + + if (length > 0) + { + // Define the firstNonSpaceChar to calculate the first + // none space alph index in last name and first name, if the + // firstNonSpaceChar is equal to the fieldText length + // then there are only spaces in first name and last name. + TInt firstNonSpaceChar = 0; + while( firstNonSpaceChar < length + && TChar(fieldText[firstNonSpaceChar]).IsSpace() ) + { + ++firstNonSpaceChar; + } + if ( firstNonSpaceChar != length ) + { + result = EFalse; + break; + } + } + } + } + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::TakePartOfName +// Inlined for performance reasons +// ----------------------------------------------------------------------------- +// +inline void CPbk2ContactNameFormatterBase::TakePartOfName + (const MVPbkBaseContactField* aField, + TDes& aTitle, const TUint32 aFormattingFlags, + const TBool aUseSeparator) const + { + if (aField && IsTitleField(*aField)) + { + const MVPbkContactFieldData& fieldData = aField->FieldData(); + if (fieldData.DataType() == EVPbkFieldStorageTypeText) + { + const TDesC& fieldText = + MVPbkContactFieldTextData::Cast(fieldData).Text(); + + if (aUseSeparator && RequiresSeparatorBetweenNames + (aTitle, fieldText)) + { + const TDesC& separator = iSortOrderManager.CurrentSeparator(); + if (aFormattingFlags & + MPbk2ContactNameFormatter::EUseSeparator) + { + aTitle.Append(separator); + // If the separator is other than space, append a space to it + if (separator.Compare(KSpace) != 0) + { + aTitle.Append(KSpace); + } + } + else + { + // If separator is not used, add space then + aTitle.Append(KSpace); + } + + } + TrimNameAppend(aFormattingFlags, fieldText, aTitle); + } + } + } + +// ----------------------------------------------------------------------------- +// CPbk2ContactNameFormatterBase::CalculatePartOfName +// Inlined for performance reasons +// ----------------------------------------------------------------------------- +// +inline void CPbk2ContactNameFormatterBase::CalculatePartOfName + (const MVPbkBaseContactField* aField, + TInt& aLength, const TUint32 aFormattingFlags, + const TBool aUseSeparator) const + { + if (aField && IsTitleField(*aField)) + { + const MVPbkContactFieldData& fieldData = aField->FieldData(); + if (fieldData.DataType() == EVPbkFieldStorageTypeText) + { + const TDesC& fieldText = + MVPbkContactFieldTextData::Cast(fieldData).Text(); + + const TInt length = fieldText.Length(); + aLength += length; + + if (aUseSeparator && length > 0) + { + if (aFormattingFlags & + MPbk2ContactNameFormatter::EUseSeparator) + { + aLength += iSortOrderManager.CurrentSeparator().Length(); + } + // There is also a space after separator + aLength += KSpace().Length(); + } + } + } + } + +// End of File