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()));
260 qRegisterMetaType<KIO::UDSEntry>(
"KIO::UDSEntry");
269 return d_func()->m_srcList;
274 return d_func()->m_dest;
277 void CopyJobPrivate::slotStart()
285 m_reportTimer =
new QTimer(q);
287 q->connect(m_reportTimer,SIGNAL(
timeout()),q,SLOT(slotReport()));
299 void CopyJobPrivate::slotResultStating(
KJob *job )
312 kDebug(7007) <<
"Error while stating source. Activating hack";
313 q->removeSubjob( job );
314 assert ( !q->hasSubjobs() );
317 info.
mtime = (time_t) -1;
318 info.
ctime = (time_t) -1;
323 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
326 files.append( info );
332 q->Job::slotResult( job );
340 if ( m_dest.isLocalFile() ) {
341 QString path = m_dest.toLocalFile();
346 path = QFileInfo(path).absolutePath();
350 m_freeSpace = KDiskFreeSpaceInfo::freeSpaceInfo( path ).available();
356 const bool isGlobalDest = m_dest == m_globalDest;
357 const bool isDir = entry.
isDir();
370 m_dest.setPath(sLocalPath);
372 m_globalDest = m_dest;
376 m_globalDestinationState = destinationState;
378 q->removeSubjob( job );
379 assert ( !q->hasSubjobs() );
384 sourceStated(entry, static_cast<SimpleJob*>(job)->url());
385 q->removeSubjob( job );
389 void CopyJobPrivate::sourceStated(
const UDSEntry& entry,
const KUrl& sourceUrl)
392 const bool isDir = entry.
isDir();
411 kDebug() <<
"Using sLocalPath. destinationState=" << destinationState;
418 addCopyInfoFromUDSEntry(entry, srcurl,
false, m_dest);
420 m_currentDest = m_dest;
421 m_bCurrentSrcIsDir =
false;
432 m_parentDirs.insert(parentDir);
435 m_bCurrentSrcIsDir =
true;
445 if (!sName.isEmpty())
449 if (!dispName.isEmpty())
450 directory = dispName;
451 else if (!sName.isEmpty())
454 m_currentDest.addPath( directory );
464 if ( m_dest == m_globalDest )
465 m_globalDestinationState = destinationState;
468 startListing( srcurl );
476 m_parentDirs.insert(parentDir);
490 void CopyJobPrivate::slotReport()
493 if ( q->isSuspended() )
501 q->setProcessedAmount(
KJob::Files, m_processedFiles );
508 emitMoving(q, m_currentSrcURL, m_currentDestURL);
509 emit q->moving( q, m_currentSrcURL, m_currentDestURL);
513 emitCopying( q, m_currentSrcURL, m_currentDestURL );
514 emit q->linking( q, m_currentSrcURL.path(), m_currentDestURL );
518 emitCopying( q, m_currentSrcURL, m_currentDestURL );
519 emit q->copying( q, m_currentSrcURL, m_currentDestURL );
529 emit q->creatingDir( q, m_currentDestURL );
530 emitCreatingDir( q, m_currentDestURL );
541 emitMoving( q, m_currentSrcURL, m_currentDestURL );
545 emitCopying( q, m_currentSrcURL, m_currentDestURL );
561 UDSEntryList::ConstIterator it = list.constBegin();
562 UDSEntryList::ConstIterator
end = list.constEnd();
563 for (; it != end; ++it) {
565 addCopyInfoFromUDSEntry(entry, static_cast<SimpleJob *>(job)->url(), m_bCurrentSrcIsDir, m_currentDest);
571 const KUrl url = subJob->
url();
581 void CopyJobPrivate::addCopyInfoFromUDSEntry(
const UDSEntry& entry,
const KUrl& srcUrl,
bool srcIsDir,
const KUrl& currentDest)
589 m_totalSize += info.size;
595 if (!urlStr.isEmpty())
598 const bool isDir = entry.
isDir();
601 if (fileName != QLatin1String(
"..") && fileName != QLatin1String(
".")) {
602 const bool hasCustomURL = !url.isEmpty() || !localPath.isEmpty();
613 url =
KUrl(localPath);
617 info.uDest = currentDest;
631 int numberOfSlashes = fileName.count(
'/');
634 for (
int n = 0; n < numberOfSlashes + 1; ++n) {
635 pos = path.lastIndexOf(
'/', pos - 1);
637 kWarning(7007) <<
"kioslave bug: not enough slashes in UDS_URL" << path <<
"- looking for" << numberOfSlashes <<
"slashes";
642 destFileName = path.mid(pos + 1);
646 destFileName = fileName;
649 destFileName = displayName.isEmpty() ? fileName : displayName;
655 if (destFileName.isEmpty()) {
660 info.uDest.addPath(destFileName);
664 if (info.linkDest.isEmpty() && isDir && m_mode !=
CopyJob::Link) {
667 dirsToRemove.append(info.uSource);
675 void CopyJobPrivate::skipSrc(
bool isDir)
677 m_dest = m_globalDest;
678 destinationState = m_globalDestinationState;
679 skip(*m_currentStatSrc, isDir);
684 void CopyJobPrivate::statNextSrc()
690 m_dest = m_globalDest;
691 destinationState = m_globalDestinationState;
696 void CopyJobPrivate::statCurrentSrc()
699 if (m_currentStatSrc != m_srcList.constEnd()) {
700 m_currentSrcURL = (*m_currentStatSrc);
704 m_currentDest = m_dest;
707 info.mtime = (time_t) -1;
708 info.ctime = (time_t) -1;
710 info.uSource = m_currentSrcURL;
711 info.uDest = m_currentDest;
713 if (destinationState ==
DEST_IS_DIR && !m_asMethod) {
715 (m_currentSrcURL.protocol() == info.uDest.protocol()) &&
716 (m_currentSrcURL.host() == info.uDest.host()) &&
717 (m_currentSrcURL.port() == info.uDest.port()) &&
718 (m_currentSrcURL.user() == info.uDest.user()) &&
719 (m_currentSrcURL.pass() == info.uDest.pass()) ) {
721 info.uDest.addPath( m_currentSrcURL.fileName() );
729 files.append( info );
737 if (!cachedItem.
isNull()) {
738 entry = cachedItem.
entry();
741 m_currentSrcURL = cachedItem.
mostLocalUrl(dummyIsLocal);
752 if ( (m_currentSrcURL.protocol() == m_dest.protocol()) &&
753 (m_currentSrcURL.host() == m_dest.host()) &&
754 (m_currentSrcURL.port() == m_dest.port()) &&
755 (m_currentSrcURL.user() == m_dest.user()) &&
756 (m_currentSrcURL.pass() == m_dest.pass()) )
758 startRenameJob( m_currentSrcURL );
763 startRenameJob( m_dest );
768 startRenameJob( m_currentSrcURL );
775 QPointer<CopyJob> that = q;
782 m_bOnlyRenames =
false;
787 kDebug(7007) <<
"fast path! found info about" << m_currentSrcURL <<
"in KDirLister";
789 QMetaObject::invokeMethod(q,
"sourceStated", Qt::QueuedConnection, Q_ARG(
KIO::UDSEntry, entry), Q_ARG(
KUrl, m_currentSrcURL));
798 m_currentDestURL = m_dest;
809 kDebug(7007)<<
"Stating finished. To copy:"<<m_totalSize<<
", available:"<<m_freeSpace;
813 emit q->aboutToCreate( q, dirs );
814 if (!files.isEmpty())
815 emit q->aboutToCreate( q, files );
817 m_bSingleFileCopy = ( files.count() == 1 &&
dirs.isEmpty() );
824 void CopyJobPrivate::startRenameJob(
const KUrl& slave_url )
829 if (m_currentSrcURL.isLocalFile()) {
831 if (!m_parentDirs.contains(parentDir)) {
833 m_parentDirs.insert(parentDir);
839 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
840 dest.
addPath( m_currentSrcURL.fileName() );
841 m_currentDestURL = dest;
842 kDebug(7007) << m_currentSrcURL <<
"->" << dest <<
"trying direct rename first";
847 info.mtime = (time_t) -1;
848 info.ctime = (time_t) -1;
850 info.uSource = m_currentSrcURL;
852 QList<CopyInfo> files;
854 emit q->aboutToCreate( q, files );
856 KIO_ARGS << m_currentSrcURL << dest << (qint8)
false ;
859 q->addSubjob( newJob );
860 if ( m_currentSrcURL.directory() != dest.directory() )
861 m_bOnlyRenames =
false;
864 void CopyJobPrivate::startListing(
const KUrl & src )
875 q->addSubjob( newjob );
878 void CopyJobPrivate::skip(
const KUrl & sourceUrl,
bool isDir)
885 while (dirsToRemove.removeAll(dir) > 0) {
892 bool CopyJobPrivate::shouldOverwriteDir(
const QString& path )
const
894 if ( m_bOverwriteAllDirs )
896 return m_overwriteList.contains(path);
899 bool CopyJobPrivate::shouldOverwriteFile(
const QString& path )
const
901 if ( m_bOverwriteAllFiles )
903 return m_overwriteList.contains(path);
906 bool CopyJobPrivate::shouldSkip(
const QString& path )
const
908 Q_FOREACH(
const QString& skipPath, m_skipList) {
909 if ( path.startsWith(skipPath) )
915 void CopyJobPrivate::slotResultCreatingDirs(
KJob * job )
919 QList<CopyInfo>::Iterator it =
dirs.begin();
923 m_conflictError = job->
error();
929 if ( m_bAutoSkipDirs ) {
936 const QString destDir = (*it).uDest.path();
937 if ( shouldOverwriteDir( destDir ) ) {
938 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
941 if (m_bAutoRenameDirs) {
944 KUrl destDirectory((*it).uDest);
945 destDirectory.setPath(destDirectory.directory());
948 KUrl newUrl((*it).uDest);
949 newUrl.setFileName(newName);
951 emit q->renamed(q, (*it).uDest, newUrl);
957 QList<CopyInfo>::Iterator renamedirit = it;
960 for(; renamedirit !=
dirs.end() ; ++renamedirit) {
961 QString path = (*renamedirit).uDest.path();
962 if (path.startsWith(oldPath)) {
964 n.replace(0, oldPath.length(), newPath);
965 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
966 <<
"was going to be" << path
967 <<
", changed into" << n;
968 (*renamedirit).uDest.setPath(n);
972 QList<CopyInfo>::Iterator renamefileit = files.begin();
973 for(; renamefileit != files.end() ; ++renamefileit) {
974 QString path = (*renamefileit).uDest.path();
975 if (path.startsWith(oldPath)) {
977 n.replace(0, oldPath.length(), newPath);
978 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
979 <<
"was going to be" << path
980 <<
", changed into" << n;
981 (*renamefileit).uDest.setPath(n);
984 if (!
dirs.isEmpty()) {
985 emit q->aboutToCreate(q, dirs);
987 if (!files.isEmpty()) {
988 emit q->aboutToCreate(q, files);
993 if (!q->isInteractive()) {
994 q->Job::slotResult(job);
998 assert(((
SimpleJob*)job)->url().url() == (*it).uDest.
url());
999 q->removeSubjob(job);
1000 assert (!q->hasSubjobs());
1003 KUrl existingDest((*it).uDest);
1006 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingDest;
1008 q->addSubjob(newJob);
1017 q->Job::slotResult( job );
1024 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true,
false );
1025 m_directoriesCopied.append( *it );
1031 q->removeSubjob( job );
1032 assert( !q->hasSubjobs() );
1036 void CopyJobPrivate::slotResultConflictCreatingDirs(
KJob * job )
1042 QList<CopyInfo>::Iterator it =
dirs.begin();
1053 q->removeSubjob( job );
1054 assert ( !q->hasSubjobs() );
1061 if( (*it).uSource == (*it).uDest ||
1062 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1069 QString existingDest = (*it).uDest.path();
1072 m_reportTimer->stop();
1074 (*it).uSource.url(),
1077 (*it).size, destsize,
1078 (*it).ctime, destctime,
1079 (*it).mtime, destmtime );
1088 m_bAutoRenameDirs =
true;
1093 KUrl newUrl( (*it).uDest );
1094 newUrl.setPath( newPath );
1095 emit q->renamed( q, (*it).uDest, newUrl );
1100 QList<CopyInfo>::Iterator renamedirit = it;
1103 for( ; renamedirit !=
dirs.end() ; ++renamedirit )
1105 QString path = (*renamedirit).uDest.path();
1106 if ( path.startsWith( oldPath ) ) {
1108 n.replace( 0, oldPath.length(), newPath );
1109 kDebug(7007) <<
"dirs list:" << (*renamedirit).uSource.path()
1110 <<
"was going to be" << path
1111 <<
", changed into" << n;
1112 (*renamedirit).uDest.setPath( n );
1116 QList<CopyInfo>::Iterator renamefileit = files.begin();
1117 for( ; renamefileit != files.end() ; ++renamefileit )
1119 QString path = (*renamefileit).uDest.path();
1120 if ( path.startsWith( oldPath ) ) {
1122 n.replace( 0, oldPath.length(), newPath );
1123 kDebug(7007) <<
"files list:" << (*renamefileit).uSource.path()
1124 <<
"was going to be" << path
1125 <<
", changed into" << n;
1126 (*renamefileit).uDest.setPath( n );
1129 if (!
dirs.isEmpty())
1130 emit q->aboutToCreate( q, dirs );
1131 if (!files.isEmpty())
1132 emit q->aboutToCreate( q, files );
1136 m_bAutoSkipDirs =
true;
1139 m_skipList.append( existingDest );
1140 skip((*it).uSource,
true);
1146 m_overwriteList.insert( existingDest );
1147 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1153 m_bOverwriteAllDirs =
true;
1154 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
true ,
false );
1167 void CopyJobPrivate::createNextDir()
1171 if ( !
dirs.isEmpty() )
1174 QList<CopyInfo>::Iterator it =
dirs.begin();
1176 while( it !=
dirs.end() && udir.isEmpty() )
1179 if ( shouldSkip( dir ) ) {
1186 if ( !udir.isEmpty() )
1192 if (shouldOverwriteFile(udir.
path())) {
1196 m_currentDestURL = udir;
1199 q->addSubjob(newjob);
1211 for ( QSet<QString>::const_iterator it = m_parentDirs.constBegin() ; it != m_parentDirs.constEnd() ; ++it )
1221 void CopyJobPrivate::slotResultCopyingFiles(
KJob * job )
1225 QList<CopyInfo>::Iterator it = files.begin();
1229 if ( m_bAutoSkipFiles )
1231 skip((*it).uSource,
false);
1232 m_fileProcessedSize = (*it).size;
1237 m_conflictError = job->
error();
1243 if (m_bAutoRenameFiles) {
1244 KUrl destDirectory((*it).uDest);
1245 destDirectory.setPath(destDirectory.directory());
1248 KUrl newUrl((*it).uDest);
1249 newUrl.setFileName(newName);
1251 emit q->renamed(q, (*it).uDest, newUrl);
1252 (*it).uDest = newUrl;
1254 QList<CopyInfo> files;
1256 emit q->aboutToCreate(q, files);
1259 if ( !q->isInteractive() ) {
1260 q->Job::slotResult( job );
1264 q->removeSubjob(job);
1265 assert (!q->hasSubjobs());
1267 KUrl existingFile((*it).uDest);
1270 kDebug(7007) <<
"KIO::stat for resolving conflict on " << existingFile;
1272 q->addSubjob(newJob);
1278 if ( m_bCurrentOperationIsLink && qobject_cast<KIO::DeleteJob*>( job ) )
1282 m_fileProcessedSize = (*it).size;
1285 if ( !q->isInteractive() ) {
1286 q->Job::slotResult( job );
1291 slotResultConflictCopyingFiles( job );
1300 && !qobject_cast<KIO::DeleteJob *>( job )
1303 q->removeSubjob( job );
1304 assert ( !q->hasSubjobs() );
1308 q->addSubjob( newjob );
1312 if ( m_bCurrentOperationIsLink )
1316 emit q->copyingLinkDone( q, (*it).uSource, target, (*it).uDest );
1320 emit q->copyingDone( q, (*it).uSource, (*it).uDest, (*it).mtime,
false,
false );
1325 m_successSrcList.append((*it).uSource);
1327 m_freeSpace -= (*it).size;
1337 m_processedSize += m_fileProcessedSize;
1338 m_fileProcessedSize = 0;
1345 m_incomingMetaData += kiojob->
metaData();
1346 q->removeSubjob( job );
1347 assert( !q->hasSubjobs() );
1351 void CopyJobPrivate::slotResultConflictCopyingFiles(
KJob * job )
1356 QList<CopyInfo>::Iterator it = files.begin();
1362 m_reportTimer->stop();
1385 if ( (*it).uSource == (*it).uDest ||
1386 ((*it).uSource.protocol() == (*it).uDest.protocol() &&
1394 if ( !m_bSingleFileCopy )
1397 res = q->ui()->askFileRename( q, !isDir ?
1398 i18n(
"File Already Exists") :
i18n(
"Already Exists as Folder"),
1399 (*it).uSource.url(),
1402 (*it).size, destsize,
1403 (*it).ctime, destctime,
1404 (*it).mtime, destmtime );
1411 else if ( !q->isInteractive() ) {
1412 q->Job::slotResult( job );
1430 q->removeSubjob( job );
1431 assert ( !q->hasSubjobs() );
1438 m_bAutoRenameFiles =
true;
1442 KUrl newUrl( (*it).uDest );
1443 newUrl.setPath( newPath );
1444 emit q->renamed( q, (*it).uDest, newUrl );
1445 (*it).uDest = newUrl;
1447 QList<CopyInfo> files;
1449 emit q->aboutToCreate( q, files );
1453 m_bAutoSkipFiles =
true;
1457 skip((*it).uSource,
false);
1458 m_processedSize += (*it).size;
1463 m_bOverwriteAllFiles =
true;
1467 m_overwriteList.insert( (*it).uDest.path() );
1476 KIO::Job* CopyJobPrivate::linkNextFile(
const KUrl& uSource,
const KUrl& uDest, JobFlags flags )
1481 (uSource.host() == uDest.host()) &&
1482 (uSource.port() == uDest.port()) &&
1483 (uSource.
user() == uDest.
user()) &&
1491 m_bCurrentOperationIsLink =
true;
1492 m_currentSrcURL=uSource;
1493 m_currentDestURL=uDest;
1506 if (
f.open( QIODevice::ReadWrite ) )
1515 config.
writeEntry(
"Type", QString::fromLatin1(
"Link") );
1517 if ( protocol == QLatin1String(
"ftp") )
1518 config.
writeEntry(
"Icon", QString::fromLatin1(
"folder-remote") );
1519 else if ( protocol == QLatin1String(
"http") )
1520 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-html") );
1521 else if ( protocol == QLatin1String(
"info") )
1522 config.
writeEntry(
"Icon", QString::fromLatin1(
"text-x-texinfo") );
1523 else if ( protocol == QLatin1String(
"mailto") )
1524 config.
writeEntry(
"Icon", QString::fromLatin1(
"internet-mail") );
1526 config.
writeEntry(
"Icon", QString::fromLatin1(
"unknown") );
1528 files.erase( files.begin() );
1536 kDebug(7007) <<
"ERR_CANNOT_OPEN_FOR_WRITING";
1552 void CopyJobPrivate::copyNextFile()
1555 bool bCopyFile =
false;
1558 QList<CopyInfo>::Iterator it = files.begin();
1560 while (it != files.end() && !bCopyFile)
1562 const QString destFile = (*it).uDest.path();
1563 bCopyFile = !shouldSkip( destFile );
1574 if (m_freeSpace < (*it).size) {
1582 const KUrl& uSource = (*it).uSource;
1583 const KUrl& uDest = (*it).uDest;
1588 if ( uDest == uSource )
1591 bOverwrite = shouldOverwriteFile( destFile );
1593 m_bCurrentOperationIsLink =
false;
1598 newjob = linkNextFile(uSource, uDest, flags);
1601 }
else if ( !(*it).linkDest.isEmpty() &&
1603 (uSource.host() == uDest.host()) &&
1604 (uSource.port() == uDest.port()) &&
1605 (uSource.
user() == uDest.
user()) &&
1614 m_currentSrcURL =
KUrl( (*it).linkDest );
1615 m_currentDestURL = uDest;
1619 m_bCurrentOperationIsLink =
true;
1626 if ((*it).mtime != -1) {
1632 m_currentSrcURL=uSource;
1633 m_currentDestURL=uDest;
1642 int permissions = (*it).permissions;
1643 if ( m_defaultPermissions || ( remoteSource && uDest.
isLocalFile() ) )
1649 if ((*it).mtime != -1) {
1654 m_currentSrcURL=uSource;
1655 m_currentDestURL=uDest;
1658 q->addSubjob(newjob);
1659 q->connect( newjob, SIGNAL(processedSize(
KJob*,qulonglong)),
1660 SLOT(slotProcessedSize(
KJob*,qulonglong)) );
1661 q->connect( newjob, SIGNAL(totalSize(
KJob*,qulonglong)),
1662 SLOT(slotTotalSize(
KJob*,qulonglong)) );
1672 void CopyJobPrivate::deleteNextDir()
1680 KUrl::List::Iterator it = --dirsToRemove.end();
1683 dirsToRemove.erase(it);
1684 q->addSubjob( job );
1690 m_directoriesCopiedIterator = m_directoriesCopied.constBegin();
1691 setNextDirAttribute();
1695 void CopyJobPrivate::setNextDirAttribute()
1698 while (m_directoriesCopiedIterator != m_directoriesCopied.constEnd() &&
1699 (*m_directoriesCopiedIterator).mtime == -1) {
1700 ++m_directoriesCopiedIterator;
1702 if ( m_directoriesCopiedIterator != m_directoriesCopied.constEnd() ) {
1703 const KUrl url = (*m_directoriesCopiedIterator).uDest;
1704 const time_t mtime = (*m_directoriesCopiedIterator).mtime;
1705 const QDateTime dt = QDateTime::fromTime_t(mtime);
1706 ++m_directoriesCopiedIterator;
1710 q->addSubjob( job );
1713 #if 0 // ifdef Q_OS_UNIX
1717 QLinkedList<CopyInfo>::const_iterator it = m_directoriesCopied.constBegin();
1718 for ( ; it != m_directoriesCopied.constEnd() ; ++it ) {
1719 const KUrl& url = (*it).uDest;
1720 if ( url.
isLocalFile() && (*it).mtime != (time_t)-1 ) {
1721 KDE_struct_stat statbuf;
1723 struct utimbuf utbuf;
1724 utbuf.actime = statbuf.st_atime;
1725 utbuf.modtime = (*it).mtime;
1726 utime( path, &utbuf );
1731 m_directoriesCopied.clear();
1736 m_reportTimer->stop();
1750 if (!d->m_bOnlyRenames) {
1752 KUrl url(d->m_globalDest);
1753 if (d->m_globalDestinationState !=
DEST_IS_DIR || d->m_asMethod)
1758 if (d->m_mode ==
CopyJob::Move && !d->m_successSrcList.isEmpty()) {
1759 kDebug(7007) <<
"KDirNotify'ing FilesRemoved" << d->m_successSrcList.toStringList();
1766 for (QSet<QString>::const_iterator it = d->m_parentDirs.constBegin() ; it != d->m_parentDirs.constEnd() ; ++it)
1772 void CopyJobPrivate::slotProcessedSize(
KJob*, qulonglong data_size )
1776 m_fileProcessedSize = data_size;
1777 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1779 if ( m_processedSize + m_fileProcessedSize > m_totalSize )
1782 m_totalSize = m_processedSize + m_fileProcessedSize;
1787 q->setProcessedAmount(
KJob::Bytes, m_processedSize + m_fileProcessedSize);
1790 void CopyJobPrivate::slotTotalSize(
KJob*, qulonglong size )
1798 if ( m_bSingleFileCopy && size != m_totalSize)
1806 void CopyJobPrivate::slotResultDeletingDirs(
KJob * job )
1814 m_successSrcList.append(static_cast<KIO::SimpleJob*>(job)->url());
1816 q->removeSubjob( job );
1817 assert( !q->hasSubjobs() );
1821 void CopyJobPrivate::slotResultSettingDirAttributes(
KJob * job )
1830 q->removeSubjob( job );
1831 assert( !q->hasSubjobs() );
1832 setNextDirAttribute();
1836 void CopyJobPrivate::slotResultRenaming(
KJob* job )
1839 int err = job->
error();
1844 m_incomingMetaData += kiojob->
metaData();
1845 q->removeSubjob( job );
1846 assert ( !q->hasSubjobs() );
1849 if ( destinationState ==
DEST_IS_DIR && !m_asMethod )
1850 dest.
addPath( m_currentSrcURL.fileName() );
1862 kDebug(7007) <<
"Couldn't rename directly, dest already exists. Detected special case of lower/uppercase renaming in same dir, try with 2 rename calls";
1863 const QString _src( m_currentSrcURL.toLocalFile() );
1864 const QString _dest( dest.toLocalFile() );
1868 const bool openOk = tmpFile.open();
1870 kWarning(7007) <<
"Couldn't open temp file in" << _tmpPrefix;
1872 const QString _tmp( tmpFile.fileName() );
1875 kDebug(7007) <<
"KTemporaryFile using" << _tmp <<
"as intermediary";
1878 if (!QFile::exists( _dest ) &&
KDE::rename(_tmp, _dest) == 0) {
1882 kDebug(7007) <<
"Didn't manage to rename" << _tmp <<
"to" << _dest <<
", reverting";
1885 kError(7007) <<
"Couldn't rename" << _tmp <<
"back to" << _src <<
'!';
1887 q->Job::slotResult(job);
1892 kDebug(7007) <<
"mv" << _src << _tmp <<
"failed:" << strerror(errno);
1913 if ((isDir && m_bAutoSkipDirs) || (!isDir && m_bAutoSkipFiles)) {
1917 }
else if ((isDir && m_bOverwriteAllDirs) || (!isDir && m_bOverwriteAllFiles)) {
1919 }
else if ((isDir && m_bAutoRenameDirs) || (!isDir && m_bAutoRenameFiles)) {
1920 KUrl destDirectory(m_currentDestURL);
1921 destDirectory.setPath(destDirectory.directory());
1924 m_dest.setPath(m_currentDestURL.path());
1925 m_dest.setFileName(newName);
1931 }
else if ( q->isInteractive() ) {
1938 time_t ctimeSrc = (time_t) -1;
1939 time_t ctimeDest = (time_t) -1;
1940 time_t mtimeSrc = (time_t) -1;
1941 time_t mtimeDest = (time_t) -1;
1948 KDE_struct_stat stat_buf;
1949 if ( m_currentSrcURL.isLocalFile() &&
1950 KDE::stat(m_currentSrcURL.toLocalFile(), &stat_buf) == 0 ) {
1951 sizeSrc = stat_buf.st_size;
1952 ctimeSrc = stat_buf.st_ctime;
1953 mtimeSrc = stat_buf.st_mtime;
1954 isDir = S_ISDIR(stat_buf.st_mode);
1956 if ( dest.isLocalFile() &&
1957 KDE::stat(dest.toLocalFile(), &stat_buf) == 0 ) {
1958 sizeDest = stat_buf.st_size;
1959 ctimeDest = stat_buf.st_ctime;
1960 mtimeDest = stat_buf.st_mtime;
1961 destIsDir = S_ISDIR(stat_buf.st_mode);
1966 if (!isDir && destIsDir) {
1971 if ( m_srcList.count() > 1 )
1977 m_reportTimer->stop();
1982 m_currentSrcURL.url(),
1986 ctimeSrc, ctimeDest,
1987 mtimeSrc, mtimeDest );
2002 m_bAutoRenameDirs =
true;
2005 m_bAutoRenameFiles =
true;
2012 m_dest.setPath( newPath );
2021 m_bAutoSkipDirs =
true;
2023 m_bAutoSkipFiles =
true;
2031 m_bOverwriteAllDirs =
true;
2033 m_bOverwriteAllFiles =
true;
2041 kDebug(7007) <<
"adding to overwrite list: " << dest.path();
2042 m_overwriteList.insert( dest.path() );
2051 q->setErrorText( errText );
2056 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", aborting";
2058 q->setErrorText( errText );
2062 kDebug(7007) <<
"Couldn't rename" << m_currentSrcURL <<
"to" << dest <<
", reverting to normal way, starting with stat";
2067 m_bOnlyRenames =
false;
2071 kDebug(7007) <<
"Renaming succeeded, move on";
2073 emit q->copyingDone( q, *m_currentStatSrc, dest, -1 ,
true,
true );
2074 m_successSrcList.append(*m_currentStatSrc);
2088 switch ( d->state ) {
2090 d->slotResultStating( job );
2094 d->slotResultRenaming( job );
2112 d->slotResultCreatingDirs( job );
2115 d->slotResultConflictCreatingDirs( job );
2118 d->slotResultCopyingFiles( job );
2121 d->slotResultConflictCopyingFiles( job );
2124 d->slotResultDeletingDirs( job );
2127 d->slotResultSettingDirAttributes( job );
2136 d_func()->m_defaultPermissions = b;
2141 return d_func()->m_mode;
2146 d_func()->m_bAutoSkipFiles = autoSkip;
2147 d_func()->m_bAutoSkipDirs = autoSkip;
2152 d_func()->m_bAutoRenameFiles = autoRename;
2153 d_func()->m_bAutoRenameDirs = autoRename;
2158 d_func()->m_bOverwriteAllDirs = overwriteAll;
2165 srcList.append( src );
2166 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
false, flags);
2173 srcList.append( src );
2174 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Copy,
true, flags);
2180 return CopyJobPrivate::newJob(src, dest,
CopyJob::Copy,
false, flags);
2187 srcList.append( src );
2188 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
false, flags);
2195 srcList.append( src );
2196 return CopyJobPrivate::newJob(srcList, dest,
CopyJob::Move,
true, flags);
2202 return CopyJobPrivate::newJob(src, dest,
CopyJob::Move,
false, flags);
2208 srcList.append( src );
2209 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2214 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2220 srcList.append( src );
2221 return CopyJobPrivate::newJob(srcList, destDir,
CopyJob::Link,
false, flags);
2227 srcList.append( src );
2228 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2233 return CopyJobPrivate::newJob(srcList,
KUrl(
"trash:/" ),
CopyJob::Move,
false, flags);
2236 #include "copyjob.moc"