filemanager/GFLM/src/CGflmFileListModel.cpp
branchRCL_3
changeset 21 65326cf895ed
parent 0 6a9f87576119
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/filemanager/GFLM/src/CGflmFileListModel.cpp	Wed Sep 01 12:31:07 2010 +0100
@@ -0,0 +1,686 @@
+/*
+* Copyright (c) 2002-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:  File list model
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "CGflmFileListModel.h"
+#include "MGflmItemGroup.h"
+#include "CGflmItemGroupImpl.h"
+#include "CGflmDirectoryListingCache.h"
+#include "CGflmFileRecognizer.h"
+#include "CGflmDriveResolver.h"
+#include "CGflmItemLocalizer.h"
+#include "CGflmFileSystemItem.h"
+#include "CGflmGlobalActionItem.h"
+#include "CGflmFileFinder.h"
+#include "MGflmItemFilter.h"
+#include "GflmUtils.h"
+#include "GFLMConsts.h"
+#include "GFLM.hrh"
+#include <e32base.h>
+#include <e32std.h>
+#include <badesca.h>
+
+
+// CONSTANTS
+
+// Granularity of iGroups array
+const TInt KItemGroupArrayGranularity = 3;
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::CGflmFileListModel
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CGflmFileListModel::CGflmFileListModel( RFs& aFs ) :
+        CActive( CActive::EPriorityStandard ),
+        iFs( aFs )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGflmFileListModel* CGflmFileListModel::NewL( RFs& aFs )
+    {
+    CGflmFileListModel* self = new( ELeave ) CGflmFileListModel( aFs );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CGflmFileListModel::ConstructL()
+    {
+    FUNC_LOG
+
+    CActiveScheduler::Add( this );
+
+    iGroups = new( ELeave )
+        CArrayPtrSeg< CGflmItemGroupImpl >
+            ( KItemGroupArrayGranularity );
+    iListingCache = CGflmDirectoryListingCache::NewL( iFs, iCanceled );
+    iDriveResolver = CGflmDriveResolver::NewL( iFs );
+    iFileRecognizer = CGflmFileRecognizer::NewL(
+        iFs, KGFLMFileRecognizerCacheSize, iDriveResolver );
+    iItemLocalizer = CGflmItemLocalizer::NewL();
+    iFileFinder = CGflmFileFinder::NewL(
+        iFs, *iItemLocalizer, *iDriveResolver, iCanceled );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::~CGflmFileListModel
+//
+// -----------------------------------------------------------------------------
+//
+CGflmFileListModel::~CGflmFileListModel()
+    {
+    FUNC_LOG
+
+    Cancel();
+    if ( iGroups )
+        {
+        iGroups->ResetAndDestroy();
+        delete iGroups;
+        }
+    delete iFileFinder;
+    delete iListingCache;
+    delete iFileRecognizer;
+    delete iItemLocalizer;
+    delete iDriveResolver;
+    iSemaphore.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::RefreshListL()
+// Creates and starts the work thread that refreshes the model
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::RefreshListL(
+        TRequestStatus& aStatus, TGflmRefreshMode aRefreshMode )
+    {
+    FUNC_LOG
+
+    if ( aStatus == KRequestPending )
+        {
+        return;
+        }
+
+    iCorrupt = ETrue;
+    iClientStatus = &aStatus;
+    *iClientStatus = KRequestPending;
+    iClientId = RThread().Id();
+
+    if ( iShutdown )
+        {
+        // Ensure client completion
+        NotifyClient( KErrNone );
+        return;
+        }
+
+    iCanceled = EFalse;
+
+    if ( !IsActive() )
+        {
+        // Create the work thread to do refresh
+        iSemaphore.Close();
+        User::LeaveIfError( iSemaphore.CreateLocal( 0 ) );
+
+        RThread workThread;
+        TInt err( workThread.Create(
+            KGFLMWorkThreadName,
+            WorkThreadStart,
+            KGFLMWorkThreadStackSize,
+            NULL,
+            this ) );
+        LOG_IF_ERROR1( err, "CGflmFileListModel::RefreshListL-err1=%d", err )
+        User::LeaveIfError( err );
+        workThread.SetPriority( EPriorityLess );
+        workThread.Logon( iStatus );
+        SetActive();
+        iRefreshMode = aRefreshMode;
+        workThread.Resume();
+        workThread.Close();
+        }
+    else
+        {
+        // Signal the work thread to do refresh
+        iRefreshMode = aRefreshMode;
+        iSemaphore.Signal();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::WorkThreadStart()
+// An entry point function for the work thread
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CGflmFileListModel::WorkThreadStart( TAny* aPtr )
+    {
+    FUNC_LOG
+
+    CGflmFileListModel* self = static_cast< CGflmFileListModel* >( aPtr );
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if ( !cleanupStack )
+        {
+        ERROR_LOG1(
+            "CGflmFileListModel::WorkThreadStart-err1=%d", KErrNoMemory )
+        return KErrNoMemory;
+        }
+
+    TRAPD( err, self->iItemLocalizer->SetupWorkThreadLocalizerL() );
+    LOG_IF_ERROR1( err, "CGflmFileListModel::WorkThreadStart-err2=%d", err )
+
+    self->WorkThread();
+    self->iItemLocalizer->ReleaseWorkThreadLocalizer();
+    delete cleanupStack;
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::WorkThread()
+// -----------------------------------------------------------------------------
+//
+void CGflmFileListModel::WorkThread()
+    {
+    TInt err( KErrNone );
+    do
+        {
+
+        // Do refresh
+        iCorrupt = ETrue;
+        err = KErrNone;
+
+        TRAP( err, DoRefreshL() );
+        if ( err == KErrNone )
+            {
+            iCorrupt = EFalse;
+            }
+
+        LOG_IF_ERROR1( err, "CGflmFileListModel::WorkThread-err=%d", err )
+
+        NotifyClient( err );
+
+        iSemaphore.Wait(); // Wait for refresh signal from main thread
+
+        } while ( !iShutdown );
+
+    if ( iShutdown )
+        {
+        // Disable list usage and ensure client completion
+        iCorrupt = ETrue;
+        NotifyClient( err );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::NotifyClient()
+// -----------------------------------------------------------------------------
+//
+void CGflmFileListModel::NotifyClient( TInt aErr )
+    {
+    FUNC_LOG
+
+    if ( iClientStatus )
+        {
+        RThread client;
+        if ( client.Open( iClientId ) == KErrNone )
+            {
+            client.RequestComplete( iClientStatus, aErr );
+            client.Close();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::DoRefreshL()
+// This method does the actual refreshing. It's not static so it can access
+// member data and it can leave as it's trap harnessed in RefreshAndNotify()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CGflmFileListModel::DoRefreshL()
+    {
+    TIMESTAMP( "GFLM refresh files and folders started: " )
+
+    INFO_LOG1(
+        "CGflmFileListModel::DoRefreshL-iSearchEnabled=%d",
+        iSearchEnabled )
+
+    if ( iSearchEnabled )
+        {
+        User::LeaveIfError( iDriveResolver->RefreshDrives( iFilter ) );
+        iFileFinder->RefreshL( iFilter, iSearchSortMethod, iRefreshMode );
+        }
+    else
+        {
+        if ( iRefreshMode == ERefreshItems )
+            {
+            iListingCache->ClearCache();
+            }
+        User::LeaveIfError( iDriveResolver->RefreshDrives( iFilter ) );
+
+        TInt groupCount( iGroups->Count() );
+        for ( TInt i( 0 ); i < groupCount; i++ )
+            {
+            iGroups->At( i )->RefreshL( iFilter, iSortMethod, iRefreshMode );
+            }
+        }
+
+    TIMESTAMP( "GFLM refresh  files and folders ended: " )
+	}
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::CancelRefresh()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::CancelRefresh()
+    {
+    FUNC_LOG
+
+    iCanceled = ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::MdcaCount()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CGflmFileListModel::MdcaCount() const
+    {
+    if ( iCorrupt )
+        {
+        return 0;
+        }
+    if ( iSearchEnabled )
+        {
+        return iFileFinder->ItemCount();
+        }
+
+    // Count the total number of items in groups
+    TInt groupCount( iGroups->Count() );
+    TInt itemCount( 0 );
+    for( TInt i( 0 ); i < groupCount; i++ )
+        {
+        itemCount += iGroups->At( i )->ItemCount();
+        }
+    return itemCount;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::MdcaPoint()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPtrC CGflmFileListModel::MdcaPoint( TInt aIndex ) const
+    {
+    if ( iSearchEnabled )
+        {
+        return iFileFinder->Item( aIndex )->Name();
+        }
+
+    // Return the formatted presentation by global index
+    MGflmItemGroup* group = NULL;
+    TInt localIndex( 0 );
+    GetGroupAndLocalIndex( aIndex, localIndex, group );
+    return group->Item( localIndex )->Name();
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::GetGroupAndLocalIndex()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CGflmFileListModel::GetGroupAndLocalIndex(
+        const TInt aGlobalIndex,
+        TInt& aLocalIndex,
+        MGflmItemGroup*& aGroup ) const
+    {
+    // Calculate the group and the requested item's local index
+    // from a global index
+    TInt groupCount( iGroups->Count() );
+    TInt offset( 0 );
+    for( TInt i( 0 ); i < groupCount; i++ )
+        {
+        MGflmItemGroup* currentGroup = iGroups->At( i );
+        TInt itemsInGroup( currentGroup->ItemCount() );
+        if ( aGlobalIndex < itemsInGroup + offset )
+            {
+            // The global index resides in this group
+            aGroup = iGroups->At( i );
+            aLocalIndex = aGlobalIndex - offset;
+            return;
+            }
+        offset += itemsInGroup;
+        }
+
+    // Group not found
+    User::Panic( KGFLMPanicText, EGlobalIndexOutOfBounds );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::Item()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGflmGroupItem* CGflmFileListModel::Item( TInt aIndex ) const
+    {
+    if ( iSearchEnabled )
+        {
+        return iFileFinder->Item( aIndex );
+        }
+    // Return the formatted presentation by global index
+    MGflmItemGroup* group = NULL;
+    TInt localIndex( 0 );
+    GetGroupAndLocalIndex( aIndex, localIndex, group );
+    return group->Item( localIndex );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::ResetModel()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::ResetModel()
+    {
+    iGroups->ResetAndDestroy();
+    iListingCache->ClearCache();
+    iDriveResolver->ClearDrives();
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::FindGroupById()
+// Used to provide clients with CGflmItemGroupImpl objects downcasted to
+// CGflmItemGroup.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C MGflmItemGroup* CGflmFileListModel::FindGroupById( TInt aId )
+    {
+    TInt groupCount( iGroups->Count() );
+
+    for( TInt i( 0 ); i < groupCount; i++ )
+        {
+        CGflmItemGroupImpl* group = iGroups->At( i );
+        if ( aId == group->Id() )
+            {
+            return group;
+            }
+        }
+
+    // Group not found
+    User::Panic( KGFLMPanicText, EInvalidGroupId );
+
+    // Execution never reaches this point
+    // following line keeps the compiler happy
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::CreateGroupL()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+EXPORT_C MGflmItemGroup* CGflmFileListModel::CreateGroupL( TInt aId )
+    {
+    // Scan the list of groups for identical IDs
+    TInt groupCount( iGroups->Count() );
+    for ( TInt i( 0 ); i < groupCount; i++ )
+        {
+        if ( iGroups->At( i )->Id() == aId )
+            {
+            User::Leave( KErrAlreadyExists );
+            }
+        }
+
+    CGflmItemGroupImpl* newGroup = CGflmItemGroupImpl::NewLC(
+        aId,
+        iFs,
+        *iListingCache,
+        *iItemLocalizer,
+        *iDriveResolver );
+
+    iGroups->AppendL( newGroup );
+    CleanupStack::Pop( newGroup );
+    return newGroup;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::CreateGroupL()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+EXPORT_C MGflmItemGroup* CGflmFileListModel::CreateGroupL(
+        TInt aId, TUint aInclusion )
+    {
+    MGflmItemGroup* newGroup = CreateGroupL( aId );
+    newGroup->SetInclusion( aInclusion );
+    return newGroup;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::SetCustomFilter()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+EXPORT_C void CGflmFileListModel::SetCustomFilter( MGflmItemFilter* aFilter )
+    {
+    iFilter = aFilter;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::ResolveMimeTypeL()
+// Uses the internal file recognition cache
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+EXPORT_C TPtrC CGflmFileListModel::ResolveMimeTypeL( const TDesC& aFilename )
+    {
+    return iFileRecognizer->RecognizeL( aFilename );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::IsCorrupt()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+EXPORT_C TBool CGflmFileListModel::IsCorrupt() const
+    {
+    return iCorrupt;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::LocalizedName()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TPtrC CGflmFileListModel::LocalizedName( const TDesC& aPath ) const
+    {
+    return iItemLocalizer->Localize( aPath );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::ClearCache()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::ClearCache()
+    {
+    iListingCache->ClearCache();
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::ClearDriveInfo()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::ClearDriveInfo()
+    {
+    iDriveResolver->ClearDrives();
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::DriveFromPath()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGflmDriveItem* CGflmFileListModel::DriveFromPath(
+        const TDesC& aPath ) const
+    {
+    if ( !iDriveResolver->DriveCount() )
+        {
+        ERROR_LOG( "CGflmFileListModel::DriveFromPath-Forced drive refresh" )
+        iDriveResolver->RefreshDrives( iFilter );
+        }
+    return iDriveResolver->DriveFromPath( aPath );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::RunL()
+// -----------------------------------------------------------------------------
+//
+void CGflmFileListModel::RunL()
+    {
+    FUNC_LOG
+
+    NotifyClient( iStatus.Int() );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::RunError
+// -----------------------------------------------------------------------------
+//
+TInt CGflmFileListModel::RunError( TInt /*aError*/ )
+    {
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CGflmFileListModel::DoCancel()
+    {
+    FUNC_LOG
+
+    iShutdown = ETrue;
+    iSemaphore.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::DriveFromId
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CGflmDriveItem* CGflmFileListModel::DriveFromId(
+        const TInt aDrive ) const
+    {
+    if ( !iDriveResolver->DriveCount() )
+        {
+        ERROR_LOG( "CGflmFileListModel::DriveFromId-Forced drive refresh" )
+        iDriveResolver->RefreshDrives( iFilter );
+        }
+    return iDriveResolver->DriveFromId( aDrive );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::EnableSearchMode
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::EnableSearchMode( const TBool aEnabled )
+    {
+    iSearchEnabled = aEnabled;
+    if ( iSearchEnabled )
+        {
+        iSearchSortMethod = EByMatch; // Default for search
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::SearchMode
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CGflmFileListModel::SearchMode()
+	{
+	return iSearchEnabled;
+	}
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::SetSearchStringL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::SetSearchStringL( const TDesC& aSearchString )
+    {
+    iFileFinder->SetSearchStringL( aSearchString );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::SetSearchFolderL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::SetSearchFolderL( const TDesC& aSearchFolder )
+    {
+    iFileFinder->SetSearchFolderL( aSearchFolder );
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::SetSortMethod
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::SetSortMethod( TGflmSortMethod aSortMethod )
+    {
+    if ( iSearchEnabled )
+        {
+        iSearchSortMethod = aSortMethod;
+        }
+    else if ( aSortMethod != EByMatch ) // EByMatch is allowed only for search
+        {
+        iSortMethod = aSortMethod;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::SortMethod
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TGflmSortMethod CGflmFileListModel::SortMethod() const
+    {
+    if ( iSearchEnabled )
+        {
+        return iSearchSortMethod;
+        }
+    return iSortMethod;
+    }
+
+// -----------------------------------------------------------------------------
+// CGflmFileListModel::FlushCache()
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGflmFileListModel::FlushCache()
+    {
+    iFileRecognizer->FlushCache();
+    }
+
+//  End of File