diff --git a/autotests/jobremotetest.cpp b/autotests/jobremotetest.cpp --- a/autotests/jobremotetest.cpp +++ b/autotests/jobremotetest.cpp @@ -67,7 +67,7 @@ static bool myExists(const QUrl &url) { - KIO::Job *job = KIO::stat(url, KIO::StatJob::DestinationSide, 0, KIO::HideProgressInfo); + KIO::Job *job = KIO::stat(url, KIO::StatJob::DestinationSide, KIO::StatJob::Basic, KIO::HideProgressInfo); job->setUiDelegate(nullptr); return job->exec(); } diff --git a/src/core/copyjob.cpp b/src/core/copyjob.cpp --- a/src/core/copyjob.cpp +++ b/src/core/copyjob.cpp @@ -362,7 +362,7 @@ // Stat the dest state = STATE_STATING; const QUrl dest = m_asMethod ? m_dest.adjusted(QUrl::RemoveFilename) : m_dest; - KIO::Job *job = KIO::stat(dest, StatJob::DestinationSide, 2, KIO::HideProgressInfo); + KIO::Job *job = KIO::stat(dest, StatJob::DestinationSide, KIO::StatJob::StatDefaultDetails, KIO::HideProgressInfo); qCDebug(KIO_COPYJOB_DEBUG) << "CopyJob: stating the dest" << m_dest; q->addSubjob(job); } @@ -907,7 +907,7 @@ } // Stat the next src url - Job *job = KIO::stat(m_currentSrcURL, StatJob::SourceSide, 2, KIO::HideProgressInfo); + Job *job = KIO::stat(m_currentSrcURL, StatJob::SourceSide, KIO::StatJob::StatDefaultDetails, KIO::HideProgressInfo); qCDebug(KIO_COPYJOB_DEBUG) << "KIO::stat on" << m_currentSrcURL; state = STATE_STATING; q->addSubjob(job); @@ -1138,7 +1138,7 @@ // We need to stat the existing dir, to get its last-modification time QUrl existingDest((*it).uDest); - SimpleJob *newJob = KIO::stat(existingDest, StatJob::DestinationSide, 2, KIO::HideProgressInfo); + SimpleJob *newJob = KIO::stat(existingDest, StatJob::DestinationSide, KIO::StatJob::StatDefaultDetails, KIO::HideProgressInfo); Scheduler::setJobPriority(newJob, 1); qCDebug(KIO_COPYJOB_DEBUG) << "KIO::stat for resolving conflict on" << existingDest; state = STATE_CONFLICT_CREATING_DIRS; @@ -1349,7 +1349,7 @@ Q_ASSERT(!q->hasSubjobs()); // We need to stat the existing file, to get its last-modification time QUrl existingFile((*it).uDest); - SimpleJob *newJob = KIO::stat(existingFile, StatJob::DestinationSide, 2, KIO::HideProgressInfo); + SimpleJob *newJob = KIO::stat(existingFile, StatJob::DestinationSide, KIO::StatJob::StatDefaultDetails, KIO::HideProgressInfo); Scheduler::setJobPriority(newJob, 1); qCDebug(KIO_COPYJOB_DEBUG) << "KIO::stat for resolving conflict on" << existingFile; state = STATE_CONFLICT_COPYING_FILES; @@ -2001,7 +2001,7 @@ m_dest = destDirectory; m_dest.setPath(concatPaths(m_dest.path(), newName)); - KIO::Job *job = KIO::stat(m_dest, StatJob::DestinationSide, 2, KIO::HideProgressInfo); + KIO::Job *job = KIO::stat(m_dest, StatJob::DestinationSide, KIO::StatJob::StatDefaultDetails, KIO::HideProgressInfo); state = STATE_STATING; destinationState = DEST_NOT_STATED; q->addSubjob(job); @@ -2092,7 +2092,7 @@ // Set m_dest to the chosen destination // This is only for this src url; the next one will revert to m_globalDest m_dest.setPath(newPath); - KIO::Job *job = KIO::stat(m_dest, StatJob::DestinationSide, 2, KIO::HideProgressInfo); + KIO::Job *job = KIO::stat(m_dest, StatJob::DestinationSide, KIO::StatJob::StatDefaultDetails, KIO::HideProgressInfo); state = STATE_STATING; destinationState = DEST_NOT_STATED; q->addSubjob(job); @@ -2146,7 +2146,7 @@ } qCDebug(KIO_COPYJOB_DEBUG) << "Couldn't rename" << m_currentSrcURL << "to" << dest << ", reverting to normal way, starting with stat"; qCDebug(KIO_COPYJOB_DEBUG) << "KIO::stat on" << m_currentSrcURL; - KIO::Job *job = KIO::stat(m_currentSrcURL, StatJob::SourceSide, 2, KIO::HideProgressInfo); + KIO::Job *job = KIO::stat(m_currentSrcURL, StatJob::SourceSide, KIO::StatJob::StatDefaultDetails, KIO::HideProgressInfo); state = STATE_STATING; q->addSubjob(job); m_bOnlyRenames = false; diff --git a/src/core/deletejob.cpp b/src/core/deletejob.cpp --- a/src/core/deletejob.cpp +++ b/src/core/deletejob.cpp @@ -251,7 +251,7 @@ // Done, jump to the last else of this method statNextSrc(); } else { - KIO::SimpleJob *job = KIO::stat(m_currentURL, StatJob::SourceSide, 0, KIO::HideProgressInfo); + KIO::SimpleJob *job = KIO::stat(m_currentURL, StatJob::SourceSide, KIO::StatJob::Basic, KIO::HideProgressInfo); Scheduler::setJobPriority(job, 1); //qDebug() << "stat'ing" << m_currentURL; q->addSubjob(job); @@ -398,7 +398,7 @@ if (!KProtocolManager::canDeleteRecursive(url)) { //qDebug() << url << "is a directory, let's list it"; ListJob *newjob = KIO::listRecursive(url, KIO::HideProgressInfo); - newjob->addMetaData(QStringLiteral("details"), QStringLiteral("0")); + newjob->addMetaData(QStringLiteral("details"), QString::number(KIO::StatJob::Basic)); newjob->setUnrestricted(true); // No KIOSK restrictions Scheduler::setJobPriority(newjob, 1); QObject::connect(newjob, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), diff --git a/src/core/directorysizejob.cpp b/src/core/directorysizejob.cpp --- a/src/core/directorysizejob.cpp +++ b/src/core/directorysizejob.cpp @@ -19,6 +19,7 @@ #include "directorysizejob.h" #include "listjob.h" +#include "statjob.h" #include #include #include @@ -133,7 +134,7 @@ Q_Q(DirectorySizeJob); //qDebug() << url; KIO::ListJob *listJob = KIO::listRecursive(url, KIO::HideProgressInfo); - listJob->addMetaData(QStringLiteral("details"), QStringLiteral("3")); + listJob->addMetaData(QStringLiteral("details"), QString::number(KIO::StatJob::StatDefaultDetails)); q->connect(listJob, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList))); q->addSubjob(listJob); diff --git a/src/core/statjob.h b/src/core/statjob.h --- a/src/core/statjob.h +++ b/src/core/statjob.h @@ -47,6 +47,26 @@ ~StatJob() override; + /// @since 5.64 + enum StatDetail { + /// Filename, access, type, size, linkdest + Basic = 0x1, + /// uid, gid + User = 0x2, + /// atime, mtime, btime + Time = 0x4, + /// Resolve symlinks + ResolveSymlink = 0x8, + /// acl Data + Acl = 0x10, + /// dev, inode + Inode = 0x20, + + /// Default value includes fields provided by other entries + StatDefaultDetails = Basic | User | Time | Acl | ResolveSymlink, + }; + Q_DECLARE_FLAGS(StatDetails, StatDetail) + /** * A stat() can have two meanings. Either we want to read from this URL, * or to check if we can write to it. First case is "source", second is "dest". @@ -70,16 +90,26 @@ void setSide(bool source); #endif + /** + * Selects the level of @p details we want. + * @since 5.64 + */ + void setDetails(StatJob::StatDetails details); + +#if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 64) /** * Selects the level of @p details we want. * By default this is 2 (all details wanted, including modification time, size, etc.), * setDetails(1) is used when deleting: we don't need all the information if it takes * too much time, no need to follow symlinks etc. * setDetails(0) is used for very simple probing: we'll only get the answer * "it's a file or a directory, or it doesn't exist". This is used by KRun. * @param details 2 for all details, 1 for simple, 0 for very simple + * @deprecated since 5.64, use setDetails(StatJob::StatDetails) */ + KIOCORE_DEPRECATED_VERSION(5, 64, "use setDetails(StatJob::statDetails)") void setDetails(short int details); +#endif /** * @brief Result of the stat operation. @@ -148,14 +178,44 @@ friend KIOCORE_EXPORT StatJob *mostLocalUrl(const QUrl &url, JobFlags flags); }; +Q_DECLARE_OPERATORS_FOR_FLAGS(StatJob::StatDetails) + /** * Find all details for one file or directory. * * @param url the URL of the file * @param flags Can be HideProgressInfo here * @return the job handling the operation. */ KIOCORE_EXPORT StatJob *stat(const QUrl &url, JobFlags flags = DefaultFlags); +/** + * Find all details for one file or directory. + * This version of the call includes two additional booleans, @p sideIsSource and @p details. + * + * @param url the URL of the file + * @param side is SourceSide when stating a source file (we will do a get on it if + * the stat works) and DestinationSide when stating a destination file (target of a copy). + * The reason for this parameter is that in some cases the kioslave might not + * be able to determine a file's existence (e.g. HTTP doesn't allow it, FTP + * has issues with case-sensitivity on some systems). + * When the slave can't reliably determine the existence of a file, it will: + * @li be optimistic if SourceSide, i.e. it will assume the file exists, + * and if it doesn't this will appear when actually trying to download it + * @li be pessimistic if DestinationSide, i.e. it will assume the file + * doesn't exist, to prevent showing "about to overwrite" errors to the user. + * If you simply want to check for existence without downloading/uploading afterwards, + * then you should use DestinationSide. + * + * @param details selects the level of details we want. + * You can fine grain the detail level you want. + * @param flags Can be HideProgressInfo here + * @return the job handling the operation. + * @since 5.64 + */ +KIOCORE_EXPORT StatJob *stat(const QUrl &url, KIO::StatJob::StatSide side, + StatJob::StatDetails details = StatJob::StatDefaultDetails, JobFlags flags = DefaultFlags); + +#if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 64) /** * Find all details for one file or directory. * This version of the call includes two additional booleans, @p sideIsSource and @p details. @@ -182,9 +242,12 @@ * "it's a file or a directory or a symlink, or it doesn't exist". This is used by KRun and DeleteJob. * @param flags Can be HideProgressInfo here * @return the job handling the operation. + * @deprecated since 5.64, use stat(const QUrl &, KIO::StatJob::StatSide, StatJob::StatDetails int, JobFlags) */ +KIOCORE_DEPRECATED_VERSION(5, 64, "Use KIO::stat(const QUrl &, KIO::StatJob::StatSide, StatJob::StatDetails int, JobFlags)") KIOCORE_EXPORT StatJob *stat(const QUrl &url, KIO::StatJob::StatSide side, short int details, JobFlags flags = DefaultFlags); +#endif #if KIOCORE_ENABLE_DEPRECATED_SINCE(4, 0) /** diff --git a/src/core/statjob.cpp b/src/core/statjob.cpp --- a/src/core/statjob.cpp +++ b/src/core/statjob.cpp @@ -32,13 +32,13 @@ { public: inline StatJobPrivate(const QUrl &url, int command, const QByteArray &packedArgs) - : SimpleJobPrivate(url, command, packedArgs), m_bSource(true), m_details(2) + : SimpleJobPrivate(url, command, packedArgs), m_bSource(true), m_details(KIO::StatJob::StatDefaultDetails) {} UDSEntry m_statResult; QUrl m_redirectionURL; bool m_bSource; - short int m_details; + StatJob::StatDetails m_details; void slotStatEntry(const KIO::UDSEntry &entry); void slotRedirection(const QUrl &url); @@ -84,11 +84,27 @@ d_func()->m_bSource = side == SourceSide; } -void StatJob::setDetails(short int details) +void StatJob::setDetails(StatJob::StatDetails details) { d_func()->m_details = details; } +void StatJob::setDetails(short int details) +{ + // for backward compatibility + StatJob::StatDetails detailsFlag = StatJob::StatDetail::Basic; + if (details > 0) { + detailsFlag |= StatJob::StatDetail::User | StatJob::StatDetail::Time; + } + if (details > 1) { + detailsFlag |= StatJob::StatDetail::ResolveSymlink | StatJob::StatDetail::Acl; + } + if (details > 2) { + detailsFlag |= StatJob::StatDetail::Inode; + } + d_func()->m_details = detailsFlag; +} + const UDSEntry &StatJob::statResult() const { return d_func()->m_statResult; @@ -176,12 +192,12 @@ StatJob *KIO::stat(const QUrl &url, JobFlags flags) { // Assume sideIsSource. Gets are more common than puts. - return stat(url, StatJob::SourceSide, 2, flags); + return stat(url, StatJob::SourceSide, KIO::StatJob::StatDefaultDetails, flags); } StatJob *KIO::mostLocalUrl(const QUrl &url, JobFlags flags) { - StatJob *job = stat(url, StatJob::SourceSide, 2, flags); + StatJob *job = stat(url, StatJob::SourceSide, KIO::StatJob::StatDefaultDetails, flags); if (url.isLocalFile()) { QTimer::singleShot(0, job, &StatJob::slotFinished); Scheduler::cancelJob(job); // deletes the slave if not 0 @@ -199,6 +215,16 @@ return job; } +StatJob *KIO::stat(const QUrl &url, KIO::StatJob::StatSide side, StatJob::StatDetails details, JobFlags flags) +{ + //qCDebug(KIO_CORE) << "stat" << url; + KIO_ARGS << url; + StatJob *job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags); + job->setSide(side); + job->setDetails(details); + return job; +} + StatJob *KIO::stat(const QUrl &url, KIO::StatJob::StatSide side, short int details, JobFlags flags) { //qCDebug(KIO_CORE) << "stat" << url; diff --git a/src/filewidgets/kdiroperator.cpp b/src/filewidgets/kdiroperator.cpp --- a/src/filewidgets/kdiroperator.cpp +++ b/src/filewidgets/kdiroperator.cpp @@ -745,7 +745,7 @@ } else { KIO::StatJob *job = KIO::stat(folderurl); KJobWidgets::setWindow(job, this); - job->setDetails(0); //We only want to know if it exists, 0 == that. + job->setDetails(KIO::StatJob::Basic); //We only want to know if it exists job->setSide(KIO::StatJob::DestinationSide); exists = job->exec(); } diff --git a/src/ioslaves/file/file.h b/src/ioslaves/file/file.h --- a/src/ioslaves/file/file.h +++ b/src/ioslaves/file/file.h @@ -40,6 +40,7 @@ #endif #include "file_p.h" +#include "statjob.h" #include Q_DECLARE_LOGGING_CATEGORY(KIO_FILE) @@ -94,7 +95,7 @@ private: bool createUDSEntry(const QString &filename, const QByteArray &path, KIO::UDSEntry &entry, - short int details); + KIO::StatJob::StatDetails details); int setACL(const char *path, mode_t perm, bool _directoryDefault); QString getUserName(KUserId uid) const; QString getGroupName(KGroupId gid) const; diff --git a/src/ioslaves/file/file.cpp b/src/ioslaves/file/file.cpp --- a/src/ioslaves/file/file.cpp +++ b/src/ioslaves/file/file.cpp @@ -79,6 +79,8 @@ #include #include +#include "statjob.h" + Q_LOGGING_CATEGORY(KIO_FILE, "kf5.kio.kio_file") // Pseudo plugin class to embed meta data @@ -887,28 +889,35 @@ #endif bool FileProtocol::createUDSEntry(const QString &filename, const QByteArray &path, UDSEntry &entry, - short int details) + KIO::StatJob::StatDetails details) { assert(entry.count() == 0); // by contract :-) - switch (details) { - case 0: + short entries = 0; + if (details.testFlag(KIO::StatJob::Basic)) { // filename, access, type, size, linkdest - entry.reserve(5); - break; - case 1: - // uid, gid, atime, mtime, btime - entry.reserve(10); - break; - case 2: + entries += 5; + } + if (details.testFlag(KIO::StatJob::User)) { + // uid, gid + entries += 2; + } + if (details.testFlag(KIO::StatJob::Time)) { + // atime, mtime, btime + entries += 3; + } + if (details.testFlag(KIO::StatJob::Acl)) { // acl data - entry.reserve(13); - break; - default: // case details > 2 + entries += 3; + } + if (details.testFlag(KIO::StatJob::Inode)) { // dev, inode - entry.reserve(15); - break; + entries += 2; + } + entry.reserve(entries); + + if (details.testFlag(KIO::StatJob::Basic)) { + entry.fastInsert(KIO::UDSEntry::UDS_NAME, filename); } - entry.fastInsert(KIO::UDSEntry::UDS_NAME, filename); mode_t type; mode_t access; @@ -927,62 +936,66 @@ if (LSTAT(path.data(), &buff) == 0) { - if (details > 2) { + if (details.testFlag(KIO::StatJob::Inode)) { entry.fastInsert(KIO::UDSEntry::UDS_DEVICE_ID, stat_dev(buff)); entry.fastInsert(KIO::UDSEntry::UDS_INODE, stat_ino(buff)); } if ((stat_mode(buff) & QT_STAT_MASK) == QT_STAT_LNK) { + if (details.testFlag(KIO::StatJob::Basic)) { #ifdef Q_OS_WIN const QString linkTarget = QFile::symLinkTarget(QFile::decodeName(path)); #else - // Use readlink on Unix because symLinkTarget turns relative targets into absolute (#352927) - #if HAVE_STATX - size_t lowerBound = 256; - size_t higherBound = 1024; - uint64_t s = stat_size(buff); - if (s > SIZE_MAX) { - qCWarning(KIO_FILE) << "file size bigger than SIZE_MAX, too big for readlink use!" << path; - return false; - } - size_t size = static_cast(s); - using SizeType = size_t; - #else - off_t lowerBound = 256; - off_t higherBound = 1024; - off_t size = stat_size(buff); - using SizeType = off_t; - #endif - SizeType bufferSize = qBound(lowerBound, size +1, higherBound); - QByteArray linkTargetBuffer; - linkTargetBuffer.resize(bufferSize); - while (true) { - ssize_t n = readlink(path.constData(), linkTargetBuffer.data(), bufferSize); - if (n < 0 && errno != ERANGE) { - qCWarning(KIO_FILE) << "readlink failed!" << path; - return false; - } else if (n > 0 && static_cast(n) != bufferSize) { - // the buffer was not filled in the last iteration - // we are finished reading, break the loop - linkTargetBuffer.truncate(n); - break; - } - bufferSize *= 2; + // Use readlink on Unix because symLinkTarget turns relative targets into absolute (#352927) + #if HAVE_STATX + size_t lowerBound = 256; + size_t higherBound = 1024; + uint64_t s = stat_size(buff); + if (s > SIZE_MAX) { + qCWarning(KIO_FILE) << "file size bigger than SIZE_MAX, too big for readlink use!" << path; + return false; + } + size_t size = static_cast(s); + using SizeType = size_t; + #else + off_t lowerBound = 256; + off_t higherBound = 1024; + off_t size = stat_size(buff); + using SizeType = off_t; + #endif + SizeType bufferSize = qBound(lowerBound, size +1, higherBound); + QByteArray linkTargetBuffer; linkTargetBuffer.resize(bufferSize); - } - const QString linkTarget = QFile::decodeName(linkTargetBuffer); + while (true) { + ssize_t n = readlink(path.constData(), linkTargetBuffer.data(), bufferSize); + if (n < 0 && errno != ERANGE) { + qCWarning(KIO_FILE) << "readlink failed!" << path; + return false; + } else if (n > 0 && static_cast(n) != bufferSize) { + // the buffer was not filled in the last iteration + // we are finished reading, break the loop + linkTargetBuffer.truncate(n); + break; + } + bufferSize *= 2; + linkTargetBuffer.resize(bufferSize); + } + const QString linkTarget = QFile::decodeName(linkTargetBuffer); #endif - entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, linkTarget); + entry.fastInsert(KIO::UDSEntry::UDS_LINK_DEST, linkTarget); + } // A symlink -> follow it only if details>1 - if (details > 1) { + if (details.testFlag(KIO::StatJob::ResolveSymlink)) { if (STAT(path.constData(), &buff) == -1) { isBrokenSymLink = true; } else { #if HAVE_POSIX_ACL - // valid symlink, will get the ACLs of the destination - targetPath = linkTargetBuffer; + if (details.testFlag(KIO::StatJob::Acl)) { + // valid symlink, will get the ACLs of the destination + targetPath = linkTargetBuffer; + } #endif } } @@ -992,39 +1005,44 @@ return false; } - if (isBrokenSymLink) { - // It is a link pointing to nowhere - type = S_IFMT - 1; - access = S_IRWXU | S_IRWXG | S_IRWXO; - size = 0LL; - } else { - type = stat_mode(buff) & S_IFMT; // extract file type - access = stat_mode(buff) & 07777; // extract permissions - size = stat_size(buff); - } + if (details.testFlag(KIO::StatJob::Basic)) { + if (isBrokenSymLink) { + // It is a link pointing to nowhere + type = S_IFMT - 1; + access = S_IRWXU | S_IRWXG | S_IRWXO; + size = 0LL; + } else { + type = stat_mode(buff) & S_IFMT; // extract file type + access = stat_mode(buff) & 07777; // extract permissions + size = stat_size(buff); + } - entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, type); - entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, access); - entry.fastInsert(KIO::UDSEntry::UDS_SIZE, size); + entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, type); + entry.fastInsert(KIO::UDSEntry::UDS_ACCESS, access); + entry.fastInsert(KIO::UDSEntry::UDS_SIZE, size); + } #if HAVE_POSIX_ACL - if (details > 1) { + if (details.testFlag(KIO::StatJob::Acl)) { /* Append an atom indicating whether the file has extended acl information * and if withACL is specified also one with the acl itself. If it's a directory * and it has a default ACL, also append that. */ appendACLAtoms(targetPath, entry, type); } #endif - if (details > 0) { - entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, stat_mtime(buff)); - entry.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, stat_atime(buff)); + if (details.testFlag(KIO::StatJob::User)) { #ifndef Q_OS_WIN entry.fastInsert(KIO::UDSEntry::UDS_USER, getUserName(KUserId(stat_uid(buff)))); entry.fastInsert(KIO::UDSEntry::UDS_GROUP, getGroupName(KGroupId(stat_gid(buff)))); #else #pragma message("TODO: st_uid and st_gid are always zero, use GetSecurityInfo to find the owner") #endif + } + + if (details.testFlag(KIO::StatJob::Time)) { + entry.fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, stat_mtime(buff)); + entry.fastInsert(KIO::UDSEntry::UDS_ACCESS_TIME, stat_atime(buff)); #ifdef st_birthtime /* For example FreeBSD's and NetBSD's stat contains a field for diff --git a/src/ioslaves/file/file_unix.cpp b/src/ioslaves/file/file_unix.cpp --- a/src/ioslaves/file/file_unix.cpp +++ b/src/ioslaves/file/file_unix.cpp @@ -47,6 +47,7 @@ #include #include "fdreceiver.h" +#include "statjob.h" //sendfile has different semantics in different platforms #if HAVE_SENDFILE && defined Q_OS_LINUX @@ -539,7 +540,7 @@ } const QString sDetails = metaData(QStringLiteral("details")); - const int details = sDetails.isEmpty() ? 2 : sDetails.toInt(); + const KIO::StatJob::StatDetails details = sDetails.isEmpty() ? KIO::StatJob::StatDefaultDetails : static_cast(sDetails.toInt()); //qDebug() << "========= LIST " << url << "details=" << details << " ========="; UDSEntry entry; @@ -562,7 +563,7 @@ * for every entry thus becoming slower. * */ - if (details == 0) { + if (details == KIO::StatJob::Basic) { entry.fastInsert(KIO::UDSEntry::UDS_NAME, filename); #ifdef HAVE_DIRENT_D_TYPE entry.fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, @@ -844,7 +845,7 @@ const QString path(url.adjusted(QUrl::StripTrailingSlash).toLocalFile()); const QByteArray _path(QFile::encodeName(path)); const QString sDetails = metaData(QStringLiteral("details")); - const int details = sDetails.isEmpty() ? 2 : sDetails.toInt(); + const KIO::StatJob::StatDetails details = sDetails.isEmpty() ? KIO::StatJob::StatDefaultDetails : static_cast(sDetails.toInt()); UDSEntry entry; if (!createUDSEntry(url.fileName(), _path, entry, details)) { diff --git a/src/widgets/krun.cpp b/src/widgets/krun.cpp --- a/src/widgets/krun.cpp +++ b/src/widgets/krun.cpp @@ -1009,7 +1009,7 @@ // It may be a directory or a file, let's stat KIO::JobFlags flags = d->m_bProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo; - KIO::StatJob *job = KIO::stat(d->m_strURL, KIO::StatJob::SourceSide, 0 /* no details */, flags); + KIO::StatJob *job = KIO::stat(d->m_strURL, KIO::StatJob::SourceSide, KIO::StatJob::Basic, flags); KJobWidgets::setWindow(job, d->m_window); connect(job, &KJob::result, this, &KRun::slotStatResult); diff --git a/src/widgets/paste.cpp b/src/widgets/paste.cpp --- a/src/widgets/paste.cpp +++ b/src/widgets/paste.cpp @@ -77,7 +77,7 @@ static QUrl getDestinationUrl(const QUrl &srcUrl, const QUrl &destUrl, QWidget *widget) { KIO::StatJob *job = KIO::stat(destUrl, destUrl.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags); - job->setDetails(0); + job->setDetails(KIO::StatJob::Basic); job->setSide(KIO::StatJob::DestinationSide); KJobWidgets::setWindow(job, widget); diff --git a/tests/kioslavetest.cpp b/tests/kioslavetest.cpp --- a/tests/kioslavetest.cpp +++ b/tests/kioslavetest.cpp @@ -249,7 +249,7 @@ break; case Stat: - myJob = KIO::stat(src, KIO::StatJob::SourceSide, 2); + myJob = KIO::stat(src, KIO::StatJob::SourceSide); break; case Get: diff --git a/tests/listjobtest.cpp b/tests/listjobtest.cpp --- a/tests/listjobtest.cpp +++ b/tests/listjobtest.cpp @@ -41,7 +41,7 @@ KIO::ListJob *job = KIO::listDir(url, KIO::HideProgressInfo); job->setUiDelegate(nullptr); - job->addMetaData(QStringLiteral("details"), QStringLiteral("2")); // Default is 2 which means all details. 0 means just a few essential fields (KIO::UDSEntry::UDS_NAME, KIO::UDSEntry::UDS_FILE_TYPE and KIO::UDSEntry::UDS_LINK_DEST if it is a symbolic link. Not provided otherwise. + job->addMetaData(QStringLiteral("details"), QString::number(KIO::StatJob::StatDefaultDetails)); QObject::connect(job, &KIO::ListJob::entries, [&entriesListed] (KIO::Job*, const KIO::UDSEntryList &entries) {