File indexing completed on 2024-12-01 03:40:40
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org> 0004 SPDX-FileCopyrightText: 2001, 2002, 2004-2006 Michael Brade <brade@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KCOREDIRLISTER_H 0010 #define KCOREDIRLISTER_H 0011 0012 #include "kfileitem.h" 0013 0014 #include <QString> 0015 #include <QStringList> 0016 #include <QUrl> 0017 0018 #include <memory> 0019 0020 class KJob; 0021 namespace KIO 0022 { 0023 class Job; 0024 class ListJob; 0025 } 0026 0027 class KCoreDirListerPrivate; 0028 0029 /** 0030 * @class KCoreDirLister kcoredirlister.h <KCoreDirLister> 0031 * 0032 * @short Helper class for the kiojob used to list and update a directory. 0033 * 0034 * The dir lister deals with the kiojob used to list and update a directory 0035 * and has signals for the user of this class (e.g. konqueror view or 0036 * kdesktop) to create/destroy its items when asked. 0037 * 0038 * This class is independent from the graphical representation of the dir 0039 * (icon container, tree view, ...) and it stores the items (as KFileItems). 0040 * 0041 * Typical usage : 0042 * @li Create an instance. 0043 * @li Connect to at least update, clear, itemsAdded, and itemsDeleted. 0044 * @li Call openUrl - the signals will be called. 0045 * @li Reuse the instance when opening a new url (openUrl). 0046 * @li Destroy the instance when not needed anymore (usually destructor). 0047 * 0048 * Advanced usage : call openUrl with OpenUrlFlag::Keep to list directories 0049 * without forgetting the ones previously read (e.g. for a tree view) 0050 * 0051 * @author Michael Brade <brade@kde.org> 0052 */ 0053 class KIOCORE_EXPORT KCoreDirLister : public QObject 0054 { 0055 friend class KCoreDirListerCache; 0056 friend struct KCoreDirListerCacheDirectoryData; 0057 0058 Q_OBJECT 0059 Q_PROPERTY(bool autoUpdate READ autoUpdate WRITE setAutoUpdate) 0060 Q_PROPERTY(bool showHiddenFiles READ showHiddenFiles WRITE setShowHiddenFiles) 0061 Q_PROPERTY(bool dirOnlyMode READ dirOnlyMode WRITE setDirOnlyMode) 0062 Q_PROPERTY(bool delayedMimeTypes READ delayedMimeTypes WRITE setDelayedMimeTypes) 0063 Q_PROPERTY(bool requestMimeTypeWhileListing READ requestMimeTypeWhileListing WRITE setRequestMimeTypeWhileListing) 0064 Q_PROPERTY(QString nameFilter READ nameFilter WRITE setNameFilter) 0065 Q_PROPERTY(QStringList mimeFilter READ mimeFilters WRITE setMimeFilter RESET clearMimeFilter) 0066 Q_PROPERTY(bool autoErrorHandlingEnabled READ autoErrorHandlingEnabled WRITE setAutoErrorHandlingEnabled) 0067 0068 public: 0069 /** 0070 * @see OpenUrlFlags 0071 */ 0072 enum OpenUrlFlag { 0073 NoFlags = 0x0, ///< No additional flags specified. 0074 0075 Keep = 0x1, ///< Previous directories aren't forgotten 0076 ///< (they are still watched by kdirwatch and their items 0077 ///< are kept for this KCoreDirLister). This is useful for e.g. 0078 ///< a treeview. 0079 0080 Reload = 0x2, ///< Indicates whether to use the cache or to reread 0081 ///< the directory from the disk. 0082 ///< Use only when opening a dir not yet listed by this lister 0083 ///< without using the cache. Otherwise use updateDirectory. 0084 }; 0085 0086 /** 0087 * Stores a combination of #OpenUrlFlag values. 0088 */ 0089 Q_DECLARE_FLAGS(OpenUrlFlags, OpenUrlFlag) 0090 0091 /** 0092 * Create a directory lister. 0093 */ 0094 KCoreDirLister(QObject *parent = nullptr); 0095 0096 /** 0097 * Destroy the directory lister. 0098 */ 0099 ~KCoreDirLister() override; 0100 0101 /** 0102 * Run the directory lister on the given url. 0103 * 0104 * This method causes KCoreDirLister to emit @em all the items of @p dirUrl, in any case. 0105 * Depending on @p flags, either clear() or clearDir(const QUrl &) will be emitted first. 0106 * 0107 * The newItems() signal may be emitted more than once to supply you with KFileItems, up 0108 * until the signal completed() is emitted (and isFinished() returns @c true). 0109 * 0110 * @param dirUrl the directory URL. 0111 * @param flags whether to keep previous directories, and whether to reload, see OpenUrlFlags 0112 * @return @c true if successful, @c false otherwise (e.g. if @p dirUrl is invalid) 0113 */ 0114 bool openUrl(const QUrl &dirUrl, OpenUrlFlags flags = NoFlags); // TODO KF6: change bool to void 0115 0116 /** 0117 * Stop listing all directories currently being listed. 0118 * 0119 * Emits canceled() if there was at least one job running. 0120 * Emits listingDirCanceled(const QUrl &) for each stopped job if there is more than one 0121 * directory being watched by this KCoreDirLister. 0122 */ 0123 void stop(); 0124 0125 /** 0126 * Stop listing the given directory. 0127 * 0128 * Emits canceled() if the killed job was the last running one. 0129 * Emits listingDirCanceled(const QUrl &) for the killed job if there is more than one 0130 * directory being watched by this KCoreDirLister. 0131 * 0132 * No signal is emitted if there was no job running for @p dirUrl. 0133 * 0134 * @param dirUrl the directory URL 0135 */ 0136 void stop(const QUrl &dirUrl); 0137 0138 /** 0139 * Stop listening for further changes in the given directory. 0140 * When a new directory is opened with OpenUrlFlag::Keep the caller will keep being notified of file changes for all directories that were kept open. 0141 * This call selectively removes a directory from sending future notifications to this KCoreDirLister. 0142 * 0143 * @param dirUrl the directory URL. 0144 * @since 5.91 0145 */ 0146 void forgetDirs(const QUrl &dirUrl); 0147 0148 /** 0149 * @return @c true if the "delayed MIME types" feature was enabled 0150 * @see setDelayedMimeTypes 0151 */ 0152 bool delayedMimeTypes() const; 0153 0154 /** 0155 * Delayed MIME types feature: 0156 * If enabled, MIME types will be fetched on demand, which leads to a 0157 * faster initial directory listing, where icons get progressively replaced 0158 * with the correct one while KMimeTypeResolver is going through the items 0159 * with unknown or imprecise MIME type (e.g. files with no extension or an 0160 * unknown extension). 0161 */ 0162 void setDelayedMimeTypes(bool delayedMimeTypes); 0163 0164 /** 0165 * Checks whether KDirWatch will automatically update directories. This is 0166 * enabled by default. 0167 * 0168 * @return @c true if KDirWatch is used to automatically update directories 0169 */ 0170 bool autoUpdate() const; 0171 0172 /** 0173 * Toggle automatic directory updating, when a directory changes (using KDirWatch). 0174 * 0175 * @param enable set to @c true to enable or @c false to disable 0176 */ 0177 void setAutoUpdate(bool enable); 0178 0179 /** 0180 * Checks whether hidden files (e.g. files whose name start with '.' on Unix) will be shown. 0181 * By default this option is disabled (hidden files are not shown). 0182 * 0183 * @return @c true if hidden files are shown, @c false otherwise 0184 * 0185 * @see setShowHiddenFiles() 0186 * @since 5.100 0187 */ 0188 bool showHiddenFiles() const; 0189 0190 /** 0191 * Toggles whether hidden files (e.g. files whose name start with '.' on Unix) are shown/ 0192 * By default hidden files are not shown. 0193 * 0194 * You need to call emitChanges() afterwards. 0195 * 0196 * @param showHiddenFiles set to @c true/false to show/hide hidden files respectively 0197 * 0198 * @see showHiddenFiles() 0199 * @since 5.100 0200 */ 0201 void setShowHiddenFiles(bool showHiddenFiles); 0202 0203 /** 0204 * Checks whether this KCoreDirLister only lists directories or all items (directories and 0205 * files), by default all items are listed. 0206 * 0207 * @return @c true if only directories are listed, @c false otherwise 0208 * 0209 * @see setDirOnlyMode(bool) 0210 */ 0211 bool dirOnlyMode() const; 0212 0213 /** 0214 * Call this to list only directories (by default all items (directories and files) 0215 * are listed). 0216 * 0217 * You need to call emitChanges() afterwards. 0218 * 0219 * @param dirsOnly set to @c true to list only directories 0220 */ 0221 void setDirOnlyMode(bool dirsOnly); 0222 0223 /** 0224 * Checks whether this KCoreDirLister requests the MIME type of files from the worker. 0225 * 0226 * Enabling this will tell the worker used for listing that it should try to 0227 * determine the mime type of entries while listing them. This potentially 0228 * reduces the speed at which entries are listed but ensures mime types are 0229 * immediately available when an entry is added, greatly speeding up things 0230 * like mime type filtering. 0231 * 0232 * By default this is disabled. 0233 * 0234 * @return @c true if the worker is asked for MIME types, @c false otherwise. 0235 * 0236 * @see setRequestMimeTypeWhileListing(bool) 0237 * 0238 * @since 5.82 0239 */ 0240 bool requestMimeTypeWhileListing() const; 0241 0242 /** 0243 * Toggles whether to request MIME types from the worker or in-process. 0244 * 0245 * @param request set to @c true to request MIME types from the worker. 0246 * 0247 * @note If this is changed while the lister is already listing a directory, 0248 * it will only have an effect the next time openUrl() is called. 0249 * 0250 * @see requestMimeTypeWhileListing() 0251 * 0252 * @since 5.82 0253 */ 0254 void setRequestMimeTypeWhileListing(bool request); 0255 0256 /** 0257 * Returns the top level URL that is listed by this KCoreDirLister. 0258 * 0259 * It might be different from the one given with openUrl() if there was a 0260 * redirection. If you called openUrl() with OpenUrlFlag::Keep this is the 0261 * first url opened (e.g. in a treeview this is the root). 0262 * 0263 * @return the url used by this instance to list the files 0264 */ 0265 QUrl url() const; 0266 0267 /** 0268 * Returns all URLs that are listed by this KCoreDirLister. This is only 0269 * useful if you called openUrl() with OpenUrlFlag::Keep, as it happens in a 0270 * treeview, for example. (Note that the base url is included in the list 0271 * as well, of course.) 0272 * 0273 * @return a list of all listed URLs 0274 */ 0275 QList<QUrl> directories() const; 0276 0277 /** 0278 * Actually emit the changes made with setShowHiddenFiles, setDirOnlyMode, 0279 * setNameFilter and setMimeFilter. 0280 */ 0281 void emitChanges(); 0282 0283 /** 0284 * Update the directory @p dirUrl. This method causes KCoreDirLister to @em only emit 0285 * the items of @p dirUrl that actually changed compared to the current state in the 0286 * cache, and updates the cache. 0287 * 0288 * The current implementation calls updateDirectory automatically for local files, using 0289 * KDirWatch (if autoUpdate() is @c true), but it might be useful to force an update manually. 0290 * 0291 * @param dirUrl the directory URL 0292 */ 0293 void updateDirectory(const QUrl &dirUrl); 0294 0295 /** 0296 * Returns @c true if no I/O operation is currently in progress. 0297 * 0298 * @return @c true if finished, @c false otherwise 0299 */ 0300 bool isFinished() const; 0301 0302 /** 0303 * Returns the file item of the URL. 0304 * 0305 * Can return an empty KFileItem. 0306 * @return the file item for url() itself (".") 0307 */ 0308 KFileItem rootItem() const; 0309 0310 /** 0311 * Find an item by its URL. 0312 * @param url the item URL 0313 * @return the KFileItem 0314 */ 0315 KFileItem findByUrl(const QUrl &url) const; 0316 0317 /** 0318 * Find an item by its name. 0319 * @param name the item name 0320 * @return the KFileItem 0321 */ 0322 KFileItem findByName(const QString &name) const; 0323 0324 /** 0325 * Set a name filter to only list items matching this name, e.g.\ "*.cpp". 0326 * 0327 * You can set more than one filter by separating them with whitespace, e.g 0328 * "*.cpp *.h". 0329 * Note: the directory is not automatically reloaded. 0330 * You need to call emitChanges() afterwards. 0331 * 0332 * @param filter the new filter, QString() to disable filtering 0333 * @see matchesFilter 0334 */ 0335 void setNameFilter(const QString &filter); 0336 0337 /** 0338 * Returns the current name filter, as set via setNameFilter() 0339 * @return the current name filter, can be QString() if filtering 0340 * is turned off 0341 */ 0342 QString nameFilter() const; 0343 0344 /** 0345 * Set MIME type based filter to only list items matching the given MIME types. 0346 * 0347 * NOTE: setting the filter does not automatically reload directory. 0348 * Also calling this function will not affect any named filter already set. 0349 * 0350 * You need to call emitChanges() afterwards. 0351 * 0352 * @param mimeList a list of MIME types 0353 * 0354 * @see clearMimeFilter 0355 * @see matchesMimeFilter 0356 */ 0357 void setMimeFilter(const QStringList &mimeList); 0358 0359 /** 0360 * Filtering should be done with KFileFilter. This will be implemented in a later 0361 * revision of KCoreDirLister. This method may be removed then. 0362 * 0363 * Set MIME type based exclude filter to only list items not matching the given MIME types 0364 * 0365 * NOTE: setting the filter does not automatically reload directory. 0366 * Also calling this function will not affect any named filter already set. 0367 * 0368 * @param mimeList a list of MIME types 0369 * @see clearMimeFilter 0370 * @see matchesMimeFilter 0371 */ 0372 void setMimeExcludeFilter(const QStringList &mimeList); 0373 0374 /** 0375 * Clears the MIME type based filter. 0376 * 0377 * You need to call emitChanges() afterwards. 0378 * 0379 * @see setMimeFilter 0380 */ 0381 void clearMimeFilter(); 0382 0383 /** 0384 * Returns the list of MIME type based filters, as set via setMimeFilter(). 0385 * @return the list of MIME type based filters. Empty, when no MIME type filter is set. 0386 */ 0387 QStringList mimeFilters() const; 0388 0389 /** 0390 * Used by items() and itemsForDir() to specify whether you want 0391 * all items for a directory or just the filtered ones. 0392 */ 0393 enum WhichItems { 0394 AllItems = 0, 0395 FilteredItems = 1, 0396 }; 0397 0398 /** 0399 * Returns the items listed for the current url(). 0400 * 0401 * This method will @em not start listing a directory, you should only call 0402 * this in a slot connected to the finished() signal. 0403 * 0404 * The items in the KFileItemList are copies of the items used by KCoreDirLister. 0405 * 0406 * @param which specifies whether the returned list will contain all entries 0407 * or only the ones that passed the nameFilter(), mimeFilter(), 0408 * etc. Note that the latter causes iteration over all the 0409 * items, filtering them. If this is too slow for you, use the 0410 * newItems() signal, sending out filtered items in chunks 0411 * @return the items listed for the current url() 0412 */ 0413 KFileItemList items(WhichItems which = FilteredItems) const; 0414 0415 /** 0416 * Returns the items listed for the given @p dirUrl. 0417 * This method will @em not start listing @p dirUrl, you should only call 0418 * this in a slot connected to the finished() signal. 0419 * 0420 * The items in the KFileItemList are copies of the items used by KCoreDirLister. 0421 * 0422 * @param dirUrl specifies the url for which the items should be returned. This 0423 * is only useful if you use KCoreDirLister with multiple URLs 0424 * i.e. using bool OpenUrlFlag::Keep in openUrl() 0425 * @param which specifies whether the returned list will contain all entries 0426 * or only the ones that passed the nameFilter, mimeFilter, etc. 0427 * Note that the latter causes iteration over all the items, 0428 * filtering them. If this is too slow for you, use the 0429 * newItems() signal, sending out filtered items in chunks 0430 * 0431 * @return the items listed for @p dirUrl 0432 */ 0433 KFileItemList itemsForDir(const QUrl &dirUrl, WhichItems which = FilteredItems) const; 0434 0435 /** 0436 * Return the KFileItem for the given URL, if it was listed recently and it's 0437 * still in the cache, which is always the case if a directory view is currently 0438 * showing this item. If not, then it might be in the cache; if not in the cache a 0439 * a null KFileItem will be returned. 0440 * 0441 * If you really need a KFileItem for this URL in all cases, then use KIO::stat() instead. 0442 * 0443 */ 0444 static KFileItem cachedItemForUrl(const QUrl &url); 0445 0446 /** 0447 * Checks whether auto error handling is enabled. 0448 * If enabled, it will show an error dialog to the user when an 0449 * error occurs (assuming the application links to KIOWidgets). 0450 * It is turned on by default. 0451 * @return @c true if auto error handling is enabled, @c false otherwise 0452 * @see setAutoErrorHandlingEnabled() 0453 * @since 5.82 0454 */ 0455 bool autoErrorHandlingEnabled() const; 0456 0457 /** 0458 * Enable or disable auto error handling. 0459 * If enabled, it will show an error dialog to the user when an 0460 * error occurs. It is turned on by default. 0461 * @param enable true to enable auto error handling, false to disable 0462 * @param parent the parent widget for the error dialogs, can be @c nullptr for 0463 * top-level 0464 * @see autoErrorHandlingEnabled() 0465 * @since 5.82 0466 */ 0467 void setAutoErrorHandlingEnabled(bool enable); 0468 0469 Q_SIGNALS: 0470 /** 0471 * Tell the view that this KCoreDirLister has started to list @p dirUrl. Note that this 0472 * does @em not imply that there is really a job running! I.e. KCoreDirLister::jobs() 0473 * may return an empty list, in which case the items are taken from the cache. 0474 * 0475 * The view knows that openUrl should start it, so this might seem useless, but the view 0476 * also needs to know when an automatic update happens. 0477 * @param dirUrl the URL to list 0478 */ 0479 void started(const QUrl &dirUrl); 0480 0481 /** 0482 * Tell the view that listing is finished. There are no jobs running anymore. 0483 */ 0484 void completed(); 0485 0486 /** 0487 * Tell the view that the listing of the directory @p dirUrl is finished. 0488 * There might be other running jobs left. 0489 * 0490 * @param dirUrl the directory URL 0491 * 0492 * @since 5.79 0493 */ 0494 void listingDirCompleted(const QUrl &dirUrl); 0495 0496 /** 0497 * Tell the view that the user canceled the listing. No running jobs are left. 0498 */ 0499 void canceled(); 0500 0501 /** 0502 * Tell the view that the listing of the directory @p dirUrl was canceled. 0503 * There might be other running jobs left. 0504 * 0505 * @param dirUrl the directory URL 0506 * 0507 * @since 5.79 0508 */ 0509 void listingDirCanceled(const QUrl &dirUrl); 0510 0511 /** 0512 * Signals a redirection. 0513 * 0514 * @param oldUrl the original URL 0515 * @param newUrl the new URL 0516 */ 0517 void redirection(const QUrl &oldUrl, const QUrl &newUrl); 0518 0519 /** 0520 * Signals to the view to remove all items (when e.g.\ going from dirA to dirB). 0521 * Make sure to connect to this signal to avoid having duplicate items in the view. 0522 */ 0523 void clear(); 0524 0525 /** 0526 * Signals to the view to clear all items from directory @p dirUrl. 0527 * 0528 * This is only emitted if the lister is holding more than one directory. 0529 * 0530 * @param dirUrl the directory that the view should clear all items from 0531 * 0532 * @since 5.79 0533 */ 0534 void clearDir(const QUrl &dirUrl); 0535 0536 /** 0537 * Signal new items. 0538 * 0539 * @param items a list of new items 0540 */ 0541 void newItems(const KFileItemList &items); 0542 0543 /** 0544 * Signal that new items were found during directory listing. 0545 * Alternative signal emitted at the same time as newItems(), 0546 * but itemsAdded also passes the url of the parent directory. 0547 * 0548 * @param items a list of new items 0549 */ 0550 void itemsAdded(const QUrl &directoryUrl, const KFileItemList &items); 0551 0552 /** 0553 * Send a list of items filtered-out by MIME type. 0554 * @param items the list of filtered items 0555 * 0556 */ 0557 void itemsFilteredByMime(const KFileItemList &items); 0558 0559 /** 0560 * Signal that items have been deleted 0561 * 0562 * @since 4.1.2 0563 * @param items the list of deleted items 0564 */ 0565 void itemsDeleted(const KFileItemList &items); 0566 0567 /** 0568 * Signal an item to refresh (its MIME-type/icon/name has changed). 0569 * Note: KFileItem::refresh has already been called on those items. 0570 * @param items the items to refresh. This is a list of pairs, where 0571 * the first item in the pair is the OLD item, and the second item is the 0572 * NEW item. This allows to track which item has changed, especially after 0573 * a renaming. 0574 */ 0575 void refreshItems(const QList<QPair<KFileItem, KFileItem>> &items); 0576 0577 /** 0578 * Emitted to display information about running jobs. 0579 * Examples of message are "Resolving host", "Connecting to host...", etc. 0580 * @param msg the info message 0581 */ 0582 void infoMessage(const QString &msg); 0583 0584 /** 0585 * Progress signal showing the overall progress of the KCoreDirLister. 0586 * This allows using a progress bar very easily. (see QProgressBar) 0587 * @param percent the progress in percent 0588 */ 0589 void percent(int percent); 0590 0591 /** 0592 * Emitted when we know the size of the jobs. 0593 * @param size the total size in bytes 0594 */ 0595 void totalSize(KIO::filesize_t size); 0596 0597 /** 0598 * Regularly emitted to show the progress of this KCoreDirLister. 0599 * @param size the processed size in bytes 0600 */ 0601 void processedSize(KIO::filesize_t size); 0602 0603 /** 0604 * Emitted to display information about the speed of the jobs. 0605 * @param bytes_per_second the speed in bytes/s 0606 */ 0607 void speed(int bytes_per_second); 0608 0609 /** 0610 * Emitted if listing a directory fails with an error. 0611 * A typical implementation in a widgets-based application 0612 * would show a message box by calling this in a slot connected to this signal: 0613 * <tt>job->uiDelegate()->showErrorMessage()</tt> 0614 * Many applications might prefer to embed the error message though 0615 * (e.g. by using the KMessageWidget class, from the KWidgetsAddons Framework). 0616 * @param the job with an error 0617 * @since 5.82 0618 */ 0619 void jobError(KIO::Job *job); 0620 0621 protected: 0622 /** 0623 * Reimplemented by KDirLister to associate windows with jobs 0624 * @since 5.0 0625 */ 0626 virtual void jobStarted(KIO::ListJob *); 0627 0628 private: 0629 friend class KCoreDirListerPrivate; 0630 std::unique_ptr<KCoreDirListerPrivate> d; 0631 }; 0632 0633 Q_DECLARE_OPERATORS_FOR_FLAGS(KCoreDirLister::OpenUrlFlags) 0634 0635 #endif