48 #include <QtCore/QTimer>
49 #include <QtCore/QFile>
60 #define REPORT_TIMEOUT 200
105 , m_defaultPermissions(
false)
108 , m_asMethod(asMethod)
114 , m_fileProcessedSize(0)
115 , m_processedFiles(0)
118 , m_currentStatSrc(m_srcList.constBegin())
119 , m_bCurrentOperationIsLink(
false)
120 , m_bSingleFileCopy(
false)
123 , m_bAutoRenameFiles(
false)
124 , m_bAutoRenameDirs(
false)
125 , m_bAutoSkipFiles(
false )
126 , m_bAutoSkipDirs(
false )
127 , m_bOverwriteAllFiles(
false )
128 , m_bOverwriteAllDirs(
false )
142 bool m_defaultPermissions;
147 QLinkedList<CopyInfo> m_directoriesCopied;
148 QLinkedList<CopyInfo>::const_iterator m_directoriesCopiedIterator;
160 int m_processedFiles;
162 QList<CopyInfo> files;
163 QList<CopyInfo>
dirs;
167 KUrl::List::const_iterator m_currentStatSrc;
168 bool m_bCurrentSrcIsDir;
169 bool m_bCurrentOperationIsLink;
170 bool m_bSingleFileCopy;
176 QSet<QString> m_overwriteList;
177 bool m_bAutoRenameFiles;
178 bool m_bAutoRenameDirs;
179 bool m_bAutoSkipFiles;
180 bool m_bAutoSkipDirs;
181 bool m_bOverwriteAllFiles;
182 bool m_bOverwriteAllDirs;
185 QTimer *m_reportTimer;
189 KUrl m_currentSrcURL;
190 KUrl m_currentDestURL;
192 QSet<QString> m_parentDirs;
194 void statCurrentSrc();
198 void slotResultStating(
KJob * job );
199 void startListing(
const KUrl & src );
200 void slotResultCreatingDirs(
KJob * job );
201 void slotResultConflictCreatingDirs(
KJob * job );
202 void createNextDir();
203 void slotResultCopyingFiles(
KJob * job );
204 void slotResultConflictCopyingFiles(
KJob * job );
206 KIO::Job* linkNextFile(
const KUrl& uSource,
const KUrl& uDest, JobFlags flags );
208 void slotResultDeletingDirs(
KJob * job );
209 void deleteNextDir();
210 void sourceStated(
const UDSEntry& entry,
const KUrl& sourceUrl);
211 void skip(
const KUrl & sourceURL,
bool isDir);
212 void slotResultRenaming(
KJob * job );
213 void slotResultSettingDirAttributes(
KJob * job );
214 void setNextDirAttribute();
216 void startRenameJob(
const KUrl &slave_url);
217 bool shouldOverwriteDir(
const QString& path )
const;
218 bool shouldOverwriteFile(
const QString& path )
const;
219 bool shouldSkip(
const QString& path )
const;
220 void skipSrc(
bool isDir);
224 void addCopyInfoFromUDSEntry(
const UDSEntry& entry,
const KUrl& srcUrl,
bool srcIsDir,
const KUrl& currentDest);
228 void slotProcessedSize(
KJob*, qulonglong data_size );
233 void slotTotalSize(
KJob*, qulonglong size );
240 CopyJob::CopyMode mode,
bool asMethod, JobFlags flags)
242 CopyJob *job =
new CopyJob(*
new CopyJobPrivate(src,dest,mode,asMethod));
247 job->d_func()->m_bOverwriteAllDirs =
true;
248 job->d_func()->m_bOverwriteAllFiles =
true;
257 setProperty(
"destUrl", d_func()->m_dest.url());
258 QTimer::singleShot(0,
this, SLOT(slotStart()));
267 return d_func()->m_srcList;
272 return d_func()->m_dest;
275 void CopyJobPrivate::slotStart()
283 m_reportTimer =
new QTimer(q);
285 q->connect(m_reportTimer,SIGNAL(
timeout()),q,SLOT(slotReport()));
297 void CopyJobPrivate::slotResultStating(
KJob *job )
310 kDebug(7007) <<
"Error while stating source. Activating hack";
311 q->removeSubjob( job );
312 assert ( !q->hasSubjobs() );
315 info.
mtime = (time_t) -1;
316 info.
ctime = (time_t) -1;
321 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
324 files.append( info );
330 q->Job::slotResult( job );
338 if ( m_dest.isLocalFile() ) {
339 QString path = m_dest.toLocalFile();
342 m_freeSpace = KDiskFreeSpaceInfo::freeSpaceInfo( path ).available();
348 const bool isGlobalDest = m_dest == m_globalDest;
349 const bool isDir = entry.
isDir();
362 m_dest.setPath(sLocalPath);
364 m_globalDest = m_dest;
368 m_globalDestinationState = destinationState;
370 q->removeSubjob( job );
371 assert ( !q->hasSubjobs() );
376 sourceStated(entry, static_cast<SimpleJob*>(job)->url());
377 q->removeSubjob( job );
381 void CopyJobPrivate::sourceStated(
const UDSEntry& entry,
const KUrl& sourceUrl)
384 const bool isDir = entry.
isDir();
403 kDebug() <<
"Using sLocalPath. destinationState=" << destinationState;
410 addCopyInfoFromUDSEntry(entry, srcurl,
false, m_dest);
412 m_currentDest = m_dest;
413 m_bCurrentSrcIsDir =
false;
424 m_parentDirs.insert(parentDir);
427 m_bCurrentSrcIsDir =
true;
437 if (!sName.isEmpty())
441 if (!dispName.isEmpty())
442 directory = dispName;
443 else if (!sName.isEmpty())
446 m_currentDest.addPath( directory );
456 if ( m_dest == m_globalDest )
457 m_globalDestinationState = destinationState;
460 startListing( srcurl );
468 m_parentDirs.insert(parentDir);
482 void CopyJobPrivate::slotReport()
485 if ( q->isSuspended() )
493 q->setProcessedAmount(
KJob::Files, m_processedFiles );
500 emitMoving(q, m_currentSrcURL, m_currentDestURL);
501 emit q->moving( q, m_currentSrcURL, m_currentDestURL);
505 emitCopying( q, m_currentSrcURL, m_currentDestURL );
506 emit q->linking( q, m_currentSrcURL.path(), m_currentDestURL );
510 emitCopying( q, m_currentSrcURL, m_currentDestURL );
511 emit q->copying( q, m_currentSrcURL, m_currentDestURL );
521 emit q->creatingDir( q, m_currentDestURL );
522 emitCreatingDir( q, m_currentDestURL );
533 emitMoving( q, m_currentSrcURL, m_currentDestURL );
537 emitCopying( q, m_currentSrcURL, m_currentDestURL );
553 UDSEntryList::ConstIterator it = list.constBegin();
554 UDSEntryList::ConstIterator
end = list.constEnd();
555 for (; it != end; ++it) {
557 addCopyInfoFromUDSEntry(entry, static_cast<SimpleJob *>(job)->url(), m_bCurrentSrcIsDir, m_currentDest);
561 void CopyJobPrivate::addCopyInfoFromUDSEntry(
const UDSEntry& entry,
const KUrl& srcUrl,
bool srcIsDir,
const KUrl& currentDest)
569 m_totalSize += info.size;
575 if (!urlStr.isEmpty())
578 const bool isDir = entry.
isDir();
581 if (fileName != QLatin1String(
"..") && fileName != QLatin1String(
".")) {
582 const bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty();
593 url =
KUrl(localPath);
597 info.uDest = currentDest;
611 int numberOfSlashes = fileName.count(
'/');
614 for (
int n = 0; n < numberOfSlashes + 1; ++n) {
615 pos = path.lastIndexOf(
'/', pos - 1);
617 kWarning(7007) <<
"kioslave bug: not enough slashes in UDS_URL" << path <<
"- looking for" << numberOfSlashes <<
"slashes";
622 destFileName = path.mid(pos + 1);
626 destFileName = fileName;
629 destFileName = displayName.isEmpty() ? fileName : displayName;
635 if (destFileName.isEmpty()) {
640 info.uDest.addPath(destFileName);
644 if (info.linkDest.isEmpty() && isDir && m_mode !=
CopyJob::Link) {
647 dirsToRemove.append(info.uSource);
655 void CopyJobPrivate::skipSrc(
bool isDir)
657 m_dest = m_globalDest;
658 destinationState = m_globalDestinationState;
659 skip(*m_currentStatSrc, isDir);
664 void CopyJobPrivate::statNextSrc()
670 m_dest = m_globalDest;
671 destinationState = m_globalDestinationState;
676 void CopyJobPrivate::statCurrentSrc()
679 if (m_currentStatSrc != m_srcList.constEnd()) {
680 m_currentSrcURL = (*m_currentStatSrc);
684 m_currentDest = m_dest;
687 info.mtime = (time_t) -1;
688 info.ctime = (time_t) -1;
690 info.uSource = m_currentSrcURL;
691 info.uDest = m_currentDest;
693 if (destinationState ==
DEST_IS_DIR && !m_asMethod) {
695 (m_currentSrcURL.protocol() == info.uDest.protocol()) &&
696 (m_currentSrcURL.host() == info.uDest.host()) &&
697 (m_currentSrcURL.port() == info.uDest.port()) &&
698 (m_currentSrcURL.user() == info.uDest.user()) &&
699 (m_currentSrcURL.pass() == info.uDest.pass()) ) {
701 info.uDest.addPath( m_currentSrcURL.fileName() );
709 files.append( info );
717 if (!cachedItem.
isNull()) {
718 entry = cachedItem.
entry();
721 m_currentSrcURL = cachedItem.
mostLocalUrl(dummyIsLocal);
732 if ( (m_currentSrcURL.protocol() == m_dest.protocol()) &&
733 (m_currentSrcURL.host() == m_dest.host()) &&
734 (m_currentSrcURL.port() == m_dest.port()) &&
735 (m_currentSrcURL.user() == m_dest.user()) &&
736 (m_currentSrcURL.pass() == m_dest.pass()) )
738 startRenameJob( m_currentSrcURL );
743 startRenameJob( m_dest );
748 startRenameJob( m_currentSrcURL );
755 QPointer<CopyJob> that = q;
762 m_bOnlyRenames =
false;
767 kDebug(7007) <<
"fast path! found info about" << m_currentSrcURL <<
"in KDirLister";
768 sourceStated(entry, m_currentSrcURL);
777 m_currentDestURL = m_dest;
788 kDebug(7007)<<
"Stating finished. To copy:"<<m_totalSize<<
", available:"<<m_freeSpace;
792 emit q->aboutToCreate( q, dirs );
793 if (!files.isEmpty())
794 emit q->aboutToCreate( q, files );
796 m_bSingleFileCopy = ( files.count() == 1 &&
dirs.isEmpty() );
803 void CopyJobPrivate::startRenameJob(
const KUrl& slave_url )
808 if (m_currentSrcURL.isLocalFile()) {
810 if (!m_parentDirs.contains(parentDir)) {
812 m_parentDirs.insert(parentDir);
818 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
819 dest.
addPath( m_currentSrcURL.fileName() );
820 m_currentDestURL = dest;
821 kDebug(7007) << m_currentSrcURL <<
"->" << dest <<
"trying direct rename first";
826 info.mtime = (time_t) -1;
827 info.ctime = (time_t) -1;
829 info.uSource = m_currentSrcURL;
831 QList<CopyInfo> files;
833 emit q->aboutToCreate( q, files );
835 KIO_ARGS << m_currentSrcURL << dest << (qint8)
false ;
838 q->addSubjob( newJob );
839 if ( m_currentSrcURL.directory() != dest.directory() )
840 m_bOnlyRenames =
false;
843 void CopyJobPrivate::startListing(
const KUrl & src )
852 q->addSubjob( newjob );
855 void CopyJobPrivate::skip(
const KUrl & sourceUrl,
bool isDir)
862 while (dirsToRemove.removeAll(dir) > 0) {
869 bool CopyJobPrivate::shouldOverwriteDir(
const QString& path )
const
871 if ( m_bOverwriteAllDirs )
873 return m_overwriteList.contains(path);
876 bool CopyJobPrivate::shouldOverwriteFile(
const QString& path )
const
878 if ( m_bOverwriteAllFiles )
880 return m_overwriteList.contains(path);
883 bool CopyJobPrivate::shouldSkip(
const QString& path )
const
885 Q_FOREACH(
const QString& skipPath, m_skipList) {
886 if ( path.startsWith(skipPath) )
892 void CopyJobPrivate::slotResultCreatingDirs(
KJob * job )
896 QList<CopyInfo>::Iterator it =
dirs.begin();
900 m_conflictError = job->
error();
906 if ( m_bAutoSkipDirs ) {
913 const QString destDir = (*it).uDest.path();
914 if ( shouldOverwriteDir( destDir ) ) {
915 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
918 if (m_bAutoRenameDirs) {
921 KUrl destDirectory((*it).uDest);
922 destDirectory.setPath(destDirectory.directory());
925 KUrl newUrl((*it).uDest);
926 newUrl.setFileName(newName);
928 emit q->renamed(q, (*it).uDest, newUrl);
934 QList<CopyInfo>::Iterator renamedirit = it;
937 for(; renamedirit !=
dirs.end() ; ++renamedirit) {
938 QString path = (*renamedirit).uDest.path();
939 if (path.startsWith(oldPath)) {
941 n.replace(0, oldPath.length(), newPath);
942 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
943 <<
"was going to be" << path
944 <<
", changed into" << n;
945 (*renamedirit).uDest.setPath(n);
949 QList<CopyInfo>::Iterator renamefileit = files.begin();
950 for(; renamefileit != files.end() ; ++renamefileit) {
951 QString path = (*renamefileit).uDest.path();
952 if (path.startsWith(oldPath)) {
954 n.replace(0, oldPath.length(), newPath);
955 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
956 <<
"was going to be" << path
957 <<
", changed into" << n;
958 (*renamefileit).uDest.setPath(n);
961 if (!
dirs.isEmpty()) {
962 emit q->aboutToCreate(q, dirs);
964 if (!files.isEmpty()) {
965 emit q->aboutToCreate(q, files);
970 if (!q->isInteractive()) {
971 q->Job::slotResult(job);
975 assert(((
SimpleJob*)job)->url().url() == (*it).uDest.
url());
976 q->removeSubjob(job);
977 assert (!q->hasSubjobs());
980 KUrl existingDest((*it).uDest);
983 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingDest;
985 q->addSubjob(newJob);
994 q->Job::slotResult( job );
1001 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true,
false );
1002 m_directoriesCopied.append( *it );
1008 q->removeSubjob( job );
1009 assert( !q->hasSubjobs() );
1013 void CopyJobPrivate::slotResultConflictCreatingDirs(
KJob * job )
1019 QList<CopyInfo>::Iterator it =
dirs.begin();
1030 q->removeSubjob( job );
1031 assert ( !q->hasSubjobs() );
1038 if( (*it).uSource == (*it).uDest ||
1039 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1046 QString existingDest = (*it).uDest.path();
1049 m_reportTimer->stop();
1051 (*it).uSource.url(),
1054 (*it).size, destsize,
1055 (*it).ctime, destctime,
1056 (*it).mtime, destmtime );
1065 m_bAutoRenameDirs =
true;
1070 KUrl newUrl( (*it).uDest );
1071 newUrl.setPath( newPath );
1072 emit q->renamed( q, (*it).uDest, newUrl );
1077 QList<CopyInfo>::Iterator renamedirit = it;
1080 for( ; renamedirit !=
dirs.end() ; ++renamedirit )
1082 QString path = (*renamedirit).uDest.path();
1083 if ( path.startsWith( oldPath ) ) {
1085 n.replace( 0, oldPath.length(), newPath );
1086 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
1087 <<
"was going to be" << path
1088 <<
", changed into" << n;
1089 (*renamedirit).uDest.setPath( n );
1093 QList<CopyInfo>::Iterator renamefileit = files.begin();
1094 for( ; renamefileit != files.end() ; ++renamefileit )
1096 QString path = (*renamefileit).uDest.path();
1097 if ( path.startsWith( oldPath ) ) {
1099 n.replace( 0, oldPath.length(), newPath );
1100 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
1101 <<
"was going to be" << path
1102 <<
", changed into" << n;
1103 (*renamefileit).uDest.setPath( n );
1106 if (!
dirs.isEmpty())
1107 emit q->aboutToCreate( q, dirs );
1108 if (!files.isEmpty())
1109 emit q->aboutToCreate( q, files );
1113 m_bAutoSkipDirs =
true;
1116 m_skipList.append( existingDest );
1117 skip((*it).uSource,
true);
1123 m_overwriteList.insert( existingDest );
1124 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1130 m_bOverwriteAllDirs =
true;
1131 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1144 void CopyJobPrivate::createNextDir()
1148 if ( !
dirs.isEmpty() )
1151 QList<CopyInfo>::Iterator it =
dirs.begin();
1153 while( it !=
dirs.end() && udir.isEmpty() )
1156 if ( shouldSkip( dir ) ) {
1163 if ( !udir.isEmpty() )
1169 if (shouldOverwriteFile(udir.
path())) {
1173 m_currentDestURL = udir;
1176 q->addSubjob(newjob);
1188 for ( QSet<QString>::const_iterator it = m_parentDirs.constBegin() ; it != m_parentDirs.constEnd() ; ++it )
1198 void CopyJobPrivate::slotResultCopyingFiles(
KJob * job )
1202 QList<CopyInfo>::Iterator it = files.begin();
1206 if ( m_bAutoSkipFiles )
1208 skip((*it).uSource,
false);
1209 m_fileProcessedSize = (*it).size;
1214 m_conflictError = job->
error();
1220 if (m_bAutoRenameFiles) {
1221 KUrl destDirectory((*it).uDest);
1222 destDirectory.setPath(destDirectory.directory());
1225 KUrl newUrl((*it).uDest);
1226 newUrl.setFileName(newName);
1228 emit q->renamed(q, (*it).uDest, newUrl);
1229 (*it).uDest = newUrl;
1231 QList<CopyInfo> files;
1233 emit q->aboutToCreate(q, files);
1236 if ( !q->isInteractive() ) {
1237 q->Job::slotResult( job );
1241 q->removeSubjob(job);
1242 assert (!q->hasSubjobs());
1244 KUrl existingFile((*it).uDest);
1247 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingFile;
1249 q->addSubjob(newJob);
1255 if ( m_bCurrentOperationIsLink && qobject_cast<KIO::DeleteJob*>( job ) )
1259 m_fileProcessedSize = (*it).size;
1262 if ( !q->isInteractive() ) {
1263 q->Job::slotResult( job );
1268 slotResultConflictCopyingFiles( job );
1277 && !qobject_cast<KIO::DeleteJob *>( job )
1280 q->removeSubjob( job );
1281 assert ( !q->hasSubjobs() );
1285 q->addSubjob( newjob );
1289 if ( m_bCurrentOperationIsLink )
1293 emit q->copyingLinkDone( q, (*it).uSource, target, (*it).uDest );
1297 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
false,
false );
1302 m_successSrcList.append((*it).uSource);
1304 m_freeSpace -= (*it).size;
1314 m_processedSize += m_fileProcessedSize;
1315 m_fileProcessedSize = 0;
1322 m_incomingMetaData += kiojob->
metaData();
1323 q->removeSubjob( job );
1324 assert( !q->hasSubjobs() );
1328 void CopyJobPrivate::slotResultConflictCopyingFiles(
KJob * job )
1333 QList<CopyInfo>::Iterator it = files.begin();
1339 m_reportTimer->stop();
1362 if ( (*it).uSource == (*it).uDest ||
1363 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1371 if ( !m_bSingleFileCopy )
1374 res = q->ui()->askFileRename( q, !isDir ?
1375 i18n(
"File Already Exists") :
i18n(
"Already Exists as Folder"),
1376 (*it).uSource.url(),
1379 (*it).size, destsize,
1380 (*it).ctime, destctime,
1381 (*it).mtime, destmtime );
1388 else if ( !q->isInteractive() ) {
1389 q->Job::slotResult( job );
1407 q->removeSubjob( job );
1408 assert ( !q->hasSubjobs() );
1415 m_bAutoRenameFiles =
true;
1419 KUrl newUrl( (*it).uDest );
1420 newUrl.setPath( newPath );
1421 emit q->renamed( q, (*it).uDest, newUrl );
1422 (*it).uDest = newUrl;
1424 QList<CopyInfo> files;
1426 emit q->aboutToCreate( q, files );
1430 m_bAutoSkipFiles =
true;
1434 skip((*it).uSource,
false);
1435 m_processedSize += (*it).size;
1440 m_bOverwriteAllFiles =
true;
1444 m_overwriteList.insert( (*it).uDest.path() );
1453 KIO::Job* CopyJobPrivate::linkNextFile(
const KUrl& uSource,
const KUrl& uDest, JobFlags flags )
1458 (uSource.host() == uDest.host()) &&
1459 (uSource.port() == uDest.port()) &&
1460 (uSource.
user() == uDest.
user()) &&
1468 m_bCurrentOperationIsLink =
true;
1469 m_currentSrcURL=uSource;
1470 m_currentDestURL=uDest;
1483 if (
f.open( QIODevice::ReadWrite ) )
1492 config.
writeEntry(
"Type", QString::fromLatin1(
"Link") );
1494 if ( protocol == QLatin1String(
"ftp") )
1495 config.
writeEntry(
"Icon", QString::fromLatin1(
"folder-remote") );
1496 else if ( protocol == QLatin1String(
"http") )
1497 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-html") );
1498 else if ( protocol == QLatin1String(
"info") )
1499 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-x-texinfo") );
1500 else if ( protocol == QLatin1String(
"mailto") )
1501 config.
writeEntry(
"Icon", QString::fromLatin1(
"internet-mail") );
1503 config.
writeEntry(
"Icon", QString::fromLatin1(
"unknown") );
1505 files.erase( files.begin() );
1513 kDebug(7007) <<
"ERR_CANNOT_OPEN_FOR_WRITING";
1529 void CopyJobPrivate::copyNextFile()
1532 bool bCopyFile =
false;
1535 QList<CopyInfo>::Iterator it = files.begin();
1537 while (it != files.end() && !bCopyFile)
1539 const QString destFile = (*it).uDest.path();
1540 bCopyFile = !shouldSkip( destFile );
1551 if (m_freeSpace < (*it).size) {
1559 const KUrl& uSource = (*it).uSource;
1560 const KUrl& uDest = (*it).uDest;
1565 if ( uDest == uSource )
1568 bOverwrite = shouldOverwriteFile( destFile );
1570 m_bCurrentOperationIsLink =
false;
1575 newjob = linkNextFile(uSource, uDest, flags);
1578 }
else if ( !(*it).linkDest.isEmpty() &&
1580 (uSource.host() == uDest.host()) &&
1581 (uSource.port() == uDest.port()) &&
1582 (uSource.
user() == uDest.
user()) &&
1591 m_currentSrcURL =
KUrl( (*it).linkDest );
1592 m_currentDestURL = uDest;
1596 m_bCurrentOperationIsLink =
true;
1603 if ((*it).mtime != -1) {
1609 m_currentSrcURL=uSource;
1610 m_currentDestURL=uDest;
1619 int permissions = (*it).permissions;
1620 if ( m_defaultPermissions || ( remoteSource && uDest.
isLocalFile() ) )
1626 if ((*it).mtime != -1) {
1631 m_currentSrcURL=uSource;
1632 m_currentDestURL=uDest;
1635 q->addSubjob(newjob);
1636 q->connect( newjob, SIGNAL(processedSize(
KJob*,qulonglong)),
1637 SLOT(slotProcessedSize(
KJob*,qulonglong)) );
1638 q->connect( newjob, SIGNAL(totalSize(
KJob*,qulonglong)),
1639 SLOT(slotTotalSize(
KJob*,qulonglong)) );
1649 void CopyJobPrivate::deleteNextDir()
1657 KUrl::List::Iterator it = --dirsToRemove.end();
1660 dirsToRemove.erase(it);
1661 q->addSubjob( job );
1667 m_directoriesCopiedIterator = m_directoriesCopied.constBegin();
1668 setNextDirAttribute();
1672 void CopyJobPrivate::setNextDirAttribute()
1675 while (m_directoriesCopiedIterator != m_directoriesCopied.constEnd() &&
1676 (*m_directoriesCopiedIterator).mtime == -1) {
1677 ++m_directoriesCopiedIterator;
1679 if ( m_directoriesCopiedIterator != m_directoriesCopied.constEnd() ) {
1680 const KUrl url = (*m_directoriesCopiedIterator).uDest;
1681 const time_t mtime = (*m_directoriesCopiedIterator).mtime;
1682 const QDateTime dt = QDateTime::fromTime_t(mtime);
1683 ++m_directoriesCopiedIterator;
1687 q->addSubjob( job );
1690 #if 0 // ifdef Q_OS_UNIX
1694 QLinkedList<CopyInfo>::const_iterator it = m_directoriesCopied.constBegin();
1695 for ( ; it != m_directoriesCopied.constEnd() ; ++it ) {
1696 const KUrl& url = (*it).uDest;
1697 if ( url.
isLocalFile() && (*it).mtime != (time_t)-1 ) {
1698 KDE_struct_stat statbuf;
1700 struct utimbuf utbuf;
1701 utbuf.actime = statbuf.st_atime;
1702 utbuf.modtime = (*it).mtime;
1703 utime( path, &utbuf );
1708 m_directoriesCopied.clear();
1713 m_reportTimer->stop();
1727 if (!d->m_bOnlyRenames) {
1728 KUrl url(d->m_globalDest);
1729 if (d->m_globalDestinationState !=
DEST_IS_DIR || d->m_asMethod)
1734 if (d->m_mode ==
CopyJob::Move && !d->m_successSrcList.isEmpty()) {
1735 kDebug(7007) <<
"KDirNotify'ing FilesRemoved" << d->m_successSrcList.toStringList();
1741 for (QSet<QString>::const_iterator it = d->m_parentDirs.constBegin() ; it != d->m_parentDirs.constEnd() ; ++it)
1748 void CopyJobPrivate::slotProcessedSize(
KJob*, qulonglong data_size )
1752 m_fileProcessedSize = data_size;
1753 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1755 if ( m_processedSize + m_fileProcessedSize > m_totalSize )
1758 m_totalSize = m_processedSize + m_fileProcessedSize;
1763 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1766 void CopyJobPrivate::slotTotalSize(
KJob*, qulonglong size )
1774 if ( m_bSingleFileCopy && size != m_totalSize)
1782 void CopyJobPrivate::slotResultDeletingDirs(
KJob * job )
1790 m_successSrcList.append(static_cast<KIO::SimpleJob*>(job)->url());
1792 q->removeSubjob( job );
1793 assert( !q->hasSubjobs() );
1797 void CopyJobPrivate::slotResultSettingDirAttributes(
KJob * job )
1806 q->removeSubjob( job );
1807 assert( !q->hasSubjobs() );
1808 setNextDirAttribute();
1812 void CopyJobPrivate::slotResultRenaming(
KJob* job )
1815 int err = job->
error();
1820 m_incomingMetaData += kiojob->
metaData();
1821 q->removeSubjob( job );
1822 assert ( !q->hasSubjobs() );
1825 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
1826 dest.
addPath( m_currentSrcURL.fileName() );
1838 kDebug(7007) <<
"Couldn't rename directly, dest already exists. Detected special case of lower/uppercase renaming in same dir, try with 2 rename calls";
1839 const QString _src( m_currentSrcURL.toLocalFile() );
1840 const QString _dest( dest.toLocalFile() );
1844 const bool openOk = tmpFile.open();
1846 kWarning(7007) <<
"Couldn't open temp file in" << _tmpPrefix;
1848 const QString _tmp( tmpFile.fileName() );
1851 kDebug(7007) <<
"KTemporaryFile using" << _tmp <<
"as intermediary";
1854 if (!QFile::exists( _dest ) &&
KDE::rename(_tmp, _dest) == 0) {
1858 kDebug(7007) <<
"Didn't manage to rename" << _tmp <<
"to" << _dest <<
", reverting";
1861 kError(7007) <<
"Couldn't rename" << _tmp <<
"back to" << _src <<
'!';
1863 q->Job::slotResult(job);
1868 kDebug(7007) <<
"mv" << _src << _tmp <<
"failed:" << strerror(errno);
1889 if ((isDir && m_bAutoSkipDirs) || (!isDir && m_bAutoSkipFiles)) {
1893 }
else if ((isDir && m_bOverwriteAllDirs) || (!isDir && m_bOverwriteAllFiles)) {
1895 }
else if ((isDir && m_bAutoRenameDirs) || (!isDir && m_bAutoRenameFiles)) {
1896 KUrl destDirectory(m_currentDestURL);
1897 destDirectory.setPath(destDirectory.directory());
1900 m_dest.setPath(m_currentDestURL.path());
1901 m_dest.setFileName(newName);
1907 }
else if ( q->isInteractive() ) {
1914 time_t ctimeSrc = (time_t) -1;
1915 time_t ctimeDest = (time_t) -1;
1916 time_t mtimeSrc = (time_t) -1;
1917 time_t mtimeDest = (time_t) -1;
1924 KDE_struct_stat stat_buf;
1925 if ( m_currentSrcURL.isLocalFile() &&
1926 KDE::stat(m_currentSrcURL.toLocalFile(), &stat_buf) == 0 ) {
1927 sizeSrc = stat_buf.st_size;
1928 ctimeSrc = stat_buf.st_ctime;
1929 mtimeSrc = stat_buf.st_mtime;
1930 isDir = S_ISDIR(stat_buf.st_mode);
1932 if ( dest.isLocalFile() &&
1933 KDE::stat(dest.toLocalFile(), &stat_buf) == 0 ) {
1934 sizeDest = stat_buf.st_size;
1935 ctimeDest = stat_buf.st_ctime;
1936 mtimeDest = stat_buf.st_mtime;
1937 destIsDir = S_ISDIR(stat_buf.st_mode);
1942 if (!isDir && destIsDir) {
1947 if ( m_srcList.count() > 1 )
1953 m_reportTimer->stop();
1958 m_currentSrcURL.url(),
1962 ctimeSrc, ctimeDest,
1963 mtimeSrc, mtimeDest );
1978 m_bAutoRenameDirs =
true;
1981 m_bAutoRenameFiles =
true;
1988 m_dest.setPath( newPath );
1997 m_bAutoSkipDirs =
true;
1999 m_bAutoSkipFiles =
true;
2007 m_bOverwriteAllDirs =
true;
2009 m_bOverwriteAllFiles =
true;
2017 kDebug(7007) <<
"adding to overwrite list: " << dest.path();
2018 m_overwriteList.insert( dest.path() );
2027 q->setErrorText( errText );
2032 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", aborting";
2034 q->setErrorText( errText );
2038 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", reverting to normal way, starting with stat";
2043 m_bOnlyRenames =
false;
2047 kDebug(7007) <<
"Renaming succeeded, move on";
2049 emit q->copyingDone( q, *m_currentStatSrc, dest, -1 ,
true,
true );
2050 m_successSrcList.append(*m_currentStatSrc);
2064 switch ( d->state ) {
2066 d->slotResultStating( job );
2070 d->slotResultRenaming( job );
2088 d->slotResultCreatingDirs( job );
2091 d->slotResultConflictCreatingDirs( job );
2094 d->slotResultCopyingFiles( job );
2097 d->slotResultConflictCopyingFiles( job );
2100 d->slotResultDeletingDirs( job );
2103 d->slotResultSettingDirAttributes( job );
2112 d_func()->m_defaultPermissions = b;
2117 return d_func()->m_mode;
2122 d_func()->m_bAutoSkipFiles = autoSkip;
2123 d_func()->m_bAutoSkipDirs = autoSkip;
2128 d_func()->m_bAutoRenameFiles = autoRename;
2129 d_func()->m_bAutoRenameDirs = autoRename;
2134 d_func()->m_bOverwriteAllDirs = overwriteAll;
2141 srcList.append( src );
2142 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
false, flags);
2149 srcList.append( src );
2150 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
true, flags);
2156 return CopyJobPrivate::newJob(src, dest,
CopyJob::Copy,
false, flags);
2163 srcList.append( src );
2164 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
false, flags);
2171 srcList.append( src );
2172 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
true, flags);
2178 return CopyJobPrivate::newJob(src, dest,
CopyJob::Move,
false, flags);
2184 srcList.append( src );
2185 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2190 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2196 srcList.append( src );
2197 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2203 srcList.append( src );
2204 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2209 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2212 #include "copyjob.moc"