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);
225 void addCopyInfoFromUDSEntry(
const UDSEntry& entry,
const KUrl& srcUrl,
bool srcIsDir,
const KUrl& currentDest);
229 void slotProcessedSize(
KJob*, qulonglong data_size );
234 void slotTotalSize(
KJob*, qulonglong size );
241 CopyJob::CopyMode mode,
bool asMethod, JobFlags flags)
243 CopyJob *job =
new CopyJob(*
new CopyJobPrivate(src,dest,mode,asMethod));
248 job->d_func()->m_bOverwriteAllDirs =
true;
249 job->d_func()->m_bOverwriteAllFiles =
true;
258 setProperty(
"destUrl", d_func()->m_dest.url());
259 QTimer::singleShot(0,
this, SLOT(slotStart()));
268 return d_func()->m_srcList;
273 return d_func()->m_dest;
276 void CopyJobPrivate::slotStart()
284 m_reportTimer =
new QTimer(q);
286 q->connect(m_reportTimer,SIGNAL(
timeout()),q,SLOT(slotReport()));
298 void CopyJobPrivate::slotResultStating(
KJob *job )
311 kDebug(7007) <<
"Error while stating source. Activating hack";
312 q->removeSubjob( job );
313 assert ( !q->hasSubjobs() );
316 info.
mtime = (time_t) -1;
317 info.
ctime = (time_t) -1;
322 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
325 files.append( info );
331 q->Job::slotResult( job );
339 if ( m_dest.isLocalFile() ) {
340 QString path = m_dest.toLocalFile();
345 path = QFileInfo(path).absolutePath();
349 m_freeSpace = KDiskFreeSpaceInfo::freeSpaceInfo( path ).available();
355 const bool isGlobalDest = m_dest == m_globalDest;
356 const bool isDir = entry.
isDir();
369 m_dest.setPath(sLocalPath);
371 m_globalDest = m_dest;
375 m_globalDestinationState = destinationState;
377 q->removeSubjob( job );
378 assert ( !q->hasSubjobs() );
383 sourceStated(entry, static_cast<SimpleJob*>(job)->url());
384 q->removeSubjob( job );
388 void CopyJobPrivate::sourceStated(
const UDSEntry& entry,
const KUrl& sourceUrl)
391 const bool isDir = entry.
isDir();
410 kDebug() <<
"Using sLocalPath. destinationState=" << destinationState;
417 addCopyInfoFromUDSEntry(entry, srcurl,
false, m_dest);
419 m_currentDest = m_dest;
420 m_bCurrentSrcIsDir =
false;
431 m_parentDirs.insert(parentDir);
434 m_bCurrentSrcIsDir =
true;
444 if (!sName.isEmpty())
448 if (!dispName.isEmpty())
449 directory = dispName;
450 else if (!sName.isEmpty())
453 m_currentDest.addPath( directory );
463 if ( m_dest == m_globalDest )
464 m_globalDestinationState = destinationState;
467 startListing( srcurl );
475 m_parentDirs.insert(parentDir);
489 void CopyJobPrivate::slotReport()
492 if ( q->isSuspended() )
500 q->setProcessedAmount(
KJob::Files, m_processedFiles );
507 emitMoving(q, m_currentSrcURL, m_currentDestURL);
508 emit q->moving( q, m_currentSrcURL, m_currentDestURL);
512 emitCopying( q, m_currentSrcURL, m_currentDestURL );
513 emit q->linking( q, m_currentSrcURL.path(), m_currentDestURL );
517 emitCopying( q, m_currentSrcURL, m_currentDestURL );
518 emit q->copying( q, m_currentSrcURL, m_currentDestURL );
528 emit q->creatingDir( q, m_currentDestURL );
529 emitCreatingDir( q, m_currentDestURL );
540 emitMoving( q, m_currentSrcURL, m_currentDestURL );
544 emitCopying( q, m_currentSrcURL, m_currentDestURL );
560 UDSEntryList::ConstIterator it = list.constBegin();
561 UDSEntryList::ConstIterator
end = list.constEnd();
562 for (; it != end; ++it) {
564 addCopyInfoFromUDSEntry(entry, static_cast<SimpleJob *>(job)->url(), m_bCurrentSrcIsDir, m_currentDest);
570 const KUrl url = subJob->
url();
580 void CopyJobPrivate::addCopyInfoFromUDSEntry(
const UDSEntry& entry,
const KUrl& srcUrl,
bool srcIsDir,
const KUrl& currentDest)
588 m_totalSize += info.size;
594 if (!urlStr.isEmpty())
597 const bool isDir = entry.
isDir();
600 if (fileName != QLatin1String(
"..") && fileName != QLatin1String(
".")) {
601 const bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty();
612 url =
KUrl(localPath);
616 info.uDest = currentDest;
630 int numberOfSlashes = fileName.count(
'/');
633 for (
int n = 0; n < numberOfSlashes + 1; ++n) {
634 pos = path.lastIndexOf(
'/', pos - 1);
636 kWarning(7007) <<
"kioslave bug: not enough slashes in UDS_URL" << path <<
"- looking for" << numberOfSlashes <<
"slashes";
641 destFileName = path.mid(pos + 1);
645 destFileName = fileName;
648 destFileName = displayName.isEmpty() ? fileName : displayName;
654 if (destFileName.isEmpty()) {
659 info.uDest.addPath(destFileName);
663 if (info.linkDest.isEmpty() && isDir && m_mode !=
CopyJob::Link) {
666 dirsToRemove.append(info.uSource);
674 void CopyJobPrivate::skipSrc(
bool isDir)
676 m_dest = m_globalDest;
677 destinationState = m_globalDestinationState;
678 skip(*m_currentStatSrc, isDir);
683 void CopyJobPrivate::statNextSrc()
689 m_dest = m_globalDest;
690 destinationState = m_globalDestinationState;
695 void CopyJobPrivate::statCurrentSrc()
698 if (m_currentStatSrc != m_srcList.constEnd()) {
699 m_currentSrcURL = (*m_currentStatSrc);
703 m_currentDest = m_dest;
706 info.mtime = (time_t) -1;
707 info.ctime = (time_t) -1;
709 info.uSource = m_currentSrcURL;
710 info.uDest = m_currentDest;
712 if (destinationState ==
DEST_IS_DIR && !m_asMethod) {
714 (m_currentSrcURL.protocol() == info.uDest.protocol()) &&
715 (m_currentSrcURL.host() == info.uDest.host()) &&
716 (m_currentSrcURL.port() == info.uDest.port()) &&
717 (m_currentSrcURL.user() == info.uDest.user()) &&
718 (m_currentSrcURL.pass() == info.uDest.pass()) ) {
720 info.uDest.addPath( m_currentSrcURL.fileName() );
728 files.append( info );
736 if (!cachedItem.
isNull()) {
737 entry = cachedItem.
entry();
740 m_currentSrcURL = cachedItem.
mostLocalUrl(dummyIsLocal);
751 if ( (m_currentSrcURL.protocol() == m_dest.protocol()) &&
752 (m_currentSrcURL.host() == m_dest.host()) &&
753 (m_currentSrcURL.port() == m_dest.port()) &&
754 (m_currentSrcURL.user() == m_dest.user()) &&
755 (m_currentSrcURL.pass() == m_dest.pass()) )
757 startRenameJob( m_currentSrcURL );
762 startRenameJob( m_dest );
767 startRenameJob( m_currentSrcURL );
774 QPointer<CopyJob> that = q;
781 m_bOnlyRenames =
false;
786 kDebug(7007) <<
"fast path! found info about" << m_currentSrcURL <<
"in KDirLister";
787 sourceStated(entry, m_currentSrcURL);
796 m_currentDestURL = m_dest;
807 kDebug(7007)<<
"Stating finished. To copy:"<<m_totalSize<<
", available:"<<m_freeSpace;
811 emit q->aboutToCreate( q, dirs );
812 if (!files.isEmpty())
813 emit q->aboutToCreate( q, files );
815 m_bSingleFileCopy = ( files.count() == 1 &&
dirs.isEmpty() );
822 void CopyJobPrivate::startRenameJob(
const KUrl& slave_url )
827 if (m_currentSrcURL.isLocalFile()) {
829 if (!m_parentDirs.contains(parentDir)) {
831 m_parentDirs.insert(parentDir);
837 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
838 dest.
addPath( m_currentSrcURL.fileName() );
839 m_currentDestURL = dest;
840 kDebug(7007) << m_currentSrcURL <<
"->" << dest <<
"trying direct rename first";
845 info.mtime = (time_t) -1;
846 info.ctime = (time_t) -1;
848 info.uSource = m_currentSrcURL;
850 QList<CopyInfo> files;
852 emit q->aboutToCreate( q, files );
854 KIO_ARGS << m_currentSrcURL << dest << (qint8)
false ;
857 q->addSubjob( newJob );
858 if ( m_currentSrcURL.directory() != dest.directory() )
859 m_bOnlyRenames =
false;
862 void CopyJobPrivate::startListing(
const KUrl & src )
873 q->addSubjob( newjob );
876 void CopyJobPrivate::skip(
const KUrl & sourceUrl,
bool isDir)
883 while (dirsToRemove.removeAll(dir) > 0) {
890 bool CopyJobPrivate::shouldOverwriteDir(
const QString& path )
const
892 if ( m_bOverwriteAllDirs )
894 return m_overwriteList.contains(path);
897 bool CopyJobPrivate::shouldOverwriteFile(
const QString& path )
const
899 if ( m_bOverwriteAllFiles )
901 return m_overwriteList.contains(path);
904 bool CopyJobPrivate::shouldSkip(
const QString& path )
const
906 Q_FOREACH(
const QString& skipPath, m_skipList) {
907 if ( path.startsWith(skipPath) )
913 void CopyJobPrivate::slotResultCreatingDirs(
KJob * job )
917 QList<CopyInfo>::Iterator it =
dirs.begin();
921 m_conflictError = job->
error();
927 if ( m_bAutoSkipDirs ) {
934 const QString destDir = (*it).uDest.path();
935 if ( shouldOverwriteDir( destDir ) ) {
936 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
939 if (m_bAutoRenameDirs) {
942 KUrl destDirectory((*it).uDest);
943 destDirectory.setPath(destDirectory.directory());
946 KUrl newUrl((*it).uDest);
947 newUrl.setFileName(newName);
949 emit q->renamed(q, (*it).uDest, newUrl);
955 QList<CopyInfo>::Iterator renamedirit = it;
958 for(; renamedirit !=
dirs.end() ; ++renamedirit) {
959 QString path = (*renamedirit).uDest.path();
960 if (path.startsWith(oldPath)) {
962 n.replace(0, oldPath.length(), newPath);
963 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
964 <<
"was going to be" << path
965 <<
", changed into" << n;
966 (*renamedirit).uDest.setPath(n);
970 QList<CopyInfo>::Iterator renamefileit = files.begin();
971 for(; renamefileit != files.end() ; ++renamefileit) {
972 QString path = (*renamefileit).uDest.path();
973 if (path.startsWith(oldPath)) {
975 n.replace(0, oldPath.length(), newPath);
976 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
977 <<
"was going to be" << path
978 <<
", changed into" << n;
979 (*renamefileit).uDest.setPath(n);
982 if (!
dirs.isEmpty()) {
983 emit q->aboutToCreate(q, dirs);
985 if (!files.isEmpty()) {
986 emit q->aboutToCreate(q, files);
991 if (!q->isInteractive()) {
992 q->Job::slotResult(job);
996 assert(((
SimpleJob*)job)->url().url() == (*it).uDest.
url());
997 q->removeSubjob(job);
998 assert (!q->hasSubjobs());
1001 KUrl existingDest((*it).uDest);
1004 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingDest;
1006 q->addSubjob(newJob);
1015 q->Job::slotResult( job );
1022 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true,
false );
1023 m_directoriesCopied.append( *it );
1029 q->removeSubjob( job );
1030 assert( !q->hasSubjobs() );
1034 void CopyJobPrivate::slotResultConflictCreatingDirs(
KJob * job )
1040 QList<CopyInfo>::Iterator it =
dirs.begin();
1051 q->removeSubjob( job );
1052 assert ( !q->hasSubjobs() );
1059 if( (*it).uSource == (*it).uDest ||
1060 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1067 QString existingDest = (*it).uDest.path();
1070 m_reportTimer->stop();
1072 (*it).uSource.url(),
1075 (*it).size, destsize,
1076 (*it).ctime, destctime,
1077 (*it).mtime, destmtime );
1086 m_bAutoRenameDirs =
true;
1091 KUrl newUrl( (*it).uDest );
1092 newUrl.setPath( newPath );
1093 emit q->renamed( q, (*it).uDest, newUrl );
1098 QList<CopyInfo>::Iterator renamedirit = it;
1101 for( ; renamedirit !=
dirs.end() ; ++renamedirit )
1103 QString path = (*renamedirit).uDest.path();
1104 if ( path.startsWith( oldPath ) ) {
1106 n.replace( 0, oldPath.length(), newPath );
1107 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
1108 <<
"was going to be" << path
1109 <<
", changed into" << n;
1110 (*renamedirit).uDest.setPath( n );
1114 QList<CopyInfo>::Iterator renamefileit = files.begin();
1115 for( ; renamefileit != files.end() ; ++renamefileit )
1117 QString path = (*renamefileit).uDest.path();
1118 if ( path.startsWith( oldPath ) ) {
1120 n.replace( 0, oldPath.length(), newPath );
1121 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
1122 <<
"was going to be" << path
1123 <<
", changed into" << n;
1124 (*renamefileit).uDest.setPath( n );
1127 if (!
dirs.isEmpty())
1128 emit q->aboutToCreate( q, dirs );
1129 if (!files.isEmpty())
1130 emit q->aboutToCreate( q, files );
1134 m_bAutoSkipDirs =
true;
1137 m_skipList.append( existingDest );
1138 skip((*it).uSource,
true);
1144 m_overwriteList.insert( existingDest );
1145 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1151 m_bOverwriteAllDirs =
true;
1152 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1165 void CopyJobPrivate::createNextDir()
1169 if ( !
dirs.isEmpty() )
1172 QList<CopyInfo>::Iterator it =
dirs.begin();
1174 while( it !=
dirs.end() && udir.isEmpty() )
1177 if ( shouldSkip( dir ) ) {
1184 if ( !udir.isEmpty() )
1190 if (shouldOverwriteFile(udir.
path())) {
1194 m_currentDestURL = udir;
1197 q->addSubjob(newjob);
1209 for ( QSet<QString>::const_iterator it = m_parentDirs.constBegin() ; it != m_parentDirs.constEnd() ; ++it )
1219 void CopyJobPrivate::slotResultCopyingFiles(
KJob * job )
1223 QList<CopyInfo>::Iterator it = files.begin();
1227 if ( m_bAutoSkipFiles )
1229 skip((*it).uSource,
false);
1230 m_fileProcessedSize = (*it).size;
1235 m_conflictError = job->
error();
1241 if (m_bAutoRenameFiles) {
1242 KUrl destDirectory((*it).uDest);
1243 destDirectory.setPath(destDirectory.directory());
1246 KUrl newUrl((*it).uDest);
1247 newUrl.setFileName(newName);
1249 emit q->renamed(q, (*it).uDest, newUrl);
1250 (*it).uDest = newUrl;
1252 QList<CopyInfo> files;
1254 emit q->aboutToCreate(q, files);
1257 if ( !q->isInteractive() ) {
1258 q->Job::slotResult( job );
1262 q->removeSubjob(job);
1263 assert (!q->hasSubjobs());
1265 KUrl existingFile((*it).uDest);
1268 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingFile;
1270 q->addSubjob(newJob);
1276 if ( m_bCurrentOperationIsLink && qobject_cast<KIO::DeleteJob*>( job ) )
1280 m_fileProcessedSize = (*it).size;
1283 if ( !q->isInteractive() ) {
1284 q->Job::slotResult( job );
1289 slotResultConflictCopyingFiles( job );
1298 && !qobject_cast<KIO::DeleteJob *>( job )
1301 q->removeSubjob( job );
1302 assert ( !q->hasSubjobs() );
1306 q->addSubjob( newjob );
1310 if ( m_bCurrentOperationIsLink )
1314 emit q->copyingLinkDone( q, (*it).uSource, target, (*it).uDest );
1318 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
false,
false );
1323 m_successSrcList.append((*it).uSource);
1325 m_freeSpace -= (*it).size;
1335 m_processedSize += m_fileProcessedSize;
1336 m_fileProcessedSize = 0;
1343 m_incomingMetaData += kiojob->
metaData();
1344 q->removeSubjob( job );
1345 assert( !q->hasSubjobs() );
1349 void CopyJobPrivate::slotResultConflictCopyingFiles(
KJob * job )
1354 QList<CopyInfo>::Iterator it = files.begin();
1360 m_reportTimer->stop();
1383 if ( (*it).uSource == (*it).uDest ||
1384 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1392 if ( !m_bSingleFileCopy )
1395 res = q->ui()->askFileRename( q, !isDir ?
1396 i18n(
"File Already Exists") :
i18n(
"Already Exists as Folder"),
1397 (*it).uSource.url(),
1400 (*it).size, destsize,
1401 (*it).ctime, destctime,
1402 (*it).mtime, destmtime );
1409 else if ( !q->isInteractive() ) {
1410 q->Job::slotResult( job );
1428 q->removeSubjob( job );
1429 assert ( !q->hasSubjobs() );
1436 m_bAutoRenameFiles =
true;
1440 KUrl newUrl( (*it).uDest );
1441 newUrl.setPath( newPath );
1442 emit q->renamed( q, (*it).uDest, newUrl );
1443 (*it).uDest = newUrl;
1445 QList<CopyInfo> files;
1447 emit q->aboutToCreate( q, files );
1451 m_bAutoSkipFiles =
true;
1455 skip((*it).uSource,
false);
1456 m_processedSize += (*it).size;
1461 m_bOverwriteAllFiles =
true;
1465 m_overwriteList.insert( (*it).uDest.path() );
1474 KIO::Job* CopyJobPrivate::linkNextFile(
const KUrl& uSource,
const KUrl& uDest, JobFlags flags )
1479 (uSource.host() == uDest.host()) &&
1480 (uSource.port() == uDest.port()) &&
1481 (uSource.
user() == uDest.
user()) &&
1489 m_bCurrentOperationIsLink =
true;
1490 m_currentSrcURL=uSource;
1491 m_currentDestURL=uDest;
1504 if (
f.open( QIODevice::ReadWrite ) )
1513 config.
writeEntry(
"Type", QString::fromLatin1(
"Link") );
1515 if ( protocol == QLatin1String(
"ftp") )
1516 config.
writeEntry(
"Icon", QString::fromLatin1(
"folder-remote") );
1517 else if ( protocol == QLatin1String(
"http") )
1518 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-html") );
1519 else if ( protocol == QLatin1String(
"info") )
1520 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-x-texinfo") );
1521 else if ( protocol == QLatin1String(
"mailto") )
1522 config.
writeEntry(
"Icon", QString::fromLatin1(
"internet-mail") );
1524 config.
writeEntry(
"Icon", QString::fromLatin1(
"unknown") );
1526 files.erase( files.begin() );
1534 kDebug(7007) <<
"ERR_CANNOT_OPEN_FOR_WRITING";
1550 void CopyJobPrivate::copyNextFile()
1553 bool bCopyFile =
false;
1556 QList<CopyInfo>::Iterator it = files.begin();
1558 while (it != files.end() && !bCopyFile)
1560 const QString destFile = (*it).uDest.path();
1561 bCopyFile = !shouldSkip( destFile );
1572 if (m_freeSpace < (*it).size) {
1580 const KUrl& uSource = (*it).uSource;
1581 const KUrl& uDest = (*it).uDest;
1586 if ( uDest == uSource )
1589 bOverwrite = shouldOverwriteFile( destFile );
1591 m_bCurrentOperationIsLink =
false;
1596 newjob = linkNextFile(uSource, uDest, flags);
1599 }
else if ( !(*it).linkDest.isEmpty() &&
1601 (uSource.host() == uDest.host()) &&
1602 (uSource.port() == uDest.port()) &&
1603 (uSource.
user() == uDest.
user()) &&
1612 m_currentSrcURL =
KUrl( (*it).linkDest );
1613 m_currentDestURL = uDest;
1617 m_bCurrentOperationIsLink =
true;
1624 if ((*it).mtime != -1) {
1630 m_currentSrcURL=uSource;
1631 m_currentDestURL=uDest;
1640 int permissions = (*it).permissions;
1641 if ( m_defaultPermissions || ( remoteSource && uDest.
isLocalFile() ) )
1647 if ((*it).mtime != -1) {
1652 m_currentSrcURL=uSource;
1653 m_currentDestURL=uDest;
1656 q->addSubjob(newjob);
1657 q->connect( newjob, SIGNAL(processedSize(
KJob*,qulonglong)),
1658 SLOT(slotProcessedSize(
KJob*,qulonglong)) );
1659 q->connect( newjob, SIGNAL(totalSize(
KJob*,qulonglong)),
1660 SLOT(slotTotalSize(
KJob*,qulonglong)) );
1670 void CopyJobPrivate::deleteNextDir()
1678 KUrl::List::Iterator it = --dirsToRemove.end();
1681 dirsToRemove.erase(it);
1682 q->addSubjob( job );
1688 m_directoriesCopiedIterator = m_directoriesCopied.constBegin();
1689 setNextDirAttribute();
1693 void CopyJobPrivate::setNextDirAttribute()
1696 while (m_directoriesCopiedIterator != m_directoriesCopied.constEnd() &&
1697 (*m_directoriesCopiedIterator).mtime == -1) {
1698 ++m_directoriesCopiedIterator;
1700 if ( m_directoriesCopiedIterator != m_directoriesCopied.constEnd() ) {
1701 const KUrl url = (*m_directoriesCopiedIterator).uDest;
1702 const time_t mtime = (*m_directoriesCopiedIterator).mtime;
1703 const QDateTime dt = QDateTime::fromTime_t(mtime);
1704 ++m_directoriesCopiedIterator;
1708 q->addSubjob( job );
1711 #if 0 // ifdef Q_OS_UNIX
1715 QLinkedList<CopyInfo>::const_iterator it = m_directoriesCopied.constBegin();
1716 for ( ; it != m_directoriesCopied.constEnd() ; ++it ) {
1717 const KUrl& url = (*it).uDest;
1718 if ( url.
isLocalFile() && (*it).mtime != (time_t)-1 ) {
1719 KDE_struct_stat statbuf;
1721 struct utimbuf utbuf;
1722 utbuf.actime = statbuf.st_atime;
1723 utbuf.modtime = (*it).mtime;
1724 utime( path, &utbuf );
1729 m_directoriesCopied.clear();
1734 m_reportTimer->stop();
1748 if (!d->m_bOnlyRenames) {
1750 KUrl url(d->m_globalDest);
1751 if (d->m_globalDestinationState !=
DEST_IS_DIR || d->m_asMethod)
1756 if (d->m_mode ==
CopyJob::Move && !d->m_successSrcList.isEmpty()) {
1757 kDebug(7007) <<
"KDirNotify'ing FilesRemoved" << d->m_successSrcList.toStringList();
1764 for (QSet<QString>::const_iterator it = d->m_parentDirs.constBegin() ; it != d->m_parentDirs.constEnd() ; ++it)
1770 void CopyJobPrivate::slotProcessedSize(
KJob*, qulonglong data_size )
1774 m_fileProcessedSize = data_size;
1775 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1777 if ( m_processedSize + m_fileProcessedSize > m_totalSize )
1780 m_totalSize = m_processedSize + m_fileProcessedSize;
1785 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1788 void CopyJobPrivate::slotTotalSize(
KJob*, qulonglong size )
1796 if ( m_bSingleFileCopy && size != m_totalSize)
1804 void CopyJobPrivate::slotResultDeletingDirs(
KJob * job )
1812 m_successSrcList.append(static_cast<KIO::SimpleJob*>(job)->url());
1814 q->removeSubjob( job );
1815 assert( !q->hasSubjobs() );
1819 void CopyJobPrivate::slotResultSettingDirAttributes(
KJob * job )
1828 q->removeSubjob( job );
1829 assert( !q->hasSubjobs() );
1830 setNextDirAttribute();
1834 void CopyJobPrivate::slotResultRenaming(
KJob* job )
1837 int err = job->
error();
1842 m_incomingMetaData += kiojob->
metaData();
1843 q->removeSubjob( job );
1844 assert ( !q->hasSubjobs() );
1847 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
1848 dest.
addPath( m_currentSrcURL.fileName() );
1860 kDebug(7007) <<
"Couldn't rename directly, dest already exists. Detected special case of lower/uppercase renaming in same dir, try with 2 rename calls";
1861 const QString _src( m_currentSrcURL.toLocalFile() );
1862 const QString _dest( dest.toLocalFile() );
1866 const bool openOk = tmpFile.open();
1868 kWarning(7007) <<
"Couldn't open temp file in" << _tmpPrefix;
1870 const QString _tmp( tmpFile.fileName() );
1873 kDebug(7007) <<
"KTemporaryFile using" << _tmp <<
"as intermediary";
1876 if (!QFile::exists( _dest ) &&
KDE::rename(_tmp, _dest) == 0) {
1880 kDebug(7007) <<
"Didn't manage to rename" << _tmp <<
"to" << _dest <<
", reverting";
1883 kError(7007) <<
"Couldn't rename" << _tmp <<
"back to" << _src <<
'!';
1885 q->Job::slotResult(job);
1890 kDebug(7007) <<
"mv" << _src << _tmp <<
"failed:" << strerror(errno);
1911 if ((isDir && m_bAutoSkipDirs) || (!isDir && m_bAutoSkipFiles)) {
1915 }
else if ((isDir && m_bOverwriteAllDirs) || (!isDir && m_bOverwriteAllFiles)) {
1917 }
else if ((isDir && m_bAutoRenameDirs) || (!isDir && m_bAutoRenameFiles)) {
1918 KUrl destDirectory(m_currentDestURL);
1919 destDirectory.setPath(destDirectory.directory());
1922 m_dest.setPath(m_currentDestURL.path());
1923 m_dest.setFileName(newName);
1929 }
else if ( q->isInteractive() ) {
1936 time_t ctimeSrc = (time_t) -1;
1937 time_t ctimeDest = (time_t) -1;
1938 time_t mtimeSrc = (time_t) -1;
1939 time_t mtimeDest = (time_t) -1;
1946 KDE_struct_stat stat_buf;
1947 if ( m_currentSrcURL.isLocalFile() &&
1948 KDE::stat(m_currentSrcURL.toLocalFile(), &stat_buf) == 0 ) {
1949 sizeSrc = stat_buf.st_size;
1950 ctimeSrc = stat_buf.st_ctime;
1951 mtimeSrc = stat_buf.st_mtime;
1952 isDir = S_ISDIR(stat_buf.st_mode);
1954 if ( dest.isLocalFile() &&
1955 KDE::stat(dest.toLocalFile(), &stat_buf) == 0 ) {
1956 sizeDest = stat_buf.st_size;
1957 ctimeDest = stat_buf.st_ctime;
1958 mtimeDest = stat_buf.st_mtime;
1959 destIsDir = S_ISDIR(stat_buf.st_mode);
1964 if (!isDir && destIsDir) {
1969 if ( m_srcList.count() > 1 )
1975 m_reportTimer->stop();
1980 m_currentSrcURL.url(),
1984 ctimeSrc, ctimeDest,
1985 mtimeSrc, mtimeDest );
2000 m_bAutoRenameDirs =
true;
2003 m_bAutoRenameFiles =
true;
2010 m_dest.setPath( newPath );
2019 m_bAutoSkipDirs =
true;
2021 m_bAutoSkipFiles =
true;
2029 m_bOverwriteAllDirs =
true;
2031 m_bOverwriteAllFiles =
true;
2039 kDebug(7007) <<
"adding to overwrite list: " << dest.path();
2040 m_overwriteList.insert( dest.path() );
2049 q->setErrorText( errText );
2054 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", aborting";
2056 q->setErrorText( errText );
2060 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", reverting to normal way, starting with stat";
2065 m_bOnlyRenames =
false;
2069 kDebug(7007) <<
"Renaming succeeded, move on";
2071 emit q->copyingDone( q, *m_currentStatSrc, dest, -1 ,
true,
true );
2072 m_successSrcList.append(*m_currentStatSrc);
2086 switch ( d->state ) {
2088 d->slotResultStating( job );
2092 d->slotResultRenaming( job );
2110 d->slotResultCreatingDirs( job );
2113 d->slotResultConflictCreatingDirs( job );
2116 d->slotResultCopyingFiles( job );
2119 d->slotResultConflictCopyingFiles( job );
2122 d->slotResultDeletingDirs( job );
2125 d->slotResultSettingDirAttributes( job );
2134 d_func()->m_defaultPermissions = b;
2139 return d_func()->m_mode;
2144 d_func()->m_bAutoSkipFiles = autoSkip;
2145 d_func()->m_bAutoSkipDirs = autoSkip;
2150 d_func()->m_bAutoRenameFiles = autoRename;
2151 d_func()->m_bAutoRenameDirs = autoRename;
2156 d_func()->m_bOverwriteAllDirs = overwriteAll;
2163 srcList.append( src );
2164 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
false, flags);
2171 srcList.append( src );
2172 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
true, flags);
2178 return CopyJobPrivate::newJob(src, dest,
CopyJob::Copy,
false, flags);
2185 srcList.append( src );
2186 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
false, flags);
2193 srcList.append( src );
2194 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
true, flags);
2200 return CopyJobPrivate::newJob(src, dest,
CopyJob::Move,
false, flags);
2206 srcList.append( src );
2207 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2212 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2218 srcList.append( src );
2219 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2225 srcList.append( src );
2226 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2231 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2234 #include "copyjob.moc"