filemanager/src/filemanager/src/operationservice/fmoperationcopyormove.cpp
branchRCL_3
changeset 39 65326cf895ed
parent 38 491b3ed49290
child 42 f5c50b8af68c
--- a/filemanager/src/filemanager/src/operationservice/fmoperationcopyormove.cpp	Tue Aug 31 15:06:05 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,446 +0,0 @@
-/*
-* 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 "fmoperationcopyormove.h"
-#include "fmcommon.h"
-#include "fmoperationbase.h"
-#include "fmdrivedetailstype.h"
-#include "fmutils.h"
-
-#include <QDir>
-#include <QFileInfo>
-#include <QStringList>
-#include <QStack>
-
-/* \fn void askForReplace( const QString &srcFile, const QString &destFile, bool *isAccepted )
- * This signal is emitted when the same file as \a srcFile exists.
- * \a destFile the destination file.
- * \a isAccepted whether to replace the destination file.
- */
-
-/* \fn void askForRename( const QString &srcFile, QString *destFile )
- * This signal is emitted when \a srcFile needs to be renamed.
- * \a destFile return the new name.
- */
-
-/* \fn  void driveSpaceChanged()
- * This signal is emitted when copy or move is completed, and used to update the drive size.
- */
-
-//the size of one time copy
-const int FmOneTimeCopyOrMoveSize = 1024;
-//the total steps of progress bar
-const int FmTotalProgressBarSteps = 100;
-/*
- * Constructs a copy or move operation with
- * \a operationService parent
- * \a type the type of operation(EOperationTypeCopy or EOperationTypeMove)
- * \a sourceList the source file or path lists that will be copied
- * \a targetPath the target path where the source file will be copied
- */
-FmOperationCopyOrMove::FmOperationCopyOrMove( FmOperationService *operationService, FmOperationService::TOperationType type, const QStringList &sourceList, const QString &targetPath )
-        : FmOperationBase( operationService, type ),
-          mOperationService( operationService ), mSourceList( sourceList ), mTargetPath( targetPath ),
-          mStop( 0 ), mTotalSize( 0 ), mCopiedOrMovedSize( 0 ), mTotalSteps( FmTotalProgressBarSteps ), mCurrentStep( 0 )
-{
-	mTargetPath = FmUtils::fillPathWithSplash( mTargetPath );
-    connect( this, SIGNAL( askForRename( QString, QString* ) ),
-                mOperationService, SLOT( on_operation_askForRename( QString, QString* )), Qt::BlockingQueuedConnection );
-    connect( this, SIGNAL( askForReplace( QString, QString, bool* ) ),
-                mOperationService, SLOT( on_operation_askForReplace( QString, QString, bool* )), Qt::BlockingQueuedConnection );    
-    connect( this, SIGNAL( driveSpaceChanged() ),
-                mOperationService, SLOT( on_operation_driveSpaceChanged() ) );
-}
-
-/*
- * Destructs the copy or move operation.
- */
-FmOperationCopyOrMove::~FmOperationCopyOrMove()
-{
-}
-
-/*
- * Returns the source file or path list
- */
-QStringList FmOperationCopyOrMove::sourceList()
-{
-    return mSourceList;
-}
-
-/*
- * Returns the target path
- */
-QString FmOperationCopyOrMove::targetPath()
-{
-    return mTargetPath;
-}
-
-/*
- * Starts the operation.
- * \a isStopped flag the outside stop operation
- */
-void FmOperationCopyOrMove::start( volatile bool *isStopped )
-{
-    mStop = isStopped; 
-    mTotalSize   = 0;
-    mCopiedOrMovedSize  = 0;
-    mCurrentStep = 0;
-
-    if ( mSourceList.empty() ) {
-        emit notifyError( FmErrWrongParam, mErrString );    
-        return ;
-    }
-	emit notifyPreparing( true );
-
-    int numofFolders = 0;
-    int numofFiles      = 0;
-
-    int ret = FmFolderDetails::queryDetailOfContentList( mSourceList, numofFolders, 
-        numofFiles, mTotalSize, mStop, true );
-    if( ret != FmErrNone ) {
-        emit notifyError( ret, mErrString );
-        return;        
-    }    
-    if ( !targetHasEnoughSpace() ) {
-        emit notifyError( FmErrDiskFull, mErrString );
-        return;
-        }    
-    emit notifyStart( true, mTotalSteps );
-
-    foreach( const QString& source, mSourceList ) {
-        // formatPath, but do not append splash in the end
-        // Otherwise could not get fileName in QFileInfo::fileName
-        QString checkedSource( FmUtils::formatPath( source ) );
-        QFileInfo fi( checkedSource );
-        if( !fi.exists() ) {
-            mErrString = checkedSource;            
-            emit notifyError( FmErrSrcPathDoNotExist, mErrString );
-            return;
-        }
-        QString newName;
-        bool    isAcceptReplace = false;
-        QFileInfo destFi( mTargetPath + fi.fileName() );
-
-        // while for duplicated file/dir
-        while( destFi.exists() ) {
-            if( destFi.isFile() && destFi.absoluteFilePath().compare( fi.absoluteFilePath(), Qt::CaseInsensitive ) != 0 ) {
-                emit askForReplace( destFi.absoluteFilePath(), fi.absoluteFilePath(), &isAcceptReplace );
-                if( isAcceptReplace ) {
-                    //delete src file
-                    if( !QFile::remove( destFi.absoluteFilePath() ) ) {
-                        mErrString = destFi.absoluteFilePath();
-                        ret = FmErrCannotRemove;
-                        break;
-                    }
-                    destFi.setFile( destFi.absoluteFilePath() );
-                } else {
-                    queryForRename( destFi.absoluteFilePath(), &newName );
-                    if( newName.isEmpty() ) {
-                        ret = FmErrCancel;
-                        break;
-                    }
-                    QString targetName = mTargetPath + newName;
-                    destFi.setFile( targetName );
-                }
-            } else{
-                // destination is dir
-                queryForRename( destFi.absoluteFilePath(), &newName );
-                if( newName.isEmpty() ) {
-                    ret = FmErrCancel;
-                    break;
-                }
-                QString targetName = mTargetPath + newName;
-                destFi.setFile( targetName );
-            }
-        }
-        if( ret != FmErrNone ) {
-            emit notifyError( ret, mErrString );
-            // refresh drive space no care if cancel, error or finished.
-            // as filemanger cannot notify drive space changed
-            // do not refresh path as QFileSystemModel will do auto-refresh
-            emit driveSpaceChanged();
-            return;
-        }
-        ret = copyOrMove( checkedSource, mTargetPath, newName );
-        if( ret != FmErrNone ) {
-            emit notifyError( ret, mErrString );            
-            emit driveSpaceChanged();
-            return;
-        }
-    }
-    emit notifyFinish();
-    emit driveSpaceChanged();
-}
-
-/*
- * Copy or move the \a source to \a targetPath
- * with \a newTargetName
- */
-int FmOperationCopyOrMove::copyOrMove( const QString &source, const QString &targetPath,
-                         const QString &newTargetName )
-{        
-    if( *mStop ) {
-        return FmErrCancel;
-    }
-
-    QFileInfo fi( source );
-    if( !fi.exists() ) {
-        mErrString = source;
-        return FmErrSrcPathDoNotExist;
-    }
-    QString newName;
-    if( !newTargetName.isEmpty() ) {
-        newName = targetPath + newTargetName;
-    } else {
-        newName = targetPath + fi.fileName();
-    }
-
-    int ret = FmErrNone;
-    
-    if ( fi.isFile() ) {
-        if ( FmUtils::getDriveLetterFromPath( source ) == 
-                FmUtils::getDriveLetterFromPath( targetPath ) && 
-                operationType() == FmOperationService::EOperationTypeMove ) 
-            {
-            return FmUtils::moveInsideDrive( source, newName );
-            
-            }
-        quint64 fileSize = fi.size();
-        ret = copyOneFile( source, newName );
-        if (ret != FmErrNone) {
-            mErrString = source;
-            return ret;
-        }        
-        if ( operationType() == FmOperationService::EOperationTypeMove 
-                && !QFile::remove( source ) ) {
-            mErrString = source;
-            return FmErrCannotRemove;           
-        }
-    } else if ( fi.isDir() ) {
-        if( operationType() == FmOperationService::EOperationTypeMove 
-                && FmUtils::isDefaultFolder( source ) ){
-            ret = FmErrRemoveDefaultFolder;
-        }
-        else{
-            ret = copyOrMoveDirInsideContent( source, newName );
-        }        
-        if( ret!= FmErrNone ) {
-            return ret;
-        }
-        if ( operationType() == FmOperationService::EOperationTypeMove 
-                && !fi.dir().rmdir( fi.absoluteFilePath() ) ) {
-            mErrString = fi.absolutePath();
-            return FmErrCannotRemove;
-        }
-    } else {
-        qWarning( "Things other than file and directory are not copied" );
-        ret = FmErrIsNotFileOrFolder;
-    }
-
-    return ret;
-}
-
-/*
-  copy \a srcPath as \a destPath
-  both \a srcPath and \a destPath are Directory
-*/
-int FmOperationCopyOrMove::copyOrMoveDirInsideContent( const QString &srcPath, const QString &destPath )
-{
-    QFileInfo srcInfo( srcPath );
-    QFileInfo destInfo( destPath );
-    
-    if( FmUtils::isSubLevelPath( srcPath, destPath ) ) {
-        mErrString = destPath;
-        if ( operationType() == FmOperationService::EOperationTypeMove ) {
-            return FmErrMoveDestToSubFolderInSrc;
-        } else {
-            return FmErrCopyDestToSubFolderInSrc;
-        }
-        
-    }
-    
-    if( !srcInfo.isDir() || !srcInfo.exists() ) {
-        mErrString = srcPath;
-        return FmErrSrcPathDoNotExist;
-    }
-    
-    if( !destInfo.exists() ) {
-        if( !destInfo.dir().mkdir( destInfo.absoluteFilePath() ) ) {
-            mErrString = destPath;
-            return FmErrCannotMakeDir;
-        }
-    }    
-    destInfo.setFile( destPath );
-    if( !destInfo.isDir() ) {
-        mErrString = destPath;
-        return FmErrCannotMakeDir;
-    }
-
-    //start to copy
-    QFileInfoList infoList = QDir( srcPath ).entryInfoList( QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden | QDir::System );
-    while( !infoList.isEmpty() ) {
-        if( *mStop ) {
-            return FmErrCancel;
-        }
-
-        QFileInfo fileInfo = infoList.takeFirst();
-        if( fileInfo.isFile() ){
-            //copy file
-            QString newFilePath = destPath + fileInfo.absoluteFilePath().mid( srcPath.length() );
-            int ret = copyOneFile( fileInfo.absoluteFilePath(), newFilePath );
-            if ( ret != FmErrNone ) {
-                mErrString = fileInfo.absoluteFilePath();
-                return ret;
-            }
-            if( operationType() == FmOperationService::EOperationTypeMove 
-                    && !QFile::remove( fileInfo.absoluteFilePath() ) ) {
-                mErrString = fileInfo.absoluteFilePath();
-                return FmErrCannotRemove;
-            }   
-        } else if( fileInfo.isDir() ) {
-            //makedir
-            QString newDirPath = destPath + fileInfo.absoluteFilePath().mid( srcPath.length() );
-            if( !QDir( newDirPath ).exists() && !QDir( destPath ).mkdir( newDirPath ) ) {
-                mErrString = newDirPath;
-                return FmErrCannotMakeDir;
-            }
-            // add dir content to list.
-            QFileInfoList infoListDir = QDir( fileInfo.absoluteFilePath() ).entryInfoList(
-                QDir::NoDotAndDotDot | QDir::AllEntries );
-            if ( operationType() == FmOperationService::EOperationTypeMove ) {
-                if( infoListDir.isEmpty() ) {
-                    if ( !fileInfo.dir().rmdir( fileInfo.absoluteFilePath() ) ) {
-                        mErrString = fileInfo.absolutePath();
-                        return FmErrCannotRemove;
-                    }
-                } else {
-                    infoList.push_front( fileInfo );
-                }
-            }
-            while( !infoListDir.isEmpty() ) {
-                infoList.push_front( infoListDir.takeLast() );
-            }
-
-        } else {
-            mErrString = fileInfo.absoluteFilePath();
-            return FmErrIsNotFileOrFolder;
-        }
-
-    }
-
-    return FmErrNone;
-}
-
-/*
- * Increase the progress bar
- * \a size the current copy or moved size
- */
-void FmOperationCopyOrMove::increaseProgress( quint64 size )
-{
-    if( mTotalSize <=0 ) {
-        return;
-    }
-    mCopiedOrMovedSize += size;
-    int step = ( mCopiedOrMovedSize * FmTotalProgressBarSteps ) / mTotalSize;
-    if( step > mCurrentStep ) {
-        mCurrentStep = step;
-        emit notifyProgress( mCurrentStep );
-    }
-}
-
-/*
- * Emits askForRename signal.
- * \a srcFile the source file path.
- * \a destFile get the new name from user input
- */
-void FmOperationCopyOrMove::queryForRename( const QString &srcFile, QString *destFile )
-{
-    emit askForRename( srcFile, destFile );
-}
-
-/*
- * Copies one file from \a srcFile to \a desFile
- */
-int FmOperationCopyOrMove::copyOneFile( const QString &srcFile, const QString &desFile )
-{
-    QFile src( srcFile );
-    QFile des( desFile );
-    if ( !src.open( QIODevice::ReadOnly ) || !des.open( QIODevice::WriteOnly ) ) {
-        return FmErrCannotCopy;
-    }
-    QDataStream  outputStream( &src );
-    QDataStream  inputStream( &des );
-    //used to cache data from source file to target file during one copy
-    QScopedPointer<char> tempString( new char[FmOneTimeCopyOrMoveSize] );
-    memset( tempString.data(), 0, FmOneTimeCopyOrMoveSize );
-    while ( !outputStream.atEnd() ) {
-        if ( *mStop ) {            
-            src.close();
-            des.close();
-            QFile::remove( desFile );
-            return FmErrCancel;
-        }
-        int ret = outputStream.readRawData(tempString.data(), FmOneTimeCopyOrMoveSize );
-        if (ret == -1) {
-            src.close();
-            des.close();
-            QFile::remove( desFile );            
-            return FmErrCannotCopy;
-        }
-        ret = inputStream.writeRawData(tempString.data(), ret);
-        if (ret == -1) {
-            src.close();
-            des.close();
-            QFile::remove( desFile );            
-            return FmErrCannotCopy;
-        }        
-        memset( tempString.data(), 0, FmOneTimeCopyOrMoveSize );
-        increaseProgress( ret );
-    }    
-    src.close();
-    des.close();
-    if ( FmUtils::setFileAttributes( srcFile, desFile ) != FmErrNone ) {
-        QFile::remove( desFile );        
-        return FmErrCannotCopy;
-    }
-    return FmErrNone;
-}
-
-/*
- * Prepare some work before starting operation.
- * Returns error number.
- */
-int FmOperationCopyOrMove::prepare()
-{
-    if( mSourceList.empty() ) {
-        return FmErrWrongParam;
-    } else {
-    return FmErrNone;
-    }
-}
-
-bool FmOperationCopyOrMove::targetHasEnoughSpace()
-{
-    QString sourceDrive = FmUtils::getDriveLetterFromPath( mSourceList.front() );
-    QString targetDrive = FmUtils::getDriveLetterFromPath( mTargetPath );
-    if ( sourceDrive == targetDrive &&
-            operationType() == FmOperationService::EOperationTypeMove ) {
-        return true;
-    } else {
-        return FmUtils::hasEnoughSpace( targetDrive, mTotalSize );
-    }
-}