testexecfw/useremul/src/ScanFolders.cpp
author Johnson Ma <johnson.ma@nokia.com>
Mon, 08 Mar 2010 15:03:44 +0800
changeset 0 3e07fef1e154
permissions -rw-r--r--
Initial EPL Contribution

/*------------------------------------------------------------------
 -
 * Software Name : UserEmulator
 * Version       : v4.2.1309
 * 
 * Copyright (c) 2009 France Telecom. All rights reserved.
 * This software is distributed under the License 
 * "Eclipse Public License - v 1.0" the text of which is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
 * Initial Contributors:
 * France Telecom 
 *
 * Contributors:
 *------------------------------------------------------------------
 -
 * File Name: ScanFolders.cpp
 * 
 * Created: 13/08/2009
 * Author(s): Marcell Kiss, Reshma Sandeep Das
 *   
 * Description:
 * Active object implementation for folder scanning operation
 *------------------------------------------------------------------
 -
 *
 */

//System Includes
#include <EikApp.h>
#include <EikEnv.h>
#include <F32File.h>

//User Includes
#include "ScanFolders.h"
#include "FolderContentsListener.h"
#include "UserEmulatorScriptsView.h"

//Constants
const TInt KDRIVESIZE      = 3;

// -----------------------------------------------------------------------------
// CScanFolders::NewL
// -----------------------------------------------------------------------------
//
CScanFolders* CScanFolders::NewL()
{
	CScanFolders* self = CScanFolders::NewLC();
	CleanupStack::Pop(self);
	return self;
}
// -----------------------------------------------------------------------------
// CScanFolders::NewLC
// -----------------------------------------------------------------------------
//
CScanFolders* CScanFolders::NewLC()
{
	CScanFolders* self = new ( ELeave ) CScanFolders;
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;	
}
// -----------------------------------------------------------------------------
// CScanFolders::CScanFolders
// -----------------------------------------------------------------------------
//
CScanFolders::CScanFolders() : CActive( EPriorityStandard )
{

}
// -----------------------------------------------------------------------------
// CScanFolders::~CScanFolders
// -----------------------------------------------------------------------------
//
CScanFolders::~CScanFolders()
{
	Cancel();
	iListeners.Close();
	iCurrentDir.Close();
	iFs.Close();

	delete iDirectories; 
	iDirectories = NULL;
	delete iFileNames; 
	iFileNames = NULL;
}
// -----------------------------------------------------------------------------
// CScanFolders::ConstructL
// -----------------------------------------------------------------------------
//
void CScanFolders::ConstructL()
{
	// Create an array to hold the directories
	iDirectories = new ( ELeave ) CDesCArrayFlat( 10 );

	// Create an array to hold the full filenames
	iFileNames = new ( ELeave ) CDesCArrayFlat( 10 );

	// Create a file server session
	User::LeaveIfError(iFs.Connect());

	// Register this as an active object (for the async file scanning)
	CActiveScheduler::Add( this );
}
// -----------------------------------------------------------------------------
// CScanFolders::AddListenerL
// -----------------------------------------------------------------------------
//
void CScanFolders::AddListenerL( CUserEmulatorScriptsView* aListener )
{
	if ( iListeners.Find( aListener ) != KErrNotFound )
	{
		User::Leave(KErrAlreadyExists);
	}
	iListeners.Append( aListener );
}
// -----------------------------------------------------------------------------
// CScanFolders::RemoveListener
// -----------------------------------------------------------------------------
//
void CScanFolders::RemoveListener( CUserEmulatorScriptsView * aListener )
{
	TInt index = iListeners.Find( aListener );
	iListeners.Remove( index );
}
// -----------------------------------------------------------------------------
// CScanFolders::SetFilter
// -----------------------------------------------------------------------------
//
void CScanFolders::SetFilter( const TDesC & aFilter )
{
	iFileFilter.Copy( aFilter );
	if ( iFileFilter[ iFileFilter.Length() - 1 ] != ';' )
	{
		iFileFilter.Append( ';' );
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::SetFilter
// -----------------------------------------------------------------------------
//
void CScanFolders::SetFilter( const TDesC8 & aFilter )
{
	iFileFilter.Copy( aFilter );
	if ( iFileFilter[ iFileFilter.Length() - 1 ] != ';' )
	{
		iFileFilter.Append( ';' );
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::ScanFolderL
// -----------------------------------------------------------------------------
//
void CScanFolders::ScanFolderL( const TDesC & aPath )
{

	iCurrentPath.Set( aPath, NULL, NULL );

	if ( IsActive() )
	{
		iStartNewScan = ETrue;
	}
	else
	{
		StartScanningL();
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::ScanFolderL
// -----------------------------------------------------------------------------
//
void CScanFolders::ScanFolderL( const TDesC8 & aPath )
{
	TBuf< KBuffer256 > temp;
	temp.Copy( aPath );
	ScanFolderL( temp );
}
// -----------------------------------------------------------------------------
// CScanFolders::DoCancel
// -----------------------------------------------------------------------------
//
void CScanFolders::DoCancel()
{
	iAbortScan = ETrue;
}
// -----------------------------------------------------------------------------
// CScanFolders::RunL
// -----------------------------------------------------------------------------
//
void CScanFolders::RunL()
{
	switch ( iScanState )
	{
	case EIdle:
		User::Panic(KIDLE, 0);
		break;

	case EScanning:
		{
			if ( iStatus == KErrNone )
			{
				FireEntriesL();
				Reset();

				// After the initial entries have been fired, set the
				// #iContinued flag so that #FolderStarting is not called
				// again for this reading session.
				iContinued = ETrue;

				ContinueScanning();
			}
			else if ( iStatus == KErrEof )
			{
				// Before delivering this last set of entries, set the
				// #iComplete flag so that #FolderComplete is called in
				// #FireEntries.
				iComplete = ETrue;

				FireEntriesL();
				Reset();
				StopScanning();
			}
			else
			{
				Reset();
				FireError( iStatus.Int() );
			}
		}
		break;

	case EStartNewScan:
		Reset();
		StartScanningL();
		break;

	case EAbortScan:
		Reset();
		break;
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::StartScanningL
// -----------------------------------------------------------------------------
//
void CScanFolders::StartScanningL()
{
	if ( iCurrentPath.FullName().Compare( KPATHDELIM ) == 0 )
	{
		DeliverDrivesL();
		return;
	}

	TInt error = iCurrentDir.Open( iFs, iCurrentPath.FullName(),
		KEntryAttNormal|KEntryAttDir|KEntryAttReadOnly|KEntryAttSystem|KEntryAttHidden );

	if ( error != KErrNone )
	{
		FireError( error );
		return;
	}

	iContinued = EFalse;
	iComplete = EFalse;

	ContinueScanning();
}

// -----------------------------------------------------------------------------
// CScanFolders::ContinueScanning
// -----------------------------------------------------------------------------
//
void CScanFolders::ContinueScanning()
{
	iCurrentDir.Read( iEntries, iStatus );
	if(!IsActive())
		SetActive();

	iScanState = EScanning;
}
// -----------------------------------------------------------------------------
// CScanFolders::StopScanning
// -----------------------------------------------------------------------------
//
void CScanFolders::StopScanning()
{
	iCurrentDir.Close();
}
// -----------------------------------------------------------------------------
// CScanFolders::DeliverDrivesL
// -----------------------------------------------------------------------------
//
void CScanFolders::DeliverDrivesL()
{
	FireFolderStarting( ETrue );

	TDriveList drives;
	User::LeaveIfError( iFs.DriveList( drives ) );

	for ( TInt idx = 0; idx < KMaxDrives; idx++ )
	{
		if ( drives[ idx ] == 0 )
		{
			continue;
		}
		TChar driveLetter;
		User::LeaveIfError( iFs.DriveToChar( idx, driveLetter ) );

		TBuf< KDRIVESIZE > temp;
		temp.Append( driveLetter );
		temp.Append( KDRIVEDEL );

		FireFolder( temp );
	}

	FireFolderCompleteL();
	Reset();
}
// -----------------------------------------------------------------------------
// CScanFolders::Reset
// -----------------------------------------------------------------------------
//
void CScanFolders::Reset()
{
	iDirectories->Reset();
	iFileNames->Reset();

	iScanState = EIdle;
}
// -----------------------------------------------------------------------------
// CScanFolders::FireError
// -----------------------------------------------------------------------------
//
void CScanFolders::FireError( TInt aReasonCode )
{
	for ( TInt idx = 0; idx < iListeners.Count(); idx++ )
	{
		iListeners[ idx ]->ErrorOccured( aReasonCode );
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::FireEntriesL
// -----------------------------------------------------------------------------
//
void CScanFolders::FireEntriesL()
{
	if ( iContinued == EFalse )
	{
		FireFolderStarting( EFalse );
	}

	for ( TInt idx = 0; idx < iEntries.Count(); idx++ )
	{
		if ( iEntries[ idx ].IsDir() || IsMatch( iEntries[ idx ].iName ) )
		{
			FireEntry( iEntries[ idx ] );
		}
	}

	if ( iComplete )
	{
		FireFolderCompleteL();
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::FireEntry
// -----------------------------------------------------------------------------
//
void CScanFolders::FireEntry( const TEntry & aEntry )
{
	if ( aEntry.IsDir() )
	{
		FireFolder( aEntry.iName );
	}
	else
	{
		FireFile( aEntry.iName );
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::FireFolder
// -----------------------------------------------------------------------------
//
void CScanFolders::FireFolder( const TDesC & aFolder )
{
	for ( TInt idx = 0; idx < iListeners.Count(); idx++ )
	{
		iListeners[ idx ]->NewFolder( aFolder );
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::FireFile
// -----------------------------------------------------------------------------
//
void CScanFolders::FireFile( const TDesC & aFile )
{
	for ( TInt idx = 0; idx < iListeners.Count(); idx++ )
	{
		iListeners[ idx ]->NewFile( aFile );
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::FireFolderStarting
// -----------------------------------------------------------------------------
//
void CScanFolders::FireFolderStarting( TBool aIsDriveListFlag )
{
	for ( TInt idx = 0; idx < iListeners.Count(); idx++ )
	{		
		iListeners[ idx ]->FolderStarting( iCurrentPath.FullName(), aIsDriveListFlag );
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::FireFolderCompleteL
// -----------------------------------------------------------------------------
//
void CScanFolders::FireFolderCompleteL()
{
	for ( TInt idx = 0; idx < iListeners.Count(); idx++ )
	{
		iListeners[ idx ]->FolderCompleteL();
	}
}
// -----------------------------------------------------------------------------
// CScanFolders::IsMatch
// -----------------------------------------------------------------------------
//
TBool CScanFolders::IsMatch( const TDesC & aFilename )
{
	TPtrC remaining = iFileFilter.Mid( 0 );
	while ( remaining.Length() > 0 )
	{
		TInt delimeterPos = remaining.Locate( ';' );
		if ( delimeterPos == KErrNotFound )
		{
			delimeterPos = remaining.Length();
		}
		TPtrC pattern = remaining.Mid( 0, delimeterPos );
		if ( aFilename.MatchF( pattern ) != KErrNotFound )
		{
			return ETrue;
		}
		if( delimeterPos + 1 <= remaining.Length() )
			remaining.Set( remaining.Mid( delimeterPos + 1 ) );
	}
	return EFalse;
}