filemanager/src/filemanager/src/operationservice/fmoperationcopy.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 "fmoperationcopy.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 
       
    30 FmOperationCopy::FmOperationCopy( QObject *parent, QStringList sourceList, QString targetPath ) :
       
    31         FmOperationBase( parent, FmOperationService::EOperationTypeCopy ), 
       
    32         mSourceList( sourceList ), mTargetPath( targetPath ),
       
    33         mStop( 0 ), mTotalSize( 0 ), mErrString( 0 ), mCopiedSize( 0 ), mTotalSteps( 100 ), mCurrentStep( 0 )
       
    34 {
       
    35 }
       
    36 
       
    37 FmOperationCopy::~FmOperationCopy()
       
    38 {
       
    39 }
       
    40 
       
    41 QStringList FmOperationCopy::sourceList()
       
    42 {
       
    43     return mSourceList;
       
    44 }
       
    45 
       
    46 QString FmOperationCopy::targetPath()
       
    47 {
       
    48     return mTargetPath;
       
    49 }
       
    50 
       
    51 int FmOperationCopy::start( volatile bool *isStopped, QString *errString )
       
    52 {
       
    53     mStop = isStopped;
       
    54     mErrString = errString;
       
    55     mTotalSize   = 0;
       
    56     mCopiedSize  = 0;
       
    57     mCurrentStep = 0;
       
    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 
       
    76     foreach( const QString& source, mSourceList ) {
       
    77         QFileInfo fi( source );
       
    78         if( !fi.exists() ) {
       
    79             *mErrString = source;
       
    80             ret = FmErrSrcPathDoNotExist;
       
    81             return ret;
       
    82         }
       
    83         QString newName;
       
    84         bool    isAcceptReplace = false;
       
    85         QFileInfo destFi( mTargetPath + fi.fileName() );
       
    86 
       
    87         // while for duplicated file/dir
       
    88         while( destFi.exists() ) {
       
    89             if( destFi.isFile() && destFi.absoluteFilePath().compare( fi.absoluteFilePath(), Qt::CaseInsensitive ) != 0 ) {
       
    90                 emit askForReplace( destFi.absoluteFilePath(), fi.absoluteFilePath(), &isAcceptReplace );
       
    91                 if( isAcceptReplace ) {
       
    92                     //delete src file
       
    93                     if( !QFile::remove( destFi.absoluteFilePath() ) ) {
       
    94                         *mErrString = destFi.absoluteFilePath();
       
    95                         ret = FmErrCannotRemove;
       
    96                         break;
       
    97                     }
       
    98                     destFi.setFile( destFi.absoluteFilePath() );
       
    99                 } else {
       
   100                     queryForRename( destFi.absoluteFilePath(), &newName );
       
   101                     if( newName.isEmpty() ) {
       
   102                         ret = FmErrCancel;
       
   103                         break;
       
   104                     }
       
   105                     QString targetName = mTargetPath + newName;
       
   106                     destFi.setFile( targetName );
       
   107                 }
       
   108             } else{
       
   109                 // destination is dir
       
   110                 queryForRename( destFi.absoluteFilePath(), &newName );
       
   111                 if( newName.isEmpty() ) {
       
   112                     ret = FmErrCancel;
       
   113                     break;
       
   114                 }
       
   115                 QString targetName = mTargetPath + newName;
       
   116                 destFi.setFile( targetName );
       
   117             }
       
   118         }
       
   119         if( ret != FmErrNone ) {
       
   120             return ret;
       
   121         }
       
   122         ret = copy( source, mTargetPath, newName );
       
   123         if( ret != FmErrNone ) {
       
   124             return ret;
       
   125         }
       
   126     }
       
   127     return FmErrNone;
       
   128 }
       
   129 
       
   130 
       
   131 
       
   132 int FmOperationCopy::copy( const QString &source, const QString &targetPath,
       
   133                           const QString &newTargetName )
       
   134 {        
       
   135     if( *mStop ) {
       
   136         return FmErrCancel;
       
   137     }
       
   138 
       
   139     QFileInfo fi( source );
       
   140     if( !fi.exists() ) {
       
   141         *mErrString = source;
       
   142         return FmErrSrcPathDoNotExist;
       
   143     }
       
   144     QString newName;
       
   145     if( !newTargetName.isEmpty() ) {
       
   146         newName = targetPath + newTargetName;
       
   147     } else {
       
   148         newName = targetPath + fi.fileName();
       
   149     }
       
   150 
       
   151     int ret = FmErrNone;
       
   152     
       
   153     if (fi.isFile()) {
       
   154         quint64 fileSize = fi.size();
       
   155         if ( !QFile::copy( source, newName )) {
       
   156             *mErrString = source;
       
   157             ret = FmErrCannotCopy;
       
   158         } else {
       
   159         increaseProgress( fileSize );
       
   160         }
       
   161     } else if (fi.isDir()) {
       
   162         ret = copyDirInsideContent( source, newName );
       
   163     } else {
       
   164         qWarning( "Things other than file and directory are not copied" );
       
   165         ret = FmErrIsNotFileOrFolder;
       
   166     }
       
   167 
       
   168     return ret;
       
   169 }
       
   170 
       
   171 
       
   172 
       
   173 int FmOperationCopy::copyDirInsideContent( const QString &srcPath, const QString &destPath )
       
   174 {
       
   175     QFileInfo srcInfo( srcPath );
       
   176     QFileInfo destInfo( destPath );
       
   177     
       
   178     QString destUpPath = FmUtils::fillPathWithSplash( destInfo.absolutePath() );
       
   179     if( destUpPath.contains( srcPath, Qt::CaseInsensitive ) ) {
       
   180         *mErrString = destPath;
       
   181         return FmErrCopyDestToSubFolderInSrc;
       
   182     }
       
   183 
       
   184     
       
   185     if( !srcInfo.isDir() || !srcInfo.exists() ) {
       
   186         *mErrString = srcPath;
       
   187         return FmErrSrcPathDoNotExist;
       
   188     }
       
   189     
       
   190     if( !destInfo.exists() ) {
       
   191         if( !destInfo.dir().mkdir( destInfo.absoluteFilePath() ) ) {
       
   192             *mErrString = destPath;
       
   193             return FmErrCannotMakeDir;
       
   194         }
       
   195     }    
       
   196 
       
   197     if( !srcInfo.isDir() ) {
       
   198         *mErrString = destPath;
       
   199         return FmErrCannotMakeDir;
       
   200     }
       
   201 
       
   202     //start to copy
       
   203     QFileInfoList infoList = QDir( srcPath ).entryInfoList( QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden | QDir::System );
       
   204     while( !infoList.isEmpty() ) {
       
   205         if( *mStop ) {
       
   206             return FmErrCancel;
       
   207         }
       
   208 
       
   209         QFileInfo fileInfo = infoList.takeFirst();
       
   210         if( fileInfo.isFile() ){
       
   211             //copy file
       
   212             QString newFilePath = destPath + fileInfo.absoluteFilePath().mid( srcPath.length() );
       
   213             if (!QFile::copy( fileInfo.absoluteFilePath(), newFilePath ) ) {
       
   214                 *mErrString = fileInfo.absoluteFilePath();
       
   215                 return FmErrCannotCopy;
       
   216             }
       
   217             increaseProgress( fileInfo.size() );
       
   218         } else if( fileInfo.isDir() ) {
       
   219             //makedir
       
   220             QString newDirPath = destPath + fileInfo.absoluteFilePath().mid( srcPath.length() );
       
   221             if( !QDir( newDirPath ).exists() && !QDir( destPath ).mkdir( newDirPath ) ) {
       
   222                 *mErrString = newDirPath;
       
   223                 return FmErrCannotMakeDir;
       
   224             }
       
   225             // add dir content to list.
       
   226             QFileInfoList infoListDir = QDir( fileInfo.absoluteFilePath() ).entryInfoList(
       
   227                 QDir::NoDotAndDotDot | QDir::AllEntries );
       
   228             while( !infoListDir.isEmpty() ) {
       
   229                 infoList.push_front( infoListDir.takeLast() );
       
   230             }
       
   231 
       
   232         } else {
       
   233             *mErrString = fileInfo.absoluteFilePath();
       
   234             return FmErrIsNotFileOrFolder;
       
   235         }
       
   236 
       
   237     }
       
   238 
       
   239     return FmErrNone;
       
   240 }
       
   241 
       
   242 void FmOperationCopy::increaseProgress( quint64 size )
       
   243 {
       
   244     if( mTotalSize <=0 ) {
       
   245         return;
       
   246     }
       
   247     mCopiedSize += size;
       
   248     int step = ( mCopiedSize * 100 ) / mTotalSize;
       
   249     if( step > mCurrentStep ) {
       
   250         mCurrentStep = step;
       
   251         emit notifyProgress( mCurrentStep );
       
   252     }
       
   253 }
       
   254 
       
   255 void FmOperationCopy::queryForRename( const QString &srcFile, QString *destFile )
       
   256 {
       
   257     emit askForRename( srcFile, destFile );
       
   258 }