clfwrapper/ClientSrc/CCLFItemListModelImpl.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 20:34:07 +0200
changeset 0 c53acadfccc6
child 1 acef663c1218
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* Copyright (c) 2002-2009 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: 
*
*/


// INCLUDE FILES
#include    "CCLFItemListModelImpl.h"
#include    "CCLFDbItemProvider.h"
#include    "CCLFDefaultOperation.h"
#include    <MCLFOperationObserver.h>
#include    <MCLFItem.h>
#include    <MCLFSortingStyle.h>
#include    "MGTracePrint.h"
#include    <ContentListingFactory.h>
#include    <barsread.h>
#include    <collate.h>
#include    "MGDebugPrint.h"

// CONSTANTS
const TInt KCLFResourceVersionNumber( 1 );
const TInt KCLFEmptyArrayGranularity( 1 );
const TInt KCLFSortingStyleArrayGranularity( 3 );
const TInt KCLFResourceVersion1( 1 );
const TInt KCLFResourceVersion2( 2 );

_LIT( KCLFAllMimeTypeMatchString, "*" );

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::CCLFItemListModelImpl
// -----------------------------------------------------------------------------
//
CCLFItemListModelImpl::CCLFItemListModelImpl(
                                        CCLFDbItemProvider* aItemProvider,
                                        MCLFOperationObserver& aObserver,
                                        MCLFChangedItemProvider& aChangedItemProvider )
    : iMimeTypeArray( NULL ),
      iMediaTypeArray( NULL ),
      iGrouper( NULL ),
      iSorter( NULL ),
      iPostFilter( NULL ),
      iItemProvider( aItemProvider ),
      iOperationObserver( aObserver ),
      iSortingStyleArray( KCLFSortingStyleArrayGranularity ),
      iChangedItemProvider( aChangedItemProvider ),
      iIsItemsFetched( EFalse )
    {
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::ConstructL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::ConstructL()
    {
    iMediaTypeArray = new ( ELeave ) CArrayFixFlat< TInt >( KCLFEmptyArrayGranularity );
    iMimeTypeArray = new ( ELeave ) CDesCArrayFlat( KCLFEmptyArrayGranularity );
    iDefaultOperation = CCLFDefaultOperation::NewL();
    iSorter = iDefaultOperation;
    iGrouper = iDefaultOperation;
    iPostFilter = iDefaultOperation;
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::ConstructL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::ConstructL( TResourceReader& aResource )
   {
    ConstructL();
    const TInt version( aResource.ReadInt16() );

    // resource versions are defined in Content Listing framework .rh file
    if( version != KCLFResourceVersion1 &&
        version != KCLFResourceVersion2 )
        {
        User::Leave( KErrNotSupported );
        }
    SetGroupingStyle( TCLFGrouping( aResource.ReadInt32() ) );
    SetWantedMimeTypesL( aResource );
    SetWantedMediaTypesL( aResource );


    const TInt count(
        version == KCLFResourceVersion2 ? aResource.ReadInt16() - 1 : 0 );

    MCLFSortingStyle* sortingStyle =
                        ContentListingFactory::NewSortingStyleLC( aResource );
    iSortingStyleArray.AppendL( sortingStyle ); // takes ownership
    CleanupStack::Pop(); // sortingStyle
    iDefaultOperation->SetSortingStyle( sortingStyle);

    for( TInt i = 0 ; i < count ; ++i )
        {
        MCLFSortingStyle* sortingStyle =
                        ContentListingFactory::NewSortingStyleLC( aResource );
        iSortingStyleArray.AppendL( sortingStyle ); // takes ownership
        CleanupStack::Pop(); // sortingStyle
        iDefaultOperation->AppendSortingStyleL( *sortingStyle );
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::NewLC
// -----------------------------------------------------------------------------
//
CCLFItemListModelImpl* CCLFItemListModelImpl::NewLC(
                                            CCLFDbItemProvider* aItemProvider,
                                            MCLFOperationObserver& aObserver,
                                            MCLFChangedItemProvider& aChangedItemProvider )
    {
    CCLFItemListModelImpl* self = new( ELeave ) CCLFItemListModelImpl( aItemProvider, aObserver, aChangedItemProvider );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::NewLC
// -----------------------------------------------------------------------------
//
CCLFItemListModelImpl* CCLFItemListModelImpl::NewLC(
                                            CCLFDbItemProvider* aItemProvider,
                                            MCLFOperationObserver& aObserver,
                                            MCLFChangedItemProvider& aChangedItemProvider,
                                            TResourceReader& aResource)
    {
    CCLFItemListModelImpl* self = new( ELeave ) CCLFItemListModelImpl( aItemProvider, aObserver, aChangedItemProvider );
    CleanupStack::PushL( self );
    self->ConstructL( aResource );
    return self;
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::~CCLFItemListModelImpl
// Destructor
// -----------------------------------------------------------------------------
//
CCLFItemListModelImpl::~CCLFItemListModelImpl()
    {
    iChangedItemProvider.RemoveChangedItemProviderObserver( this );
    delete iMimeTypeArray;
    delete iMediaTypeArray;
    iItemArray.ResetAndDestroy();
    delete iItemProvider;
    iResultArray.Close();
    delete iDefaultOperation;
    iSortingStyleArray.ResetAndDestroy();
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::Item
// -----------------------------------------------------------------------------
//
const MCLFItem& CCLFItemListModelImpl::Item( TInt aIndex ) const
    {
    return *( iResultArray[aIndex] );
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::ItemCount
// -----------------------------------------------------------------------------
//
TInt CCLFItemListModelImpl::ItemCount() const
    {
    return iResultArray.Count();
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetSortingStyle
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetSortingStyle( MCLFSortingStyle* aSortingStyle )
    {
    iDefaultOperation->SetSortingStyle( aSortingStyle );
    iSortingStyleArray.ResetAndDestroy();
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::AppendSecondarySortingStyleL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::AppendSecondarySortingStyleL(
                                            MCLFSortingStyle& aSortingStyle )
    {
    iDefaultOperation->AppendSortingStyleL( aSortingStyle );
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetCustomSorter
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetCustomSorter( MCLFCustomSorter* aCustomSorter )
    {
    if( aCustomSorter )
        {
        iSorter = aCustomSorter;
        }
    else
        {
        iSorter = iDefaultOperation;
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetGroupingStyle
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetGroupingStyle( TCLFGrouping aGrouping )
    {
    iDefaultOperation->SetGrouping( aGrouping );
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetCustomGrouper
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetCustomGrouper(
                                            MCLFCustomGrouper* aCustomGrouper )
    {
    if( aCustomGrouper )
        {
        iGrouper = aCustomGrouper;
        }
    else
        {
        iGrouper = iDefaultOperation;
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetPostFilter
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetPostFilter( MCLFPostFilter* aPostFilter )
    {
    if( aPostFilter )
        {
        iPostFilter = aPostFilter;
        }
    else
        {
        iPostFilter = iDefaultOperation;
        }
    }


// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetWantedMimeTypesL
// Method makes new array, because if we can't make new then old array is used
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetWantedMimeTypesL( const MDesCArray& aMimeTypes )
    {
    const TInt mimeTypeCount( aMimeTypes.MdcaCount() );
    
    if( mimeTypeCount > 0 )
        {
        if( mimeTypeCount == 1 )
            {
            TCollationMethod m = *Mem::CollationMethodByIndex( 0 );
            m.iFlags = ( TCollationMethod::EIgnoreNone | TCollationMethod::EFoldCase );   
            
            const TDesC& mimeType = aMimeTypes.MdcaPoint( 0 );
            if ( mimeType.CompareC( KCLFAllMimeTypeMatchString, 3, &m ) == 0 )
                {
                ResetMimeTypeArrayL();
                return;
                }
            }
        CDesCArray* array = new (ELeave) CDesCArrayFlat( mimeTypeCount );
        CleanupStack::PushL( array );
        for( TInt i = 0 ; i < mimeTypeCount ; ++i )
            {
            array->AppendL( aMimeTypes.MdcaPoint( i ) );
            }
        CleanupStack::Pop( array );
        delete iMimeTypeArray;
        iMimeTypeArray = array;
        }
    else
        {
        ResetMimeTypeArrayL();
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetWantedMimeTypesL
// Method makes new array, because if we can't make new then old array is used
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetWantedMimeTypesL( TResourceReader& aResource )
    {
    CheckVersionL( aResource, KCLFResourceVersionNumber );
    const TInt numMimeTypes( aResource.ReadInt16() );
    if ( numMimeTypes > 0 )
        {
        // TResourceReader re-reads the length, have to rewind
        aResource.Rewind( sizeof( TInt16 ) );
        CDesCArray* array = aResource.ReadDesCArrayL();
        delete iMimeTypeArray;
        iMimeTypeArray = array;
        }
    else
        {
        ResetMimeTypeArrayL();
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetWantedMediaTypesL
// Method makes new array, because if we can't make new then old array is used
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetWantedMediaTypesL(
                            const TArray<TInt>& aMediaTypes )
    {
    const TInt count( aMediaTypes.Count() );
    if( count > 0 )
        {
        CArrayFix<TInt>* array =
                        new ( ELeave ) CArrayFixFlat<TInt>( count );
        CleanupStack::PushL( array );
        for( TInt i = 0 ; i < count ; ++i )
            {
            array->AppendL( aMediaTypes[i] );
            }
        CleanupStack::Pop( array );
        delete iMediaTypeArray;
        iMediaTypeArray = array;
        }
    else
        {
        ResetMediaTypeArrayL();
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::SetWantedMediaTypesL
// Method makes new array, because if we can't make new then old array is used
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::SetWantedMediaTypesL( TResourceReader& aResource )
    {
    CheckVersionL( aResource, KCLFResourceVersionNumber );
    const TInt numMediaTypes( aResource.ReadInt16() );
    if ( numMediaTypes > 0 )
        {
        CArrayFix<TInt>* array =
                new ( ELeave ) CArrayFixFlat<TInt>( numMediaTypes );
        CleanupStack::PushL( array );
        for( TInt i = 0 ; i < numMediaTypes ; ++i )
            {
            array->AppendL( aResource.ReadInt32() );
            }
        CleanupStack::Pop( array );
        delete iMediaTypeArray;
        iMediaTypeArray = array;
        }
    else
        {
        ResetMediaTypeArrayL();
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::RefreshL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::RefreshL()
    {
    MG_TRACE1( KCLFTrace, "CLF list model refresh start" )

    iIsItemsFetched = EFalse;
    iItemArray.ResetAndDestroy();
    iItemProvider->PrepareItemsL( *iMimeTypeArray,
                             iMediaTypeArray->Array(),
                             *this );

    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::RefreshL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::RefreshL( TInt32 aRefreshType )
    {
    RPointerArray<MCLFItem> tmpArray;
    CleanupClosePushL( tmpArray );

    MG_TRACE1( KCLFTrace, "CLF list model refresh post filter start" )

    if( aRefreshType & ECLFRefreshPostFilter )
        {
        iPostFilter->FilterItemsL( iItemArray.Array(), tmpArray );
        }
    else
        {
        CopyArrayL( iItemArray.Array(), tmpArray );
        }
    iResultArray.Reset();

    MG_TRACE1( KCLFTrace1, "CLF list model refresh grouping start" )

    if( aRefreshType & ECLFRefreshGrouping )
        {
        iGrouper->GroupItemsL( tmpArray.Array(), iResultArray );
        }
    else
        {
        CopyArrayL( tmpArray.Array(), iResultArray );
        }
    CleanupStack::PopAndDestroy( &tmpArray );

    MG_TRACE1( KCLFTrace2, "CLF list model refresh sorting start" )

    if( aRefreshType & ECLFRefreshSorting )
        {
        iSorter->SortItemsL( iResultArray );
        }

    MG_TRACE1( KCLFTrace3, "CLF list model refresh sorting done" )
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::CopyArrayL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::CopyArrayL( const TArray<MCLFItem*>& aSource,
                                        RPointerArray<MCLFItem>& aDest )
    {
    MG_DEBUG3( AI1, "CCLFItemListModelImpl::CopyArrayL start, aSource: 0x%08x, aDest: 0x%08x",
               &aSource, &aDest );

    const TInt count( aSource.Count() );
    for( TInt i = 0 ; i < count ; ++i )
        {
        MG_DEBUG3( AI2, "aSource[ %d ]: 0x%08x", i, aSource[ i ] );
        aDest.AppendL( aSource[i] );
        }

    MG_DEBUG1( AI3, "CCLFItemListModelImpl::CopyArrayL end" );
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::CancelRefresh
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::CancelRefresh()
    {
    iItemProvider->Cancel();
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::OperationCompleteL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::OperationCompleteL( TInt aError )
    {
    MG_TRACE1( KCLFTrace, "CLF list model items ready" )

    TInt error( aError );
    if ( error == KErrNone )
        {
        iIsItemsFetched = ETrue;
        iResultArray.Reset(); // reset result array before items are deleted
        iItemArray.ResetAndDestroy();
        error = iItemProvider->GetItems( iItemArray );
        if ( error == KErrNone )
            {
            TRAP( error, RefreshL( ECLFRefreshAll ) );
            }
        }
    iOperationObserver.HandleOperationEventL( ECLFRefreshComplete, error );
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::CheckVersionL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::CheckVersionL( TResourceReader& aResource,
                                           TInt aVersion )
    {
    const TInt version( aResource.ReadInt16() );
    if( version != aVersion )
        {
        User::Leave( KErrNotSupported );
        }
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::ResetMimeTypeArrayL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::ResetMimeTypeArrayL()
    {
    CDesCArray* array =
                new (ELeave) CDesCArrayFlat( KCLFEmptyArrayGranularity );
    delete iMimeTypeArray;
    iMimeTypeArray = array;
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::ResetMediaTypeArrayL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::ResetMediaTypeArrayL()
    {
    CArrayFix<TInt>* array =
                        new ( ELeave ) CArrayFixFlat<TInt>(
                                            KCLFEmptyArrayGranularity );
    delete iMediaTypeArray;
    iMediaTypeArray = array;
    }

// -----------------------------------------------------------------------------
// CCLFItemListModelImpl::ChangedItemsL
// -----------------------------------------------------------------------------
//
void CCLFItemListModelImpl::NewChangedItemsL()
    {
    if( iIsItemsFetched )
        {
        const TInt count( iItemArray.Count() );
        RArray<TCLFItemId> idArray( count == 0 ? 1 : count );
        CleanupClosePushL( idArray );
        for( TInt i = 0 ; i < count ; ++i )
            {
            idArray.AppendL( iItemArray[i]->ItemId() );
            }
        
        if( iChangedItemProvider.IsItemsForModel( *iMimeTypeArray,
                                                  iMediaTypeArray->Array(),
                                                  idArray.Array() ) )
            {
            iOperationObserver.HandleOperationEventL( ECLFModelOutdated, KErrNone );
            }
        CleanupStack::PopAndDestroy( &idArray );
        }
    }

//  End of File