diff options
Diffstat (limited to 'kio/kio/kdirlister.cpp')
-rw-r--r-- | kio/kio/kdirlister.cpp | 2538 |
1 files changed, 0 insertions, 2538 deletions
diff --git a/kio/kio/kdirlister.cpp b/kio/kio/kdirlister.cpp deleted file mode 100644 index 90cfca041..000000000 --- a/kio/kio/kdirlister.cpp +++ /dev/null @@ -1,2538 +0,0 @@ -/* This file is part of the KDE project - Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> - 2000 Carsten Pfeiffer <pfeiffer@kde.org> - 2001-2005 Michael Brade <brade@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kdirlister.h" - -#include <tqregexp.h> -#include <tqptrlist.h> -#include <tqtimer.h> -#include <tqeventloop.h> - -#include <kapplication.h> -#include <kdebug.h> -#include <klocale.h> -#include <kio/job.h> -#include <kmessagebox.h> -#include <kglobal.h> -#include <kglobalsettings.h> -#include <kstaticdeleter.h> -#include <kprotocolinfo.h> - -#include "kdirlister_p.h" - -#include <assert.h> -#include <unistd.h> - -KDirListerCache* KDirListerCache::s_pSelf = 0; -static KStaticDeleter<KDirListerCache> sd_KDirListerCache; - -// Enable this to get printDebug() called often, to see the contents of the cache -//#define DEBUG_CACHE - -// Make really sure it doesn't get activated in the final build -#ifdef NDEBUG -#undef DEBUG_CACHE -#endif - -KDirListerCache::KDirListerCache( int maxCount ) - : itemsCached( maxCount ) -{ - kdDebug(7004) << "+KDirListerCache" << endl; - - itemsInUse.setAutoDelete( false ); - itemsCached.setAutoDelete( true ); - urlsCurrentlyListed.setAutoDelete( true ); - urlsCurrentlyHeld.setAutoDelete( true ); - pendingUpdates.setAutoDelete( true ); - - connect( kdirwatch, TQT_SIGNAL( dirty( const TQString& ) ), - this, TQT_SLOT( slotFileDirty( const TQString& ) ) ); - connect( kdirwatch, TQT_SIGNAL( created( const TQString& ) ), - this, TQT_SLOT( slotFileCreated( const TQString& ) ) ); - connect( kdirwatch, TQT_SIGNAL( deleted( const TQString& ) ), - this, TQT_SLOT( slotFileDeleted( const TQString& ) ) ); -} - -KDirListerCache::~KDirListerCache() -{ - kdDebug(7004) << "-KDirListerCache" << endl; - - itemsInUse.setAutoDelete( true ); - itemsInUse.clear(); - itemsCached.clear(); - urlsCurrentlyListed.clear(); - urlsCurrentlyHeld.clear(); - - if ( KDirWatch::exists() ) - kdirwatch->disconnect( this ); -} - -// setting _reload to true will emit the old files and -// call updateDirectory -bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, - bool _keep, bool _reload ) -{ - // like this we don't have to worry about trailing slashes any further - KURL _url = _u; - _url.cleanPath(); // kill consecutive slashes - _url.adjustPath(-1); - TQString urlStr = _url.url(); - - if ( !lister->validURL( _url ) ) - return false; - -#ifdef DEBUG_CACHE - printDebug(); -#endif - kdDebug(7004) << k_funcinfo << lister << " url=" << _url - << " keep=" << _keep << " reload=" << _reload << endl; - - if ( !_keep ) - { - // stop any running jobs for lister - stop( lister ); - - // clear our internal list for lister - forgetDirs( lister ); - - lister->d->rootFileItem = 0; - } - else if ( lister->d->lstDirs.find( _url ) != lister->d->lstDirs.end() ) - { - // stop the job listing _url for this lister - stop( lister, _url ); - - // clear _url for lister - forgetDirs( lister, _url, true ); - - if ( lister->d->url == _url ) - lister->d->rootFileItem = 0; - } - - lister->d->lstDirs.append( _url ); - - if ( lister->d->url.isEmpty() || !_keep ) // set toplevel URL only if not set yet - lister->d->url = _url; - - DirItem *itemU = itemsInUse[urlStr]; - DirItem *itemC; - - if ( !urlsCurrentlyListed[urlStr] ) - { - // if there is an update running for _url already we get into - // the following case - it will just be restarted by updateDirectory(). - - if ( itemU ) - { - kdDebug(7004) << "listDir: Entry already in use: " << _url << endl; - - bool oldState = lister->d->complete; - lister->d->complete = false; - - emit lister->started( _url ); - - if ( !lister->d->rootFileItem && lister->d->url == _url ) - lister->d->rootFileItem = itemU->rootItem; - - lister->addNewItems( *(itemU->lstItems) ); - lister->emitItems(); - - // _url is already in use, so there is already an entry in urlsCurrentlyHeld - assert( urlsCurrentlyHeld[urlStr] ); - urlsCurrentlyHeld[urlStr]->append( lister ); - - lister->d->complete = oldState; - - emit lister->completed( _url ); - if ( lister->d->complete ) - emit lister->completed(); - - if ( _reload || !itemU->complete ) - updateDirectory( _url ); - } - else if ( !_reload && (itemC = itemsCached.take( urlStr )) ) - { - kdDebug(7004) << "listDir: Entry in cache: " << _url << endl; - - itemC->decAutoUpdate(); - itemsInUse.insert( urlStr, itemC ); - itemU = itemC; - - bool oldState = lister->d->complete; - lister->d->complete = false; - - emit lister->started( _url ); - - if ( !lister->d->rootFileItem && lister->d->url == _url ) - lister->d->rootFileItem = itemC->rootItem; - - lister->addNewItems( *(itemC->lstItems) ); - lister->emitItems(); - - Q_ASSERT( !urlsCurrentlyHeld[urlStr] ); - TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>; - list->append( lister ); - urlsCurrentlyHeld.insert( urlStr, list ); - - lister->d->complete = oldState; - - emit lister->completed( _url ); - if ( lister->d->complete ) - emit lister->completed(); - - if ( !itemC->complete ) - updateDirectory( _url ); - } - else // dir not in cache or _reload is true - { - kdDebug(7004) << "listDir: Entry not in cache or reloaded: " << _url << endl; - - TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>; - list->append( lister ); - urlsCurrentlyListed.insert( urlStr, list ); - - itemsCached.remove( urlStr ); - itemU = new DirItem( _url ); - itemsInUse.insert( urlStr, itemU ); - -// // we have a limit of MAX_JOBS_PER_LISTER concurrently running jobs -// if ( lister->numJobs() >= MAX_JOBS_PER_LISTER ) -// { -// lstPendingUpdates.append( _url ); -// } -// else -// { - - if ( lister->d->url == _url ) - lister->d->rootFileItem = 0; - - TDEIO::ListJob* job = TDEIO::listDir( _url, false /* no default GUI */ ); - jobs.insert( job, TQValueList<TDEIO::UDSEntry>() ); - - lister->jobStarted( job ); - lister->connectJob( job ); - - if ( lister->d->window ) - job->setWindow( lister->d->window ); - - connect( job, TQT_SIGNAL( entries( TDEIO::Job *, const TDEIO::UDSEntryList & ) ), - this, TQT_SLOT( slotEntries( TDEIO::Job *, const TDEIO::UDSEntryList & ) ) ); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotResult( TDEIO::Job * ) ) ); - connect( job, TQT_SIGNAL( redirection( TDEIO::Job *, const KURL & ) ), - this, TQT_SLOT( slotRedirection( TDEIO::Job *, const KURL & ) ) ); - - emit lister->started( _url ); - -// } - } - } - else - { - kdDebug(7004) << "listDir: Entry currently being listed: " << _url << endl; - - emit lister->started( _url ); - - urlsCurrentlyListed[urlStr]->append( lister ); - - TDEIO::ListJob *job = jobForUrl( urlStr ); - Q_ASSERT( job ); - - lister->jobStarted( job ); - lister->connectJob( job ); - - Q_ASSERT( itemU ); - - if ( !lister->d->rootFileItem && lister->d->url == _url ) - lister->d->rootFileItem = itemU->rootItem; - - lister->addNewItems( *(itemU->lstItems) ); - lister->emitItems(); - } - - // automatic updating of directories - if ( lister->d->autoUpdate ) - itemU->incAutoUpdate(); - - return true; -} - -bool KDirListerCache::validURL( const KDirLister *lister, const KURL& url ) const -{ - if ( !url.isValid() ) - { - if ( lister->d->autoErrorHandling ) - { - TQString tmp = i18n("Malformed URL\n%1").arg( url.prettyURL() ); - KMessageBox::error( lister->d->errorParent, tmp ); - } - return false; - } - - if ( !KProtocolInfo::supportsListing( url ) ) - { - if ( lister->d->autoErrorHandling ) - { - // TODO: this message should be changed during next string unfreeze! - TQString tmp = i18n("Malformed URL\n%1").arg( url.prettyURL() ); - KMessageBox::error( lister->d->errorParent, tmp ); - } - return false; - } - - return true; -} - -void KDirListerCache::stop( KDirLister *lister ) -{ -#ifdef DEBUG_CACHE - printDebug(); -#endif - kdDebug(7004) << k_funcinfo << "lister: " << lister << endl; - bool stopped = false; - - TQDictIterator< TQPtrList<KDirLister> > it( urlsCurrentlyListed ); - TQPtrList<KDirLister> *listers; - while ( (listers = it.current()) ) - { - if ( listers->findRef( lister ) > -1 ) - { - // lister is listing url - TQString url = it.currentKey(); - - //kdDebug(7004) << k_funcinfo << " found lister in list - for " << url << endl; - bool ret = listers->removeRef( lister ); - Q_ASSERT( ret ); - - TDEIO::ListJob *job = jobForUrl( url ); - if ( job ) - lister->jobDone( job ); - - // move lister to urlsCurrentlyHeld - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[url]; - if ( !holders ) - { - holders = new TQPtrList<KDirLister>; - urlsCurrentlyHeld.insert( url, holders ); - } - - holders->append( lister ); - - emit lister->canceled( KURL( url ) ); - - //kdDebug(7004) << k_funcinfo << "remaining list: " << listers->count() << " listers" << endl; - - if ( listers->isEmpty() ) - { - // kill the job since it isn't used any more - if ( job ) - killJob( job ); - - urlsCurrentlyListed.remove( url ); - } - - stopped = true; - } - else - ++it; - } - - if ( stopped ) - { - emit lister->canceled(); - lister->d->complete = true; - } - - // this is wrong if there is still an update running! - //Q_ASSERT( lister->d->complete ); -} - -void KDirListerCache::stop( KDirLister *lister, const KURL& _u ) -{ - TQString urlStr( _u.url(-1) ); - KURL _url( urlStr ); - - // TODO: consider to stop all the "child jobs" of _url as well - kdDebug(7004) << k_funcinfo << lister << " url=" << _url << endl; - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; - if ( !listers || !listers->removeRef( lister ) ) - return; - - // move lister to urlsCurrentlyHeld - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; - if ( !holders ) - { - holders = new TQPtrList<KDirLister>; - urlsCurrentlyHeld.insert( urlStr, holders ); - } - - holders->append( lister ); - - - TDEIO::ListJob *job = jobForUrl( urlStr ); - if ( job ) - lister->jobDone( job ); - - emit lister->canceled( _url ); - - if ( listers->isEmpty() ) - { - // kill the job since it isn't used any more - if ( job ) - killJob( job ); - - urlsCurrentlyListed.remove( urlStr ); - } - - if ( lister->numJobs() == 0 ) - { - lister->d->complete = true; - - // we killed the last job for lister - emit lister->canceled(); - } -} - -void KDirListerCache::setAutoUpdate( KDirLister *lister, bool enable ) -{ - // IMPORTANT: this method does not check for the current autoUpdate state! - - for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); - it != lister->d->lstDirs.end(); ++it ) - { - if ( enable ) - itemsInUse[(*it).url()]->incAutoUpdate(); - else - itemsInUse[(*it).url()]->decAutoUpdate(); - } -} - -void KDirListerCache::forgetDirs( KDirLister *lister ) -{ - kdDebug(7004) << k_funcinfo << lister << endl; - - emit lister->clear(); - - // forgetDirs() will modify lstDirs, make a copy first - KURL::List lstDirsCopy = lister->d->lstDirs; - for ( KURL::List::Iterator it = lstDirsCopy.begin(); - it != lstDirsCopy.end(); ++it ) - { - forgetDirs( lister, *it, false ); - } -} - -void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool notify ) -{ - kdDebug(7004) << k_funcinfo << lister << " _url: " << _url << endl; - - KURL url( _url ); - url.adjustPath( -1 ); - TQString urlStr = url.url(); - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; - //Q_ASSERT( holders ); - if ( holders ) - { - holders->removeRef( lister ); - } - - // remove the dir from lister->d->lstDirs so that it doesn't contain things - // that itemsInUse doesn't. When emitting the canceled signals lstDirs must - // not contain anything that itemsInUse does not contain. (otherwise it - // might crash in findByName()). - lister->d->lstDirs.remove( lister->d->lstDirs.find( url ) ); - - DirItem *item = itemsInUse[urlStr]; - - if ( holders && holders->isEmpty() ) - { - urlsCurrentlyHeld.remove( urlStr ); // this deletes the (empty) holders list - if ( !urlsCurrentlyListed[urlStr] ) - { - // item not in use anymore -> move into cache if complete - itemsInUse.remove( urlStr ); - - // this job is a running update - TDEIO::ListJob *job = jobForUrl( urlStr ); - if ( job ) - { - lister->jobDone( job ); - killJob( job ); - kdDebug(7004) << k_funcinfo << "Killing update job for " << urlStr << endl; - - emit lister->canceled( url ); - if ( lister->numJobs() == 0 ) - { - lister->d->complete = true; - emit lister->canceled(); - } - } - - if ( notify ) - emit lister->clear( url ); - - if ( item && item->complete ) - { - kdDebug(7004) << k_funcinfo << lister << " item moved into cache: " << url << endl; - itemsCached.insert( urlStr, item ); // TODO: may return false!! - - // Should we forget the dir for good, or keep a watch on it? - // Generally keep a watch, except when it would prevent - // unmounting a removable device (#37780) - const bool isLocal = item->url.isLocalFile(); - const bool isManuallyMounted = isLocal && TDEIO::manually_mounted( item->url.path() ); - bool containsManuallyMounted = false; - if ( !isManuallyMounted && item->lstItems && isLocal ) - { - // Look for a manually-mounted directory inside - // If there's one, we can't keep a watch either, FAM would prevent unmounting the CDROM - // I hope this isn't too slow (manually_mounted caches the last device so most - // of the time this is just a stat per subdir) - KFileItemListIterator kit( *item->lstItems ); - for ( ; kit.current() && !containsManuallyMounted; ++kit ) - if ( (*kit)->isDir() && TDEIO::manually_mounted( (*kit)->url().path() ) ) - containsManuallyMounted = true; - } - - if ( isManuallyMounted || containsManuallyMounted ) - { - kdDebug(7004) << "Not adding a watch on " << item->url << " because it " << - ( isManuallyMounted ? "is manually mounted" : "contains a manually mounted subdir" ) << endl; - item->complete = false; // set to "dirty" - } - else - item->incAutoUpdate(); // keep watch - } - else - { - delete item; - item = 0; - } - } - } - - if ( item && lister->d->autoUpdate ) - item->decAutoUpdate(); -} - -void KDirListerCache::updateDirectory( const KURL& _dir ) -{ - kdDebug(7004) << k_funcinfo << _dir << endl; - - TQString urlStr = _dir.url(-1); - if ( !checkUpdate( urlStr ) ) - return; - - // A job can be running to - // - only list a new directory: the listers are in urlsCurrentlyListed - // - only update a directory: the listers are in urlsCurrentlyHeld - // - update a currently running listing: the listers are in urlsCurrentlyListed - // and urlsCurrentlyHeld - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; - - // restart the job for _dir if it is running already - bool killed = false; - TQWidget *window = 0; - TDEIO::ListJob *job = jobForUrl( urlStr ); - if ( job ) - { - window = job->window(); - - killJob( job ); - killed = true; - - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->jobDone( job ); - - if ( holders ) - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - kdl->jobDone( job ); - } - kdDebug(7004) << k_funcinfo << "Killed = " << killed << endl; - - // we don't need to emit canceled signals since we only replaced the job, - // the listing is continuing. - - Q_ASSERT( !listers || (listers && killed) ); - - job = TDEIO::listDir( _dir, false /* no default GUI */ ); - jobs.insert( job, TQValueList<TDEIO::UDSEntry>() ); - - connect( job, TQT_SIGNAL(entries( TDEIO::Job *, const TDEIO::UDSEntryList & )), - this, TQT_SLOT(slotUpdateEntries( TDEIO::Job *, const TDEIO::UDSEntryList & )) ); - connect( job, TQT_SIGNAL(result( TDEIO::Job * )), - this, TQT_SLOT(slotUpdateResult( TDEIO::Job * )) ); - - kdDebug(7004) << k_funcinfo << "update started in " << _dir << endl; - - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->jobStarted( job ); - - if ( holders ) - { - if ( !killed ) - { - bool first = true; - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - kdl->jobStarted( job ); - if ( first && kdl->d->window ) - { - first = false; - job->setWindow( kdl->d->window ); - } - emit kdl->started( _dir ); - } - } - else - { - job->setWindow( window ); - - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - kdl->jobStarted( job ); - } - } -} - -bool KDirListerCache::checkUpdate( const TQString& _dir ) -{ - if ( !itemsInUse[_dir] ) - { - DirItem *item = itemsCached[_dir]; - if ( item && item->complete ) - { - item->complete = false; - item->decAutoUpdate(); - // Hmm, this debug output might include login/password from the _dir URL. - //kdDebug(7004) << k_funcinfo << "directory " << _dir << " not in use, marked dirty." << endl; - } - //else - //kdDebug(7004) << k_funcinfo << "aborted, directory " << _dir << " not in cache." << endl; - - return false; - } - else - return true; -} - -KFileItemList *KDirListerCache::itemsForDir( const KURL &_dir ) const -{ - TQString urlStr = _dir.url(-1); - DirItem *item = itemsInUse[ urlStr ]; - if ( !item ) - item = itemsCached[ urlStr ]; - return item ? item->lstItems : 0; -} - -KFileItem *KDirListerCache::findByName( const KDirLister *lister, const TQString& _name ) const -{ - Q_ASSERT( lister ); - - for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); - it != lister->d->lstDirs.end(); ++it ) - { - KFileItemListIterator kit( *itemsInUse[(*it).url()]->lstItems ); - for ( ; kit.current(); ++kit ) - if ( (*kit)->name() == _name ) - return (*kit); - } - - return 0L; -} - -KFileItem *KDirListerCache::findByURL( const KDirLister *lister, const KURL& _u ) const -{ - KURL _url = _u; - _url.adjustPath(-1); - - KURL parentDir( _url ); - parentDir.setPath( parentDir.directory() ); - - // If lister is set, check that it contains this dir - if ( lister && !lister->d->lstDirs.contains( parentDir ) ) - return 0L; - - KFileItemList *itemList = itemsForDir( parentDir ); - if ( itemList ) - { - KFileItemListIterator kit( *itemList ); - for ( ; kit.current(); ++kit ) - if ( (*kit)->url() == _url ) - return (*kit); - } - return 0L; -} - -void KDirListerCache::FilesAdded( const KURL &dir ) -{ - kdDebug(7004) << k_funcinfo << dir << endl; - updateDirectory( dir ); -} - -void KDirListerCache::FilesRemoved( const KURL::List &fileList ) -{ - kdDebug(7004) << k_funcinfo << endl; - KURL::List::ConstIterator it = fileList.begin(); - for ( ; it != fileList.end() ; ++it ) - { - // emit the deleteItem signal if this file was shown in any view - KFileItem *fileitem = 0L; - KURL parentDir( *it ); - parentDir.setPath( parentDir.directory() ); - KFileItemList *lstItems = itemsForDir( parentDir ); - if ( lstItems ) - { - KFileItem *fit = lstItems->first(); - for ( ; fit; fit = lstItems->next() ) - if ( fit->url() == *it ) { - fileitem = fit; - lstItems->take(); // remove fileitem from list - break; - } - } - - // Tell the views about it before deleting the KFileItems. They might need the subdirs' - // file items (see the dirtree). - if ( fileitem ) - { - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDir.url()]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->emitDeleteItem( fileitem ); - } - - // If we found a fileitem, we can test if it's a dir. If not, we'll go to deleteDir just in case. - if ( !fileitem || fileitem->isDir() ) - { - // in case of a dir, check if we have any known children, there's much to do in that case - // (stopping jobs, removing dirs from cache etc.) - deleteDir( *it ); - } - - // now remove the item itself - delete fileitem; - } -} - -void KDirListerCache::FilesChanged( const KURL::List &fileList ) -{ - KURL::List dirsToUpdate; - kdDebug(7004) << k_funcinfo << "only half implemented" << endl; - KURL::List::ConstIterator it = fileList.begin(); - for ( ; it != fileList.end() ; ++it ) - { - if ( ( *it ).isLocalFile() ) - { - kdDebug(7004) << "KDirListerCache::FilesChanged " << *it << endl; - KFileItem *fileitem = findByURL( 0, *it ); - if ( fileitem ) - { - // we need to refresh the item, because e.g. the permissions can have changed. - aboutToRefreshItem( fileitem ); - fileitem->refresh(); - emitRefreshItem( fileitem ); - } - else - kdDebug(7004) << "item not found" << endl; - } else { - // For remote files, refresh() won't be able to figure out the new information. - // Let's update the dir. - KURL dir( *it ); - dir.setPath( dir.directory( true ) ); - if ( dirsToUpdate.find( dir ) == dirsToUpdate.end() ) - dirsToUpdate.prepend( dir ); - } - } - - KURL::List::ConstIterator itdir = dirsToUpdate.begin(); - for ( ; itdir != dirsToUpdate.end() ; ++itdir ) - updateDirectory( *itdir ); - // ## TODO problems with current jobs listing/updating that dir - // ( see kde-2.2.2's kdirlister ) -} - -void KDirListerCache::FileRenamed( const KURL &src, const KURL &dst ) -{ - kdDebug(7004) << k_funcinfo << src.prettyURL() << " -> " << dst.prettyURL() << endl; -#ifdef DEBUG_CACHE - printDebug(); -#endif - - // Somehow this should only be called if src is a dir. But how could we know if it is? - // (Note that looking into itemsInUse isn't good enough. One could rename a subdir in a view.) - renameDir( src, dst ); - - // Now update the KFileItem representing that file or dir (not exclusive with the above!) - KURL oldurl( src ); - oldurl.adjustPath( -1 ); - KFileItem *fileitem = findByURL( 0, oldurl ); - if ( fileitem ) - { - if ( !fileitem->isLocalFile() && !fileitem->localPath().isEmpty() ) // it uses UDS_LOCAL_PATH? ouch, needs an update then - FilesChanged( src ); - else - { - aboutToRefreshItem( fileitem ); - fileitem->setURL( dst ); - fileitem->refreshMimeType(); - emitRefreshItem( fileitem ); - } - } -#ifdef DEBUG_CACHE - printDebug(); -#endif -} - -void KDirListerCache::aboutToRefreshItem( KFileItem *fileitem ) -{ - // Look whether this item was shown in any view, i.e. held by any dirlister - KURL parentDir( fileitem->url() ); - parentDir.setPath( parentDir.directory() ); - TQString parentDirURL = parentDir.url(); - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->aboutToRefreshItem( fileitem ); - - // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing - listers = urlsCurrentlyListed[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->aboutToRefreshItem( fileitem ); -} - -void KDirListerCache::emitRefreshItem( KFileItem *fileitem ) -{ - // Look whether this item was shown in any view, i.e. held by any dirlister - KURL parentDir( fileitem->url() ); - parentDir.setPath( parentDir.directory() ); - TQString parentDirURL = parentDir.url(); - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->addRefreshItem( fileitem ); - kdl->emitItems(); - } - - // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing - listers = urlsCurrentlyListed[parentDirURL]; - if ( listers ) - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->addRefreshItem( fileitem ); - kdl->emitItems(); - } -} - -KDirListerCache* KDirListerCache::self() -{ - if ( !s_pSelf ) - s_pSelf = sd_KDirListerCache.setObject( s_pSelf, new KDirListerCache ); - - return s_pSelf; -} - -bool KDirListerCache::exists() -{ - return s_pSelf != 0; -} - - -// private slots - -// _file can also be a directory being currently held! -void KDirListerCache::slotFileDirty( const TQString& _file ) -{ - kdDebug(7004) << k_funcinfo << _file << endl; - - if ( !pendingUpdates[_file] ) - { - KURL dir; - dir.setPath( _file ); - if ( checkUpdate( dir.url(-1) ) ) - updateDirectory( dir ); - - // the parent directory of _file - dir.setPath( dir.directory() ); - if ( checkUpdate( dir.url() ) ) - { - // Nice hack to save memory: use the qt object name to store the filename - TQTimer *timer = new TQTimer( this, _file.utf8() ); - connect( timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotFileDirtyDelayed()) ); - pendingUpdates.insert( _file, timer ); - timer->start( 500, true ); - } - } -} - -// delayed updating of files, FAM is flooding us with events -void KDirListerCache::slotFileDirtyDelayed() -{ - TQString file = TQString::fromUtf8( TQT_TQOBJECT_CONST(sender())->name() ); - - kdDebug(7004) << k_funcinfo << file << endl; - - // TODO: do it better: don't always create/delete the TQTimer but reuse it. - // Delete the timer after the parent directory is removed from the cache. - pendingUpdates.remove( file ); - - KURL u; - u.setPath( file ); - KFileItem *item = findByURL( 0, u ); // search all items - if ( item ) - { - // we need to refresh the item, because e.g. the permissions can have changed. - aboutToRefreshItem( item ); - item->refresh(); - emitRefreshItem( item ); - } -} - -void KDirListerCache::slotFileCreated( const TQString& _file ) -{ - kdDebug(7004) << k_funcinfo << _file << endl; - // XXX: how to avoid a complete rescan here? - KURL u; - u.setPath( _file ); - u.setPath( u.directory() ); - FilesAdded( u ); -} - -void KDirListerCache::slotFileDeleted( const TQString& _file ) -{ - kdDebug(7004) << k_funcinfo << _file << endl; - KURL u; - u.setPath( _file ); - FilesRemoved( u ); -} - -void KDirListerCache::slotEntries( TDEIO::Job *job, const TDEIO::UDSEntryList &entries ) -{ - KURL url = joburl( static_cast<TDEIO::ListJob *>(job) ); - url.adjustPath(-1); - TQString urlStr = url.url(); - - kdDebug(7004) << k_funcinfo << "new entries for " << url << endl; - - DirItem *dir = itemsInUse[urlStr]; - Q_ASSERT( dir ); - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; - Q_ASSERT( listers ); - Q_ASSERT( !listers->isEmpty() ); - - // check if anyone wants the mimetypes immediately - bool delayedMimeTypes = true; - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - delayedMimeTypes = delayedMimeTypes && kdl->d->delayedMimeTypes; - - // avoid creating these QStrings again and again - static const TQString& dot = TDEGlobal::staticQString("."); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - TDEIO::UDSEntryListConstIterator it = entries.begin(); - TDEIO::UDSEntryListConstIterator end = entries.end(); - - for ( ; it != end; ++it ) - { - TQString name; - - // find out about the name - TDEIO::UDSEntry::ConstIterator entit = (*it).begin(); - for( ; entit != (*it).end(); ++entit ) - if ( (*entit).m_uds == TDEIO::UDS_NAME ) - { - name = (*entit).m_str; - break; - } - - Q_ASSERT( !name.isEmpty() ); - if ( name.isEmpty() ) - continue; - - if ( name == dot ) - { - Q_ASSERT( !dir->rootItem ); - dir->rootItem = new KFileItem( *it, url, delayedMimeTypes, true ); - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - if ( !kdl->d->rootFileItem && kdl->d->url == url ) - kdl->d->rootFileItem = dir->rootItem; - } - else if ( name != dotdot ) - { - KFileItem* item = new KFileItem( *it, url, delayedMimeTypes, true ); - Q_ASSERT( item ); - - //kdDebug(7004)<< "Adding item: " << item->url() << endl; - dir->lstItems->append( item ); - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->addNewItem( item ); - } - } - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->emitItems(); -} - -void KDirListerCache::slotResult( TDEIO::Job *j ) -{ - Q_ASSERT( j ); - TDEIO::ListJob *job = static_cast<TDEIO::ListJob *>( j ); - jobs.remove( job ); - - KURL jobUrl = joburl( job ); - jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections - TQString jobUrlStr = jobUrl.url(); - - kdDebug(7004) << k_funcinfo << "finished listing " << jobUrl << endl; -#ifdef DEBUG_CACHE - printDebug(); -#endif - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( jobUrlStr ); - Q_ASSERT( listers ); - - // move the directory to the held directories, do it before emitting - // the signals to make sure it exists in KDirListerCache in case someone - // calls listDir during the signal emission - Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr] ); - urlsCurrentlyHeld.insert( jobUrlStr, listers ); - - KDirLister *kdl; - - if ( job->error() ) - { - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->jobDone( job ); - kdl->handleError( job ); - emit kdl->canceled( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->canceled(); - } - } - } - else - { - DirItem *dir = itemsInUse[jobUrlStr]; - Q_ASSERT( dir ); - dir->complete = true; - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->jobDone( job ); - emit kdl->completed( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->completed(); - } - } - } - - // TODO: hmm, if there was an error and job is a parent of one or more - // of the pending urls we should cancel it/them as well - processPendingUpdates(); - -#ifdef DEBUG_CACHE - printDebug(); -#endif -} - -void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) -{ - Q_ASSERT( j ); - TDEIO::ListJob *job = static_cast<TDEIO::ListJob *>( j ); - - KURL oldUrl = job->url(); // here we really need the old url! - KURL newUrl = url; - - // strip trailing slashes - oldUrl.adjustPath(-1); - newUrl.adjustPath(-1); - - if ( oldUrl == newUrl ) - { - kdDebug(7004) << k_funcinfo << "New redirection url same as old, giving up." << endl; - return; - } - - kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl; - -#ifdef DEBUG_CACHE - printDebug(); -#endif - - // I don't think there can be dirItems that are childs of oldUrl. - // Am I wrong here? And even if so, we don't need to delete them, right? - // DF: redirection happens before listDir emits any item. Makes little sense otherwise. - - // oldUrl cannot be in itemsCached because only completed items are moved there - DirItem *dir = itemsInUse.take( oldUrl.url() ); - Q_ASSERT( dir ); - - TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrl.url() ); - Q_ASSERT( listers ); - Q_ASSERT( !listers->isEmpty() ); - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - // TODO: put in own method? - if ( kdl->d->url.equals( oldUrl, true ) ) - { - kdl->d->rootFileItem = 0; - kdl->d->url = newUrl; - } - - *kdl->d->lstDirs.find( oldUrl ) = newUrl; - - if ( kdl->d->lstDirs.count() == 1 ) - { - emit kdl->clear(); - emit kdl->redirection( newUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - else - { - emit kdl->clear( oldUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - } - - // when a lister was stopped before the job emits the redirection signal, the old url will - // also be in urlsCurrentlyHeld - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrl.url() ); - if ( holders ) - { - Q_ASSERT( !holders->isEmpty() ); - - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - kdl->jobStarted( job ); - - // do it like when starting a new list-job that will redirect later - emit kdl->started( oldUrl ); - - // TODO: maybe don't emit started if there's an update running for newUrl already? - - if ( kdl->d->url.equals( oldUrl, true ) ) - { - kdl->d->rootFileItem = 0; - kdl->d->url = newUrl; - } - - *kdl->d->lstDirs.find( oldUrl ) = newUrl; - - if ( kdl->d->lstDirs.count() == 1 ) - { - emit kdl->clear(); - emit kdl->redirection( newUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - else - { - emit kdl->clear( oldUrl ); - emit kdl->redirection( oldUrl, newUrl ); - } - } - } - - DirItem *newDir = itemsInUse[newUrl.url()]; - if ( newDir ) - { - kdDebug(7004) << "slotRedirection: " << newUrl.url() << " already in use" << endl; - - // only in this case there can newUrl already be in urlsCurrentlyListed or urlsCurrentlyHeld - delete dir; - - // get the job if one's running for newUrl already (can be a list-job or an update-job), but - // do not return this 'job', which would happen because of the use of redirectionURL() - TDEIO::ListJob *oldJob = jobForUrl( newUrl.url(), job ); - - // listers of newUrl with oldJob: forget about the oldJob and use the already running one - // which will be converted to an updateJob - TQPtrList<KDirLister> *curListers = urlsCurrentlyListed[newUrl.url()]; - if ( curListers ) - { - kdDebug(7004) << "slotRedirection: and it is currently listed" << endl; - - Q_ASSERT( oldJob ); // ?! - - for ( KDirLister *kdl = curListers->first(); kdl; kdl = curListers->next() ) // listers of newUrl - { - kdl->jobDone( oldJob ); - - kdl->jobStarted( job ); - kdl->connectJob( job ); - } - - // append listers of oldUrl with newJob to listers of newUrl with oldJob - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - curListers->append( kdl ); - } - else - urlsCurrentlyListed.insert( newUrl.url(), listers ); - - if ( oldJob ) // kill the old job, be it a list-job or an update-job - killJob( oldJob ); - - // holders of newUrl: use the already running job which will be converted to an updateJob - TQPtrList<KDirLister> *curHolders = urlsCurrentlyHeld[newUrl.url()]; - if ( curHolders ) - { - kdDebug(7004) << "slotRedirection: and it is currently held." << endl; - - for ( KDirLister *kdl = curHolders->first(); kdl; kdl = curHolders->next() ) // holders of newUrl - { - kdl->jobStarted( job ); - emit kdl->started( newUrl ); - } - - // append holders of oldUrl to holders of newUrl - if ( holders ) - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - curHolders->append( kdl ); - } - else if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); - - - // emit old items: listers, holders. NOT: newUrlListers/newUrlHolders, they already have them listed - // TODO: make this a separate method? - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - - if ( holders ) - { - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - } - } - else if ( (newDir = itemsCached.take( newUrl.url() )) ) - { - kdDebug(7004) << "slotRedirection: " << newUrl.url() << " is unused, but already in the cache." << endl; - - delete dir; - itemsInUse.insert( newUrl.url(), newDir ); - urlsCurrentlyListed.insert( newUrl.url(), listers ); - if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); - - // emit old items: listers, holders - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - - if ( holders ) - { - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - if ( !kdl->d->rootFileItem && kdl->d->url == newUrl ) - kdl->d->rootFileItem = newDir->rootItem; - - kdl->addNewItems( *(newDir->lstItems) ); - kdl->emitItems(); - } - } - } - else - { - kdDebug(7004) << "slotRedirection: " << newUrl.url() << " has not been listed yet." << endl; - - delete dir->rootItem; - dir->rootItem = 0; - dir->lstItems->clear(); - dir->redirect( newUrl ); - itemsInUse.insert( newUrl.url(), dir ); - urlsCurrentlyListed.insert( newUrl.url(), listers ); - - if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); - else - { -#ifdef DEBUG_CACHE - printDebug(); -#endif - return; // only in this case the job doesn't need to be converted, - } - } - - // make the job an update job - job->disconnect( this ); - - connect( job, TQT_SIGNAL(entries( TDEIO::Job *, const TDEIO::UDSEntryList & )), - this, TQT_SLOT(slotUpdateEntries( TDEIO::Job *, const TDEIO::UDSEntryList & )) ); - connect( job, TQT_SIGNAL(result( TDEIO::Job * )), - this, TQT_SLOT(slotUpdateResult( TDEIO::Job * )) ); - - // FIXME: autoUpdate-Counts!! - -#ifdef DEBUG_CACHE - printDebug(); -#endif -} - -void KDirListerCache::renameDir( const KURL &oldUrl, const KURL &newUrl ) -{ - kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl; - TQString oldUrlStr = oldUrl.url(-1); - TQString newUrlStr = newUrl.url(-1); - - // Not enough. Also need to look at any child dir, even sub-sub-sub-dir. - //DirItem *dir = itemsInUse.take( oldUrlStr ); - //emitRedirections( oldUrl, url ); - - // Look at all dirs being listed/shown - TQDictIterator<DirItem> itu( itemsInUse ); - bool goNext; - while ( itu.current() ) - { - goNext = true; - DirItem *dir = itu.current(); - KURL oldDirUrl ( itu.currentKey() ); - //kdDebug(7004) << "itemInUse: " << oldDirUrl.prettyURL() << endl; - // Check if this dir is oldUrl, or a subfolder of it - if ( oldUrl.isParentOf( oldDirUrl ) ) - { - // TODO should use KURL::cleanpath like isParentOf does - TQString relPath = oldDirUrl.path().mid( oldUrl.path().length() ); - - KURL newDirUrl( newUrl ); // take new base - if ( !relPath.isEmpty() ) - newDirUrl.addPath( relPath ); // add unchanged relative path - //kdDebug(7004) << "KDirListerCache::renameDir new url=" << newDirUrl.prettyURL() << endl; - - // Update URL in dir item and in itemsInUse - dir->redirect( newDirUrl ); - itemsInUse.remove( itu.currentKey() ); // implies ++itu - itemsInUse.insert( newDirUrl.url(-1), dir ); - goNext = false; // because of the implied ++itu above - if ( dir->lstItems ) - { - // Rename all items under that dir - KFileItemListIterator kit( *dir->lstItems ); - for ( ; kit.current(); ++kit ) - { - KURL oldItemUrl = (*kit)->url(); - TQString oldItemUrlStr( oldItemUrl.url(-1) ); - KURL newItemUrl( oldItemUrl ); - newItemUrl.setPath( newDirUrl.path() ); - newItemUrl.addPath( oldItemUrl.fileName() ); - kdDebug(7004) << "KDirListerCache::renameDir renaming " << oldItemUrlStr << " to " << newItemUrl.url() << endl; - (*kit)->setURL( newItemUrl ); - } - } - emitRedirections( oldDirUrl, newDirUrl ); - } - if ( goNext ) - ++itu; - } - - // Is oldUrl a directory in the cache? - // Remove any child of oldUrl from the cache - even if the renamed dir itself isn't in it! - removeDirFromCache( oldUrl ); - // TODO rename, instead. -} - -void KDirListerCache::emitRedirections( const KURL &oldUrl, const KURL &url ) -{ - kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << url.prettyURL() << endl; - TQString oldUrlStr = oldUrl.url(-1); - TQString urlStr = url.url(-1); - - TDEIO::ListJob *job = jobForUrl( oldUrlStr ); - if ( job ) - killJob( job ); - - // Check if we were listing this dir. Need to abort and restart with new name in that case. - TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrlStr ); - if ( listers ) - { - // Tell the world that the job listing the old url is dead. - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - { - if ( job ) - kdl->jobDone( job ); - - emit kdl->canceled( oldUrl ); - } - - urlsCurrentlyListed.insert( urlStr, listers ); - } - - // Check if we are currently displaying this directory (odds opposite wrt above) - // Update urlsCurrentlyHeld dict with new URL - TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrlStr ); - if ( holders ) - { - if ( job ) - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - kdl->jobDone( job ); - - urlsCurrentlyHeld.insert( urlStr, holders ); - } - - if ( listers ) - { - updateDirectory( url ); - - // Tell the world about the new url - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - emit kdl->started( url ); - } - - if ( holders ) - { - // And notify the dirlisters of the redirection - for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) - { - *kdl->d->lstDirs.find( oldUrl ) = url; - - if ( kdl->d->lstDirs.count() == 1 ) - emit kdl->redirection( url ); - - emit kdl->redirection( oldUrl, url ); - } - } -} - -void KDirListerCache::removeDirFromCache( const KURL& dir ) -{ - kdDebug(7004) << "KDirListerCache::removeDirFromCache " << dir.prettyURL() << endl; - TQCacheIterator<DirItem> itc( itemsCached ); - while ( itc.current() ) - { - if ( dir.isParentOf( KURL( itc.currentKey() ) ) ) - itemsCached.remove( itc.currentKey() ); - else - ++itc; - } -} - -void KDirListerCache::slotUpdateEntries( TDEIO::Job* job, const TDEIO::UDSEntryList& list ) -{ - jobs[static_cast<TDEIO::ListJob*>(job)] += list; -} - -void KDirListerCache::slotUpdateResult( TDEIO::Job * j ) -{ - Q_ASSERT( j ); - TDEIO::ListJob *job = static_cast<TDEIO::ListJob *>( j ); - - KURL jobUrl = joburl( job ); - jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections - TQString jobUrlStr = jobUrl.url(); - - kdDebug(7004) << k_funcinfo << "finished update " << jobUrl << endl; - - KDirLister *kdl; - - TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[jobUrlStr]; - TQPtrList<KDirLister> *tmpLst = urlsCurrentlyListed.take( jobUrlStr ); - - if ( tmpLst ) - { - if ( listers ) - for ( kdl = tmpLst->first(); kdl; kdl = tmpLst->next() ) - { - Q_ASSERT( listers->containsRef( kdl ) == 0 ); - listers->append( kdl ); - } - else - { - listers = tmpLst; - urlsCurrentlyHeld.insert( jobUrlStr, listers ); - } - } - - // once we are updating dirs that are only in the cache this will fail! - Q_ASSERT( listers ); - - if ( job->error() ) - { - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->jobDone( job ); - - //don't bother the user - //kdl->handleError( job ); - - emit kdl->canceled( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->canceled(); - } - } - - jobs.remove( job ); - - // TODO: if job is a parent of one or more - // of the pending urls we should cancel them - processPendingUpdates(); - return; - } - - DirItem *dir = itemsInUse[jobUrlStr]; - dir->complete = true; - - - // check if anyone wants the mimetypes immediately - bool delayedMimeTypes = true; - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - delayedMimeTypes = delayedMimeTypes && kdl->d->delayedMimeTypes; - - // should be enough to get reasonable speed in most cases - TQDict<KFileItem> fileItems( 9973 ); - - KFileItemListIterator kit ( *(dir->lstItems) ); - - // Unmark all items in url - for ( ; kit.current(); ++kit ) - { - (*kit)->unmark(); - fileItems.insert( (*kit)->url().url(), *kit ); - } - - static const TQString& dot = TDEGlobal::staticQString("."); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - KFileItem *item = 0, *tmp; - - TQValueList<TDEIO::UDSEntry> buf = jobs[job]; - TQValueListIterator<TDEIO::UDSEntry> it = buf.begin(); - for ( ; it != buf.end(); ++it ) - { - // Form the complete url - if ( !item ) - item = new KFileItem( *it, jobUrl, delayedMimeTypes, true ); - else - item->setUDSEntry( *it, jobUrl, delayedMimeTypes, true ); - - // Find out about the name - TQString name = item->name(); - Q_ASSERT( !name.isEmpty() ); - - // we duplicate the check for dotdot here, to avoid iterating over - // all items again and checking in matchesFilter() that way. - if ( name.isEmpty() || name == dotdot ) - continue; - - if ( name == dot ) - { - // if the update was started before finishing the original listing - // there is no root item yet - if ( !dir->rootItem ) - { - dir->rootItem = item; - item = 0; - - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - if ( !kdl->d->rootFileItem && kdl->d->url == jobUrl ) - kdl->d->rootFileItem = dir->rootItem; - } - - continue; - } - - // Find this item - if ( (tmp = fileItems[item->url().url()]) ) - { - tmp->mark(); - - // check if something changed for this file - if ( !tmp->cmp( *item ) ) - { - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->aboutToRefreshItem( tmp ); - - //kdDebug(7004) << "slotUpdateResult: file changed: " << tmp->name() << endl; - tmp->assign( *item ); - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->addRefreshItem( tmp ); - } - } - else // this is a new file - { - //kdDebug(7004) << "slotUpdateResult: new file: " << name << endl; - - item->mark(); - dir->lstItems->append( item ); - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->addNewItem( item ); - - // item used, we need a new one for the next iteration - item = 0; - } - } - - if ( item ) - delete item; - - jobs.remove( job ); - - deleteUnmarkedItems( listers, dir->lstItems ); - - for ( kdl = listers->first(); kdl; kdl = listers->next() ) - { - kdl->emitItems(); - - kdl->jobDone( job ); - - emit kdl->completed( jobUrl ); - if ( kdl->numJobs() == 0 ) - { - kdl->d->complete = true; - emit kdl->completed(); - } - } - - // TODO: hmm, if there was an error and job is a parent of one or more - // of the pending urls we should cancel it/them as well - processPendingUpdates(); -} - -// private - -TDEIO::ListJob *KDirListerCache::jobForUrl( const TQString& url, TDEIO::ListJob *not_job ) -{ - TDEIO::ListJob *job; - TQMap< TDEIO::ListJob *, TQValueList<TDEIO::UDSEntry> >::Iterator it = jobs.begin(); - while ( it != jobs.end() ) - { - job = it.key(); - if ( joburl( job ).url(-1) == url && job != not_job ) - return job; - ++it; - } - return 0; -} - -const KURL& KDirListerCache::joburl( TDEIO::ListJob *job ) -{ - if ( job->redirectionURL().isValid() ) - return job->redirectionURL(); - else - return job->url(); -} - -void KDirListerCache::killJob( TDEIO::ListJob *job ) -{ - jobs.remove( job ); - job->disconnect( this ); - job->kill(); -} - -void KDirListerCache::deleteUnmarkedItems( TQPtrList<KDirLister> *listers, KFileItemList *lstItems ) -{ - // Find all unmarked items and delete them - KFileItem* item; - lstItems->first(); - while ( (item = lstItems->current()) ) - if ( !item->isMarked() ) - { - //kdDebug() << k_funcinfo << item->name() << endl; - for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) - kdl->emitDeleteItem( item ); - - if ( item->isDir() ) - deleteDir( item->url() ); - - // finally actually delete the item - lstItems->take(); - delete item; - } - else - lstItems->next(); -} - -void KDirListerCache::deleteDir( const KURL& dirUrl ) -{ - //kdDebug() << k_funcinfo << dirUrl.prettyURL() << endl; - // unregister and remove the childs of the deleted item. - // Idea: tell all the KDirListers that they should forget the dir - // and then remove it from the cache. - - TQDictIterator<DirItem> itu( itemsInUse ); - while ( itu.current() ) - { - KURL deletedUrl( itu.currentKey() ); - if ( dirUrl.isParentOf( deletedUrl ) ) - { - // stop all jobs for deletedUrl - - TQPtrList<KDirLister> *kdls = urlsCurrentlyListed[deletedUrl.url()]; - if ( kdls ) // yeah, I lack good names - { - // we need a copy because stop modifies the list - kdls = new TQPtrList<KDirLister>( *kdls ); - for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() ) - stop( kdl, deletedUrl ); - - delete kdls; - } - - // tell listers holding deletedUrl to forget about it - // this will stop running updates for deletedUrl as well - - kdls = urlsCurrentlyHeld[deletedUrl.url()]; - if ( kdls ) - { - // we need a copy because forgetDirs modifies the list - kdls = new TQPtrList<KDirLister>( *kdls ); - - for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() ) - { - // lister's root is the deleted item - if ( kdl->d->url == deletedUrl ) - { - // tell the view first. It might need the subdirs' items (which forgetDirs will delete) - if ( kdl->d->rootFileItem ) - emit kdl->deleteItem( kdl->d->rootFileItem ); - forgetDirs( kdl ); - kdl->d->rootFileItem = 0; - } - else - { - bool treeview = kdl->d->lstDirs.count() > 1; - if ( !treeview ) - emit kdl->clear(); - - forgetDirs( kdl, deletedUrl, treeview ); - } - } - - delete kdls; - } - - // delete the entry for deletedUrl - should not be needed, it's in - // items cached now - - DirItem *dir = itemsInUse.take( deletedUrl.url() ); - Q_ASSERT( !dir ); - if ( !dir ) // take didn't find it - move on - ++itu; - } - else - ++itu; - } - - // remove the children from the cache - removeDirFromCache( dirUrl ); -} - -void KDirListerCache::processPendingUpdates() -{ - // TODO -} - -#ifndef NDEBUG -void KDirListerCache::printDebug() -{ - kdDebug(7004) << "Items in use: " << endl; - TQDictIterator<DirItem> itu( itemsInUse ); - for ( ; itu.current() ; ++itu ) { - kdDebug(7004) << " " << itu.currentKey() << " URL: " << itu.current()->url - << " rootItem: " << ( itu.current()->rootItem ? itu.current()->rootItem->url() : KURL() ) - << " autoUpdates refcount: " << itu.current()->autoUpdates - << " complete: " << itu.current()->complete - << ( itu.current()->lstItems ? TQString(" with %1 items.").arg(itu.current()->lstItems->count()) : TQString(" lstItems=NULL") ) << endl; - } - - kdDebug(7004) << "urlsCurrentlyHeld: " << endl; - TQDictIterator< TQPtrList<KDirLister> > it( urlsCurrentlyHeld ); - for ( ; it.current() ; ++it ) - { - TQString list; - for ( TQPtrListIterator<KDirLister> listit( *it.current() ); listit.current(); ++listit ) - list += " 0x" + TQString::number( (long)listit.current(), 16 ); - kdDebug(7004) << " " << it.currentKey() << " " << it.current()->count() << " listers: " << list << endl; - } - - kdDebug(7004) << "urlsCurrentlyListed: " << endl; - TQDictIterator< TQPtrList<KDirLister> > it2( urlsCurrentlyListed ); - for ( ; it2.current() ; ++it2 ) - { - TQString list; - for ( TQPtrListIterator<KDirLister> listit( *it2.current() ); listit.current(); ++listit ) - list += " 0x" + TQString::number( (long)listit.current(), 16 ); - kdDebug(7004) << " " << it2.currentKey() << " " << it2.current()->count() << " listers: " << list << endl; - } - - TQMap< TDEIO::ListJob *, TQValueList<TDEIO::UDSEntry> >::Iterator jit = jobs.begin(); - kdDebug(7004) << "Jobs: " << endl; - for ( ; jit != jobs.end() ; ++jit ) - kdDebug(7004) << " " << jit.key() << " listing " << joburl( jit.key() ).prettyURL() << ": " << (*jit).count() << " entries." << endl; - - kdDebug(7004) << "Items in cache: " << endl; - TQCacheIterator<DirItem> itc( itemsCached ); - for ( ; itc.current() ; ++itc ) - kdDebug(7004) << " " << itc.currentKey() << " rootItem: " - << ( itc.current()->rootItem ? itc.current()->rootItem->url().prettyURL() : TQString("NULL") ) - << ( itc.current()->lstItems ? TQString(" with %1 items.").arg(itc.current()->lstItems->count()) : TQString(" lstItems=NULL") ) << endl; -} -#endif - -/*********************** -- The new KDirLister -- ************************/ - - -KDirLister::KDirLister( bool _delayedMimeTypes ) -{ - kdDebug(7003) << "+KDirLister" << endl; - - d = new KDirListerPrivate; - - d->complete = true; - d->delayedMimeTypes = _delayedMimeTypes; - - setAutoUpdate( true ); - setDirOnlyMode( false ); - setShowingDotFiles( false ); - - setAutoErrorHandlingEnabled( true, 0 ); -} - -KDirLister::~KDirLister() -{ - kdDebug(7003) << "-KDirLister" << endl; - - if ( KDirListerCache::exists() ) - { - // Stop all running jobs - stop(); - s_pCache->forgetDirs( this ); - } - - delete d; -} - -bool KDirLister::openURL( const KURL& _url, bool _keep, bool _reload ) -{ - kdDebug(7003) << k_funcinfo << _url.prettyURL() - << " keep=" << _keep << " reload=" << _reload << endl; - - // emit the current changes made to avoid an inconsistent treeview - if ( d->changes != NONE && _keep ) - emitChanges(); - - d->changes = NONE; - - // If a local path is available, monitor that instead of the given remote URL... - KURL realURL = _url; - if (!realURL.isLocalFile()) { - TDEIO::LocalURLJob* localURLJob = TDEIO::localURL(_url); - if (localURLJob) { - connect(localURLJob, TQT_SIGNAL(localURL(TDEIO::Job*, const KURL&, bool)), this, TQT_SLOT(slotLocalURL(TDEIO::Job*, const KURL&, bool))); - connect(localURLJob, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotLocalURLKIODestroyed())); - d->localURLSlotFired = false; - while (!d->localURLSlotFired) { - tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput); - usleep(1000); - } - if (d->localURLResultIsLocal) { - realURL = d->localURLResultURL; - } - } - } - - return s_pCache->listDir( this, realURL, _keep, _reload ); -} - -void KDirLister::slotLocalURL(TDEIO::Job *job, const KURL& url, bool isLocal) { - d->localURLSlotFired = true; - d->localURLResultURL = url; - d->localURLResultIsLocal = isLocal; -} - -void KDirLister::slotLocalURLKIODestroyed() { - if (!d->localURLSlotFired) { - d->localURLSlotFired = true; - d->localURLResultURL = KURL(); - d->localURLResultIsLocal = false; - } -} - -void KDirLister::stop() -{ - kdDebug(7003) << k_funcinfo << endl; - s_pCache->stop( this ); -} - -void KDirLister::stop( const KURL& _url ) -{ - kdDebug(7003) << k_funcinfo << _url.prettyURL() << endl; - s_pCache->stop( this, _url ); -} - -bool KDirLister::autoUpdate() const -{ - return d->autoUpdate; -} - -void KDirLister::setAutoUpdate( bool _enable ) -{ - if ( d->autoUpdate == _enable ) - return; - - d->autoUpdate = _enable; - s_pCache->setAutoUpdate( this, _enable ); -} - -bool KDirLister::showingDotFiles() const -{ - return d->isShowingDotFiles; -} - -void KDirLister::setShowingDotFiles( bool _showDotFiles ) -{ - if ( d->isShowingDotFiles == _showDotFiles ) - return; - - d->isShowingDotFiles = _showDotFiles; - d->changes ^= DOT_FILES; -} - -bool KDirLister::dirOnlyMode() const -{ - return d->dirOnlyMode; -} - -void KDirLister::setDirOnlyMode( bool _dirsOnly ) -{ - if ( d->dirOnlyMode == _dirsOnly ) - return; - - d->dirOnlyMode = _dirsOnly; - d->changes ^= DIR_ONLY_MODE; -} - -bool KDirLister::autoErrorHandlingEnabled() const -{ - return d->autoErrorHandling; -} - -void KDirLister::setAutoErrorHandlingEnabled( bool enable, TQWidget* parent ) -{ - d->autoErrorHandling = enable; - d->errorParent = parent; -} - -const KURL& KDirLister::url() const -{ - return d->url; -} - -const KURL::List& KDirLister::directories() const -{ - return d->lstDirs; -} - -void KDirLister::emitChanges() -{ - if ( d->changes == NONE ) - return; - - static const TQString& dot = TDEGlobal::staticQString("."); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - for ( KURL::List::Iterator it = d->lstDirs.begin(); - it != d->lstDirs.end(); ++it ) - { - KFileItemListIterator kit( *s_pCache->itemsForDir( *it ) ); - for ( ; kit.current(); ++kit ) - { - if ( (*kit)->text() == dot || (*kit)->text() == dotdot ) - continue; - - bool oldMime = true, newMime = true; - - if ( d->changes & MIME_FILTER ) - { - oldMime = doMimeFilter( (*kit)->mimetype(), d->oldMimeFilter ) - && doMimeExcludeFilter( (*kit)->mimetype(), d->oldMimeExcludeFilter ); - newMime = doMimeFilter( (*kit)->mimetype(), d->mimeFilter ) - && doMimeExcludeFilter( (*kit)->mimetype(), d->mimeExcludeFilter ); - - if ( oldMime && !newMime ) - { - emit deleteItem( *kit ); - continue; - } - } - - if ( d->changes & DIR_ONLY_MODE ) - { - // the lister switched to dirOnlyMode - if ( d->dirOnlyMode ) - { - if ( !(*kit)->isDir() ) - emit deleteItem( *kit ); - } - else if ( !(*kit)->isDir() ) - addNewItem( *kit ); - - continue; - } - - if ( (*kit)->isHidden() ) - { - if ( d->changes & DOT_FILES ) - { - // the lister switched to dot files mode - if ( d->isShowingDotFiles ) - addNewItem( *kit ); - else - emit deleteItem( *kit ); - - continue; - } - } - else if ( d->changes & NAME_FILTER ) - { - bool oldName = (*kit)->isDir() || - d->oldFilters.isEmpty() || - doNameFilter( (*kit)->text(), d->oldFilters ); - - bool newName = (*kit)->isDir() || - d->lstFilters.isEmpty() || - doNameFilter( (*kit)->text(), d->lstFilters ); - - if ( oldName && !newName ) - { - emit deleteItem( *kit ); - continue; - } - else if ( !oldName && newName ) - addNewItem( *kit ); - } - - if ( (d->changes & MIME_FILTER) && !oldMime && newMime ) - addNewItem( *kit ); - } - - emitItems(); - } - - d->changes = NONE; -} - -void KDirLister::updateDirectory( const KURL& _u ) -{ - s_pCache->updateDirectory( _u ); -} - -bool KDirLister::isFinished() const -{ - return d->complete; -} - -KFileItem *KDirLister::rootItem() const -{ - return d->rootFileItem; -} - -KFileItem *KDirLister::findByURL( const KURL& _url ) const -{ - return s_pCache->findByURL( this, _url ); -} - -KFileItem *KDirLister::findByName( const TQString& _name ) const -{ - return s_pCache->findByName( this, _name ); -} - -#ifndef KDE_NO_COMPAT -KFileItem *KDirLister::find( const KURL& _url ) const -{ - return findByURL( _url ); -} -#endif - - -// ================ public filter methods ================ // - -void KDirLister::setNameFilter( const TQString& nameFilter ) -{ - if ( !(d->changes & NAME_FILTER) ) - { - d->oldFilters = d->lstFilters; - d->lstFilters.setAutoDelete( false ); - } - - d->lstFilters.clear(); - d->lstFilters.setAutoDelete( true ); - - d->nameFilter = nameFilter; - - // Split on white space - TQStringList list = TQStringList::split( ' ', nameFilter ); - for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) - d->lstFilters.append( new TQRegExp(*it, false, true ) ); - - d->changes |= NAME_FILTER; -} - -const TQString& KDirLister::nameFilter() const -{ - return d->nameFilter; -} - -void KDirLister::setMimeFilter( const TQStringList& mimeFilter ) -{ - if ( !(d->changes & MIME_FILTER) ) - d->oldMimeFilter = d->mimeFilter; - - if ( mimeFilter.find("all/allfiles") != mimeFilter.end() || - mimeFilter.find("all/all") != mimeFilter.end() ) - d->mimeFilter.clear(); - else - d->mimeFilter = mimeFilter; - - d->changes |= MIME_FILTER; -} - -void KDirLister::setMimeExcludeFilter( const TQStringList& mimeExcludeFilter ) -{ - if ( !(d->changes & MIME_FILTER) ) - d->oldMimeExcludeFilter = d->mimeExcludeFilter; - - d->mimeExcludeFilter = mimeExcludeFilter; - d->changes |= MIME_FILTER; -} - - -void KDirLister::clearMimeFilter() -{ - if ( !(d->changes & MIME_FILTER) ) - { - d->oldMimeFilter = d->mimeFilter; - d->oldMimeExcludeFilter = d->mimeExcludeFilter; - } - d->mimeFilter.clear(); - d->mimeExcludeFilter.clear(); - d->changes |= MIME_FILTER; -} - -const TQStringList& KDirLister::mimeFilters() const -{ - return d->mimeFilter; -} - -bool KDirLister::matchesFilter( const TQString& name ) const -{ - return doNameFilter( name, d->lstFilters ); -} - -bool KDirLister::matchesMimeFilter( const TQString& mime ) const -{ - return doMimeFilter( mime, d->mimeFilter ) && doMimeExcludeFilter(mime,d->mimeExcludeFilter); -} - -// ================ protected methods ================ // - -bool KDirLister::matchesFilter( const KFileItem *item ) const -{ - Q_ASSERT( item ); - static const TQString& dotdot = TDEGlobal::staticQString(".."); - - if ( item->text() == dotdot ) - return false; - - if ( !d->isShowingDotFiles && item->isHidden() ) - return false; - - if ( item->isDir() || d->lstFilters.isEmpty() ) - return true; - - return matchesFilter( item->text() ); -} - -bool KDirLister::matchesMimeFilter( const KFileItem *item ) const -{ - Q_ASSERT( item ); - // Don't lose time determining the mimetype if there is no filter - if ( d->mimeFilter.isEmpty() && d->mimeExcludeFilter.isEmpty() ) - return true; - return matchesMimeFilter( item->mimetype() ); -} - -bool KDirLister::doNameFilter( const TQString& name, const TQPtrList<TQRegExp>& filters ) const -{ - for ( TQPtrListIterator<TQRegExp> it( filters ); it.current(); ++it ) - if ( it.current()->exactMatch( name ) ) - return true; - - return false; -} - -bool KDirLister::doMimeFilter( const TQString& mime, const TQStringList& filters ) const -{ - if ( filters.isEmpty() ) - return true; - - KMimeType::Ptr mimeptr = KMimeType::mimeType(mime); - //kdDebug(7004) << "doMimeFilter: investigating: "<<mimeptr->name()<<endl; - TQStringList::ConstIterator it = filters.begin(); - for ( ; it != filters.end(); ++it ) - if ( mimeptr->is(*it) ) - return true; - //else kdDebug(7004) << "doMimeFilter: compared without result to "<<*it<<endl; - - - return false; -} - -bool KDirLister::doMimeExcludeFilter( const TQString& mime, const TQStringList& filters ) const -{ - if ( filters.isEmpty() ) - return true; - - TQStringList::ConstIterator it = filters.begin(); - for ( ; it != filters.end(); ++it ) - if ( (*it) == mime ) - return false; - - return true; -} - - -bool KDirLister::validURL( const KURL& _url ) const -{ - return s_pCache->validURL( this, _url ); -} - -void KDirLister::handleError( TDEIO::Job *job ) -{ - if ( d->autoErrorHandling ) - job->showErrorDialog( d->errorParent ); -} - - -// ================= private methods ================= // - -void KDirLister::addNewItem( const KFileItem *item ) -{ - if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) ) - return; // No reason to continue... bailing out here prevents a mimetype scan. - - if ( matchesMimeFilter( item ) ) - { - if ( !d->lstNewItems ) - d->lstNewItems = new KFileItemList; - - d->lstNewItems->append( item ); // items not filtered - } - else - { - if ( !d->lstMimeFilteredItems ) - d->lstMimeFilteredItems = new KFileItemList; - - d->lstMimeFilteredItems->append( item ); // only filtered by mime - } -} - -void KDirLister::addNewItems( const KFileItemList& items ) -{ - // TODO: make this faster - test if we have a filter at all first - // DF: was this profiled? The matchesFoo() functions should be fast, w/o filters... - // Of course if there is no filter and we can do a range-insertion instead of a loop, that might be good. - // But that's for Qt4, not possible with TQPtrList. - for ( KFileItemListIterator kit( items ); kit.current(); ++kit ) - addNewItem( *kit ); -} - -void KDirLister::aboutToRefreshItem( const KFileItem *item ) -{ - // The code here follows the logic in addNewItem - if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) ) - d->refreshItemWasFiltered = true; - else if ( !matchesMimeFilter( item ) ) - d->refreshItemWasFiltered = true; - else - d->refreshItemWasFiltered = false; -} - -void KDirLister::addRefreshItem( const KFileItem *item ) -{ - bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item ); - - if ( !isExcluded && matchesMimeFilter( item ) ) - { - if ( d->refreshItemWasFiltered ) - { - if ( !d->lstNewItems ) - d->lstNewItems = new KFileItemList; - - d->lstNewItems->append( item ); - } - else - { - if ( !d->lstRefreshItems ) - d->lstRefreshItems = new KFileItemList; - - d->lstRefreshItems->append( item ); - } - } - else if ( !d->refreshItemWasFiltered ) - { - if ( !d->lstRemoveItems ) - d->lstRemoveItems = new KFileItemList; - - // notify the user that the mimetype of a file changed that doesn't match - // a filter or does match an exclude filter - d->lstRemoveItems->append( item ); - } -} - -void KDirLister::emitItems() -{ - KFileItemList *tmpNew = d->lstNewItems; - d->lstNewItems = 0; - - KFileItemList *tmpMime = d->lstMimeFilteredItems; - d->lstMimeFilteredItems = 0; - - KFileItemList *tmpRefresh = d->lstRefreshItems; - d->lstRefreshItems = 0; - - KFileItemList *tmpRemove = d->lstRemoveItems; - d->lstRemoveItems = 0; - - if ( tmpNew ) - { - emit newItems( *tmpNew ); - delete tmpNew; - } - - if ( tmpMime ) - { - emit itemsFilteredByMime( *tmpMime ); - delete tmpMime; - } - - if ( tmpRefresh ) - { - emit refreshItems( *tmpRefresh ); - delete tmpRefresh; - } - - if ( tmpRemove ) - { - for ( KFileItem *tmp = tmpRemove->first(); tmp; tmp = tmpRemove->next() ) - emit deleteItem( tmp ); - delete tmpRemove; - } -} - -void KDirLister::emitDeleteItem( KFileItem *item ) -{ - if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) ) - return; // No reason to continue... bailing out here prevents a mimetype scan. - if ( matchesMimeFilter( item ) ) - emit deleteItem( item ); -} - - -// ================ private slots ================ // - -void KDirLister::slotInfoMessage( TDEIO::Job *, const TQString& message ) -{ - emit infoMessage( message ); -} - -void KDirLister::slotPercent( TDEIO::Job *job, unsigned long pcnt ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].percent = pcnt; - - int result = 0; - - TDEIO::filesize_t size = 0; - - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).percent * (*dataIt).totalSize; - size += (*dataIt).totalSize; - ++dataIt; - } - - if ( size != 0 ) - result /= size; - else - result = 100; - emit percent( result ); -} - -void KDirLister::slotTotalSize( TDEIO::Job *job, TDEIO::filesize_t size ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].totalSize = size; - - TDEIO::filesize_t result = 0; - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).totalSize; - ++dataIt; - } - - emit totalSize( result ); -} - -void KDirLister::slotProcessedSize( TDEIO::Job *job, TDEIO::filesize_t size ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].processedSize = size; - - TDEIO::filesize_t result = 0; - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).processedSize; - ++dataIt; - } - - emit processedSize( result ); -} - -void KDirLister::slotSpeed( TDEIO::Job *job, unsigned long spd ) -{ - d->jobData[static_cast<TDEIO::ListJob *>(job)].speed = spd; - - int result = 0; - TQMap< TDEIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin(); - while ( dataIt != d->jobData.end() ) - { - result += (*dataIt).speed; - ++dataIt; - } - - emit speed( result ); -} - -uint KDirLister::numJobs() -{ - return d->jobData.count(); -} - -void KDirLister::jobDone( TDEIO::ListJob *job ) -{ - d->jobData.remove( job ); -} - -void KDirLister::jobStarted( TDEIO::ListJob *job ) -{ - KDirListerPrivate::JobData jobData; - jobData.speed = 0; - jobData.percent = 0; - jobData.processedSize = 0; - jobData.totalSize = 0; - - d->jobData.insert( job, jobData ); - d->complete = false; -} - -void KDirLister::connectJob( TDEIO::ListJob *job ) -{ - connect( job, TQT_SIGNAL(infoMessage( TDEIO::Job *, const TQString& )), - this, TQT_SLOT(slotInfoMessage( TDEIO::Job *, const TQString& )) ); - connect( job, TQT_SIGNAL(percent( TDEIO::Job *, unsigned long )), - this, TQT_SLOT(slotPercent( TDEIO::Job *, unsigned long )) ); - connect( job, TQT_SIGNAL(totalSize( TDEIO::Job *, TDEIO::filesize_t )), - this, TQT_SLOT(slotTotalSize( TDEIO::Job *, TDEIO::filesize_t )) ); - connect( job, TQT_SIGNAL(processedSize( TDEIO::Job *, TDEIO::filesize_t )), - this, TQT_SLOT(slotProcessedSize( TDEIO::Job *, TDEIO::filesize_t )) ); - connect( job, TQT_SIGNAL(speed( TDEIO::Job *, unsigned long )), - this, TQT_SLOT(slotSpeed( TDEIO::Job *, unsigned long )) ); -} - -void KDirLister::setMainWindow( TQWidget *window ) -{ - d->window = window; -} - -TQWidget *KDirLister::mainWindow() -{ - return d->window; -} - -KFileItemList KDirLister::items( WhichItems which ) const -{ - return itemsForDir( url(), which ); -} - -KFileItemList KDirLister::itemsForDir( const KURL& dir, WhichItems which ) const -{ - KFileItemList result; - KFileItemList *allItems = s_pCache->itemsForDir( dir ); - if ( !allItems ) - return result; - - if ( which == AllItems ) - result = *allItems; // shallow copy - else // only items passing the filters - { - for ( KFileItemListIterator kit( *allItems ); kit.current(); ++kit ) - { - KFileItem *item = *kit; - bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item ); - if ( !isExcluded && matchesMimeFilter( item ) ) - result.append( item ); - } - } - - return result; -} - -// to keep BC changes - -void KDirLister::virtual_hook( int, void * ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "kdirlister.moc" -#include "kdirlister_p.moc" |