diff -r 491b3ed49290 -r 65326cf895ed filemanager/src/filemanager/src/operationservice/fmoperationcopyormove.cpp --- 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 -#include -#include -#include - -/* \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 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 ); - } -}