filemanager/Engine/src/CFileManagerActiveRename.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 20:09:41 +0200
changeset 0 6a9f87576119
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* Copyright (c) 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:  Class wraps rename operation
*
*/


// INCLUDES
#include <e32std.h>
#include "CFileManagerActiveRename.h"
#include "CFileManagerEngine.h"
#include "CFileManagerUtils.h"
#include "CFileManagerCommonDefinitions.h"
#include "FileManagerDebug.h"


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

// -----------------------------------------------------------------------------
// CFileManagerActiveRename::CFileManagerActiveRename
// -----------------------------------------------------------------------------
//
CFileManagerActiveRename::CFileManagerActiveRename(
        CFileManagerEngine& aEngine,
        CFileManagerUtils& aUtils ) :
    iEngine( aEngine ),
    iUtils( aUtils ),
    iFs( aEngine.Fs() )
    {
    FUNC_LOG
    }

// -----------------------------------------------------------------------------
// CFileManagerActiveRename::~CFileManagerActiveRename
// -----------------------------------------------------------------------------
//
CFileManagerActiveRename::~CFileManagerActiveRename()
    {
    FUNC_LOG

    delete iName;
    delete iNewName;
    }

// -----------------------------------------------------------------------------
// CFileManagerActiveRename::NewL
// -----------------------------------------------------------------------------
//
CFileManagerActiveRename* CFileManagerActiveRename::NewL(
        CFileManagerEngine& aEngine,
        CFileManagerUtils& aUtils,
        const TDesC& aName,
        const TDesC& aNewName )
    {
    FUNC_LOG

    CFileManagerActiveRename* self = new ( ELeave ) CFileManagerActiveRename(
        aEngine, aUtils );
    CleanupStack::PushL( self );
    self->ConstructL( aName, aNewName );
    CleanupStack::Pop( self );
    return self;
    }

// -----------------------------------------------------------------------------
// CFileManagerActiveRename::ConstructL
// -----------------------------------------------------------------------------
//
void CFileManagerActiveRename::ConstructL(
        const TDesC& aName, const TDesC& aNewName )
    {
    FUNC_LOG

    iName = aName.AllocL();
    iNewName = aNewName.AllocL();
    // Remove white spaces from end, file server also ignores those
    iNewName->Des().TrimRight();
    iName->Des().TrimRight();

    iIsRemoteDrive = iUtils.IsRemoteDrive( aName );
    BaseConstructL();
    }

// -----------------------------------------------------------------------------
// CFileManagerActiveRename::ThreadFunctionL
// -----------------------------------------------------------------------------
//
void CFileManagerActiveRename::ThreadFunctionL( const TBool& aCanceled )
    {
    FUNC_LOG

    TInt maxSubPath( 0 );
    TBool isFolder( CFileManagerUtils::HasFinalBackslash( *iName ) );
    if ( isFolder && !iIsRemoteDrive )
        {
        // On local drives, solve maximum subfolder path to avoid too long paths
        maxSubPath = ThreadGetMaxSubfolderPathL( aCanceled );
        }
    if ( iNewName->Length() + maxSubPath > KMaxFileName )
        {
        User::Leave( KErrBadName );
        }
    if ( isFolder )
        {
        User::LeaveIfError( iFs.Rename( *iName, *iNewName ) );
        }
    else
        {
        // Replace the target item if exist
        // if we have came here, it is already asked that
        // user want's to overwrite other item
        User::LeaveIfError( iFs.Replace( *iName, *iNewName ) );
        }
    }

// -----------------------------------------------------------------------------
// CFileManagerActiveRename::ThreadGetMaxSubfolderPathL
// -----------------------------------------------------------------------------
//
TInt CFileManagerActiveRename::ThreadGetMaxSubfolderPathL(
        const TBool& aCanceled )
    {
    FUNC_LOG

    CDirScan* dirScan = CDirScan::NewLC( iFs );

    // Set scanning from current directory, 
    // take files and folder including the hidden and system files
    // No sorting needed
    dirScan->SetScanDataL(
        *iName,
        KEntryAttNormal | KEntryAttDir | KEntryAttHidden | KEntryAttSystem,
        ESortNone );

    TInt ret( 0 );
    CDir* dir = NULL;
    dirScan->NextL( dir );
    while( dir )
        {
        CleanupStack::PushL( dir );
        if ( aCanceled )
            {
            User::Leave( KErrCancel );
            }
        TInt count( dir->Count() );
        for ( TInt i( 0 ); i < count; ++i )
            {
            if ( aCanceled )
                {
                User::Leave( KErrCancel );
                }
            const TEntry& entry( ( *dir )[ i ] );
            TPtrC abbrPath( dirScan->AbbreviatedPath() );
            TInt abbrPathLen( abbrPath.Length() );
            if ( abbrPathLen && abbrPath[ 0 ] == KFmgrBackslash()[ 0 ] )
                {
                --abbrPathLen; // Initial backslash is already included
                }
            TInt pathLen( abbrPathLen + entry.iName.Length() );
            if( entry.IsDir() ) // Add space for trailing backslash
                {
                ++pathLen;
                }
            if( pathLen > ret )
                {
                ret = pathLen;
                }
            if ( pathLen > KMaxFileName )
                {
                User::Leave( KErrBadName );
                }
            }
        CleanupStack::PopAndDestroy( dir );
        dirScan->NextL( dir );
        }
    CleanupStack::PopAndDestroy( dirScan );
    return ret;
    }

// -----------------------------------------------------------------------------
// CFileManagerActiveRename::CancelThreadFunction
// -----------------------------------------------------------------------------
//
void CFileManagerActiveRename::CancelThreadFunction()
    {
    FUNC_LOG

    if ( iName )
        {
        iEngine.CancelTransfer( *iName );
        }
    }

// End of File