• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.8.5 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kio
kdirlister_p.h
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  Copyright (C) 2002-2006 Michael Brade <brade@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #ifndef kdirlister_p_h
21 #define kdirlister_p_h
22 
23 #include "kfileitem.h"
24 
25 #include <QtCore/QMap>
26 #include <QtCore/QHash>
27 #include <QtCore/QCache>
28 #include <QtCore/QSet>
29 #include <QtCore/QTimer>
30 #include <QtGui/QWidget>
31 
32 #include <kurl.h>
33 #include <kdebug.h>
34 #include <kio/global.h>
35 #include <kdirwatch.h>
36 
37 class KDirLister;
38 namespace KIO { class Job; class ListJob; }
39 class OrgKdeKDirNotifyInterface;
40 struct KDirListerCacheDirectoryData;
41 
42 class KDirLister::Private
43 {
44 public:
45  Private(KDirLister *parent)
46  : m_parent(parent)
47  {
48  complete = false;
49 
50  autoUpdate = false;
51 
52  autoErrorHandling = false;
53  errorParent = 0;
54 
55  delayedMimeTypes = false;
56 
57  rootFileItem = KFileItem();
58 
59  lstNewItems = 0;
60  lstRefreshItems = 0;
61  lstMimeFilteredItems = 0;
62  lstRemoveItems = 0;
63 
64  hasPendingChanges = false;
65 
66  window = 0;
67  }
68 
69  void _k_emitCachedItems(const KUrl&, bool, bool);
70  void _k_slotInfoMessage( KJob*, const QString& );
71  void _k_slotPercent( KJob*, unsigned long );
72  void _k_slotTotalSize( KJob*, qulonglong );
73  void _k_slotProcessedSize( KJob*, qulonglong );
74  void _k_slotSpeed( KJob*, unsigned long );
75 
76  bool doMimeExcludeFilter( const QString& mimeExclude, const QStringList& filters ) const;
77  void jobStarted( KIO::ListJob * );
78  void connectJob( KIO::ListJob * );
79  void jobDone( KIO::ListJob * );
80  uint numJobs();
81  void addNewItem(const KUrl& directoryUrl, const KFileItem& item);
82  void addNewItems(const KUrl& directoryUrl, const KFileItemList& items);
83  void addRefreshItem(const KUrl& directoryUrl, const KFileItem& oldItem, const KFileItem& item);
84  void emitItems();
85  void emitItemsDeleted(const KFileItemList &items);
86 
92  void redirect(const KUrl& oldUrl, const KUrl& newUrl, bool keepItems);
93 
97  bool isItemVisible(const KFileItem& item) const;
98 
99  void prepareForSettingsChange() {
100  if (!hasPendingChanges) {
101  hasPendingChanges = true;
102  oldSettings = settings;
103  }
104  }
105 
106  void emitChanges();
107 
108  class CachedItemsJob;
109  CachedItemsJob* cachedItemsJobForUrl(const KUrl& url) const;
110 
111 
112  KDirLister *m_parent;
113 
118  KUrl::List lstDirs;
119 
120  // toplevel URL
121  KUrl url;
122 
123  bool complete:1;
124 
125  bool autoUpdate:1;
126 
127  bool delayedMimeTypes:1;
128 
129  bool hasPendingChanges:1; // i.e. settings != oldSettings
130 
131  bool autoErrorHandling:2;
132  QWidget *errorParent;
133 
134  struct JobData {
135  long unsigned int percent, speed;
136  KIO::filesize_t processedSize, totalSize;
137  };
138 
139  QMap<KIO::ListJob *, JobData> jobData;
140 
141  // file item for the root itself (".")
142  KFileItem rootFileItem;
143 
144  typedef QHash<KUrl, KFileItemList> NewItemsHash;
145  NewItemsHash *lstNewItems;
146  QList<QPair<KFileItem,KFileItem> > *lstRefreshItems;
147  KFileItemList *lstMimeFilteredItems, *lstRemoveItems;
148 
149  QWidget *window; // Main window this lister is associated with
150  QList<CachedItemsJob*> m_cachedItemsJobs;
151 
152  QString nameFilter; // parsed into lstFilters
153 
154  struct FilterSettings {
155  FilterSettings() : isShowingDotFiles(false), dirOnlyMode(false) {}
156  bool isShowingDotFiles;
157  bool dirOnlyMode;
158  QList<QRegExp> lstFilters;
159  QStringList mimeFilter;
160  QStringList mimeExcludeFilter;
161  };
162  FilterSettings settings;
163  FilterSettings oldSettings;
164 
165  friend class KDirListerCache;
166 };
167 
181 class KDirListerCache : public QObject
182 {
183  Q_OBJECT
184 public:
185  KDirListerCache(); // only called by K_GLOBAL_STATIC
186  ~KDirListerCache();
187 
188  void updateDirectory( const KUrl& dir );
189 
190  KFileItem itemForUrl( const KUrl& url ) const;
191  KFileItemList *itemsForDir(const KUrl& dir) const;
192 
193  bool listDir( KDirLister *lister, const KUrl& _url, bool _keep, bool _reload );
194 
195  // stop all running jobs for lister
196  void stop( KDirLister *lister, bool silent = false );
197  // stop just the job listing url for lister
198  void stopListingUrl( KDirLister *lister, const KUrl &_url, bool silent = false );
199 
200  void setAutoUpdate( KDirLister *lister, bool enable );
201 
202  void forgetDirs( KDirLister *lister );
203  void forgetDirs( KDirLister *lister, const KUrl &_url, bool notify );
204 
205  KFileItem findByName( const KDirLister *lister, const QString &_name ) const;
206  // findByUrl returns a pointer so that it's possible to modify the item.
207  // See itemForUrl for the version that returns a readonly kfileitem.
208  // @param lister can be 0. If set, it is checked that the url is held by the lister
209  KFileItem *findByUrl(const KDirLister *lister, const KUrl &url) const;
210 
211  // Called by CachedItemsJob:
212  // Emits the cached items, for this lister and this url
213  void emitItemsFromCache(KDirLister::Private::CachedItemsJob* job, KDirLister* lister,
214  const KUrl& _url, bool _reload, bool _emitCompleted);
215  // Called by CachedItemsJob:
216  void forgetCachedItemsJob(KDirLister::Private::CachedItemsJob* job, KDirLister* lister,
217  const KUrl& url);
218 
219 public Q_SLOTS:
226  void slotFilesAdded( const QString& urlDirectory );
227 
235  void slotFilesRemoved( const QStringList& fileList );
236 
243  void slotFilesChanged( const QStringList& fileList );
244  void slotFileRenamed( const QString& srcUrl, const QString& dstUrl );
245 
246 private Q_SLOTS:
247  void slotFileDirty( const QString &_file );
248  void slotFileCreated( const QString &_file );
249  void slotFileDeleted( const QString &_file );
250 
251  void slotEntries( KIO::Job *job, const KIO::UDSEntryList &entries );
252  void slotResult( KJob *j );
253  void slotRedirection( KIO::Job *job, const KUrl &url );
254 
255  void slotUpdateEntries( KIO::Job *job, const KIO::UDSEntryList &entries );
256  void slotUpdateResult( KJob *job );
257  void processPendingUpdates();
258 
259 private:
260  class DirItem;
261  DirItem* dirItemForUrl(const KUrl& dir) const;
262 
263  bool validUrl( const KDirLister *lister, const KUrl& _url ) const;
264 
265  void stopListJob(const QString& url, bool silent);
266 
267  KIO::ListJob *jobForUrl( const QString& url, KIO::ListJob *not_job = 0 );
268  const KUrl& joburl( KIO::ListJob *job );
269 
270  void killJob( KIO::ListJob *job );
271 
272  // Called when something tells us that the directory @p url has changed.
273  // Returns true if @p url is held by some lister (meaning: do the update now)
274  // otherwise mark the cached item as not-up-to-date for later and return false
275  bool checkUpdate( const QString& url );
276 
277  // Helper method for slotFileDirty
278  void handleFileDirty(const KUrl& url);
279  void handleDirDirty(const KUrl& url);
280 
281  // when there were items deleted from the filesystem all the listers holding
282  // the parent directory need to be notified, the unmarked items have to be deleted
283  // and removed from the cache including all the children.
284  void deleteUnmarkedItems( const QList<KDirLister *>&, KFileItemList & );
285  // Helper method called when we know that a list of items was deleted
286  void itemsDeleted(const QList<KDirLister *>& listers, const KFileItemList& deletedItems);
287  void slotFilesRemoved(const KUrl::List& urls);
288  // common for slotRedirection and slotFileRenamed
289  void renameDir( const KUrl &oldUrl, const KUrl &url );
290  // common for deleteUnmarkedItems and slotFilesRemoved
291  void deleteDir( const KUrl& dirUrl );
292  // remove directory from cache (itemsCached), including all child dirs
293  void removeDirFromCache( const KUrl& dir );
294  // helper for renameDir
295  void emitRedirections( const KUrl &oldUrl, const KUrl &url );
296 
302  QSet<KDirLister *> emitRefreshItem(const KFileItem& oldItem, const KFileItem& fileitem);
303 
308  QStringList directoriesForCanonicalPath(const QString& dir) const;
309 
310 #ifndef NDEBUG
311  void printDebug();
312 #endif
313 
314  class DirItem
315  {
316  public:
317  DirItem(const KUrl &dir, const QString& canonicalPath)
318  : url(dir), m_canonicalPath(canonicalPath)
319  {
320  autoUpdates = 0;
321  complete = false;
322  }
323 
324  ~DirItem()
325  {
326  if ( autoUpdates )
327  {
328  if ( KDirWatch::exists() && url.isLocalFile() )
329  KDirWatch::self()->removeDir(m_canonicalPath);
330  sendSignal( false, url );
331  }
332  lstItems.clear();
333  }
334 
335  void sendSignal( bool entering, const KUrl& url )
336  {
337  // Note that "entering" means "start watching", and "leaving" means "stop watching"
338  // (i.e. it's not when the user leaves the directory, it's when the directory is removed from the cache)
339  if (entering)
340  org::kde::KDirNotify::emitEnteredDirectory( url.url() );
341  else
342  org::kde::KDirNotify::emitLeftDirectory( url.url() );
343  }
344 
345  void redirect( const KUrl& newUrl )
346  {
347  if ( autoUpdates )
348  {
349  if ( url.isLocalFile() )
350  KDirWatch::self()->removeDir(m_canonicalPath);
351  sendSignal( false, url );
352 
353  if (newUrl.isLocalFile()) {
354  m_canonicalPath = QFileInfo(newUrl.toLocalFile()).canonicalFilePath();
355  KDirWatch::self()->addDir(m_canonicalPath);
356  }
357  sendSignal( true, newUrl );
358  }
359 
360  url = newUrl;
361 
362  if ( !rootItem.isNull() )
363  rootItem.setUrl( newUrl );
364  }
365 
366  void incAutoUpdate()
367  {
368  if ( autoUpdates++ == 0 )
369  {
370  if ( url.isLocalFile() )
371  KDirWatch::self()->addDir(m_canonicalPath);
372  sendSignal( true, url );
373  }
374  }
375 
376  void decAutoUpdate()
377  {
378  if ( --autoUpdates == 0 )
379  {
380  if ( url.isLocalFile() )
381  KDirWatch::self()->removeDir(m_canonicalPath);
382  sendSignal( false, url );
383  }
384 
385  else if ( autoUpdates < 0 )
386  autoUpdates = 0;
387  }
388 
389  // number of KDirListers using autoUpdate for this dir
390  short autoUpdates;
391 
392  // this directory is up-to-date
393  bool complete;
394 
395  // the complete url of this directory
396  KUrl url;
397 
398  // the local path, with symlinks resolved, so that KDirWatch works
399  QString m_canonicalPath;
400 
401  // KFileItem representing the root of this directory.
402  // Remember that this is optional. FTP sites don't return '.' in
403  // the list, so they give no root item
404  KFileItem rootItem;
405  KFileItemList lstItems;
406  };
407 
408  //static const unsigned short MAX_JOBS_PER_LISTER;
409 
410  QMap<KIO::ListJob *, KIO::UDSEntryList> runningListJobs;
411 
412  // an item is a complete directory
413  QHash<QString /*url*/, DirItem*> itemsInUse;
414  QCache<QString /*url*/, DirItem> itemsCached;
415 
416  typedef QHash<QString /*url*/, KDirListerCacheDirectoryData> DirectoryDataHash;
417  DirectoryDataHash directoryData;
418 
419  // Symlink-to-directories are registered here so that we can
420  // find the url that changed, when kdirwatch tells us about
421  // changes in the canonical url. (#213799)
422  QHash<QString /*canonical path*/, QStringList /*dirlister urls*/> canonicalUrls;
423 
424  // Set of local files that we have changed recently (according to KDirWatch)
425  // We temporize the notifications by keeping them 500ms in this list.
426  QSet<QString /*path*/> pendingUpdates;
427  // The timer for doing the delayed updates
428  QTimer pendingUpdateTimer;
429 
430  // Set of remote files that have changed recently -- but we can't emit those
431  // changes yet, we need to wait for the "update" directory listing.
432  // The cmp() call can't differ mimetypes since they are determined on demand,
433  // this is why we need to remember those files here.
434  QSet<KFileItem*> pendingRemoteUpdates;
435 
436  // the KDirNotify signals
437  OrgKdeKDirNotifyInterface *kdirnotify;
438 
439  struct ItemInUseChange;
440 };
441 
442 // Data associated with a directory url
443 // This could be in DirItem but only in the itemsInUse dict...
444 struct KDirListerCacheDirectoryData
445 {
446  // A lister can be EITHER in listersCurrentlyListing OR listersCurrentlyHolding
447  // but NOT in both at the same time.
448  // But both lists can have different listers at the same time; this
449  // happens if more listers are requesting url at the same time and
450  // one lister was stopped during the listing of files.
451 
452  // Listers that are currently listing this url
453  QList<KDirLister *> listersCurrentlyListing;
454  // Listers that are currently holding this url
455  QList<KDirLister *> listersCurrentlyHolding;
456 
457  void moveListersWithoutCachedItemsJob(const KUrl& url);
458 };
459 
460 //const unsigned short KDirListerCache::MAX_JOBS_PER_LISTER = 5;
461 
462 // This job tells KDirListerCache to emit cached items asynchronously from listDir()
463 // to give the KDirLister user enough time for connecting to its signals, and so
464 // that KDirListerCache behaves just like when a real KIO::Job is used: nothing
465 // is emitted during the openUrl call itself.
466 class KDirLister::Private::CachedItemsJob : public KJob {
467  Q_OBJECT
468 public:
469  CachedItemsJob(KDirLister* lister, const KUrl& url, bool reload);
470 
471  /*reimp*/ void start() { QMetaObject::invokeMethod(this, "done", Qt::QueuedConnection); }
472 
473  // For updateDirectory() to cancel m_emitCompleted;
474  void setEmitCompleted(bool b) { m_emitCompleted = b; }
475 
476  KUrl url() const { return m_url; }
477 
478 protected:
479  virtual bool doKill();
480 
481 public Q_SLOTS:
482  void done();
483 
484 private:
485  KDirLister* m_lister;
486  KUrl m_url;
487  bool m_reload;
488  bool m_emitCompleted;
489 };
490 
491 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Fri Dec 7 2012 16:08:37 by doxygen 1.8.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.8.5 API Reference

Skip menu "kdelibs-4.8.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal