--- /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 <f32file.h>
+#include <barsread.h>
+#include <barsc.h>
+#include <coemain.h>
+
+#include <MVPbkFieldType.h>
+#include <MVPbkBaseContactFieldCollection.h>
+#include <MVPbkBaseContactField.h>
+#include <MVPbkContactFieldData.h>
+#include <MVPbkContactFieldTextData.h>
+#include <CVPbkFieldTypeSelector.h>
+#include <CVPbkFieldTypeRefsList.h>
+
+#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