1/* This file is part of the KDE project
2 Copyright (C) 1999 David Faure <faure@kde.org>
3 2001, 2002, 2004-2006 Michael Brade <brade@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#ifndef kdirlister_h
22#define kdirlister_h
23
24#include "kfileitem.h"
25#include "kdirnotify.h"
26
27#include <QtCore/QString>
28#include <QtCore/QStringList>
29
30#include <kurl.h>
31
32class KJob;
33namespace KIO { class Job; class ListJob; }
34
35/**
36 * @short Helper class for the kiojob used to list and update a directory.
37 *
38 * The dir lister deals with the kiojob used to list and update a directory
39 * and has signals for the user of this class (e.g. konqueror view or
40 * kdesktop) to create/destroy its items when asked.
41 *
42 * This class is independent from the graphical representation of the dir
43 * (icon container, tree view, ...) and it stores the items (as KFileItems).
44 *
45 * Typical usage :
46 * @li Create an instance.
47 * @li Connect to at least update, clear, itemsAdded, and itemsDeleted.
48 * @li Call openUrl - the signals will be called.
49 * @li Reuse the instance when opening a new url (openUrl).
50 * @li Destroy the instance when not needed anymore (usually destructor).
51 *
52 * Advanced usage : call openUrl with OpenUrlFlag::Keep to list directories
53 * without forgetting the ones previously read (e.g. for a tree view)
54 *
55 * @author Michael Brade <brade@kde.org>
56 */
57class KIO_EXPORT KDirLister : public QObject
58{
59 friend class KDirListerCache;
60 friend struct KDirListerCacheDirectoryData;
61
62 Q_OBJECT
63 Q_PROPERTY( bool autoUpdate READ autoUpdate WRITE setAutoUpdate )
64 Q_PROPERTY( bool showingDotFiles READ showingDotFiles WRITE setShowingDotFiles )
65 Q_PROPERTY( bool dirOnlyMode READ dirOnlyMode WRITE setDirOnlyMode )
66 Q_PROPERTY( bool autoErrorHandlingEnabled READ autoErrorHandlingEnabled )
67 Q_PROPERTY( bool delayedMimeTypes READ delayedMimeTypes WRITE setDelayedMimeTypes )
68 Q_PROPERTY( QString nameFilter READ nameFilter WRITE setNameFilter )
69 Q_PROPERTY( QStringList mimeFilter READ mimeFilters WRITE setMimeFilter RESET clearMimeFilter )
70
71public:
72 enum OpenUrlFlag
73 {
74 NoFlags = 0x0, ///< No additional flags specified.
75
76 Keep = 0x1, ///< Previous directories aren't forgotten
77 ///< (they are still watched by kdirwatch and their items
78 ///< are kept for this KDirLister). This is useful for e.g.
79 ///< a treeview.
80
81 Reload = 0x2 ///< Indicates whether to use the cache or to reread
82 ///< the directory from the disk.
83 ///< Use only when opening a dir not yet listed by this lister
84 ///< without using the cache. Otherwise use updateDirectory.
85 };
86
87 Q_DECLARE_FLAGS(OpenUrlFlags, OpenUrlFlag)
88
89 /**
90 * Create a directory lister.
91 */
92 KDirLister( QObject* parent = 0 );
93
94 /**
95 * Destroy the directory lister.
96 */
97 virtual ~KDirLister();
98
99 /**
100 * Run the directory lister on the given url.
101 *
102 * This method causes KDirLister to emit _all_ the items of @p _url, in any case.
103 * Depending on _flags, either clear() or clear(const KUrl &) will be
104 * emitted first.
105 *
106 * The newItems() signal may be emitted more than once to supply you
107 * with KFileItems, up until the signal completed() is emitted
108 * (and isFinished() returns true).
109 *
110 * @param _url the directory URL.
111 * @param _flags whether to keep previous directories, and whether to reload, see OpenUrlFlags
112 * @return true if successful,
113 * false otherwise (e.g. invalid @p _url)
114 */
115 virtual bool openUrl( const KUrl& _url, OpenUrlFlags _flags = NoFlags );
116
117 /**
118 * Stop listing all directories currently being listed.
119 *
120 * Emits canceled() if there was at least one job running.
121 * Emits canceled( const KUrl& ) for each stopped job if
122 * there are at least two directories being watched by KDirLister.
123 */
124 virtual void stop();
125
126 /**
127 * Stop listing the given directory.
128 *
129 * Emits canceled() if the killed job was the last running one.
130 * Emits canceled( const KUrl& ) for the killed job if
131 * there are at least two directories being watched by KDirLister.
132 * No signal is emitted if there was no job running for @p _url.
133 * @param _url the directory URL
134 */
135 virtual void stop( const KUrl& _url );
136
137 /**
138 * @return true if the "delayed mimetypes" feature was enabled
139 * @see setDelayedMimeTypes
140 */
141 bool delayedMimeTypes() const;
142
143 /**
144 * Delayed mimetypes feature:
145 * If enabled, mime types will be fetched on demand, which leads to a
146 * faster initial directory listing, where icons get progressively replaced
147 * with the correct one while KMimeTypeResolver is going through the items
148 * with unknown or imprecise mimetype (e.g. files with no extension or an
149 * unknown extension).
150 */
151 void setDelayedMimeTypes( bool delayedMimeTypes );
152
153
154 /**
155 * Checks whether KDirWatch will automatically update directories. This is
156 * enabled by default.
157 * @return true if KDirWatch is used to automatically update directories.
158 */
159 bool autoUpdate() const;
160
161 /**
162 * Enable/disable automatic directory updating, when a directory changes
163 * (using KDirWatch).
164 * @param enable true to enable, false to disable
165 */
166 virtual void setAutoUpdate( bool enable );
167
168 /**
169 * Check whether auto error handling is enabled.
170 * If enabled, it will show an error dialog to the user when an
171 * error occurs. It is turned on by default.
172 * @return true if auto error handling is enabled, false otherwise
173 * @see setAutoErrorHandlingEnabled()
174 */
175 bool autoErrorHandlingEnabled() const;
176
177 /**
178 * Enable or disable auto error handling is enabled.
179 * If enabled, it will show an error dialog to the user when an
180 * error occurs. It is turned on by default.
181 * @param enable true to enable auto error handling, false to disable
182 * @param parent the parent widget for the error dialogs, can be 0 for
183 * top-level
184 * @see autoErrorHandlingEnabled()
185 */
186 void setAutoErrorHandlingEnabled( bool enable, QWidget *parent );
187
188 /**
189 * Checks whether hidden files (files beginning with a dot) will be
190 * shown.
191 * By default this option is disabled (hidden files will be not shown).
192 * @return true if dot files are shown, false otherwise
193 * @see setShowingDotFiles()
194 */
195 bool showingDotFiles() const;
196
197 /**
198 * Changes the "is viewing dot files" setting.
199 * You need to call emitChanges() afterwards.
200 * By default this option is disabled (hidden files will not be shown).
201 * @param _showDotFiles true to enable showing hidden files, false to
202 * disable
203 * @see showingDotFiles()
204 */
205 virtual void setShowingDotFiles( bool _showDotFiles );
206
207 /**
208 * Checks whether the KDirLister only lists directories or all
209 * files.
210 * By default this option is disabled (all files will be shown).
211 * @return true if setDirOnlyMode(true) was called
212 */
213 bool dirOnlyMode() const;
214
215 /**
216 * Call this to list only directories.
217 * You need to call emitChanges() afterwards.
218 * By default this option is disabled (all files will be shown).
219 * @param dirsOnly true to list only directories
220 */
221 virtual void setDirOnlyMode( bool dirsOnly );
222
223 /**
224 * Returns the top level URL that is listed by this KDirLister.
225 * It might be different from the one given with openUrl() if there was a
226 * redirection. If you called openUrl() with OpenUrlFlag::Keep this is the
227 * first url opened (e.g. in a treeview this is the root).
228 *
229 * @return the url used by this instance to list the files.
230 */
231 KUrl url() const;
232
233 /**
234 * Returns all URLs that are listed by this KDirLister. This is only
235 * useful if you called openUrl() with OpenUrlFlag::Keep, as it happens in a
236 * treeview, for example. (Note that the base url is included in the list
237 * as well, of course.)
238 *
239 * @return the list of all listed URLs
240 */
241 KUrl::List directories() const;
242
243 /**
244 * Actually emit the changes made with setShowingDotFiles, setDirOnlyMode,
245 * setNameFilter and setMimeFilter.
246 */
247 virtual void emitChanges();
248
249 /**
250 * Update the directory @p _dir. This method causes KDirLister to _only_ emit
251 * the items of @p _dir that actually changed compared to the current state in the
252 * cache and updates the cache.
253 *
254 * The current implementation calls updateDirectory automatically for
255 * local files, using KDirWatch (if autoUpdate() is true), but it might be
256 * useful to force an update manually.
257 *
258 * @param _dir the directory URL
259 */
260 virtual void updateDirectory( const KUrl& _dir );
261
262 /**
263 * Returns true if no io operation is currently in progress.
264 * @return true if finished, false otherwise
265 */
266 bool isFinished() const;
267
268 /**
269 * Returns the file item of the URL.
270 *
271 * Can return an empty KFileItem.
272 * @return the file item for url() itself (".")
273 */
274 KFileItem rootItem() const;
275
276 /**
277 * Find an item by its URL.
278 * @param _url the item URL
279 * @return the KFileItem
280 */
281 virtual KFileItem findByUrl( const KUrl& _url ) const;
282
283 /**
284 * Find an item by its name.
285 * @param name the item name
286 * @return the KFileItem
287 */
288 virtual KFileItem findByName( const QString& name ) const;
289
290 /**
291 * Set a name filter to only list items matching this name, e.g. "*.cpp".
292 *
293 * You can set more than one filter by separating them with whitespace, e.g
294 * "*.cpp *.h".
295 * Note: the directory is not automatically reloaded.
296 * You need to call emitChanges() afterwards.
297 *
298 * @param filter the new filter, QString() to disable filtering
299 * @see matchesFilter
300 */
301 virtual void setNameFilter( const QString &filter );
302
303 /**
304 * Returns the current name filter, as set via setNameFilter()
305 * @return the current name filter, can be QString() if filtering
306 * is turned off
307 */
308 QString nameFilter() const;
309
310 /**
311 * Set mime-based filter to only list items matching the given mimetypes.
312 *
313 * NOTE: setting the filter does not automatically reload directory.
314 * Also calling this function will not affect any named filter already set.
315 *
316 * You need to call emitChanges() afterwards.
317 *
318 * @param mimeList a list of mime-types.
319 *
320 * @see clearMimeFilter
321 * @see matchesMimeFilter
322 */
323 virtual void setMimeFilter( const QStringList &mimeList );
324
325 /**
326 * Filtering should be done with KFileFilter. This will be implemented in a later
327 * revision of KDirLister. This method may be removed then.
328 *
329 * Set mime-based exclude filter to only list items not matching the given mimetypes
330 *
331 * NOTE: setting the filter does not automatically reload directory.
332 * Also calling this function will not affect any named filter already set.
333 *
334 * @param mimeList a list of mime-types.
335 * @see clearMimeFilter
336 * @see matchesMimeFilter
337 * @internal
338 */
339 void setMimeExcludeFilter(const QStringList &mimeList );
340
341
342 /**
343 * Clears the mime based filter.
344 *
345 * You need to call emitChanges() afterwards.
346 *
347 * @see setMimeFilter
348 */
349 virtual void clearMimeFilter();
350
351 /**
352 * Returns the list of mime based filters, as set via setMimeFilter().
353 * @return the list of mime based filters. Empty, when no mime filter is set.
354 */
355 QStringList mimeFilters() const;
356
357 /**
358 * Checks whether @p name matches a filter in the list of name filters.
359 * @return true if @p name matches a filter in the list,
360 * otherwise false.
361 * @see setNameFilter
362 */
363 bool matchesFilter( const QString& name ) const;
364
365 /**
366 * Checks whether @p mime matches a filter in the list of mime types
367 * @param mime the mimetype to find in the filter list.
368 * @return true if @p name matches a filter in the list,
369 * otherwise false.
370 * @see setMimeFilter.
371 */
372 bool matchesMimeFilter( const QString& mime ) const;
373
374 /**
375 * Pass the main window this object is associated with
376 * this is used for caching authentication data
377 * @param window the window to associate with, 0 to disassociate
378 */
379 void setMainWindow( QWidget *window );
380
381 /**
382 * Returns the main window associated with this object.
383 * @return the associated main window, or 0 if there is none
384 */
385 QWidget *mainWindow();
386
387 /**
388 * Used by items() and itemsForDir() to specify whether you want
389 * all items for a directory or just the filtered ones.
390 */
391 enum WhichItems
392 {
393 AllItems = 0,
394 FilteredItems = 1
395 };
396
397 /**
398 * Returns the items listed for the current url().
399 * This method will NOT start listing a directory, you should only call
400 * this when receiving the finished() signal.
401 *
402 * The items in the KFileItemList are copies of the items used
403 * by KDirLister.
404 *
405 * @param which specifies whether the returned list will contain all entries
406 * or only the ones that passed the nameFilter(), mimeFilter(),
407 * etc. Note that the latter causes iteration over all the
408 * items, filtering them. If this is too slow for you, use the
409 * newItems() signal, sending out filtered items in chunks.
410 * @return the items listed for the current url().
411 */
412 KFileItemList items( WhichItems which = FilteredItems ) const;
413
414 /**
415 * Returns the items listed for the given @p dir.
416 * This method will NOT start listing @p dir, you should only call
417 * this when receiving the finished() signal.
418 *
419 * The items in the KFileItemList are copies of the items used
420 * by KDirLister.
421 *
422 * @param dir specifies the url for which the items should be returned. This
423 * is only useful if you use KDirLister with multiple URLs
424 * i.e. using bool OpenUrlFlag::Keep in openUrl().
425 * @param which specifies whether the returned list will contain all entries
426 * or only the ones that passed the nameFilter, mimeFilter, etc.
427 * Note that the latter causes iteration over all the items,
428 * filtering them. If this is too slow for you, use the
429 * newItems() signal, sending out filtered items in chunks.
430 * @return the items listed for @p dir.
431 */
432 KFileItemList itemsForDir( const KUrl& dir,
433 WhichItems which = FilteredItems ) const;
434
435 /**
436 * Return the KFileItem for the given URL, if we listed it recently
437 * and it's still in the cache - which is always the case if a directory
438 * view is currently showing this item. If not, then it might be in the
439 * cache, or it might not, in which case you get a null KFileItem.
440 * If you really need a KFileItem for this URL in all cases, then use
441 * KIO::stat() instead.
442 *
443 * @since 4.2
444 */
445 static KFileItem cachedItemForUrl(const KUrl& url);
446
447Q_SIGNALS:
448
449 /**
450 * Tell the view that we started to list @p _url. NOTE: this does _not_ imply that there
451 * is really a job running! I.e. KDirLister::jobs() may return an empty list. In this case
452 * the items are taken from the cache.
453 *
454 * The view knows that openUrl should start it, so it might seem useless,
455 * but the view also needs to know when an automatic update happens.
456 * @param _url the URL to list
457 */
458 void started( const KUrl& _url );
459
460 /**
461 * Tell the view that listing is finished. There are no jobs running anymore.
462 */
463 void completed();
464
465 /**
466 * Tell the view that the listing of the directory @p _url is finished.
467 * There might be other running jobs left.
468 * @param _url the directory URL
469 */
470 void completed( const KUrl& _url );
471
472 /**
473 * Tell the view that the user canceled the listing. No running jobs are left.
474 */
475 void canceled();
476
477 /**
478 * Tell the view that the listing of the directory @p _url was canceled.
479 * There might be other running jobs left.
480 * @param _url the directory URL
481 */
482 void canceled( const KUrl& _url );
483
484 /**
485 * Signal a redirection.
486 * Only emitted if there's just one directory to list, i.e. most
487 * probably openUrl() has been called without OpenUrlFlag::Keep.
488 * @param _url the new URL
489 */
490 void redirection( const KUrl& _url );
491
492 /**
493 * Signal a redirection.
494 * @param oldUrl the original URL
495 * @param newUrl the new URL
496 */
497 void redirection( const KUrl& oldUrl, const KUrl& newUrl );
498
499 /**
500 * Signal to clear all items.
501 * Make sure to connect to this signal to avoid doubled items.
502 */
503 void clear();
504
505 /**
506 * Signal to empty the directory @p _url.
507 * It is only emitted if the lister is holding more than one directory.
508 * @param _url the directory that will be emptied
509 */
510 void clear( const KUrl& _url );
511
512 /**
513 * Signal new items.
514 *
515 * @param items a list of new items
516 */
517 void newItems( const KFileItemList& items );
518
519 /**
520 * Signal that new items were found during directory listing.
521 * Alternative signal emitted at the same time as newItems(),
522 * but itemsAdded also passes the url of the parent directory.
523 *
524 * @param items a list of new items
525 * @since 4.2
526 */
527 void itemsAdded(const KUrl& directoryUrl, const KFileItemList& items);
528
529 /**
530 * Send a list of items filtered-out by mime-type.
531 * @param items the list of filtered items
532 */
533 void itemsFilteredByMime( const KFileItemList& items );
534
535 /**
536 * Signals that an item has been deleted
537 *
538 * @deprecated Don't connect to this signal. Use itemsDeleted instead.
539 *
540 * @param _fileItem the fileItem to delete
541 */
542 QT_MOC_COMPAT void deleteItem( const KFileItem &_fileItem ); // KDE5: remove, and port to itemsDeleted
543
544 /**
545 * Signal that items have been deleted.
546 *
547 * @since 4.1.2
548 * @param items the list of deleted items
549 */
550 void itemsDeleted( const KFileItemList& items );
551
552 /**
553 * Signal an item to refresh (its mimetype/icon/name has changed).
554 * Note: KFileItem::refresh has already been called on those items.
555 * @param items the items to refresh. This is a list of pairs, where
556 * the first item in the pair is the OLD item, and the second item is the
557 * NEW item. This allows to track which item has changed, especially after
558 * a renaming.
559 */
560 void refreshItems( const QList<QPair<KFileItem, KFileItem> >& items );
561
562 /**
563 * Emitted to display information about running jobs.
564 * Examples of message are "Resolving host", "Connecting to host...", etc.
565 * @param msg the info message
566 */
567 void infoMessage( const QString& msg );
568
569 /**
570 * Progress signal showing the overall progress of the KDirLister.
571 * This allows using a progress bar very easily. (see QProgressBar)
572 * @param percent the progress in percent
573 */
574 void percent( int percent );
575
576 /**
577 * Emitted when we know the size of the jobs.
578 * @param size the total size in bytes
579 */
580 void totalSize( KIO::filesize_t size );
581
582 /**
583 * Regularly emitted to show the progress of this KDirLister.
584 * @param size the processed size in bytes
585 */
586 void processedSize( KIO::filesize_t size );
587
588 /**
589 * Emitted to display information about the speed of the jobs.
590 * @param bytes_per_second the speed in bytes/s
591 */
592 void speed( int bytes_per_second );
593
594protected:
595 /// @deprecated and unused, ignore this
596 enum Changes { NONE=0, NAME_FILTER=1, MIME_FILTER=2, DOT_FILES=4, DIR_ONLY_MODE=8 };
597
598 /**
599 * Called for every new item before emitting newItems().
600 * You may reimplement this method in a subclass to implement your own
601 * filtering.
602 * The default implementation filters out ".." and everything not matching
603 * the name filter(s)
604 * @return true if the item is "ok".
605 * false if the item shall not be shown in a view, e.g.
606 * files not matching a pattern *.cpp ( KFileItem::isHidden())
607 * @see matchesFilter
608 * @see setNameFilter
609 */
610 virtual bool matchesFilter( const KFileItem& ) const;
611
612 /**
613 * Called for every new item before emitting newItems().
614 * You may reimplement this method in a subclass to implement your own
615 * filtering.
616 * The default implementation filters out ".." and everything not matching
617 * the name filter(s)
618 * @return true if the item is "ok".
619 * false if the item shall not be shown in a view, e.g.
620 * files not matching a pattern *.cpp ( KFileItem::isHidden())
621 * @see matchesMimeFilter
622 * @see setMimeFilter
623 */
624 virtual bool matchesMimeFilter( const KFileItem& ) const;
625
626 /**
627 * Called by the public matchesFilter() to do the
628 * actual filtering. Those methods may be reimplemented to customize
629 * filtering.
630 * @param name the name to filter
631 * @param filters a list of regular expressions for filtering
632 */
633 virtual bool doNameFilter( const QString& name, const QList<QRegExp>& filters ) const;
634
635 /**
636 * Called by the public matchesMimeFilter() to do the
637 * actual filtering. Those methods may be reimplemented to customize
638 * filtering.
639 * @param mime the mime type to filter
640 * @param filters the list of mime types to filter
641 */
642 virtual bool doMimeFilter( const QString& mime, const QStringList& filters ) const;
643
644 /** Reimplement to customize error handling */
645 virtual void handleError( KIO::Job * );
646
647private:
648 class Private;
649 Private* const d;
650 friend class Private;
651
652 Q_PRIVATE_SLOT( d, void _k_slotInfoMessage( KJob*, const QString& ) )
653 Q_PRIVATE_SLOT( d, void _k_slotPercent( KJob*, unsigned long ) )
654 Q_PRIVATE_SLOT( d, void _k_slotTotalSize( KJob*, qulonglong ) )
655 Q_PRIVATE_SLOT( d, void _k_slotProcessedSize( KJob*, qulonglong ) )
656 Q_PRIVATE_SLOT( d, void _k_slotSpeed( KJob*, unsigned long ) )
657};
658
659Q_DECLARE_OPERATORS_FOR_FLAGS(KDirLister::OpenUrlFlags)
660
661#endif
662
663