1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 1999-2006 David Faure <faure@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8 #ifndef KFILEITEM_H
9 #define KFILEITEM_H
10
11 #include "kiocore_export.h"
12 #include <QDateTime>
13 #include <QFile>
14 #include <QUrl>
15 #include <kacl.h>
16 #include <kio/global.h>
17 #include <kio/udsentry.h>
18
19 #include <QList>
20 #include <QMimeType>
21 #include <qplatformdefs.h>
22
23 class KFileItemPrivate;
24
25 /**
26 * @class KFileItem kfileitem.h <KFileItem>
27 *
28 * A KFileItem is a generic class to handle a file, local or remote.
29 * In particular, it makes it easier to handle the result of KIO::listDir
30 * (UDSEntry isn't very friendly to use).
31 * It includes many file attributes such as MIME type, icon, text, mode, link...
32 *
33 * KFileItem is implicitly shared, i.e. it can be used as a value and copied around at almost no cost.
34 */
35 class KIOCORE_EXPORT KFileItem
36 {
37 public:
38 enum { Unknown = static_cast<mode_t>(-1) };
39
40 /**
41 * The timestamps associated with a file.
42 * - ModificationTime: the time the file's contents were last modified
43 * - AccessTime: the time the file was last accessed (last read or written to)
44 * - CreationTime: the time the file was created
45 */
46 enum FileTimes {
47 // warning: don't change without looking at the Private class
48 ModificationTime = 0,
49 AccessTime = 1,
50 CreationTime = 2,
51 // ChangeTime
52 };
53
54 enum MimeTypeDetermination {
55 NormalMimeTypeDetermination = 0,
56 SkipMimeTypeFromContent,
57 };
58
59 /**
60 * Null KFileItem. Doesn't represent any file, only exists for convenience.
61 */
62 KFileItem();
63
64 /**
65 * Creates an item representing a file, from a UDSEntry.
66 * This is the preferred constructor when using KIO::listDir().
67 *
68 * @param entry the KIO entry used to get the file, contains info about it
69 * @param itemOrDirUrl the URL of the item or of the directory containing this item (see urlIsDirectory).
70 * @param delayedMimeTypes specifies if the MIME type of the given
71 * URL should be determined immediately or on demand.
72 * See the bool delayedMimeTypes in the KDirLister constructor.
73 * @param urlIsDirectory specifies if the url is just the directory of the
74 * fileitem and the filename from the UDSEntry should be used.
75 *
76 * When creating KFileItems out of the UDSEntry emitted by a KIO list job,
77 * use KFileItem(entry, listjob->url(), delayedMimeTypes, true);
78 */
79 KFileItem(const KIO::UDSEntry &entry, const QUrl &itemOrDirUrl, bool delayedMimeTypes = false, bool urlIsDirectory = false);
80
81 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 0)
82 /**
83 * Creates an item representing a file, from all the necessary info for it.
84 * @param mode the file mode (according to stat() (e.g. S_IFDIR...)
85 * Set to KFileItem::Unknown if unknown. For local files, KFileItem will use stat().
86 * @param permissions the access permissions
87 * If you set both the mode and the permissions, you save a ::stat() for
88 * local files.
89 * Set to KFileItem::Unknown if you don't know the mode or the permission.
90 * @param url the file url
91 *
92 * @param delayedMimeTypes specify if the MIME type of the given URL
93 * should be determined immediately or on demand
94 * @deprecated since 5.0. Most callers gave Unknown for mode and permissions,
95 * so just port to KFileItem(url) and setDelayedMimeTypes(true) if necessary.
96 */
97 KIOCORE_DEPRECATED_VERSION(5, 0, "See API docs")
98 KFileItem(mode_t mode, mode_t permissions, const QUrl &url, bool delayedMimeTypes = false);
99 #endif
100
101 /**
102 * Creates an item representing a file, for which the MIME type is already known.
103 * @param url the file url
104 * @param mimeType the name of the file's MIME type
105 * @param mode the mode (S_IFDIR...)
106 */
107 KFileItem(const QUrl &url, const QString &mimeType = QString(), mode_t mode = KFileItem::Unknown); // KF6 TODO: explicit!
108
109 /**
110 * Creates an item representing a file, with the option of skipping MIME type determination.
111 * @param url the file url
112 * @param mimeTypeDetermination the mode of determining the MIME type:
113 * NormalMimeTypeDetermination by content if local file, i.e. access the file,
114 * open and read part of it;
115 * by QMimeDatabase::MatchMode::MatchExtension if not local.
116 * SkipMimeTypeFromContent always by QMimeDatabase::MatchMode::MatchExtension,
117 * i.e. won't access the file by stat() or opening it;
118 * only suitable for files, directories won't be recognized.
119 * @since 5.57
120 */
121 KFileItem(const QUrl &url, KFileItem::MimeTypeDetermination mimeTypeDetermination);
122
123 /**
124 * Copy constructor
125 */
126 KFileItem(const KFileItem &);
127
128 /**
129 * Destructor
130 */
131 ~KFileItem();
132
133 /**
134 * Move constructor
135 * @since 5.43
136 */
137 KFileItem(KFileItem &&);
138
139 /**
140 * Copy assignment
141 */
142 KFileItem &operator=(const KFileItem &);
143
144 /**
145 * Move assignment
146 * @since 5.43
147 */
148 KFileItem &operator=(KFileItem &&);
149
150 /**
151 * Throw away and re-read (for local files) all information about the file.
152 * This is called when the _file_ changes.
153 */
154 void refresh();
155
156 /**
157 * Re-reads MIME type information.
158 * This is called when the MIME type database changes.
159 */
160 void refreshMimeType();
161
162 /**
163 * Sets MIME type determination to be immediate or on demand.
164 * Call this after the constructor, and before using any MIME-type-related method.
165 * @since 5.0
166 */
167 void setDelayedMimeTypes(bool b);
168
169 /**
170 * Returns the url of the file.
171 * @return the url of the file
172 */
173 QUrl url() const;
174
175 /**
176 * Sets the item's URL. Do not call unless you know what you are doing!
177 * (used for example when an item got renamed).
178 * @param url the item's URL
179 */
180 void setUrl(const QUrl &url);
181
182 /**
183 * Sets the item's local path (UDS_LOCAL_PATH). Do not call unless you know what you are doing!
184 * This won't change the item's name or URL.
185 * (used for example when an item got renamed).
186 * @param path the item's local path
187 * @since 5.20
188 */
189 void setLocalPath(const QString &path);
190
191 /**
192 * Sets the item's name (i.e. the filename).
193 * This is automatically done by setUrl, to set the name from the URL's fileName().
194 * This method is provided for some special cases like relative paths as names (KFindPart)
195 * @param name the item's name
196 */
197 void setName(const QString &name);
198
199 /**
200 * Returns the permissions of the file (stat.st_mode containing only permissions).
201 * @return the permissions of the file
202 */
203 mode_t permissions() const;
204
205 /**
206 * Returns the access permissions for the file as a string.
207 * @return the access permission as string
208 */
209 QString permissionsString() const;
210
211 /**
212 * Tells if the file has extended access level information ( Posix ACL )
213 * @return true if the file has extend ACL information or false if it hasn't
214 */
215 bool hasExtendedACL() const;
216
217 /**
218 * Returns the access control list for the file.
219 * @return the access control list as a KACL
220 */
221 KACL ACL() const;
222
223 /**
224 * Returns the default access control list for the directory.
225 * @return the default access control list as a KACL
226 */
227 KACL defaultACL() const;
228
229 /**
230 * Returns the file type (stat.st_mode containing only S_IFDIR, S_IFLNK, ...).
231 * @return the file type
232 */
233 mode_t mode() const;
234
235 /**
236 * Returns the owner of the file.
237 * @return the file's owner
238 */
239 QString user() const;
240
241 /**
242 * Returns the group of the file.
243 * @return the file's group
244 */
245 QString group() const;
246
247 /**
248 * Returns true if this item represents a link in the UNIX sense of
249 * a link.
250 * @return true if the file is a link
251 */
252 bool isLink() const;
253
254 /**
255 * Returns true if this item represents a directory.
256 * @return true if the item is a directory
257 */
258 bool isDir() const;
259
260 /**
261 * Returns true if this item represents a file (and not a directory)
262 * @return true if the item is a file
263 */
264 bool isFile() const;
265
266 /**
267 * Checks whether the file or directory is readable. In some cases
268 * (remote files), we may return true even though it can't be read.
269 * @return true if the file can be read - more precisely,
270 * false if we know for sure it can't
271 */
272 bool isReadable() const;
273
274 /**
275 * Checks whether the file or directory is writable. In some cases
276 * (remote files), we may return true even though it can't be written to.
277 * @return true if the file or directory can be written to - more precisely,
278 * false if we know for sure it can't
279 */
280 bool isWritable() const;
281
282 /**
283 * Checks whether the file is hidden.
284 * @return true if the file is hidden.
285 */
286 bool isHidden() const;
287
288 /**
289 * @return true if the file is a remote URL, or a local file on a network mount.
290 * It will return false only for really-local file systems.
291 * @since 4.7.4
292 */
293 bool isSlow() const;
294
295 /**
296 * Checks whether the file is a readable local .desktop file,
297 * i.e. a file whose path can be given to KDesktopFile
298 * @return true if the file is a desktop file.
299 * @since 4.1
300 */
301 bool isDesktopFile() const;
302
303 /**
304 * Returns the link destination if isLink() == true.
305 * @return the link destination. QString() if the item is not a link
306 */
307 QString linkDest() const;
308
309 /**
310 * Returns the target url of the file, which is the same as url()
311 * in cases where the slave doesn't specify UDS_TARGET_URL
312 * @return the target url.
313 * @since 4.1
314 */
315 QUrl targetUrl() const;
316
317 /**
318 * Returns the local path if isLocalFile() == true or the KIO item has
319 * a UDS_LOCAL_PATH atom.
320 * @return the item local path, or QString() if not known
321 */
322 QString localPath() const;
323
324 /**
325 * Returns the size of the file, if known.
326 * @return the file size, or 0 if not known
327 */
328 KIO::filesize_t size() const;
329
330 /**
331 * @brief For folders, its recursive size:
332 * the size of its files plus the recursiveSize of its folder
333 *
334 * Initially only implemented for trash:/
335 *
336 * @since 5.70
337 * @return The recursive size
338 */
339 KIO::filesize_t recursiveSize() const;
340
341 /**
342 * Requests the modification, access or creation time, depending on @p which.
343 * @param which the timestamp
344 * @return the time asked for, QDateTime() if not available
345 * @see timeString()
346 */
347 QDateTime time(FileTimes which) const;
348
349 /**
350 * Requests the modification, access or creation time as a string, depending
351 * on @p which.
352 * @param which the timestamp
353 * @returns a formatted string of the requested time.
354 * @see time
355 */
356 QString timeString(FileTimes which = ModificationTime) const;
357
358 #if KIOCORE_ENABLE_DEPRECATED_SINCE(4, 0)
359 KIOCORE_DEPRECATED_VERSION(4, 0, "Use KFileItem::timeString(FileTimes)")
360 QString timeString(unsigned int which) const;
361 #endif
362
363 /**
364 * Returns true if the file is a local file.
365 * @return true if the file is local, false otherwise
366 */
367 bool isLocalFile() const;
368
369 /**
370 * Returns the text of the file item.
371 * It's not exactly the filename since some decoding happens ('%2F'->'/').
372 * @return the text of the file item
373 */
374 QString text() const;
375
376 /**
377 * Return the name of the file item (without a path).
378 * Similar to text(), but unencoded, i.e. the original name.
379 * @param lowerCase if true, the name will be returned in lower case,
380 * which is useful to speed up sorting by name, case insensitively.
381 * @return the file's name
382 */
383 QString name(bool lowerCase = false) const;
384
385 /**
386 * Returns the MIME type of the file item.
387 * If @p delayedMimeTypes was used in the constructor, this will determine
388 * the MIME type first. Equivalent to determineMimeType()->name()
389 * @return the MIME type of the file
390 */
391 QString mimetype() const;
392
393 /**
394 * Returns the MIME type of the file item.
395 * If delayedMimeTypes was used in the constructor, this will determine
396 * the MIME type first.
397 * @return the MIME type
398 */
399 QMimeType determineMimeType() const;
400
401 /**
402 * Returns the currently known MIME type of the file item.
403 * This will not try to determine the MIME type if unknown.
404 * @return the known MIME type
405 */
406 QMimeType currentMimeType() const;
407
408 /**
409 * @return true if we have determined the final icon of this file already.
410 * @since 4.10.2
411 */
412 bool isFinalIconKnown() const;
413
414 /**
415 * @return true if we have determined the MIME type of this file already,
416 * i.e. if determineMimeType() will be fast. Otherwise it will have to
417 * find what the MIME type is, which is a possibly slow operation; usually
418 * this is delayed until necessary.
419 */
420 bool isMimeTypeKnown() const;
421
422 /**
423 * Returns the user-readable string representing the type of this file,
424 * like "OpenDocument Text File".
425 * @return the type of this KFileItem
426 */
427 QString mimeComment() const;
428
429 /**
430 * Returns the full path name to the icon that represents
431 * this MIME type.
432 * @return iconName the name of the file's icon
433 */
434 QString iconName() const;
435
436 /**
437 * Returns the overlays (bitfield of KIconLoader::*Overlay flags) that are used
438 * for this item's pixmap. Overlays are used to show for example, whether
439 * a file can be modified.
440 * @return the overlays of the pixmap
441 */
442 QStringList overlays() const;
443
444 /**
445 * A comment which can contain anything - even rich text. It will
446 * simply be displayed to the user as is.
447 *
448 * @since 4.6
449 */
450 QString comment() const;
451
452 /**
453 * Returns the string to be displayed in the statusbar,
454 * e.g. when the mouse is over this item
455 * @return the status bar information
456 */
457 QString getStatusBarInfo() const;
458
459 #if KIOCORE_ENABLE_DEPRECATED_SINCE(4, 0)
460 /**
461 * Returns true if files can be dropped over this item.
462 * Contrary to popular belief, not only dirs will return true :)
463 * Executables, .desktop files, will do so as well.
464 * @return true if you can drop files over the item
465 *
466 * @deprecated Since 4.0. This logic is application-dependent, the behavior described above
467 * mostly makes sense for file managers only.
468 * KDirModel has setDropsAllowed for similar (but configurable) logic.
469 */
470 KIOCORE_DEPRECATED_VERSION(4, 0, "See API docs")
471 bool acceptsDrops() const;
472 #endif
473
474 /**
475 * Returns the UDS entry. Used by the tree view to access all details
476 * by position.
477 * @return the UDS entry
478 */
479 KIO::UDSEntry entry() const;
480
481 /**
482 * Return true if this item is a regular file,
483 * false otherwise (directory, link, character/block device, fifo, socket)
484 * @since 4.3
485 */
486 bool isRegularFile() const;
487
488 /**
489 * Somewhat like a comparison operator, but more explicit,
490 * and it can detect that two fileitems differ if any property of the file item
491 * has changed (file size, modification date, etc.). Two items are equal if
492 * all properties are equal. In contrast, operator== only compares URLs.
493 * @param item the item to compare
494 * @return true if all values are equal
495 */
496 bool cmp(const KFileItem &item) const;
497
498 /**
499 * Returns true if both items share the same URL.
500 */
501 bool operator==(const KFileItem &other) const;
502
503 /**
504 * Returns true if both items do not share the same URL.
505 */
506 bool operator!=(const KFileItem &other) const;
507
508 /**
509 * Returns true if this item's URL is lexically less than other's URL; otherwise returns false
510 * @since 5.48
511 */
512 bool operator<(const KFileItem &other) const;
513
514 /**
515 * Returns true if this item's URL is lexically less than url other; otherwise returns false
516 * @since 5.48
517 */
518 bool operator<(const QUrl &other) const;
519
520 /**
521 * Converts this KFileItem to a QVariant, this allows to use KFileItem
522 * in QVariant() constructor
523 */
524 operator QVariant() const;
525
526 #if KIOCORE_ENABLE_DEPRECATED_SINCE(4, 0)
527 /**
528 * @deprecated Since 4.0, simply use '='
529 */
530 KIOCORE_DEPRECATED_VERSION(4, 0, "Use KFileItem::operator=(const KFileItem&)")
531 void assign(const KFileItem &item);
532 #endif
533
534 /**
535 * Tries to give a local URL for this file item if possible.
536 * The given boolean indicates if the returned url is local or not.
537 * \since 4.6
538 */
539 QUrl mostLocalUrl(bool *local = nullptr) const;
540
541 struct MostLocalUrlResult {
542 QUrl url;
543 bool local;
544 };
545
546 /**
547 * Returns a MostLocalUrlResult, with the local Url for this item if possible
548 * (otherwise an empty Url), and a bool that is set to @c true if this Url
549 * does represent a local file otherwise @c false.
550 *
551 * @since 5.84
552 */
553 MostLocalUrlResult isMostLocalUrl() const;
554
555 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 0)
556 /**
557 * @deprecated since 5.0 add '&' in front of your boolean argument
558 */
559 KIOCORE_DEPRECATED_VERSION(5, 0, "Use KFileItem::mostLocalUrl(bool *)")
mostLocalUrl(bool & local)560 QUrl mostLocalUrl(bool &local) const
561 {
562 return mostLocalUrl(&local);
563 }
564 #endif
565
566 /**
567 * Return true if default-constructed
568 */
569 bool isNull() const;
570
571 private:
572 QSharedDataPointer<KFileItemPrivate> d;
573
574 /**
575 * Hides the file.
576 */
577 void setHidden();
578
579 private:
580 KIOCORE_EXPORT friend QDataStream &operator<<(QDataStream &s, const KFileItem &a);
581 KIOCORE_EXPORT friend QDataStream &operator>>(QDataStream &s, KFileItem &a);
582
583 friend class KFileItemTest;
584 friend class KCoreDirListerCache;
585 };
586
587 Q_DECLARE_METATYPE(KFileItem)
588 Q_DECLARE_TYPEINFO(KFileItem, Q_MOVABLE_TYPE);
589
qHash(const KFileItem & item)590 inline uint qHash(const KFileItem &item)
591 {
592 return qHash(item.url());
593 }
594
595 /**
596 * @class KFileItemList kfileitem.h <KFileItem>
597 *
598 * List of KFileItems, which adds a few helper
599 * methods to QList<KFileItem>.
600 */
601 class KIOCORE_EXPORT KFileItemList : public QList<KFileItem>
602 {
603 public:
604 /// Creates an empty list of file items.
605 KFileItemList();
606
607 /// Creates a new KFileItemList from a QList of file @p items.
608 KFileItemList(const QList<KFileItem> &items);
609
610 /// Creates a new KFileItemList from an initializer_list of file @p items.
611 /// @since 5.76
612 KFileItemList(std::initializer_list<KFileItem> items);
613
614 /**
615 * Find a KFileItem by name and return it.
616 * @return the item with the given name, or a null-item if none was found
617 * (see KFileItem::isNull())
618 */
619 KFileItem findByName(const QString &fileName) const;
620
621 /**
622 * Find a KFileItem by URL and return it.
623 * @return the item with the given URL, or a null-item if none was found
624 * (see KFileItem::isNull())
625 */
626 KFileItem findByUrl(const QUrl &url) const;
627
628 /// @return the list of URLs that those items represent
629 QList<QUrl> urlList() const;
630
631 /// @return the list of target URLs that those items represent
632 /// @since 4.2
633 QList<QUrl> targetUrlList() const;
634
635 // TODO KDE-5 add d pointer here so that we can merge KFileItemListProperties into KFileItemList
636 };
637
638 KIOCORE_EXPORT QDataStream &operator<<(QDataStream &s, const KFileItem &a);
639 KIOCORE_EXPORT QDataStream &operator>>(QDataStream &s, KFileItem &a);
640
641 /**
642 * Support for qDebug() << aFileItem
643 * \since 4.4
644 */
645 KIOCORE_EXPORT QDebug operator<<(QDebug stream, const KFileItem &item);
646
647 #endif
648