phonebookui/Phonebook2/UIControls/src/CPbk2ContactViewListBoxModel.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
--- /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 <MPbk2ContactNameFormatter.h>
+#include <MPbk2ContactNameFormatter2.h>
+#include <CPbk2StoreProperty.h>
+#include <CPbk2StoreViewDefinition.h>
+#include <CPbk2StorePropertyArray.h>
+#include <MPbk2ContactUiControlExtension.h>
+#include <MPbk2ContactUiControlExtension2.h>
+#include <Pbk2UIControls.rsg>
+#include <Pbk2PresentationUtils.h>
+#include <CPbk2ContactIconsUtils.h>
+#include "Pbk2NamesListExUID.h"
+#include "cpbk2predictiveviewstack.h"
+
+// Virtual Phonebook
+#include <MVPbkContactViewBase.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkViewContact.h>
+#include <CVPbkContactViewDefinition.h>
+#include <CVPbkContactManager.h>
+#include <MVPbkFieldType.h>
+#include <MVPbkBaseContactField.h>
+#include <CVPbkFieldTypeSelector.h>
+#include <MVPbkBaseContactFieldCollection.h>
+#include <MVPbkContactFieldData.h>
+
+// System includes
+#include <eikenv.h>
+#include <barsread.h>
+#include <featmgr.h>
+
+// Debugging headers
+#include <Pbk2Debug.h>
+
+//from PCS engine
+#include <CPsRequestHandler.h>
+#include <CPsQuery.h>
+
+/// 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
+            <MPbk2ContactUiControlExtension2*>( aUiExtension->
+                ContactUiControlExtensionExtension(
+                    KMPbk2ContactUiControlExtensionExtension2Uid ) );
+        if ( ext != NULL )
+            {
+            CPbk2IconArray* extIconArray = const_cast<CPbk2IconArray*>(
+                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<TPbk2IconId> 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<MPbk2ContactNameFormatter2*>(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<TPbk2IconId>& 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
+                <const CPbk2PredictiveViewStack*>( iView );
+           
+    if ( view )
+        {
+        return view->LastPCSQuery();
+        }
+    
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2ContactViewListBoxModel::GetMatchingPartsL
+// ---------------------------------------------------------------------------
+void CPbk2ContactViewListBoxModel::GetMatchingPartsL( const TDesC& aSearchData,
+                      RArray<TPsMatchLocation>& aMatchLocation)
+    {
+    const CPbk2PredictiveViewStack* view = static_cast
+                    <const CPbk2PredictiveViewStack*>( iView );
+               
+    if ( view )
+        {
+        view->GetMatchingPartsL(aSearchData, aMatchLocation);
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+// CPbk2ContactViewListBoxModel::PSHandler
+// ---------------------------------------------------------------------------
+CPSRequestHandler* CPbk2ContactViewListBoxModel::PSHandler() const
+    {    
+    const CPbk2PredictiveViewStack* view = static_cast
+                    <const CPbk2PredictiveViewStack*>( iView );
+           
+    if ( view )
+        {
+        return view->PSHandler();
+        }
+    
+    return NULL;
+    }
+
+//  End of File