filemanager/src/filemanager/src/operationservice/fmoperationmove.cpp
changeset 33 328cf6fbe40c
parent 32 39cf9ced4cc4
child 40 4167eb56f30d
equal deleted inserted replaced
32:39cf9ced4cc4 33:328cf6fbe40c
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include "fmoperationmove.h"
       
    19 #include "fmcommon.h"
       
    20 #include "fmoperationbase.h"
       
    21 #include "fmdrivedetailstype.h"
       
    22 #include "fmutils.h"
       
    23 
       
    24 #include <QDir>
       
    25 #include <QFileInfo>
       
    26 #include <QStringList>
       
    27 #include <QStack>
       
    28 
       
    29 FmOperationMove::FmOperationMove( QObject *parent, QStringList sourceList, QString targetPath  ) :
       
    30         FmOperationBase( parent, FmOperationService::EOperationTypeMove ),
       
    31         mSourceList( sourceList ), mTargetPath( targetPath ),
       
    32         mStop( 0 ), mTotalSize( 0 ), mErrString( 0 ), mMovedSize( 0 ), mTotalSteps( 100 ), mCurrentStep( 0 )
       
    33 {
       
    34 }
       
    35 
       
    36 FmOperationMove::~FmOperationMove()
       
    37 {
       
    38 }
       
    39 
       
    40 QStringList FmOperationMove::sourceList()
       
    41 {
       
    42     return mSourceList;
       
    43 }
       
    44 QString     FmOperationMove::targetPath()
       
    45 {
       
    46     return mTargetPath;
       
    47 }
       
    48 
       
    49 int FmOperationMove::start(  volatile bool *isStopped, QString *errString )
       
    50 {
       
    51     mStop = isStopped;
       
    52     mErrString = errString;
       
    53 
       
    54     mTotalSize   = 0;
       
    55     mMovedSize  = 0;
       
    56     mCurrentStep = 0;
       
    57 
       
    58     
       
    59     if( mSourceList.empty() ) {
       
    60         return FmErrWrongParam;
       
    61     }
       
    62 
       
    63     emit notifyPreparing( true );
       
    64 
       
    65     int numofFolders = 0;
       
    66     int numofFiles      = 0;
       
    67 
       
    68     int ret = FmFolderDetails::queryDetailOfContentList( mSourceList, numofFolders, 
       
    69         numofFiles, mTotalSize, mStop, true );
       
    70     if( ret != FmErrNone ) {
       
    71         return ret;
       
    72     }
       
    73 
       
    74     emit notifyStart( true, mTotalSteps );
       
    75     foreach( const QString& source, mSourceList ) {
       
    76         QFileInfo fi( source );
       
    77         if( !fi.exists() ) {
       
    78             *mErrString = source;
       
    79             ret = FmErrSrcPathDoNotExist;
       
    80             return ret;
       
    81         }
       
    82         QString newName;
       
    83         bool isAcceptReplace = false;
       
    84         QFileInfo destFi( mTargetPath + fi.fileName() );
       
    85         // while for duplicated file/dir
       
    86         while( destFi.exists() ) {
       
    87             if( destFi.isFile() && destFi.absoluteFilePath().compare( fi.absoluteFilePath(), Qt::CaseInsensitive ) != 0  ) {
       
    88                 emit askForReplace( destFi.absoluteFilePath(), fi.absoluteFilePath(), &isAcceptReplace );
       
    89                 if( isAcceptReplace ) {
       
    90                     //delete src file
       
    91                     if( !QFile::remove( destFi.absoluteFilePath() ) ) {
       
    92                         *mErrString = destFi.absoluteFilePath();
       
    93                         ret = FmErrCannotRemove;
       
    94                         break;
       
    95                     }
       
    96                     destFi.setFile( destFi.absoluteFilePath() );
       
    97                 } else {
       
    98                     queryForRename( destFi.absoluteFilePath(), &newName );
       
    99                     if( newName.isEmpty() ) {
       
   100                         ret = FmErrCancel;
       
   101                         break;
       
   102                     }
       
   103                     QString targetName = mTargetPath + newName;
       
   104                     destFi.setFile( targetName );
       
   105                 }
       
   106             } else{
       
   107                 // destination is dir
       
   108                 queryForRename( destFi.absoluteFilePath(), &newName );
       
   109                 if( newName.isEmpty() ) {
       
   110                     ret = FmErrCancel;
       
   111                     break;
       
   112                 }
       
   113                 QString targetName = mTargetPath + newName;
       
   114                 destFi.setFile( targetName );
       
   115             }
       
   116         }
       
   117         if( ret != FmErrNone ) {
       
   118             return ret;
       
   119         }
       
   120 
       
   121         int ret = move( source, mTargetPath, newName );
       
   122         if( ret != FmErrNone ) {
       
   123             return ret;
       
   124         }
       
   125     }
       
   126     return FmErrNone;
       
   127 }
       
   128 
       
   129 int FmOperationMove::move( const QString &source, const QString &targetPath, const QString &newTargetName )
       
   130 {
       
   131     if( *mStop ) {
       
   132         return FmErrCancel;
       
   133     }
       
   134 
       
   135     QFileInfo fi( source );
       
   136     if( !fi.exists() ) {
       
   137         *mErrString = source;
       
   138         return FmErrSrcPathDoNotExist;
       
   139     }
       
   140     QString newName;
       
   141     if( !newTargetName.isEmpty() ) {
       
   142         newName = targetPath + newTargetName;
       
   143     } else {
       
   144         newName = targetPath + fi.fileName();
       
   145     }
       
   146 
       
   147     int ret = FmErrNone;
       
   148     if (fi.isFile()) {
       
   149         int fileSize = fi.size();
       
   150         if ( !QFile::copy( source, newName )) {
       
   151             *mErrString = source;
       
   152             ret = FmErrCannotCopy;
       
   153         }
       
   154         if( !QFile::remove( source ) ) {
       
   155             *mErrString = source;
       
   156             ret = FmErrCannotRemove;
       
   157         }
       
   158         increaseProgress( fileSize );
       
   159     } else if (fi.isDir()) {
       
   160         if( FmUtils::isDefaultFolder( source ) ){
       
   161             ret = FmErrRemoveDefaultFolder;
       
   162         }
       
   163         else{
       
   164             ret = moveDirInsideContent( source, newName );
       
   165         }
       
   166         
       
   167         if( ret!= FmErrNone ) {
       
   168             return ret;
       
   169         }
       
   170         if ( !fi.dir().rmdir( fi.absoluteFilePath() ) ) {
       
   171             *mErrString = fi.absolutePath();
       
   172             return FmErrCannotRemove;
       
   173         }
       
   174     } else {
       
   175         qWarning( "Things other than file and directory are not copied" );
       
   176         ret = FmErrIsNotFileOrFolder;
       
   177     }
       
   178 
       
   179     return ret;
       
   180 }
       
   181 int FmOperationMove::moveDirInsideContent( const QString &srcPath, const QString &destPath )
       
   182 {
       
   183     QFileInfo srcInfo( srcPath );
       
   184     QFileInfo destInfo( destPath );
       
   185         
       
   186     QString destUpPath = FmUtils::fillPathWithSplash( destInfo.absolutePath() );
       
   187     if( destUpPath.contains( srcPath, Qt::CaseInsensitive ) ) {
       
   188         *mErrString = destPath;
       
   189         return FmErrMoveDestToSubFolderInSrc;
       
   190     }
       
   191     
       
   192     if( !srcInfo.isDir() || !srcInfo.exists() ) {
       
   193         *mErrString = srcPath;
       
   194         return FmErrSrcPathDoNotExist;
       
   195     }
       
   196     
       
   197     if( !destInfo.exists() ) {
       
   198         if( !destInfo.dir().mkdir( destInfo.absoluteFilePath() ) ) {
       
   199             *mErrString = destPath;
       
   200             return FmErrCannotMakeDir;
       
   201         }
       
   202     }
       
   203     if( !srcInfo.isDir() ) {
       
   204         *mErrString = destPath;
       
   205         return FmErrCannotMakeDir;
       
   206     }
       
   207 
       
   208     //start to move
       
   209     QFileInfoList infoList = QDir( srcPath ).entryInfoList( QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden | QDir::System  );
       
   210     while( !infoList.isEmpty() ) {
       
   211         if( *mStop ) {
       
   212             return FmErrCancel;
       
   213         }
       
   214 
       
   215         QFileInfo fileInfo = infoList.takeFirst();
       
   216         if( fileInfo.isFile() ){
       
   217             //copy file
       
   218             quint64 fileSize = fileInfo.size();
       
   219             QString newFilePath = destPath + fileInfo.absoluteFilePath().mid( srcPath.length() );
       
   220             if (!QFile::copy( fileInfo.absoluteFilePath(), newFilePath ) ) {
       
   221                  *mErrString = fileInfo.absoluteFilePath();
       
   222                 return FmErrCannotCopy;
       
   223             }
       
   224             if( !QFile::remove( fileInfo.absoluteFilePath() ) ) {
       
   225                 *mErrString = fileInfo.absoluteFilePath();
       
   226                 return FmErrCannotRemove;
       
   227             }
       
   228             increaseProgress( fileSize );
       
   229         } else if( fileInfo.isDir() ) {
       
   230             //makedir
       
   231             QString newDirPath = destPath + fileInfo.absoluteFilePath().mid( srcPath.length() );
       
   232             if( !QDir( newDirPath ).exists() && !QDir( destPath ).mkdir( newDirPath ) ) {
       
   233                 *mErrString = newDirPath;
       
   234                 return FmErrCannotMakeDir;
       
   235             }
       
   236             // add dir content to list.
       
   237             QFileInfoList infoListDir = QDir( fileInfo.absoluteFilePath() ).entryInfoList(
       
   238                 QDir::NoDotAndDotDot | QDir::AllEntries );
       
   239             if( infoListDir.isEmpty() ) {
       
   240                 if ( !fileInfo.dir().rmdir( fileInfo.absoluteFilePath() ) ) {
       
   241                     *mErrString = fileInfo.absolutePath();
       
   242                     return FmErrCannotRemove;
       
   243                 }
       
   244             } else {
       
   245                 infoList.push_front( fileInfo );
       
   246             }
       
   247             while( !infoListDir.isEmpty() ) {
       
   248                 infoList.push_front( infoListDir.takeLast() );
       
   249             }
       
   250 
       
   251         } else {
       
   252             *mErrString = fileInfo.absoluteFilePath();
       
   253             return FmErrIsNotFileOrFolder;
       
   254         }
       
   255 
       
   256     }
       
   257 
       
   258     return FmErrNone;
       
   259 }
       
   260 
       
   261 void FmOperationMove::increaseProgress( quint64 size )
       
   262 {
       
   263     if( mTotalSize <=0 ) {
       
   264         return;
       
   265     }
       
   266     mMovedSize += size;
       
   267     int step = ( mMovedSize * 100 ) / mTotalSize;
       
   268     if( step > mCurrentStep ) {
       
   269         mCurrentStep = step;
       
   270         emit notifyProgress( mCurrentStep );
       
   271     }
       
   272 }
       
   273 
       
   274 void FmOperationMove::queryForRename( const QString &srcFile, QString *destFile )
       
   275 {
       
   276     emit askForRename( srcFile, destFile );
       
   277 }