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