harvester/monitorplugins/fileplugin/src/FolderRenamer.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 14 Apr 2010 16:24:03 +0300
branchRCL_3
changeset 9 82c0024438c8
parent 6 646a02f170b9
child 19 b73252188534
permissions -rw-r--r--
Revision: 201013 Kit: 201015

/*
* Copyright (c) 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 <e32std.h>

#include "FolderRenamer.h"
#include "harvesterlog.h"
#include "mdeharvestersession.h"
#include "mdeharvestersession.h"
#include "harvesterdata.h"
#include "fileeventhandlerao.h"
#include "harvestercommon.h"

CRenameItem * CRenameItem::NewL(
		const TDesC &aOldName, const TDesC &aNewName)
	{	
	CRenameItem *self = new (ELeave) CRenameItem();
	CleanupStack::PushL(self);
	self->ConstructL(aOldName,aNewName);
	CleanupStack::Pop(self);
	return self;
	}
	
CRenameItem::~CRenameItem()
	{
	delete iOldName;
	delete iNewName;
	iFileEvents.ResetAndDestroy();
	}
	

void CRenameItem::ConstructL(const TDesC &aOldName, const TDesC &aNewName)
	{
	iOldName = HBufC::NewL( aOldName.Length() );
	iNewName = HBufC::NewL( aNewName.Length() );

	// convert paths to lower case
	// Note: CopyLC doesn't push anything to cleanup stack
	iOldName->Des().CopyLC( aOldName );
	iNewName->Des().CopyLC( aNewName );
	}

CRenameItem::CRenameItem() : iOldName( NULL ), iNewName( NULL )
	{
	//No implementation required
	}

void CRenameItem::AddFileEvent(TMdsFSPStatus &aEvent)
	{
	TMdsFSPStatus* event = NULL;
	event = new TMdsFSPStatus(aEvent);
	if (event)
		{
		iFileEvents.Append(event);
		}
	}

void CRenameItem::HandleFileEventsL(CFileEventHandlerAO &aCFileEventHandlerAO)
	{
	const TInt count = iFileEvents.Count();
	for (TInt i = 0; i < count; i++)
		{
		aCFileEventHandlerAO.HandleNotificationL(* (iFileEvents[i]));
		}
	iFileEvents.ResetAndDestroy();
	}

TPtrC CRenameItem::OldName()
	{
	return iOldName->Des();
	}


TPtrC CRenameItem::NewName()
	{
	return iNewName->Des();
	}


CFolderRenamer * CFolderRenamer::NewL(CFileEventHandlerAO &aCFileEventHandlerAO)
	{	
	CFolderRenamer *self = new (ELeave) CFolderRenamer(aCFileEventHandlerAO);
	CleanupStack::PushL(self);
	self->ConstructL();
	CleanupStack::Pop(self);
	return self;
	}


CFolderRenamer::CFolderRenamer(CFileEventHandlerAO &aCFileEventHandlerAO) : 
	CActive(KHarvesterPriorityMonitorPlugin),
	iState(ERenameStateIdle),
	iCFileEventHandlerAO(aCFileEventHandlerAO),
	iIsRunning( EFalse )
	{
	}

CFolderRenamer::~CFolderRenamer()
	{
	Cancel();
	iRenamedFolders.ResetAndDestroy();
	}

void CFolderRenamer::ConstructL()
	{
	CActiveScheduler::Add(this);
	}
	
void CFolderRenamer::DoCancel()
	{	
	}
	

void CFolderRenamer::RunL()
	{
	switch (iState)
		{
		case ERenameStateIdle:
			{
			if (iRenamedFolders.Count() == 0)
				{
				iIsRunning = EFalse;
				return;
				}
			} //Flow to Renaming case -> no break
			
		case ERenameStateRenaming:
			{
			if (iRenamedFolders.Count())
				{
				iState = ERenameStateWaitingMdeRename;			
				CRenameItem &currItem = *iRenamedFolders[0];				
				CMdEHarvesterSession* session = iCFileEventHandlerAO.MdeHarvesterSession();
				session->ChangePath( currItem.OldName(), currItem.NewName(), iStatus );
				SetActive();
				}
			}
			break;
			
		case ERenameStateWaitingMdeRename:
			{
			CRenameItem *currItem = iRenamedFolders[0];
			iRenamedFolders.Remove(0);
			TRAP_IGNORE(currItem->HandleFileEventsL(iCFileEventHandlerAO));
			delete currItem;
			SetNextRequest(ERenameStateIdle);
			if (iRenamedFolders.Count() == 0)
				{
				iIsRunning = EFalse;
				iRenamedFolders.Compress();
				}
			}
			break;
			
		default:
			{
			WRITELOG("Unexpected state in FolderRenamer");
			SetNextRequest(ERenameStateIdle);
			}			
			break;
		}
	}

TInt CFolderRenamer::RunError( TInt aError )
    {
    WRITELOG("Unexpected error in FolderRenamer");
    SetNextRequest(ERenameStateIdle);
    return aError;
    }

void CFolderRenamer::RenameL(const TDesC &aOldName, const TDesC &aNewName)
	{
    //There comes multiple events for single rename, drop these 
	const TInt count = iRenamedFolders.Count();
	for (TInt i = 0; i < count; i++)
		{
		if ( iRenamedFolders[i]->OldName().CompareF(aOldName) == 0 && 
				iRenamedFolders[i]->NewName().CompareF(aNewName) == 0 )
			{
			return;
			}
		}
	
	CRenameItem *renameItem = CRenameItem::NewL(aOldName,aNewName);
	iRenamedFolders.AppendL(renameItem);
	iIsRunning = ETrue;
	//First item --> Kickstart
		
	if (iState == ERenameStateIdle)
		{
		SetNextRequest(ERenameStateRenaming);
		}
	}


void CFolderRenamer::SetNextRequest(TFolderRenameState aState)
	{
	iState = aState;	
	if (!IsActive())
		{
		SetActive();				
		TRequestStatus * status = &iStatus;
		User::RequestComplete(status,KErrNone);	
		}
	}


void CFolderRenamer::HandleFileEventL(TMdsFSPStatus &aEvent)
	{
	if (aEvent.iFileEventType == EMdsDirRenamed)
		{
		RenameL(aEvent.iFileName,aEvent.iNewFileName);
		return;
		}

	//Check whether new folder name of the rename events matches to received path. If it matches
    //queue events until folder is renamed, otherwise send notification to filemonitor immediatedly
    //has to be started from last event!
	if (iIsRunning)
		{
		const TInt count = iRenamedFolders.Count();	
		for (TInt i = count-1; i >= 0; i--)
			{
			if (aEvent.iFileName.FindF(iRenamedFolders[i]->NewName()) != KErrNotFound)
				{
				iRenamedFolders[i]->AddFileEvent(aEvent);
				return;
				}
			}		
		}
			
	iCFileEventHandlerAO.HandleNotificationL(aEvent);
	}

void CFolderRenamer::HandleFileEventsL( CArrayFixSeg< TMdsFSPStatus >* aEvents )
    {
    const TInt count( aEvents->Count() );  // Can hold only delete events
    
    if( iIsRunning )
        {
        for( TInt i( 0 ); i < count; i++ )
            {
            //Check whether new folder name of the rename events matches to received path. If it matches
            //queue events until folder is renamed, otherwise send notification to filemonitor immediatedly
            //has to be started from last event!
            const TInt count = iRenamedFolders.Count();   
            for (TInt i = count-1; i >= 0; i--)
                {
                if ((*aEvents)[i].iFileName.FindF(iRenamedFolders[i]->NewName()) != KErrNotFound)
                    {
                    iRenamedFolders[i]->AddFileEvent((*aEvents)[i]);
                    aEvents->Delete( i );
                    break;
                    } 
                }
            }
        aEvents->Compress();
        }
    
    if( aEvents->Count() )
        {
        iCFileEventHandlerAO.HandleMultideletionL(aEvents);
        }
    }