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

KIO

kdirlister_p.h

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2002-2006 Michael Brade <brade@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #ifndef kdirlister_p_h
00021 #define kdirlister_p_h
00022 
00023 #include "kfileitem.h"
00024 
00025 #include <QtCore/QMap>
00026 #include <QtCore/QHash>
00027 #include <QtCore/QCache>
00028 #include <QtCore/QSet>
00029 #include <QtCore/QTimer>
00030 #include <QtGui/QWidget>
00031 
00032 #include <kurl.h>
00033 #include <kdebug.h>
00034 #include <kio/global.h>
00035 #include <kdirwatch.h>
00036 
00037 class KDirLister;
00038 namespace KIO { class Job; class ListJob; }
00039 class OrgKdeKDirNotifyInterface;
00040 struct KDirListerCacheDirectoryData;
00041 
00042 class KDirLister::Private
00043 {
00044 public:
00045   Private(KDirLister *parent)
00046       : m_parent(parent)
00047   {
00048     complete = false;
00049 
00050     autoUpdate = false;
00051 
00052     autoErrorHandling = false;
00053     errorParent = 0;
00054 
00055     delayedMimeTypes = false;
00056 
00057     rootFileItem = KFileItem();
00058 
00059     lstNewItems = 0;
00060     lstRefreshItems = 0;
00061     lstMimeFilteredItems = 0;
00062     lstRemoveItems = 0;
00063 
00064     hasPendingChanges = false;
00065 
00066     window = 0;
00067   }
00068 
00069     void _k_emitCachedItems(const KUrl&, bool, bool);
00070   void _k_slotInfoMessage( KJob*, const QString& );
00071   void _k_slotPercent( KJob*, unsigned long );
00072   void _k_slotTotalSize( KJob*, qulonglong );
00073   void _k_slotProcessedSize( KJob*, qulonglong );
00074   void _k_slotSpeed( KJob*, unsigned long );
00075 
00076   bool doMimeExcludeFilter( const QString& mimeExclude, const QStringList& filters ) const;
00077   void jobStarted( KIO::ListJob * );
00078   void connectJob( KIO::ListJob * );
00079   void jobDone( KIO::ListJob * );
00080   uint numJobs();
00081     void addNewItem(const KUrl& directoryUrl, const KFileItem& item);
00082     void addNewItems(const KUrl& directoryUrl, const KFileItemList& items);
00083     void addRefreshItem(const KUrl& directoryUrl, const KFileItem& oldItem, const KFileItem& item);
00084   void emitItems();
00085   void emitItemsDeleted(const KFileItemList &items);
00086 
00092     void redirect(const KUrl& oldUrl, const KUrl& newUrl, bool keepItems);
00093 
00097     bool isItemVisible(const KFileItem& item) const;
00098 
00099     void prepareForSettingsChange() {
00100         if (!hasPendingChanges) {
00101             hasPendingChanges = true;
00102             oldSettings = settings;
00103         }
00104     }
00105 
00106     void emitChanges();
00107 
00108     class CachedItemsJob;
00109     CachedItemsJob* cachedItemsJobForUrl(const KUrl& url) const;
00110 
00111 
00112   KDirLister *m_parent;
00113 
00118   KUrl::List lstDirs;
00119 
00120   // toplevel URL
00121   KUrl url;
00122 
00123   bool complete:1;
00124 
00125   bool autoUpdate:1;
00126 
00127   bool delayedMimeTypes:1;
00128 
00129     bool hasPendingChanges:1; // i.e. settings != oldSettings
00130 
00131   bool autoErrorHandling:2;
00132   QWidget *errorParent;
00133 
00134   struct JobData {
00135     long unsigned int percent, speed;
00136     KIO::filesize_t processedSize, totalSize;
00137   };
00138 
00139   QMap<KIO::ListJob *, JobData> jobData;
00140 
00141   // file item for the root itself (".")
00142   KFileItem rootFileItem;
00143 
00144     typedef QHash<KUrl, KFileItemList> NewItemsHash;
00145     NewItemsHash *lstNewItems;
00146   QList<QPair<KFileItem,KFileItem> > *lstRefreshItems;
00147   KFileItemList *lstMimeFilteredItems, *lstRemoveItems;
00148 
00149     QWidget *window; // Main window this lister is associated with
00150     QList<CachedItemsJob*> m_cachedItemsJobs;
00151 
00152     QString nameFilter; // parsed into lstFilters
00153 
00154     struct FilterSettings {
00155         FilterSettings() : isShowingDotFiles(false), dirOnlyMode(false) {}
00156         bool isShowingDotFiles;
00157         bool dirOnlyMode;
00158         QList<QRegExp> lstFilters;
00159         QStringList mimeFilter;
00160         QStringList mimeExcludeFilter;
00161     };
00162     FilterSettings settings;
00163     FilterSettings oldSettings;
00164 
00165     friend class KDirListerCache;
00166 };
00167 
00181 class KDirListerCache : public QObject
00182 {
00183     Q_OBJECT
00184 public:
00185     KDirListerCache(); // only called by K_GLOBAL_STATIC
00186     ~KDirListerCache();
00187 
00188     void updateDirectory( const KUrl& dir );
00189 
00190     KFileItem itemForUrl( const KUrl& url ) const;
00191     KFileItemList *itemsForDir(const KUrl& dir) const;
00192 
00193     bool listDir( KDirLister *lister, const KUrl& _url, bool _keep, bool _reload );
00194 
00195     // stop all running jobs for lister
00196     void stop( KDirLister *lister, bool silent = false );
00197     // stop just the job listing url for lister
00198     void stopListingUrl( KDirLister *lister, const KUrl &_url, bool silent = false );
00199 
00200   void setAutoUpdate( KDirLister *lister, bool enable );
00201 
00202   void forgetDirs( KDirLister *lister );
00203   void forgetDirs( KDirLister *lister, const KUrl &_url, bool notify );
00204 
00205     KFileItem findByName( const KDirLister *lister, const QString &_name ) const;
00206     // findByUrl returns a pointer so that it's possible to modify the item.
00207     // See itemForUrl for the version that returns a readonly kfileitem.
00208     // @param lister can be 0. If set, it is checked that the url is held by the lister
00209     KFileItem *findByUrl(const KDirLister *lister, const KUrl &url) const;
00210 
00211     // Called by CachedItemsJob:
00212     // Emits the cached items, for this lister and this url
00213     void emitItemsFromCache(KDirLister::Private::CachedItemsJob* job, KDirLister* lister,
00214                             const KUrl& _url, bool _reload, bool _emitCompleted);
00215     // Called by CachedItemsJob:
00216     void forgetCachedItemsJob(KDirLister::Private::CachedItemsJob* job, KDirLister* lister,
00217                               const KUrl& url);
00218 
00219 public Q_SLOTS:
00226   void slotFilesAdded( const QString& urlDirectory );
00227 
00235   void slotFilesRemoved( const QStringList& fileList );
00236 
00243   void slotFilesChanged( const QStringList& fileList );
00244   void slotFileRenamed( const QString& srcUrl, const QString& dstUrl );
00245 
00246 private Q_SLOTS:
00247   void slotFileDirty( const QString &_file );
00248   void slotFileCreated( const QString &_file );
00249   void slotFileDeleted( const QString &_file );
00250 
00251   void slotEntries( KIO::Job *job, const KIO::UDSEntryList &entries );
00252   void slotResult( KJob *j );
00253   void slotRedirection( KIO::Job *job, const KUrl &url );
00254 
00255   void slotUpdateEntries( KIO::Job *job, const KIO::UDSEntryList &entries );
00256   void slotUpdateResult( KJob *job );
00257   void processPendingUpdates();
00258 
00259 private:
00260     class DirItem;
00261     DirItem* dirItemForUrl(const KUrl& dir) const;
00262 
00263     bool validUrl( const KDirLister *lister, const KUrl& _url ) const;
00264 
00265     void stopListJob(const QString& url, bool silent);
00266 
00267     KIO::ListJob *jobForUrl( const QString& url, KIO::ListJob *not_job = 0 );
00268     const KUrl& joburl( KIO::ListJob *job );
00269 
00270     void killJob( KIO::ListJob *job );
00271 
00272     // Called when something tells us that the directory @p url has changed.
00273     // Returns true if @p url is held by some lister (meaning: do the update now)
00274     // otherwise mark the cached item as not-up-to-date for later and return false
00275     bool checkUpdate( const QString& url );
00276 
00277     // Helper method for slotFileDirty
00278     void handleFileDirty(const KUrl& url);
00279     void handleDirDirty(const KUrl& url);
00280 
00281   // when there were items deleted from the filesystem all the listers holding
00282   // the parent directory need to be notified, the unmarked items have to be deleted
00283   // and removed from the cache including all the children.
00284   void deleteUnmarkedItems( const QList<KDirLister *>&, KFileItemList & );
00285     // Helper method called when we know that a list of items was deleted
00286     void itemsDeleted(const QList<KDirLister *>& listers, const KFileItemList& deletedItems);
00287     void slotFilesRemoved(const KUrl::List& urls);
00288     // common for slotRedirection and slotFileRenamed
00289   void renameDir( const KUrl &oldUrl, const KUrl &url );
00290   // common for deleteUnmarkedItems and slotFilesRemoved
00291   void deleteDir( const KUrl& dirUrl );
00292   // remove directory from cache (itemsCached), including all child dirs
00293   void removeDirFromCache( const KUrl& dir );
00294   // helper for renameDir
00295   void emitRedirections( const KUrl &oldUrl, const KUrl &url );
00296 
00302     QSet<KDirLister *> emitRefreshItem(const KFileItem& oldItem, const KFileItem& fileitem);
00303 
00308     QStringList directoriesForCanonicalPath(const QString& dir) const;
00309 
00310 #ifndef NDEBUG
00311   void printDebug();
00312 #endif
00313 
00314   class DirItem
00315   {
00316   public:
00317     DirItem(const KUrl &dir, const QString& canonicalPath)
00318       : url(dir), m_canonicalPath(canonicalPath)
00319     {
00320       autoUpdates = 0;
00321       complete = false;
00322     }
00323 
00324     ~DirItem()
00325     {
00326       if ( autoUpdates )
00327       {
00328         if ( KDirWatch::exists() && url.isLocalFile() )
00329             KDirWatch::self()->removeDir(m_canonicalPath);
00330         sendSignal( false, url );
00331       }
00332       lstItems.clear();
00333     }
00334 
00335     void sendSignal( bool entering, const KUrl& url )
00336     {
00337         // Note that "entering" means "start watching", and "leaving" means "stop watching"
00338         // (i.e. it's not when the user leaves the directory, it's when the directory is removed from the cache)
00339         if (entering)
00340             org::kde::KDirNotify::emitEnteredDirectory( url.url() );
00341         else
00342             org::kde::KDirNotify::emitLeftDirectory( url.url() );
00343     }
00344 
00345     void redirect( const KUrl& newUrl )
00346     {
00347       if ( autoUpdates )
00348       {
00349         if ( url.isLocalFile() )
00350             KDirWatch::self()->removeDir(m_canonicalPath);
00351         sendSignal( false, url );
00352 
00353         if (newUrl.isLocalFile()) {
00354             m_canonicalPath = QFileInfo(newUrl.toLocalFile()).canonicalFilePath();
00355             KDirWatch::self()->addDir(m_canonicalPath);
00356         }
00357         sendSignal( true, newUrl );
00358       }
00359 
00360       url = newUrl;
00361 
00362       if ( !rootItem.isNull() )
00363         rootItem.setUrl( newUrl );
00364     }
00365 
00366     void incAutoUpdate()
00367     {
00368       if ( autoUpdates++ == 0 )
00369       {
00370         if ( url.isLocalFile() )
00371           KDirWatch::self()->addDir(m_canonicalPath);
00372         sendSignal( true, url );
00373       }
00374     }
00375 
00376     void decAutoUpdate()
00377     {
00378       if ( --autoUpdates == 0 )
00379       {
00380         if ( url.isLocalFile() )
00381           KDirWatch::self()->removeDir(m_canonicalPath);
00382         sendSignal( false, url );
00383       }
00384 
00385       else if ( autoUpdates < 0 )
00386         autoUpdates = 0;
00387     }
00388 
00389     // number of KDirListers using autoUpdate for this dir
00390     short autoUpdates;
00391 
00392     // this directory is up-to-date
00393     bool complete;
00394 
00395     // the complete url of this directory
00396     KUrl url;
00397 
00398     // the local path, with symlinks resolved, so that KDirWatch works
00399     QString m_canonicalPath;
00400 
00401     // KFileItem representing the root of this directory.
00402     // Remember that this is optional. FTP sites don't return '.' in
00403     // the list, so they give no root item
00404     KFileItem rootItem;
00405     KFileItemList lstItems;
00406   };
00407 
00408     //static const unsigned short MAX_JOBS_PER_LISTER;
00409 
00410     QMap<KIO::ListJob *, KIO::UDSEntryList> runningListJobs;
00411 
00412     // an item is a complete directory
00413     QHash<QString /*url*/, DirItem*> itemsInUse;
00414     QCache<QString /*url*/, DirItem> itemsCached;
00415 
00416     typedef QHash<QString /*url*/, KDirListerCacheDirectoryData> DirectoryDataHash;
00417     DirectoryDataHash directoryData;
00418 
00419     // Symlink-to-directories are registered here so that we can
00420     // find the url that changed, when kdirwatch tells us about
00421     // changes in the canonical url. (#213799)
00422     QHash<QString /*canonical path*/, QStringList /*dirlister urls*/> canonicalUrls;
00423 
00424     // Set of local files that we have changed recently (according to KDirWatch)
00425     // We temporize the notifications by keeping them 500ms in this list.
00426     QSet<QString /*path*/> pendingUpdates;
00427     // The timer for doing the delayed updates
00428     QTimer pendingUpdateTimer;
00429 
00430     // Set of remote files that have changed recently -- but we can't emit those
00431     // changes yet, we need to wait for the "update" directory listing.
00432     // The cmp() call can't differ mimetypes since they are determined on demand,
00433     // this is why we need to remember those files here.
00434     QSet<KFileItem*> pendingRemoteUpdates;
00435 
00436     // the KDirNotify signals
00437     OrgKdeKDirNotifyInterface *kdirnotify;
00438 
00439     struct ItemInUseChange;
00440 };
00441 
00442 // Data associated with a directory url
00443 // This could be in DirItem but only in the itemsInUse dict...
00444 struct KDirListerCacheDirectoryData
00445 {
00446     // A lister can be EITHER in listersCurrentlyListing OR listersCurrentlyHolding
00447     // but NOT in both at the same time.
00448     // But both lists can have different listers at the same time; this
00449     // happens if more listers are requesting url at the same time and
00450     // one lister was stopped during the listing of files.
00451 
00452     // Listers that are currently listing this url
00453     QList<KDirLister *> listersCurrentlyListing;
00454     // Listers that are currently holding this url
00455     QList<KDirLister *> listersCurrentlyHolding;
00456 
00457     void moveListersWithoutCachedItemsJob(const KUrl& url);
00458 };
00459 
00460 //const unsigned short KDirListerCache::MAX_JOBS_PER_LISTER = 5;
00461 
00462 // This job tells KDirListerCache to emit cached items asynchronously from listDir()
00463 // to give the KDirLister user enough time for connecting to its signals, and so
00464 // that KDirListerCache behaves just like when a real KIO::Job is used: nothing
00465 // is emitted during the openUrl call itself.
00466 class KDirLister::Private::CachedItemsJob : public KJob {
00467     Q_OBJECT
00468 public:
00469     CachedItemsJob(KDirLister* lister, const KUrl& url, bool reload);
00470 
00471     /*reimp*/ void start() { QMetaObject::invokeMethod(this, "done", Qt::QueuedConnection); }
00472 
00473     // For updateDirectory() to cancel m_emitCompleted;
00474     void setEmitCompleted(bool b) { m_emitCompleted = b; }
00475 
00476     KUrl url() const { return m_url; }
00477 
00478 protected:
00479     virtual bool doKill();
00480 
00481 public Q_SLOTS:
00482     void done();
00483 
00484 private:
00485     KDirLister* m_lister;
00486     KUrl m_url;
00487     bool m_reload;
00488     bool m_emitCompleted;
00489 };
00490 
00491 #endif

KIO

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • 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
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal