File indexing completed on 2024-04-14 03:52:56

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 1999-2006 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KFILEITEM_H
0009 #define KFILEITEM_H
0010 
0011 #include "kiocore_export.h"
0012 #include <QDateTime>
0013 #include <QFile>
0014 #include <QUrl>
0015 #include <kacl.h>
0016 #include <kio/global.h>
0017 #include <kio/udsentry.h>
0018 
0019 #include <QList>
0020 #include <QMimeType>
0021 #include <qplatformdefs.h>
0022 
0023 class KFileItemPrivate;
0024 
0025 /**
0026  * @class KFileItem kfileitem.h <KFileItem>
0027  *
0028  * A KFileItem is a generic class to handle a file, local or remote.
0029  * In particular, it makes it easier to handle the result of KIO::listDir
0030  * (UDSEntry isn't very friendly to use).
0031  * It includes many file attributes such as MIME type, icon, text, mode, link...
0032  *
0033  * KFileItem is implicitly shared, i.e. it can be used as a value and copied around at almost no cost.
0034  */
0035 class KIOCORE_EXPORT KFileItem
0036 {
0037     Q_GADGET
0038 
0039     Q_PROPERTY(QUrl url READ url WRITE setUrl)
0040     Q_PROPERTY(QString user READ user)
0041     Q_PROPERTY(QString group READ group)
0042     Q_PROPERTY(bool isLink READ isLink)
0043     Q_PROPERTY(bool isDir READ isDir)
0044     Q_PROPERTY(bool isFile READ isFile)
0045     Q_PROPERTY(bool isReadable READ isReadable)
0046     Q_PROPERTY(bool isWritable READ isWritable)
0047     Q_PROPERTY(bool isHidden READ isHidden)
0048     Q_PROPERTY(bool isSlow READ isSlow)
0049     Q_PROPERTY(bool isDesktopFile READ isDesktopFile)
0050     Q_PROPERTY(QString linkDest READ linkDest)
0051     Q_PROPERTY(QUrl targetUrl READ targetUrl)
0052     Q_PROPERTY(QString localPath READ localPath WRITE setLocalPath)
0053     Q_PROPERTY(bool isLocalFile READ isLocalFile)
0054     Q_PROPERTY(QString text READ text)
0055     Q_PROPERTY(QString name READ name WRITE setName)
0056     Q_PROPERTY(QString mimetype READ mimetype)
0057     Q_PROPERTY(QMimeType determineMimeType READ determineMimeType)
0058     Q_PROPERTY(QMimeType currentMimeType READ currentMimeType)
0059     Q_PROPERTY(bool isFinalIconKnown READ isFinalIconKnown)
0060     Q_PROPERTY(bool isMimeTypeKnown READ isMimeTypeKnown)
0061     Q_PROPERTY(QString mimeComment READ mimeComment)
0062     Q_PROPERTY(QString iconName READ iconName)
0063     Q_PROPERTY(QStringList overlays READ overlays)
0064     Q_PROPERTY(QString comment READ comment)
0065     Q_PROPERTY(QString getStatusBarInfo READ getStatusBarInfo)
0066     Q_PROPERTY(bool isRegularFile READ isRegularFile)
0067 
0068 public:
0069     enum { Unknown = static_cast<mode_t>(-1) };
0070 
0071     /**
0072      * The timestamps associated with a file.
0073      * - ModificationTime: the time the file's contents were last modified
0074      * - AccessTime: the time the file was last accessed (last read or written to)
0075      * - CreationTime: the time the file was created
0076      */
0077     enum FileTimes {
0078         // warning: don't change without looking at the Private class
0079         ModificationTime = 0,
0080         AccessTime = 1,
0081         CreationTime = 2,
0082         // ChangeTime
0083     };
0084     Q_ENUM(FileTimes)
0085 
0086     enum MimeTypeDetermination {
0087         NormalMimeTypeDetermination = 0,
0088         SkipMimeTypeFromContent,
0089     };
0090     Q_ENUM(MimeTypeDetermination)
0091 
0092     /**
0093      * Null KFileItem. Doesn't represent any file, only exists for convenience.
0094      */
0095     KFileItem();
0096 
0097     /**
0098      * Creates an item representing a file, from a UDSEntry.
0099      * This is the preferred constructor when using KIO::listDir().
0100      *
0101      * @param entry the KIO entry used to get the file, contains info about it
0102      * @param itemOrDirUrl the URL of the item or of the directory containing this item (see urlIsDirectory).
0103      * @param delayedMimeTypes specifies if the MIME type of the given
0104      *       URL should be determined immediately or on demand.
0105      *       See the bool delayedMimeTypes in the KDirLister constructor.
0106      * @param urlIsDirectory specifies if the url is just the directory of the
0107      *       fileitem and the filename from the UDSEntry should be used.
0108      *
0109      * When creating KFileItems out of the UDSEntry emitted by a KIO list job,
0110      * use KFileItem(entry, listjob->url(), delayedMimeTypes, true);
0111      */
0112     KFileItem(const KIO::UDSEntry &entry, const QUrl &itemOrDirUrl, bool delayedMimeTypes = false, bool urlIsDirectory = false);
0113 
0114     /**
0115      * Creates an item representing a file, for which the MIME type is already known.
0116      * @param url the file url
0117      * @param mimeType the name of the file's MIME type
0118      * @param mode the mode (S_IFDIR...)
0119      */
0120     explicit KFileItem(const QUrl &url, const QString &mimeType = QString(), mode_t mode = KFileItem::Unknown);
0121 
0122     /**
0123      * Creates an item representing a file, with the option of skipping MIME type determination.
0124      * @param url the file url
0125      * @param mimeTypeDetermination the mode of determining the MIME type:
0126      *       NormalMimeTypeDetermination by content if local file, i.e. access the file,
0127      *                                   open and read part of it;
0128      *                                   by QMimeDatabase::MatchMode::MatchExtension if not local.
0129      *       SkipMimeTypeFromContent     always by QMimeDatabase::MatchMode::MatchExtension,
0130      *                                   i.e. won't access the file by stat() or opening it;
0131      *                                   only suitable for files, directories won't be recognized.
0132      * @since 5.57
0133      */
0134     KFileItem(const QUrl &url, KFileItem::MimeTypeDetermination mimeTypeDetermination);
0135 
0136     /**
0137      * Copy constructor
0138      */
0139     KFileItem(const KFileItem &);
0140 
0141     /**
0142      * Destructor
0143      */
0144     ~KFileItem();
0145 
0146     /**
0147      * Move constructor
0148      * @since 5.43
0149      */
0150     KFileItem(KFileItem &&);
0151 
0152     /**
0153      * Copy assignment
0154      */
0155     KFileItem &operator=(const KFileItem &);
0156 
0157     /**
0158      * Move assignment
0159      * @since 5.43
0160      */
0161     KFileItem &operator=(KFileItem &&);
0162 
0163     /**
0164      * Throw away and re-read (for local files) all information about the file.
0165      * This is called when the _file_ changes.
0166      */
0167     void refresh();
0168 
0169     /**
0170      * Re-reads MIME type information.
0171      * This is called when the MIME type database changes.
0172      */
0173     void refreshMimeType();
0174 
0175     /**
0176      * Sets MIME type determination to be immediate or on demand.
0177      * Call this after the constructor, and before using any MIME-type-related method.
0178      * @since 5.0
0179      */
0180     void setDelayedMimeTypes(bool b);
0181 
0182     /**
0183      * Returns the url of the file.
0184      * @return the url of the file
0185      */
0186     QUrl url() const;
0187 
0188     /**
0189      * Sets the item's URL. Do not call unless you know what you are doing!
0190      * (used for example when an item got renamed).
0191      * @param url the item's URL
0192      */
0193     void setUrl(const QUrl &url);
0194 
0195     /**
0196      * Sets the item's local path (UDS_LOCAL_PATH). Do not call unless you know what you are doing!
0197      * This won't change the item's name or URL.
0198      * (used for example when an item got renamed).
0199      * @param path the item's local path
0200      * @since 5.20
0201      */
0202     void setLocalPath(const QString &path);
0203 
0204     /**
0205      * Sets the item's name (i.e.\ the filename).
0206      * This is automatically done by setUrl, to set the name from the URL's fileName().
0207      * This method is provided for some special cases like relative paths as names (KFindPart)
0208      * @param name the item's name
0209      */
0210     void setName(const QString &name);
0211 
0212     /**
0213      * Returns the permissions of the file (stat.st_mode containing only permissions).
0214      * @return the permissions of the file
0215      */
0216     mode_t permissions() const;
0217 
0218     /**
0219      * Returns the access permissions for the file as a string.
0220      * @return the access permission as string
0221      */
0222     QString permissionsString() const;
0223 
0224     /**
0225      * Tells if the file has extended access level information ( Posix ACL )
0226      * @return true if the file has extend ACL information or false if it hasn't
0227      */
0228     bool hasExtendedACL() const;
0229 
0230     /**
0231      * Returns the access control list for the file.
0232      * @return the access control list as a KACL
0233      */
0234     KACL ACL() const;
0235 
0236     /**
0237      * Returns the default access control list for the directory.
0238      * @return the default access control list as a KACL
0239      */
0240     KACL defaultACL() const;
0241 
0242     /**
0243      * Returns the file type (stat.st_mode containing only S_IFDIR, S_IFLNK, ...).
0244      * @return the file type
0245      */
0246     mode_t mode() const;
0247 
0248     /**
0249      * Returns the file's owner's user id.
0250      * Available only on supported protocols.
0251      * @since 6.0
0252      */
0253     int userId() const;
0254     /**
0255      * Returns the file's owner's group id.
0256      * Available only on supported protocols.
0257      * @since 6.0
0258      */
0259     int groupId() const;
0260 
0261     /**
0262      * Returns the owner of the file.
0263      * @return the file's owner
0264      */
0265     QString user() const;
0266 
0267     /**
0268      * Returns the group of the file.
0269      * @return the file's group
0270      */
0271     QString group() const;
0272 
0273     /**
0274      * Returns true if this item represents a link in the UNIX sense of
0275      * a link.
0276      * @return true if the file is a link
0277      */
0278     bool isLink() const;
0279 
0280     /**
0281      * Returns true if this item represents a directory.
0282      * @return true if the item is a directory
0283      */
0284     bool isDir() const;
0285 
0286     /**
0287      * Returns true if this item represents a file (and not a directory)
0288      * @return true if the item is a file
0289      */
0290     bool isFile() const;
0291 
0292     /**
0293      * Checks whether the file or directory is readable. In some cases
0294      * (remote files), we may return true even though it can't be read.
0295      * @return true if the file can be read - more precisely,
0296      *         false if we know for sure it can't
0297      */
0298     bool isReadable() const;
0299 
0300     /**
0301      * Checks whether the file or directory is writable. In some cases
0302      * (remote files), we may return true even though it can't be written to.
0303      * @return true if the file or directory can be written to - more precisely,
0304      *         false if we know for sure it can't
0305      */
0306     bool isWritable() const;
0307 
0308     /**
0309      * Checks whether the file is hidden.
0310      * @return true if the file is hidden.
0311      */
0312     bool isHidden() const;
0313 
0314     /**
0315      * @return true if the file is a remote URL, or a local file on a network mount.
0316      * It will return false only for really-local file systems.
0317      * @since 4.7.4
0318      */
0319     bool isSlow() const;
0320 
0321     /**
0322      * Checks whether the file is a readable local .desktop file,
0323      * i.e.\ a file whose path can be given to KDesktopFile
0324      * @return true if the file is a desktop file.
0325      */
0326     bool isDesktopFile() const;
0327 
0328     /**
0329      * Returns the link destination if isLink() == true.
0330      * @return the link destination. QString() if the item is not a link
0331      */
0332     QString linkDest() const;
0333 
0334     /**
0335      * Returns the target url of the file, which is the same as url()
0336      * in cases where the worker doesn't specify UDS_TARGET_URL
0337      * @return the target url.
0338      */
0339     QUrl targetUrl() const;
0340 
0341     /**
0342      * Returns the local path if isLocalFile() == true or the KIO item has
0343      * a UDS_LOCAL_PATH atom.
0344      *
0345      * Treat it as a readonly path to open/list contents, use original url to move/delete files.
0346      *
0347      * @return the item local path, or QString() if not known
0348      */
0349     QString localPath() const;
0350 
0351     /**
0352      * Returns the size of the file, if known.
0353      * @return the file size, or 0 if not known
0354      */
0355     KIO::filesize_t size() const;
0356 
0357     /**
0358      * @brief For folders, its recursive size:
0359      * the size of its files plus the recursiveSize of its folder
0360      *
0361      * Initially only implemented for trash:/
0362      *
0363      * @since 5.70
0364      * @return The recursive size
0365      */
0366     KIO::filesize_t recursiveSize() const;
0367 
0368     /**
0369      * Requests the modification, access or creation time, depending on @p which.
0370      * @param which the timestamp
0371      * @return the time asked for, QDateTime() if not available
0372      * @see timeString()
0373      */
0374     Q_INVOKABLE QDateTime time(KFileItem::FileTimes which) const;
0375 
0376     /**
0377      * Requests the modification, access or creation time as a string, depending
0378      * on @p which.
0379      * @param which the timestamp
0380      * @returns a formatted string of the requested time.
0381      * @see time
0382      */
0383     Q_INVOKABLE QString timeString(KFileItem::FileTimes which = ModificationTime) const;
0384 
0385     /**
0386      * Returns true if the file is a local file.
0387      * @return true if the file is local, false otherwise
0388      */
0389     bool isLocalFile() const;
0390 
0391     /**
0392      * Returns the text of the file item.
0393      * It's not exactly the filename since some decoding happens ('%2F'->'/').
0394      * @return the text of the file item
0395      */
0396     QString text() const;
0397 
0398     /**
0399      * Return the name of the file item (without a path).
0400      * Similar to text(), but unencoded, i.e. the original name.
0401      * @param lowerCase if true, the name will be returned in lower case,
0402      * which is useful to speed up sorting by name, case insensitively.
0403      * @return the file's name
0404      */
0405     QString name(bool lowerCase = false) const;
0406 
0407     /**
0408      * Returns the MIME type of the file item.
0409      * If @p delayedMimeTypes was used in the constructor, this will determine
0410      * the MIME type first. Equivalent to determineMimeType()->name()
0411      * @return the MIME type of the file
0412      */
0413     QString mimetype() const;
0414 
0415     /**
0416      * Returns the MIME type of the file item.
0417      * If delayedMimeTypes was used in the constructor, this will determine
0418      * the MIME type first.
0419      * @return the MIME type
0420      */
0421     QMimeType determineMimeType() const;
0422 
0423     /**
0424      * Returns the currently known MIME type of the file item.
0425      * This will not try to determine the MIME type if unknown.
0426      * @return the known MIME type
0427      */
0428     QMimeType currentMimeType() const;
0429 
0430     /**
0431      * @return true if we have determined the final icon of this file already.
0432      * @since 4.10.2
0433      */
0434     bool isFinalIconKnown() const;
0435 
0436     /**
0437      * @return true if we have determined the MIME type of this file already,
0438      * i.e. if determineMimeType() will be fast. Otherwise it will have to
0439      * find what the MIME type is, which is a possibly slow operation; usually
0440      * this is delayed until necessary.
0441      */
0442     bool isMimeTypeKnown() const;
0443 
0444     /**
0445      * Returns the user-readable string representing the type of this file,
0446      * like "OpenDocument Text File".
0447      * @return the type of this KFileItem
0448      */
0449     QString mimeComment() const;
0450 
0451     /**
0452      * Returns the full path name to the icon that represents
0453      * this MIME type.
0454      * @return iconName the name of the file's icon
0455      */
0456     QString iconName() const;
0457 
0458     /**
0459      * Returns the overlays (bitfield of KIconLoader::*Overlay flags) that are used
0460      * for this item's pixmap. Overlays are used to show for example, whether
0461      * a file can be modified.
0462      * @return the overlays of the pixmap
0463      */
0464     QStringList overlays() const;
0465 
0466     /**
0467      * A comment which can contain anything - even rich text. It will
0468      * simply be displayed to the user as is.
0469      *
0470      */
0471     QString comment() const;
0472 
0473     /**
0474      * Returns the string to be displayed in the statusbar,
0475      * e.g.\ when the mouse is over this item.
0476      * @return the status bar information
0477      */
0478     QString getStatusBarInfo() const;
0479 
0480     /**
0481      * Returns the UDS entry. Used by the tree view to access all details
0482      * by position.
0483      * @return the UDS entry
0484      */
0485     KIO::UDSEntry entry() const;
0486 
0487     /**
0488      * Return true if this item is a regular file,
0489      * false otherwise (directory, link, character/block device, fifo, socket)
0490      */
0491     bool isRegularFile() const;
0492 
0493     /**
0494      * Returns the file extension
0495      * Similar to QFileInfo::suffix except it takes into account UDS_DISPLAY_NAME and saves a stat call
0496      * @since 6.0
0497      */
0498     QString suffix() const;
0499 
0500     /**
0501      * Somewhat like a comparison operator, but more explicit,
0502      * and it can detect that two fileitems differ if any property of the file item
0503      * has changed (file size, modification date, etc.). Two items are equal if
0504      * all properties are equal. In contrast, operator== only compares URLs.
0505      * @param item the item to compare
0506      * @return true if all values are equal
0507      */
0508     bool cmp(const KFileItem &item) const;
0509 
0510     /**
0511      * Returns true if both items share the same URL.
0512      */
0513     bool operator==(const KFileItem &other) const;
0514 
0515     /**
0516      * Returns true if both items do not share the same URL.
0517      */
0518     bool operator!=(const KFileItem &other) const;
0519 
0520     /**
0521      * Returns true if this item's URL is lexically less than other's URL; otherwise returns false
0522      * @since 5.48
0523      */
0524     bool operator<(const KFileItem &other) const;
0525 
0526     /**
0527      * Returns true if this item's URL is lexically less than url other; otherwise returns false
0528      * @since 5.48
0529      */
0530     bool operator<(const QUrl &other) const;
0531 
0532     /**
0533      * Converts this KFileItem to a QVariant, this allows to use KFileItem
0534      * in QVariant() constructor
0535      */
0536     operator QVariant() const;
0537 
0538     /**
0539      * Tries to return a local URL for this file item if possible.
0540      * If @p local is not null, it will be set to @c true if the returned url is local,
0541      * @c false otherwise.
0542      *
0543      * Example:
0544      * @code
0545      * bool isLocal = false;
0546      * KFileItem item;
0547      * const QUrl url = item.mostLocalUrl(&isLocal);
0548      * if (isLocal) {
0549      *    // Use url
0550      * }
0551      * @endcode
0552      *
0553      */
0554     QUrl mostLocalUrl(bool *local = nullptr) const;
0555 
0556     struct MostLocalUrlResult {
0557         QUrl url;
0558         bool local;
0559     };
0560 
0561     /**
0562      * Returns a MostLocalUrlResult, with the local Url for this item if possible
0563      * (otherwise an empty Url), and a bool that is set to @c true if this Url
0564      * does represent a local file otherwise @c false.
0565      *
0566      * Basically this is an alternative to mostLocalUrl(bool*), that does not use an
0567      * output parameter.
0568      *
0569      * Example:
0570      * @code
0571      * KFileItem item;
0572      * const MostLocalUrlResult result = item.isMostLocalUrl();
0573      * if (result.local) { // A local file
0574      *    // Use result.url
0575      * }
0576      * @endcode
0577      * @since 5.84
0578      */
0579     MostLocalUrlResult isMostLocalUrl() const;
0580 
0581     /**
0582      * Return true if default-constructed
0583      */
0584     bool isNull() const;
0585 
0586     /**
0587      * returns whether the KFileItem exists on-disk
0588      * Call only after initialization (i.e `KIO::stat` or `refresh()` for local files)
0589      * @since 6.0
0590      */
0591     bool exists() const;
0592 
0593     /**
0594      * Return true if the file has executable permission
0595      * @since 6.0
0596      */
0597     bool isExecutable() const;
0598 
0599 private:
0600     QSharedDataPointer<KFileItemPrivate> d;
0601 
0602     /**
0603      * Hides the file.
0604      */
0605     KIOCORE_NO_EXPORT void setHidden();
0606 
0607 private:
0608     KIOCORE_EXPORT friend QDataStream &operator<<(QDataStream &s, const KFileItem &a);
0609     KIOCORE_EXPORT friend QDataStream &operator>>(QDataStream &s, KFileItem &a);
0610 
0611     friend class KFileItemTest;
0612     friend class KCoreDirListerCache;
0613 };
0614 
0615 Q_DECLARE_METATYPE(KFileItem)
0616 Q_DECLARE_TYPEINFO(KFileItem, Q_RELOCATABLE_TYPE);
0617 
0618 inline size_t qHash(const KFileItem &item, size_t seed = 0)
0619 {
0620     return qHash(item.url(), seed);
0621 }
0622 
0623 /**
0624  * @class KFileItemList kfileitem.h <KFileItem>
0625  *
0626  * List of KFileItems, which adds a few helper
0627  * methods to QList<KFileItem>.
0628  */
0629 class KIOCORE_EXPORT KFileItemList : public QList<KFileItem>
0630 {
0631 public:
0632     /// Creates an empty list of file items.
0633     KFileItemList();
0634 
0635     /// Creates a new KFileItemList from a QList of file @p items.
0636     KFileItemList(const QList<KFileItem> &items);
0637 
0638     /// Creates a new KFileItemList from an initializer_list of file @p items.
0639     /// @since 5.76
0640     KFileItemList(std::initializer_list<KFileItem> items);
0641 
0642     /**
0643      * Find a KFileItem by name and return it.
0644      * @return the item with the given name, or a null-item if none was found
0645      *         (see KFileItem::isNull())
0646      */
0647     KFileItem findByName(const QString &fileName) const;
0648 
0649     /**
0650      * Find a KFileItem by URL and return it.
0651      * @return the item with the given URL, or a null-item if none was found
0652      *         (see KFileItem::isNull())
0653      */
0654     KFileItem findByUrl(const QUrl &url) const;
0655 
0656     /// @return the list of URLs that those items represent
0657     QList<QUrl> urlList() const;
0658 
0659     /// @return the list of target URLs that those items represent
0660     /// @since 4.2
0661     QList<QUrl> targetUrlList() const;
0662 
0663     // TODO KDE-5 add d pointer here so that we can merge KFileItemListProperties into KFileItemList
0664 };
0665 
0666 KIOCORE_EXPORT QDataStream &operator<<(QDataStream &s, const KFileItem &a);
0667 KIOCORE_EXPORT QDataStream &operator>>(QDataStream &s, KFileItem &a);
0668 
0669 /**
0670  * Support for qDebug() << aFileItem
0671  * \since 4.4
0672  */
0673 KIOCORE_EXPORT QDebug operator<<(QDebug stream, const KFileItem &item);
0674 
0675 #endif