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();
344 path = QFileInfo(path).absolutePath();
348 m_freeSpace = KDiskFreeSpaceInfo::freeSpaceInfo( path ).available();
354 const bool isGlobalDest = m_dest == m_globalDest;
355 const bool isDir = entry.
isDir();
368 m_dest.setPath(sLocalPath);
370 m_globalDest = m_dest;
374 m_globalDestinationState = destinationState;
376 q->removeSubjob( job );
377 assert ( !q->hasSubjobs() );
382 sourceStated(entry, static_cast<SimpleJob*>(job)->url());
383 q->removeSubjob( job );
387 void CopyJobPrivate::sourceStated(
const UDSEntry& entry,
const KUrl& sourceUrl)
390 const bool isDir = entry.
isDir();
409 kDebug() <<
"Using sLocalPath. destinationState=" << destinationState;
416 addCopyInfoFromUDSEntry(entry, srcurl,
false, m_dest);
418 m_currentDest = m_dest;
419 m_bCurrentSrcIsDir =
false;
430 m_parentDirs.insert(parentDir);
433 m_bCurrentSrcIsDir =
true;
443 if (!sName.isEmpty())
447 if (!dispName.isEmpty())
448 directory = dispName;
449 else if (!sName.isEmpty())
452 m_currentDest.addPath( directory );
462 if ( m_dest == m_globalDest )
463 m_globalDestinationState = destinationState;
466 startListing( srcurl );
474 m_parentDirs.insert(parentDir);
488 void CopyJobPrivate::slotReport()
491 if ( q->isSuspended() )
499 q->setProcessedAmount(
KJob::Files, m_processedFiles );
506 emitMoving(q, m_currentSrcURL, m_currentDestURL);
507 emit q->moving( q, m_currentSrcURL, m_currentDestURL);
511 emitCopying( q, m_currentSrcURL, m_currentDestURL );
512 emit q->linking( q, m_currentSrcURL.path(), m_currentDestURL );
516 emitCopying( q, m_currentSrcURL, m_currentDestURL );
517 emit q->copying( q, m_currentSrcURL, m_currentDestURL );
527 emit q->creatingDir( q, m_currentDestURL );
528 emitCreatingDir( q, m_currentDestURL );
539 emitMoving( q, m_currentSrcURL, m_currentDestURL );
543 emitCopying( q, m_currentSrcURL, m_currentDestURL );
559 UDSEntryList::ConstIterator it = list.constBegin();
560 UDSEntryList::ConstIterator
end = list.constEnd();
561 for (; it != end; ++it) {
563 addCopyInfoFromUDSEntry(entry, static_cast<SimpleJob *>(job)->url(), m_bCurrentSrcIsDir, m_currentDest);
567 void CopyJobPrivate::addCopyInfoFromUDSEntry(
const UDSEntry& entry,
const KUrl& srcUrl,
bool srcIsDir,
const KUrl& currentDest)
575 m_totalSize += info.size;
581 if (!urlStr.isEmpty())
584 const bool isDir = entry.
isDir();
587 if (fileName != QLatin1String(
"..") && fileName != QLatin1String(
".")) {
588 const bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty();
599 url =
KUrl(localPath);
603 info.uDest = currentDest;
617 int numberOfSlashes = fileName.count(
'/');
620 for (
int n = 0; n < numberOfSlashes + 1; ++n) {
621 pos = path.lastIndexOf(
'/', pos - 1);
623 kWarning(7007) <<
"kioslave bug: not enough slashes in UDS_URL" << path <<
"- looking for" << numberOfSlashes <<
"slashes";
628 destFileName = path.mid(pos + 1);
632 destFileName = fileName;
635 destFileName = displayName.isEmpty() ? fileName : displayName;
641 if (destFileName.isEmpty()) {
646 info.uDest.addPath(destFileName);
650 if (info.linkDest.isEmpty() && isDir && m_mode !=
CopyJob::Link) {
653 dirsToRemove.append(info.uSource);
661 void CopyJobPrivate::skipSrc(
bool isDir)
663 m_dest = m_globalDest;
664 destinationState = m_globalDestinationState;
665 skip(*m_currentStatSrc, isDir);
670 void CopyJobPrivate::statNextSrc()
676 m_dest = m_globalDest;
677 destinationState = m_globalDestinationState;
682 void CopyJobPrivate::statCurrentSrc()
685 if (m_currentStatSrc != m_srcList.constEnd()) {
686 m_currentSrcURL = (*m_currentStatSrc);
690 m_currentDest = m_dest;
693 info.mtime = (time_t) -1;
694 info.ctime = (time_t) -1;
696 info.uSource = m_currentSrcURL;
697 info.uDest = m_currentDest;
699 if (destinationState ==
DEST_IS_DIR && !m_asMethod) {
701 (m_currentSrcURL.protocol() == info.uDest.protocol()) &&
702 (m_currentSrcURL.host() == info.uDest.host()) &&
703 (m_currentSrcURL.port() == info.uDest.port()) &&
704 (m_currentSrcURL.user() == info.uDest.user()) &&
705 (m_currentSrcURL.pass() == info.uDest.pass()) ) {
707 info.uDest.addPath( m_currentSrcURL.fileName() );
715 files.append( info );
723 if (!cachedItem.
isNull()) {
724 entry = cachedItem.
entry();
727 m_currentSrcURL = cachedItem.
mostLocalUrl(dummyIsLocal);
738 if ( (m_currentSrcURL.protocol() == m_dest.protocol()) &&
739 (m_currentSrcURL.host() == m_dest.host()) &&
740 (m_currentSrcURL.port() == m_dest.port()) &&
741 (m_currentSrcURL.user() == m_dest.user()) &&
742 (m_currentSrcURL.pass() == m_dest.pass()) )
744 startRenameJob( m_currentSrcURL );
749 startRenameJob( m_dest );
754 startRenameJob( m_currentSrcURL );
761 QPointer<CopyJob> that = q;
768 m_bOnlyRenames =
false;
773 kDebug(7007) <<
"fast path! found info about" << m_currentSrcURL <<
"in KDirLister";
774 sourceStated(entry, m_currentSrcURL);
783 m_currentDestURL = m_dest;
794 kDebug(7007)<<
"Stating finished. To copy:"<<m_totalSize<<
", available:"<<m_freeSpace;
798 emit q->aboutToCreate( q, dirs );
799 if (!files.isEmpty())
800 emit q->aboutToCreate( q, files );
802 m_bSingleFileCopy = ( files.count() == 1 &&
dirs.isEmpty() );
809 void CopyJobPrivate::startRenameJob(
const KUrl& slave_url )
814 if (m_currentSrcURL.isLocalFile()) {
816 if (!m_parentDirs.contains(parentDir)) {
818 m_parentDirs.insert(parentDir);
824 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
825 dest.
addPath( m_currentSrcURL.fileName() );
826 m_currentDestURL = dest;
827 kDebug(7007) << m_currentSrcURL <<
"->" << dest <<
"trying direct rename first";
832 info.mtime = (time_t) -1;
833 info.ctime = (time_t) -1;
835 info.uSource = m_currentSrcURL;
837 QList<CopyInfo> files;
839 emit q->aboutToCreate( q, files );
841 KIO_ARGS << m_currentSrcURL << dest << (qint8)
false ;
844 q->addSubjob( newJob );
845 if ( m_currentSrcURL.directory() != dest.directory() )
846 m_bOnlyRenames =
false;
849 void CopyJobPrivate::startListing(
const KUrl & src )
858 q->addSubjob( newjob );
861 void CopyJobPrivate::skip(
const KUrl & sourceUrl,
bool isDir)
868 while (dirsToRemove.removeAll(dir) > 0) {
875 bool CopyJobPrivate::shouldOverwriteDir(
const QString& path )
const
877 if ( m_bOverwriteAllDirs )
879 return m_overwriteList.contains(path);
882 bool CopyJobPrivate::shouldOverwriteFile(
const QString& path )
const
884 if ( m_bOverwriteAllFiles )
886 return m_overwriteList.contains(path);
889 bool CopyJobPrivate::shouldSkip(
const QString& path )
const
891 Q_FOREACH(
const QString& skipPath, m_skipList) {
892 if ( path.startsWith(skipPath) )
898 void CopyJobPrivate::slotResultCreatingDirs(
KJob * job )
902 QList<CopyInfo>::Iterator it =
dirs.begin();
906 m_conflictError = job->
error();
912 if ( m_bAutoSkipDirs ) {
919 const QString destDir = (*it).uDest.path();
920 if ( shouldOverwriteDir( destDir ) ) {
921 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
924 if (m_bAutoRenameDirs) {
927 KUrl destDirectory((*it).uDest);
928 destDirectory.setPath(destDirectory.directory());
931 KUrl newUrl((*it).uDest);
932 newUrl.setFileName(newName);
934 emit q->renamed(q, (*it).uDest, newUrl);
940 QList<CopyInfo>::Iterator renamedirit = it;
943 for(; renamedirit !=
dirs.end() ; ++renamedirit) {
944 QString path = (*renamedirit).uDest.path();
945 if (path.startsWith(oldPath)) {
947 n.replace(0, oldPath.length(), newPath);
948 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
949 <<
"was going to be" << path
950 <<
", changed into" << n;
951 (*renamedirit).uDest.setPath(n);
955 QList<CopyInfo>::Iterator renamefileit = files.begin();
956 for(; renamefileit != files.end() ; ++renamefileit) {
957 QString path = (*renamefileit).uDest.path();
958 if (path.startsWith(oldPath)) {
960 n.replace(0, oldPath.length(), newPath);
961 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
962 <<
"was going to be" << path
963 <<
", changed into" << n;
964 (*renamefileit).uDest.setPath(n);
967 if (!
dirs.isEmpty()) {
968 emit q->aboutToCreate(q, dirs);
970 if (!files.isEmpty()) {
971 emit q->aboutToCreate(q, files);
976 if (!q->isInteractive()) {
977 q->Job::slotResult(job);
981 assert(((
SimpleJob*)job)->url().url() == (*it).uDest.
url());
982 q->removeSubjob(job);
983 assert (!q->hasSubjobs());
986 KUrl existingDest((*it).uDest);
989 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingDest;
991 q->addSubjob(newJob);
1000 q->Job::slotResult( job );
1007 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true,
false );
1008 m_directoriesCopied.append( *it );
1014 q->removeSubjob( job );
1015 assert( !q->hasSubjobs() );
1019 void CopyJobPrivate::slotResultConflictCreatingDirs(
KJob * job )
1025 QList<CopyInfo>::Iterator it =
dirs.begin();
1036 q->removeSubjob( job );
1037 assert ( !q->hasSubjobs() );
1044 if( (*it).uSource == (*it).uDest ||
1045 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1052 QString existingDest = (*it).uDest.path();
1055 m_reportTimer->stop();
1057 (*it).uSource.url(),
1060 (*it).size, destsize,
1061 (*it).ctime, destctime,
1062 (*it).mtime, destmtime );
1071 m_bAutoRenameDirs =
true;
1076 KUrl newUrl( (*it).uDest );
1077 newUrl.setPath( newPath );
1078 emit q->renamed( q, (*it).uDest, newUrl );
1083 QList<CopyInfo>::Iterator renamedirit = it;
1086 for( ; renamedirit !=
dirs.end() ; ++renamedirit )
1088 QString path = (*renamedirit).uDest.path();
1089 if ( path.startsWith( oldPath ) ) {
1091 n.replace( 0, oldPath.length(), newPath );
1092 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
1093 <<
"was going to be" << path
1094 <<
", changed into" << n;
1095 (*renamedirit).uDest.setPath( n );
1099 QList<CopyInfo>::Iterator renamefileit = files.begin();
1100 for( ; renamefileit != files.end() ; ++renamefileit )
1102 QString path = (*renamefileit).uDest.path();
1103 if ( path.startsWith( oldPath ) ) {
1105 n.replace( 0, oldPath.length(), newPath );
1106 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
1107 <<
"was going to be" << path
1108 <<
", changed into" << n;
1109 (*renamefileit).uDest.setPath( n );
1112 if (!
dirs.isEmpty())
1113 emit q->aboutToCreate( q, dirs );
1114 if (!files.isEmpty())
1115 emit q->aboutToCreate( q, files );
1119 m_bAutoSkipDirs =
true;
1122 m_skipList.append( existingDest );
1123 skip((*it).uSource,
true);
1129 m_overwriteList.insert( existingDest );
1130 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1136 m_bOverwriteAllDirs =
true;
1137 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1150 void CopyJobPrivate::createNextDir()
1154 if ( !
dirs.isEmpty() )
1157 QList<CopyInfo>::Iterator it =
dirs.begin();
1159 while( it !=
dirs.end() && udir.isEmpty() )
1162 if ( shouldSkip( dir ) ) {
1169 if ( !udir.isEmpty() )
1175 if (shouldOverwriteFile(udir.
path())) {
1179 m_currentDestURL = udir;
1182 q->addSubjob(newjob);
1194 for ( QSet<QString>::const_iterator it = m_parentDirs.constBegin() ; it != m_parentDirs.constEnd() ; ++it )
1204 void CopyJobPrivate::slotResultCopyingFiles(
KJob * job )
1208 QList<CopyInfo>::Iterator it = files.begin();
1212 if ( m_bAutoSkipFiles )
1214 skip((*it).uSource,
false);
1215 m_fileProcessedSize = (*it).size;
1220 m_conflictError = job->
error();
1226 if (m_bAutoRenameFiles) {
1227 KUrl destDirectory((*it).uDest);
1228 destDirectory.setPath(destDirectory.directory());
1231 KUrl newUrl((*it).uDest);
1232 newUrl.setFileName(newName);
1234 emit q->renamed(q, (*it).uDest, newUrl);
1235 (*it).uDest = newUrl;
1237 QList<CopyInfo> files;
1239 emit q->aboutToCreate(q, files);
1242 if ( !q->isInteractive() ) {
1243 q->Job::slotResult( job );
1247 q->removeSubjob(job);
1248 assert (!q->hasSubjobs());
1250 KUrl existingFile((*it).uDest);
1253 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingFile;
1255 q->addSubjob(newJob);
1261 if ( m_bCurrentOperationIsLink && qobject_cast<KIO::DeleteJob*>( job ) )
1265 m_fileProcessedSize = (*it).size;
1268 if ( !q->isInteractive() ) {
1269 q->Job::slotResult( job );
1274 slotResultConflictCopyingFiles( job );
1283 && !qobject_cast<KIO::DeleteJob *>( job )
1286 q->removeSubjob( job );
1287 assert ( !q->hasSubjobs() );
1291 q->addSubjob( newjob );
1295 if ( m_bCurrentOperationIsLink )
1299 emit q->copyingLinkDone( q, (*it).uSource, target, (*it).uDest );
1303 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
false,
false );
1308 m_successSrcList.append((*it).uSource);
1310 m_freeSpace -= (*it).size;
1320 m_processedSize += m_fileProcessedSize;
1321 m_fileProcessedSize = 0;
1328 m_incomingMetaData += kiojob->
metaData();
1329 q->removeSubjob( job );
1330 assert( !q->hasSubjobs() );
1334 void CopyJobPrivate::slotResultConflictCopyingFiles(
KJob * job )
1339 QList<CopyInfo>::Iterator it = files.begin();
1345 m_reportTimer->stop();
1368 if ( (*it).uSource == (*it).uDest ||
1369 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1377 if ( !m_bSingleFileCopy )
1380 res = q->ui()->askFileRename( q, !isDir ?
1381 i18n(
"File Already Exists") :
i18n(
"Already Exists as Folder"),
1382 (*it).uSource.url(),
1385 (*it).size, destsize,
1386 (*it).ctime, destctime,
1387 (*it).mtime, destmtime );
1394 else if ( !q->isInteractive() ) {
1395 q->Job::slotResult( job );
1413 q->removeSubjob( job );
1414 assert ( !q->hasSubjobs() );
1421 m_bAutoRenameFiles =
true;
1425 KUrl newUrl( (*it).uDest );
1426 newUrl.setPath( newPath );
1427 emit q->renamed( q, (*it).uDest, newUrl );
1428 (*it).uDest = newUrl;
1430 QList<CopyInfo> files;
1432 emit q->aboutToCreate( q, files );
1436 m_bAutoSkipFiles =
true;
1440 skip((*it).uSource,
false);
1441 m_processedSize += (*it).size;
1446 m_bOverwriteAllFiles =
true;
1450 m_overwriteList.insert( (*it).uDest.path() );
1459 KIO::Job* CopyJobPrivate::linkNextFile(
const KUrl& uSource,
const KUrl& uDest, JobFlags flags )
1464 (uSource.host() == uDest.host()) &&
1465 (uSource.port() == uDest.port()) &&
1466 (uSource.
user() == uDest.
user()) &&
1474 m_bCurrentOperationIsLink =
true;
1475 m_currentSrcURL=uSource;
1476 m_currentDestURL=uDest;
1489 if (
f.open( QIODevice::ReadWrite ) )
1498 config.
writeEntry(
"Type", QString::fromLatin1(
"Link") );
1500 if ( protocol == QLatin1String(
"ftp") )
1501 config.
writeEntry(
"Icon", QString::fromLatin1(
"folder-remote") );
1502 else if ( protocol == QLatin1String(
"http") )
1503 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-html") );
1504 else if ( protocol == QLatin1String(
"info") )
1505 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-x-texinfo") );
1506 else if ( protocol == QLatin1String(
"mailto") )
1507 config.
writeEntry(
"Icon", QString::fromLatin1(
"internet-mail") );
1509 config.
writeEntry(
"Icon", QString::fromLatin1(
"unknown") );
1511 files.erase( files.begin() );
1519 kDebug(7007) <<
"ERR_CANNOT_OPEN_FOR_WRITING";
1535 void CopyJobPrivate::copyNextFile()
1538 bool bCopyFile =
false;
1541 QList<CopyInfo>::Iterator it = files.begin();
1543 while (it != files.end() && !bCopyFile)
1545 const QString destFile = (*it).uDest.path();
1546 bCopyFile = !shouldSkip( destFile );
1557 if (m_freeSpace < (*it).size) {
1565 const KUrl& uSource = (*it).uSource;
1566 const KUrl& uDest = (*it).uDest;
1571 if ( uDest == uSource )
1574 bOverwrite = shouldOverwriteFile( destFile );
1576 m_bCurrentOperationIsLink =
false;
1581 newjob = linkNextFile(uSource, uDest, flags);
1584 }
else if ( !(*it).linkDest.isEmpty() &&
1586 (uSource.host() == uDest.host()) &&
1587 (uSource.port() == uDest.port()) &&
1588 (uSource.
user() == uDest.
user()) &&
1597 m_currentSrcURL =
KUrl( (*it).linkDest );
1598 m_currentDestURL = uDest;
1602 m_bCurrentOperationIsLink =
true;
1609 if ((*it).mtime != -1) {
1615 m_currentSrcURL=uSource;
1616 m_currentDestURL=uDest;
1625 int permissions = (*it).permissions;
1626 if ( m_defaultPermissions || ( remoteSource && uDest.
isLocalFile() ) )
1632 if ((*it).mtime != -1) {
1637 m_currentSrcURL=uSource;
1638 m_currentDestURL=uDest;
1641 q->addSubjob(newjob);
1642 q->connect( newjob, SIGNAL(processedSize(
KJob*,qulonglong)),
1643 SLOT(slotProcessedSize(
KJob*,qulonglong)) );
1644 q->connect( newjob, SIGNAL(totalSize(
KJob*,qulonglong)),
1645 SLOT(slotTotalSize(
KJob*,qulonglong)) );
1655 void CopyJobPrivate::deleteNextDir()
1663 KUrl::List::Iterator it = --dirsToRemove.end();
1666 dirsToRemove.erase(it);
1667 q->addSubjob( job );
1673 m_directoriesCopiedIterator = m_directoriesCopied.constBegin();
1674 setNextDirAttribute();
1678 void CopyJobPrivate::setNextDirAttribute()
1681 while (m_directoriesCopiedIterator != m_directoriesCopied.constEnd() &&
1682 (*m_directoriesCopiedIterator).mtime == -1) {
1683 ++m_directoriesCopiedIterator;
1685 if ( m_directoriesCopiedIterator != m_directoriesCopied.constEnd() ) {
1686 const KUrl url = (*m_directoriesCopiedIterator).uDest;
1687 const time_t mtime = (*m_directoriesCopiedIterator).mtime;
1688 const QDateTime dt = QDateTime::fromTime_t(mtime);
1689 ++m_directoriesCopiedIterator;
1693 q->addSubjob( job );
1696 #if 0 // ifdef Q_OS_UNIX
1700 QLinkedList<CopyInfo>::const_iterator it = m_directoriesCopied.constBegin();
1701 for ( ; it != m_directoriesCopied.constEnd() ; ++it ) {
1702 const KUrl& url = (*it).uDest;
1703 if ( url.
isLocalFile() && (*it).mtime != (time_t)-1 ) {
1704 KDE_struct_stat statbuf;
1706 struct utimbuf utbuf;
1707 utbuf.actime = statbuf.st_atime;
1708 utbuf.modtime = (*it).mtime;
1709 utime( path, &utbuf );
1714 m_directoriesCopied.clear();
1719 m_reportTimer->stop();
1733 if (!d->m_bOnlyRenames) {
1734 KUrl url(d->m_globalDest);
1735 if (d->m_globalDestinationState !=
DEST_IS_DIR || d->m_asMethod)
1740 if (d->m_mode ==
CopyJob::Move && !d->m_successSrcList.isEmpty()) {
1741 kDebug(7007) <<
"KDirNotify'ing FilesRemoved" << d->m_successSrcList.toStringList();
1747 for (QSet<QString>::const_iterator it = d->m_parentDirs.constBegin() ; it != d->m_parentDirs.constEnd() ; ++it)
1754 void CopyJobPrivate::slotProcessedSize(
KJob*, qulonglong data_size )
1758 m_fileProcessedSize = data_size;
1759 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1761 if ( m_processedSize + m_fileProcessedSize > m_totalSize )
1764 m_totalSize = m_processedSize + m_fileProcessedSize;
1769 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1772 void CopyJobPrivate::slotTotalSize(
KJob*, qulonglong size )
1780 if ( m_bSingleFileCopy && size != m_totalSize)
1788 void CopyJobPrivate::slotResultDeletingDirs(
KJob * job )
1796 m_successSrcList.append(static_cast<KIO::SimpleJob*>(job)->url());
1798 q->removeSubjob( job );
1799 assert( !q->hasSubjobs() );
1803 void CopyJobPrivate::slotResultSettingDirAttributes(
KJob * job )
1812 q->removeSubjob( job );
1813 assert( !q->hasSubjobs() );
1814 setNextDirAttribute();
1818 void CopyJobPrivate::slotResultRenaming(
KJob* job )
1821 int err = job->
error();
1826 m_incomingMetaData += kiojob->
metaData();
1827 q->removeSubjob( job );
1828 assert ( !q->hasSubjobs() );
1831 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
1832 dest.
addPath( m_currentSrcURL.fileName() );
1844 kDebug(7007) <<
"Couldn't rename directly, dest already exists. Detected special case of lower/uppercase renaming in same dir, try with 2 rename calls";
1845 const QString _src( m_currentSrcURL.toLocalFile() );
1846 const QString _dest( dest.toLocalFile() );
1850 const bool openOk = tmpFile.open();
1852 kWarning(7007) <<
"Couldn't open temp file in" << _tmpPrefix;
1854 const QString _tmp( tmpFile.fileName() );
1857 kDebug(7007) <<
"KTemporaryFile using" << _tmp <<
"as intermediary";
1860 if (!QFile::exists( _dest ) &&
KDE::rename(_tmp, _dest) == 0) {
1864 kDebug(7007) <<
"Didn't manage to rename" << _tmp <<
"to" << _dest <<
", reverting";
1867 kError(7007) <<
"Couldn't rename" << _tmp <<
"back to" << _src <<
'!';
1869 q->Job::slotResult(job);
1874 kDebug(7007) <<
"mv" << _src << _tmp <<
"failed:" << strerror(errno);
1895 if ((isDir && m_bAutoSkipDirs) || (!isDir && m_bAutoSkipFiles)) {
1899 }
else if ((isDir && m_bOverwriteAllDirs) || (!isDir && m_bOverwriteAllFiles)) {
1901 }
else if ((isDir && m_bAutoRenameDirs) || (!isDir && m_bAutoRenameFiles)) {
1902 KUrl destDirectory(m_currentDestURL);
1903 destDirectory.setPath(destDirectory.directory());
1906 m_dest.setPath(m_currentDestURL.path());
1907 m_dest.setFileName(newName);
1913 }
else if ( q->isInteractive() ) {
1920 time_t ctimeSrc = (time_t) -1;
1921 time_t ctimeDest = (time_t) -1;
1922 time_t mtimeSrc = (time_t) -1;
1923 time_t mtimeDest = (time_t) -1;
1930 KDE_struct_stat stat_buf;
1931 if ( m_currentSrcURL.isLocalFile() &&
1932 KDE::stat(m_currentSrcURL.toLocalFile(), &stat_buf) == 0 ) {
1933 sizeSrc = stat_buf.st_size;
1934 ctimeSrc = stat_buf.st_ctime;
1935 mtimeSrc = stat_buf.st_mtime;
1936 isDir = S_ISDIR(stat_buf.st_mode);
1938 if ( dest.isLocalFile() &&
1939 KDE::stat(dest.toLocalFile(), &stat_buf) == 0 ) {
1940 sizeDest = stat_buf.st_size;
1941 ctimeDest = stat_buf.st_ctime;
1942 mtimeDest = stat_buf.st_mtime;
1943 destIsDir = S_ISDIR(stat_buf.st_mode);
1948 if (!isDir && destIsDir) {
1953 if ( m_srcList.count() > 1 )
1959 m_reportTimer->stop();
1964 m_currentSrcURL.url(),
1968 ctimeSrc, ctimeDest,
1969 mtimeSrc, mtimeDest );
1984 m_bAutoRenameDirs =
true;
1987 m_bAutoRenameFiles =
true;
1994 m_dest.setPath( newPath );
2003 m_bAutoSkipDirs =
true;
2005 m_bAutoSkipFiles =
true;
2013 m_bOverwriteAllDirs =
true;
2015 m_bOverwriteAllFiles =
true;
2023 kDebug(7007) <<
"adding to overwrite list: " << dest.path();
2024 m_overwriteList.insert( dest.path() );
2033 q->setErrorText( errText );
2038 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", aborting";
2040 q->setErrorText( errText );
2044 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", reverting to normal way, starting with stat";
2049 m_bOnlyRenames =
false;
2053 kDebug(7007) <<
"Renaming succeeded, move on";
2055 emit q->copyingDone( q, *m_currentStatSrc, dest, -1 ,
true,
true );
2056 m_successSrcList.append(*m_currentStatSrc);
2070 switch ( d->state ) {
2072 d->slotResultStating( job );
2076 d->slotResultRenaming( job );
2094 d->slotResultCreatingDirs( job );
2097 d->slotResultConflictCreatingDirs( job );
2100 d->slotResultCopyingFiles( job );
2103 d->slotResultConflictCopyingFiles( job );
2106 d->slotResultDeletingDirs( job );
2109 d->slotResultSettingDirAttributes( job );
2118 d_func()->m_defaultPermissions = b;
2123 return d_func()->m_mode;
2128 d_func()->m_bAutoSkipFiles = autoSkip;
2129 d_func()->m_bAutoSkipDirs = autoSkip;
2134 d_func()->m_bAutoRenameFiles = autoRename;
2135 d_func()->m_bAutoRenameDirs = autoRename;
2140 d_func()->m_bOverwriteAllDirs = overwriteAll;
2147 srcList.append( src );
2148 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
false, flags);
2155 srcList.append( src );
2156 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
true, flags);
2162 return CopyJobPrivate::newJob(src, dest,
CopyJob::Copy,
false, flags);
2169 srcList.append( src );
2170 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
false, flags);
2177 srcList.append( src );
2178 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
true, flags);
2184 return CopyJobPrivate::newJob(src, dest,
CopyJob::Move,
false, flags);
2190 srcList.append( src );
2191 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2196 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2202 srcList.append( src );
2203 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2209 srcList.append( src );
2210 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2215 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2218 #include "copyjob.moc"