00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kdirlister.h"
00023
00024 #include <qregexp.h>
00025 #include <qptrlist.h>
00026 #include <qtimer.h>
00027
00028 #include <kapplication.h>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <kio/job.h>
00032 #include <kmessagebox.h>
00033 #include <kglobal.h>
00034 #include <kglobalsettings.h>
00035 #include <kstaticdeleter.h>
00036
00037 #include "kdirlister_p.h"
00038
00039 #include <assert.h>
00040
00041 KDirListerCache* KDirListerCache::s_pSelf = 0;
00042 static KStaticDeleter<KDirListerCache> sd_KDirListerCache;
00043
00044
00045
00046
00047
00048 #ifdef NDEBUG
00049 #undef DEBUG_CACHE
00050 #endif
00051
00052 KDirListerCache::KDirListerCache( int maxCount )
00053 : itemsCached( maxCount )
00054 {
00055 kdDebug(7004) << "+KDirListerCache" << endl;
00056
00057 itemsInUse.setAutoDelete( false );
00058 itemsCached.setAutoDelete( true );
00059 urlsCurrentlyListed.setAutoDelete( true );
00060 urlsCurrentlyHeld.setAutoDelete( true );
00061 pendingUpdates.setAutoDelete( true );
00062
00063 connect( kdirwatch, SIGNAL( dirty( const QString& ) ),
00064 this, SLOT( slotFileDirty( const QString& ) ) );
00065 connect( kdirwatch, SIGNAL( created( const QString& ) ),
00066 this, SLOT( slotFileCreated( const QString& ) ) );
00067 connect( kdirwatch, SIGNAL( deleted( const QString& ) ),
00068 this, SLOT( slotFileDeleted( const QString& ) ) );
00069 }
00070
00071 KDirListerCache::~KDirListerCache()
00072 {
00073 kdDebug(7004) << "-KDirListerCache" << endl;
00074
00075 itemsInUse.setAutoDelete( true );
00076 itemsInUse.clear();
00077 itemsCached.clear();
00078 urlsCurrentlyListed.clear();
00079 urlsCurrentlyHeld.clear();
00080
00081 if ( KDirWatch::exists() )
00082 kdirwatch->disconnect( this );
00083 }
00084
00085
00086
00087 void KDirListerCache::listDir( KDirLister* lister, const KURL& _u,
00088 bool _keep, bool _reload )
00089 {
00090
00091 KURL _url = _u;
00092 _url.cleanPath();
00093 _url.adjustPath(-1);
00094 QString urlStr = _url.url();
00095
00096 #ifdef DEBUG_CACHE
00097 printDebug();
00098 #endif
00099 kdDebug(7004) << k_funcinfo << lister << " url=" << _url
00100 << " keep=" << _keep << " reload=" << _reload << endl;
00101
00102 if ( !_keep )
00103 {
00104
00105 stop( lister );
00106
00107
00108 forgetDirs( lister );
00109
00110 lister->d->rootFileItem = 0;
00111 }
00112 else if ( lister->d->lstDirs.find( _url ) != lister->d->lstDirs.end() )
00113 {
00114
00115 stop( lister, _url );
00116
00117
00118 forgetDirs( lister, _url, true );
00119
00120 if ( lister->d->url == _url )
00121 lister->d->rootFileItem = 0;
00122 }
00123
00124 lister->d->lstDirs.append( _url );
00125
00126 if ( lister->d->url.isEmpty() || !_keep )
00127 lister->d->url = _url;
00128
00129 DirItem *itemU = itemsInUse[urlStr];
00130 DirItem *itemC;
00131
00132 if ( !urlsCurrentlyListed[urlStr] )
00133 {
00134
00135
00136
00137 if ( itemU )
00138 {
00139 kdDebug(7004) << "listDir: Entry already in use: " << _url << endl;
00140
00141 bool oldState = lister->d->complete;
00142 lister->d->complete = false;
00143
00144 emit lister->started( _url );
00145
00146 if ( !lister->d->rootFileItem && lister->d->url == _url )
00147 lister->d->rootFileItem = itemU->rootItem;
00148
00149 lister->addNewItems( *(itemU->lstItems) );
00150 lister->emitItems();
00151
00152
00153 assert( urlsCurrentlyHeld[urlStr] );
00154 urlsCurrentlyHeld[urlStr]->append( lister );
00155
00156 lister->d->complete = oldState;
00157
00158 emit lister->completed( _url );
00159 if ( lister->d->complete )
00160 emit lister->completed();
00161
00162 if ( _reload || !itemU->complete )
00163 updateDirectory( _url );
00164 }
00165 else if ( !_reload && (itemC = itemsCached.take( urlStr )) )
00166 {
00167 kdDebug(7004) << "listDir: Entry in cache: " << _url << endl;
00168
00169 itemC->decAutoUpdate();
00170 itemsInUse.insert( urlStr, itemC );
00171 itemU = itemC;
00172
00173 bool oldState = lister->d->complete;
00174 lister->d->complete = false;
00175
00176 emit lister->started( _url );
00177
00178 if ( !lister->d->rootFileItem && lister->d->url == _url )
00179 lister->d->rootFileItem = itemC->rootItem;
00180
00181 lister->addNewItems( *(itemC->lstItems) );
00182 lister->emitItems();
00183
00184 Q_ASSERT( !urlsCurrentlyHeld[urlStr] );
00185 QPtrList<KDirLister> *list = new QPtrList<KDirLister>;
00186 list->append( lister );
00187 urlsCurrentlyHeld.insert( urlStr, list );
00188
00189 lister->d->complete = oldState;
00190
00191 emit lister->completed( _url );
00192 if ( lister->d->complete )
00193 emit lister->completed();
00194
00195 if ( !itemC->complete )
00196 updateDirectory( _url );
00197 }
00198 else
00199 {
00200 kdDebug(7004) << "listDir: Entry not in cache or reloaded: " << _url << endl;
00201
00202 QPtrList<KDirLister> *list = new QPtrList<KDirLister>;
00203 list->append( lister );
00204 urlsCurrentlyListed.insert( urlStr, list );
00205
00206 itemsCached.remove( urlStr );
00207 itemU = new DirItem( _url );
00208 itemsInUse.insert( urlStr, itemU );
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 if ( lister->d->url == _url )
00219 lister->d->rootFileItem = 0;
00220
00221 KIO::ListJob* job = KIO::listDir( _url, false );
00222 jobs.insert( job, QValueList<KIO::UDSEntry>() );
00223
00224 lister->jobStarted( job );
00225 lister->connectJob( job );
00226
00227 if ( lister->d->window )
00228 job->setWindow( lister->d->window );
00229
00230 connect( job, SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList & ) ),
00231 this, SLOT( slotEntries( KIO::Job *, const KIO::UDSEntryList & ) ) );
00232 connect( job, SIGNAL( result( KIO::Job * ) ),
00233 this, SLOT( slotResult( KIO::Job * ) ) );
00234 connect( job, SIGNAL( redirection( KIO::Job *, const KURL & ) ),
00235 this, SLOT( slotRedirection( KIO::Job *, const KURL & ) ) );
00236
00237 emit lister->started( _url );
00238
00239
00240 }
00241 }
00242 else
00243 {
00244 kdDebug(7004) << "listDir: Entry currently being listed: " << _url << endl;
00245
00246 emit lister->started( _url );
00247
00248 urlsCurrentlyListed[urlStr]->append( lister );
00249
00250 KIO::ListJob *job = jobForUrl( urlStr );
00251 Q_ASSERT( job );
00252
00253 lister->jobStarted( job );
00254 lister->connectJob( job );
00255
00256 Q_ASSERT( itemU );
00257
00258 if ( !lister->d->rootFileItem && lister->d->url == _url )
00259 lister->d->rootFileItem = itemU->rootItem;
00260
00261 lister->addNewItems( *(itemU->lstItems) );
00262 lister->emitItems();
00263 }
00264
00265
00266 if ( lister->d->autoUpdate )
00267 itemU->incAutoUpdate();
00268 }
00269
00270 void KDirListerCache::stop( KDirLister *lister )
00271 {
00272 #ifdef DEBUG_CACHE
00273 printDebug();
00274 #endif
00275 kdDebug(7004) << k_funcinfo << "lister: " << lister << endl;
00276 bool stopped = false;
00277
00278 QDictIterator< QPtrList<KDirLister> > it( urlsCurrentlyListed );
00279 QPtrList<KDirLister> *listers;
00280 while ( (listers = it.current()) )
00281 {
00282 if ( listers->findRef( lister ) > -1 )
00283 {
00284
00285 QString url = it.currentKey();
00286
00287
00288 bool ret = listers->removeRef( lister );
00289 Q_ASSERT( ret );
00290
00291 KIO::ListJob *job = jobForUrl( url );
00292 if ( job )
00293 lister->jobDone( job );
00294
00295
00296 QPtrList<KDirLister> *holders = urlsCurrentlyHeld[url];
00297 if ( !holders )
00298 {
00299 holders = new QPtrList<KDirLister>;
00300 urlsCurrentlyHeld.insert( url, holders );
00301 }
00302
00303 holders->append( lister );
00304
00305 emit lister->canceled( KURL( url ) );
00306
00307
00308
00309 if ( listers->isEmpty() )
00310 {
00311
00312 if ( job )
00313 killJob( job );
00314
00315 urlsCurrentlyListed.remove( url );
00316 }
00317
00318 stopped = true;
00319 }
00320 else
00321 ++it;
00322 }
00323
00324 if ( stopped )
00325 {
00326 emit lister->canceled();
00327 lister->d->complete = true;
00328 }
00329
00330
00331
00332 }
00333
00334 void KDirListerCache::stop( KDirLister *lister, const KURL& _u )
00335 {
00336 QString urlStr( _u.url(-1) );
00337 KURL _url( urlStr );
00338
00339
00340 kdDebug(7004) << k_funcinfo << lister << " url=" << _url << endl;
00341
00342 QPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr];
00343 if ( !listers || !listers->removeRef( lister ) )
00344 return;
00345
00346
00347 QPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr];
00348 if ( !holders )
00349 {
00350 holders = new QPtrList<KDirLister>;
00351 urlsCurrentlyHeld.insert( urlStr, holders );
00352 }
00353
00354 holders->append( lister );
00355
00356
00357 KIO::ListJob *job = jobForUrl( urlStr );
00358 if ( job )
00359 lister->jobDone( job );
00360
00361 emit lister->canceled( _url );
00362
00363 if ( listers->isEmpty() )
00364 {
00365
00366 if ( job )
00367 killJob( job );
00368
00369 urlsCurrentlyListed.remove( urlStr );
00370 }
00371
00372 if ( lister->numJobs() == 0 )
00373 {
00374 lister->d->complete = true;
00375
00376
00377 emit lister->canceled();
00378 }
00379 }
00380
00381 void KDirListerCache::setAutoUpdate( KDirLister *lister, bool enable )
00382 {
00383
00384
00385 for ( KURL::List::Iterator it = lister->d->lstDirs.begin();
00386 it != lister->d->lstDirs.end(); ++it )
00387 {
00388 if ( enable )
00389 itemsInUse[(*it).url()]->incAutoUpdate();
00390 else
00391 itemsInUse[(*it).url()]->decAutoUpdate();
00392 }
00393 }
00394
00395 void KDirListerCache::forgetDirs( KDirLister *lister )
00396 {
00397 kdDebug(7004) << k_funcinfo << lister << endl;
00398
00399 emit lister->clear();
00400
00401
00402 KURL::List lstDirsCopy = lister->d->lstDirs;
00403 for ( KURL::List::Iterator it = lstDirsCopy.begin();
00404 it != lstDirsCopy.end(); ++it )
00405 {
00406 forgetDirs( lister, *it, false );
00407 }
00408 }
00409
00410 void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool notify )
00411 {
00412 kdDebug(7004) << k_funcinfo << lister << " _url: " << _url << endl;
00413
00414 KURL url( _url );
00415 url.adjustPath( -1 );
00416 QString urlStr = url.url();
00417 QPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr];
00418 Q_ASSERT( holders );
00419 holders->removeRef( lister );
00420
00421
00422
00423
00424
00425 lister->d->lstDirs.remove( lister->d->lstDirs.find( url ) );
00426
00427 DirItem *item = itemsInUse[urlStr];
00428 Q_ASSERT( item );
00429
00430 if ( holders->isEmpty() )
00431 {
00432 urlsCurrentlyHeld.remove( urlStr );
00433 if ( !urlsCurrentlyListed[urlStr] )
00434 {
00435
00436 itemsInUse.remove( urlStr );
00437
00438
00439 KIO::ListJob *job = jobForUrl( urlStr );
00440 if ( job )
00441 {
00442 lister->jobDone( job );
00443 killJob( job );
00444 kdDebug(7004) << k_funcinfo << "Killing update job for " << urlStr << endl;
00445
00446 emit lister->canceled( url );
00447 if ( lister->numJobs() == 0 )
00448 {
00449 lister->d->complete = true;
00450 emit lister->canceled();
00451 }
00452 }
00453
00454 if ( notify )
00455 emit lister->clear( url );
00456
00457 if ( item->complete )
00458 {
00459 kdDebug(7004) << k_funcinfo << lister << " item moved into cache: " << url << endl;
00460 itemsCached.insert( urlStr, item );
00461
00462
00463
00464
00465 const bool isLocal = item->url.isLocalFile();
00466 const bool isManuallyMounted = isLocal && KIO::manually_mounted( item->url.path() );
00467 bool containsManuallyMounted = false;
00468 if ( !isManuallyMounted && item->lstItems && isLocal )
00469 {
00470
00471
00472
00473
00474 KFileItemListIterator kit( *item->lstItems );
00475 for ( ; kit.current() && !containsManuallyMounted; ++kit )
00476 if ( (*kit)->isDir() && KIO::manually_mounted( (*kit)->url().path() ) )
00477 containsManuallyMounted = true;
00478 }
00479
00480 if ( isManuallyMounted || containsManuallyMounted )
00481 {
00482 kdDebug(7004) << "Not adding a watch on " << item->url << " because it " <<
00483 ( isManuallyMounted ? "is manually mounted" : "contains a manually mounted subdir" ) << endl;
00484 item->complete = false;
00485 }
00486 else
00487 item->incAutoUpdate();
00488 }
00489 else
00490 {
00491 delete item;
00492 item = 0;
00493 }
00494 }
00495 }
00496
00497 if ( item && lister->d->autoUpdate )
00498 item->decAutoUpdate();
00499 }
00500
00501 void KDirListerCache::updateDirectory( const KURL& _dir )
00502 {
00503 kdDebug(7004) << k_funcinfo << _dir << endl;
00504
00505 QString urlStr = _dir.url(-1);
00506 if ( !checkUpdate( urlStr ) )
00507 return;
00508
00509
00510
00511
00512
00513
00514
00515 QPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr];
00516 QPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr];
00517
00518
00519 bool killed = false;
00520 QWidget *window = 0;
00521 KIO::ListJob *job = jobForUrl( urlStr );
00522 if ( job )
00523 {
00524 window = job->window();
00525
00526 killJob( job );
00527 killed = true;
00528
00529 if ( listers )
00530 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00531 kdl->jobDone( job );
00532
00533 if ( holders )
00534 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
00535 kdl->jobDone( job );
00536 }
00537 kdDebug(7004) << k_funcinfo << "Killed = " << killed << endl;
00538
00539
00540
00541
00542 Q_ASSERT( !listers || (listers && killed) );
00543
00544 job = KIO::listDir( _dir, false );
00545 jobs.insert( job, QValueList<KIO::UDSEntry>() );
00546
00547 connect( job, SIGNAL(entries( KIO::Job *, const KIO::UDSEntryList & )),
00548 this, SLOT(slotUpdateEntries( KIO::Job *, const KIO::UDSEntryList & )) );
00549 connect( job, SIGNAL(result( KIO::Job * )),
00550 this, SLOT(slotUpdateResult( KIO::Job * )) );
00551
00552 kdDebug(7004) << k_funcinfo << "update started in " << _dir << endl;
00553
00554 if ( listers )
00555 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00556 kdl->jobStarted( job );
00557
00558 if ( holders )
00559 {
00560 if ( !killed )
00561 {
00562 bool first = true;
00563 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
00564 {
00565 kdl->jobStarted( job );
00566 if ( first && kdl->d->window )
00567 {
00568 first = false;
00569 job->setWindow( kdl->d->window );
00570 }
00571 emit kdl->started( _dir );
00572 }
00573 }
00574 else
00575 {
00576 job->setWindow( window );
00577
00578 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
00579 kdl->jobStarted( job );
00580 }
00581 }
00582 }
00583
00584 bool KDirListerCache::checkUpdate( const QString& _dir )
00585 {
00586 if ( !itemsInUse[_dir] )
00587 {
00588 DirItem *item = itemsCached[_dir];
00589 if ( item && item->complete )
00590 {
00591 item->complete = false;
00592 item->decAutoUpdate();
00593
00594
00595 }
00596
00597
00598
00599 return false;
00600 }
00601 else
00602 return true;
00603 }
00604
00605 KFileItemList *KDirListerCache::itemsForDir( const KURL &_dir ) const
00606 {
00607 QString urlStr = _dir.url(-1);
00608 DirItem *item = itemsInUse[ urlStr ];
00609 if ( !item )
00610 item = itemsCached[ urlStr ];
00611 return item ? item->lstItems : 0;
00612 }
00613
00614 KFileItem *KDirListerCache::findByName( const KDirLister *lister, const QString& _name ) const
00615 {
00616 Q_ASSERT( lister );
00617
00618 for ( KURL::List::Iterator it = lister->d->lstDirs.begin();
00619 it != lister->d->lstDirs.end(); ++it )
00620 {
00621 KFileItemListIterator kit( *itemsInUse[(*it).url()]->lstItems );
00622 for ( ; kit.current(); ++kit )
00623 if ( (*kit)->name() == _name )
00624 return (*kit);
00625 }
00626
00627 return 0L;
00628 }
00629
00630 KFileItem *KDirListerCache::findByURL( const KDirLister *lister, const KURL& _u ) const
00631 {
00632 KURL _url = _u;
00633 _url.adjustPath(-1);
00634
00635 KURL parentDir( _url );
00636 parentDir.setPath( parentDir.directory() );
00637
00638
00639 if ( lister && !lister->d->lstDirs.contains( parentDir ) )
00640 return 0L;
00641
00642 KFileItemList *itemList = itemsForDir( parentDir );
00643 if ( itemList )
00644 {
00645 KFileItemListIterator kit( *itemList );
00646 for ( ; kit.current(); ++kit )
00647 if ( (*kit)->url() == _url )
00648 return (*kit);
00649 }
00650 return 0L;
00651 }
00652
00653 void KDirListerCache::FilesAdded( const KURL &dir )
00654 {
00655 kdDebug(7004) << k_funcinfo << dir << endl;
00656 updateDirectory( dir );
00657 }
00658
00659 void KDirListerCache::FilesRemoved( const KURL::List &fileList )
00660 {
00661 kdDebug(7004) << k_funcinfo << endl;
00662 KURL::List::ConstIterator it = fileList.begin();
00663 for ( ; it != fileList.end() ; ++it )
00664 {
00665
00666 KFileItem *fileitem = 0L;
00667 KURL parentDir( *it );
00668 parentDir.setPath( parentDir.directory() );
00669 KFileItemList *lstItems = itemsForDir( parentDir );
00670 if ( lstItems )
00671 {
00672 KFileItem *fit = lstItems->first();
00673 for ( ; fit; fit = lstItems->next() )
00674 if ( fit->url() == *it ) {
00675 fileitem = fit;
00676 lstItems->take();
00677 break;
00678 }
00679 }
00680
00681
00682
00683 if ( fileitem )
00684 {
00685 QPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDir.url()];
00686 if ( listers )
00687 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00688 kdl->emitDeleteItem( fileitem );
00689 }
00690
00691
00692 if ( !fileitem || fileitem->isDir() )
00693 {
00694
00695
00696 deleteDir( *it );
00697 }
00698
00699
00700 delete fileitem;
00701 }
00702 }
00703
00704 void KDirListerCache::FilesChanged( const KURL::List &fileList )
00705 {
00706 KURL::List dirsToUpdate;
00707 kdDebug(7004) << k_funcinfo << "only half implemented" << endl;
00708 KURL::List::ConstIterator it = fileList.begin();
00709 for ( ; it != fileList.end() ; ++it )
00710 {
00711 if ( ( *it ).isLocalFile() )
00712 {
00713 kdDebug(7004) << "KDirListerCache::FilesChanged " << *it << endl;
00714 KFileItem *fileitem = findByURL( 0, *it );
00715 if ( fileitem )
00716 {
00717
00718 aboutToRefreshItem( fileitem );
00719 fileitem->refresh();
00720 emitRefreshItem( fileitem );
00721 }
00722 else
00723 kdDebug(7004) << "item not found" << endl;
00724 } else {
00725
00726
00727 KURL dir( *it );
00728 dir.setPath( dir.directory( true ) );
00729 if ( dirsToUpdate.find( dir ) == dirsToUpdate.end() )
00730 dirsToUpdate.prepend( dir );
00731 }
00732 }
00733
00734 KURL::List::ConstIterator itdir = dirsToUpdate.begin();
00735 for ( ; itdir != dirsToUpdate.end() ; ++itdir )
00736 updateDirectory( *itdir );
00737
00738
00739 }
00740
00741 void KDirListerCache::FileRenamed( const KURL &src, const KURL &dst )
00742 {
00743 kdDebug(7004) << k_funcinfo << src.prettyURL() << " -> " << dst.prettyURL() << endl;
00744 #ifdef DEBUG_CACHE
00745 printDebug();
00746 #endif
00747
00748
00749
00750 renameDir( src, dst );
00751
00752
00753 KURL oldurl( src );
00754 oldurl.adjustPath( -1 );
00755 KFileItem *fileitem = findByURL( 0, oldurl );
00756 if ( fileitem )
00757 {
00758 if ( !fileitem->isLocalFile() && !fileitem->localPath().isEmpty() )
00759 FilesChanged( src );
00760 else
00761 {
00762 aboutToRefreshItem( fileitem );
00763 fileitem->setURL( dst );
00764 fileitem->refreshMimeType();
00765 emitRefreshItem( fileitem );
00766 }
00767 }
00768 #ifdef DEBUG_CACHE
00769 printDebug();
00770 #endif
00771 }
00772
00773 void KDirListerCache::aboutToRefreshItem( KFileItem *fileitem )
00774 {
00775
00776 KURL parentDir( fileitem->url() );
00777 parentDir.setPath( parentDir.directory() );
00778 QString parentDirURL = parentDir.url();
00779 QPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL];
00780 if ( listers )
00781 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00782 kdl->aboutToRefreshItem( fileitem );
00783
00784
00785 listers = urlsCurrentlyListed[parentDirURL];
00786 if ( listers )
00787 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00788 kdl->aboutToRefreshItem( fileitem );
00789 }
00790
00791 void KDirListerCache::emitRefreshItem( KFileItem *fileitem )
00792 {
00793
00794 KURL parentDir( fileitem->url() );
00795 parentDir.setPath( parentDir.directory() );
00796 QString parentDirURL = parentDir.url();
00797 QPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL];
00798 if ( listers )
00799 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00800 {
00801 kdl->addRefreshItem( fileitem );
00802 kdl->emitItems();
00803 }
00804
00805
00806 listers = urlsCurrentlyListed[parentDirURL];
00807 if ( listers )
00808 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00809 {
00810 kdl->addRefreshItem( fileitem );
00811 kdl->emitItems();
00812 }
00813 }
00814
00815 KDirListerCache* KDirListerCache::self()
00816 {
00817 if ( !s_pSelf )
00818 s_pSelf = sd_KDirListerCache.setObject( s_pSelf, new KDirListerCache );
00819
00820 return s_pSelf;
00821 }
00822
00823 bool KDirListerCache::exists()
00824 {
00825 return s_pSelf != 0;
00826 }
00827
00828
00829
00830
00831
00832 void KDirListerCache::slotFileDirty( const QString& _file )
00833 {
00834 kdDebug(7004) << k_funcinfo << _file << endl;
00835
00836 if ( !pendingUpdates[_file] )
00837 {
00838 KURL dir;
00839 dir.setPath( _file );
00840 if ( checkUpdate( dir.url(-1) ) )
00841 updateDirectory( dir );
00842
00843
00844 dir.setPath( dir.directory() );
00845 if ( checkUpdate( dir.url() ) )
00846 {
00847
00848 QTimer *timer = new QTimer( this, _file.utf8() );
00849 connect( timer, SIGNAL(timeout()), this, SLOT(slotFileDirtyDelayed()) );
00850 pendingUpdates.insert( _file, timer );
00851 timer->start( 500, true );
00852 }
00853 }
00854 }
00855
00856
00857 void KDirListerCache::slotFileDirtyDelayed()
00858 {
00859 QString file = QString::fromUtf8( sender()->name() );
00860
00861 kdDebug(7004) << k_funcinfo << file << endl;
00862
00863
00864
00865 pendingUpdates.remove( file );
00866
00867 KURL u;
00868 u.setPath( file );
00869 KFileItem *item = findByURL( 0, u );
00870 if ( item )
00871 {
00872
00873 aboutToRefreshItem( item );
00874 item->refresh();
00875 emitRefreshItem( item );
00876 }
00877 }
00878
00879 void KDirListerCache::slotFileCreated( const QString& _file )
00880 {
00881 kdDebug(7004) << k_funcinfo << _file << endl;
00882
00883 KURL u;
00884 u.setPath( _file );
00885 u.setPath( u.directory() );
00886 FilesAdded( u );
00887 }
00888
00889 void KDirListerCache::slotFileDeleted( const QString& _file )
00890 {
00891 kdDebug(7004) << k_funcinfo << _file << endl;
00892 KURL u;
00893 u.setPath( _file );
00894 FilesRemoved( u );
00895 }
00896
00897 void KDirListerCache::slotEntries( KIO::Job *job, const KIO::UDSEntryList &entries )
00898 {
00899 KURL url = joburl( static_cast<KIO::ListJob *>(job) );
00900 url.adjustPath(-1);
00901 QString urlStr = url.url();
00902
00903 kdDebug(7004) << k_funcinfo << "new entries for " << url << endl;
00904
00905 DirItem *dir = itemsInUse[urlStr];
00906 Q_ASSERT( dir );
00907
00908 QPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr];
00909 Q_ASSERT( listers );
00910 Q_ASSERT( !listers->isEmpty() );
00911
00912
00913 bool delayedMimeTypes = true;
00914 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00915 delayedMimeTypes &= kdl->d->delayedMimeTypes;
00916
00917
00918 static const QString& dot = KGlobal::staticQString(".");
00919 static const QString& dotdot = KGlobal::staticQString("..");
00920
00921 KIO::UDSEntryListConstIterator it = entries.begin();
00922 KIO::UDSEntryListConstIterator end = entries.end();
00923
00924 for ( ; it != end; ++it )
00925 {
00926 QString name;
00927
00928
00929 KIO::UDSEntry::ConstIterator entit = (*it).begin();
00930 for( ; entit != (*it).end(); ++entit )
00931 if ( (*entit).m_uds == KIO::UDS_NAME )
00932 {
00933 name = (*entit).m_str;
00934 break;
00935 }
00936
00937 Q_ASSERT( !name.isEmpty() );
00938 if ( name.isEmpty() )
00939 continue;
00940
00941 if ( name == dot )
00942 {
00943 Q_ASSERT( !dir->rootItem );
00944 dir->rootItem = new KFileItem( *it, url, delayedMimeTypes, true );
00945
00946 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00947 if ( !kdl->d->rootFileItem && kdl->d->url == url )
00948 kdl->d->rootFileItem = dir->rootItem;
00949 }
00950 else if ( name != dotdot )
00951 {
00952 KFileItem* item = new KFileItem( *it, url, delayedMimeTypes, true );
00953 Q_ASSERT( item );
00954
00955
00956 dir->lstItems->append( item );
00957
00958 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00959 kdl->addNewItem( item );
00960 }
00961 }
00962
00963 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
00964 kdl->emitItems();
00965 }
00966
00967 void KDirListerCache::slotResult( KIO::Job *j )
00968 {
00969 Q_ASSERT( j );
00970 KIO::ListJob *job = static_cast<KIO::ListJob *>( j );
00971 jobs.remove( job );
00972
00973 KURL jobUrl = joburl( job );
00974 jobUrl.adjustPath(-1);
00975 QString jobUrlStr = jobUrl.url();
00976
00977 kdDebug(7004) << k_funcinfo << "finished listing " << jobUrl << endl;
00978 #ifdef DEBUG_CACHE
00979 printDebug();
00980 #endif
00981
00982 QPtrList<KDirLister> *listers = urlsCurrentlyListed.take( jobUrlStr );
00983 Q_ASSERT( listers );
00984
00985
00986
00987
00988 Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr] );
00989 urlsCurrentlyHeld.insert( jobUrlStr, listers );
00990
00991 KDirLister *kdl;
00992
00993 if ( job->error() )
00994 {
00995 for ( kdl = listers->first(); kdl; kdl = listers->next() )
00996 {
00997 kdl->jobDone( job );
00998 kdl->handleError( job );
00999 emit kdl->canceled( jobUrl );
01000 if ( kdl->numJobs() == 0 )
01001 {
01002 kdl->d->complete = true;
01003 emit kdl->canceled();
01004 }
01005 }
01006 }
01007 else
01008 {
01009 DirItem *dir = itemsInUse[jobUrlStr];
01010 Q_ASSERT( dir );
01011 dir->complete = true;
01012
01013 for ( kdl = listers->first(); kdl; kdl = listers->next() )
01014 {
01015 kdl->jobDone( job );
01016 emit kdl->completed( jobUrl );
01017 if ( kdl->numJobs() == 0 )
01018 {
01019 kdl->d->complete = true;
01020 emit kdl->completed();
01021 }
01022 }
01023 }
01024
01025
01026
01027 processPendingUpdates();
01028
01029 #ifdef DEBUG_CACHE
01030 printDebug();
01031 #endif
01032 }
01033
01034 void KDirListerCache::slotRedirection( KIO::Job *j, const KURL& url )
01035 {
01036 Q_ASSERT( j );
01037 KIO::ListJob *job = static_cast<KIO::ListJob *>( j );
01038
01039 KURL oldUrl = job->url();
01040 KURL newUrl = url;
01041
01042
01043 oldUrl.adjustPath(-1);
01044 newUrl.adjustPath(-1);
01045
01046 kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl;
01047
01048 #ifdef DEBUG_CACHE
01049 printDebug();
01050 #endif
01051
01052
01053
01054
01055
01056
01057 DirItem *dir = itemsInUse.take( oldUrl.url() );
01058 Q_ASSERT( dir );
01059
01060 QPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrl.url() );
01061 Q_ASSERT( listers );
01062 Q_ASSERT( !listers->isEmpty() );
01063
01064 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01065 {
01066
01067 if ( kdl->d->url.equals( oldUrl, true ) )
01068 {
01069 kdl->d->rootFileItem = 0;
01070 kdl->d->url = newUrl;
01071 }
01072
01073 *kdl->d->lstDirs.find( oldUrl ) = newUrl;
01074
01075 if ( kdl->d->lstDirs.count() == 1 )
01076 {
01077 emit kdl->clear();
01078 emit kdl->redirection( newUrl );
01079 emit kdl->redirection( oldUrl, newUrl );
01080 }
01081 else
01082 {
01083 emit kdl->clear( oldUrl );
01084 emit kdl->redirection( oldUrl, newUrl );
01085 }
01086 }
01087
01088
01089
01090 QPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrl.url() );
01091 if ( holders )
01092 {
01093 Q_ASSERT( !holders->isEmpty() );
01094
01095 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
01096 {
01097 kdl->jobStarted( job );
01098
01099
01100 emit kdl->started( oldUrl );
01101
01102
01103
01104 if ( kdl->d->url.equals( oldUrl, true ) )
01105 {
01106 kdl->d->rootFileItem = 0;
01107 kdl->d->url = newUrl;
01108 }
01109
01110 *kdl->d->lstDirs.find( oldUrl ) = newUrl;
01111
01112 if ( kdl->d->lstDirs.count() == 1 )
01113 {
01114 emit kdl->clear();
01115 emit kdl->redirection( newUrl );
01116 emit kdl->redirection( oldUrl, newUrl );
01117 }
01118 else
01119 {
01120 emit kdl->clear( oldUrl );
01121 emit kdl->redirection( oldUrl, newUrl );
01122 }
01123 }
01124 }
01125
01126 DirItem *newDir = itemsInUse[newUrl.url()];
01127 if ( newDir )
01128 {
01129 kdDebug(7004) << "slotRedirection: " << newUrl.url() << " already in use" << endl;
01130
01131
01132 delete dir;
01133
01134
01135
01136 KIO::ListJob *oldJob = jobForUrl( newUrl.url(), job );
01137
01138
01139
01140 QPtrList<KDirLister> *curListers = urlsCurrentlyListed[newUrl.url()];
01141 if ( curListers )
01142 {
01143 kdDebug(7004) << "slotRedirection: and it is currently listed" << endl;
01144
01145 Q_ASSERT( oldJob );
01146
01147 for ( KDirLister *kdl = curListers->first(); kdl; kdl = curListers->next() )
01148 {
01149 kdl->jobDone( oldJob );
01150
01151 kdl->jobStarted( job );
01152 kdl->connectJob( job );
01153 }
01154
01155
01156 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01157 curListers->append( kdl );
01158 }
01159 else
01160 urlsCurrentlyListed.insert( newUrl.url(), listers );
01161
01162 if ( oldJob )
01163 killJob( oldJob );
01164
01165
01166 QPtrList<KDirLister> *curHolders = urlsCurrentlyHeld[newUrl.url()];
01167 if ( curHolders )
01168 {
01169 kdDebug(7004) << "slotRedirection: and it is currently held." << endl;
01170
01171 for ( KDirLister *kdl = curHolders->first(); kdl; kdl = curHolders->next() )
01172 {
01173 kdl->jobStarted( job );
01174 emit kdl->started( newUrl );
01175 }
01176
01177
01178 if ( holders )
01179 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
01180 curHolders->append( kdl );
01181 }
01182 else if ( holders )
01183 urlsCurrentlyHeld.insert( newUrl.url(), holders );
01184
01185
01186
01187
01188 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01189 {
01190 if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
01191 kdl->d->rootFileItem = newDir->rootItem;
01192
01193 kdl->addNewItems( *(newDir->lstItems) );
01194 kdl->emitItems();
01195 }
01196
01197 if ( holders )
01198 {
01199 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
01200 {
01201 if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
01202 kdl->d->rootFileItem = newDir->rootItem;
01203
01204 kdl->addNewItems( *(newDir->lstItems) );
01205 kdl->emitItems();
01206 }
01207 }
01208 }
01209 else if ( (newDir = itemsCached.take( newUrl.url() )) )
01210 {
01211 kdDebug(7004) << "slotRedirection: " << newUrl.url() << " is unused, but already in the cache." << endl;
01212
01213 delete dir;
01214 itemsInUse.insert( newUrl.url(), newDir );
01215 urlsCurrentlyListed.insert( newUrl.url(), listers );
01216 if ( holders )
01217 urlsCurrentlyHeld.insert( newUrl.url(), holders );
01218
01219
01220 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01221 {
01222 if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
01223 kdl->d->rootFileItem = newDir->rootItem;
01224
01225 kdl->addNewItems( *(newDir->lstItems) );
01226 kdl->emitItems();
01227 }
01228
01229 if ( holders )
01230 {
01231 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
01232 {
01233 if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
01234 kdl->d->rootFileItem = newDir->rootItem;
01235
01236 kdl->addNewItems( *(newDir->lstItems) );
01237 kdl->emitItems();
01238 }
01239 }
01240 }
01241 else
01242 {
01243 kdDebug(7004) << "slotRedirection: " << newUrl.url() << " has not been listed yet." << endl;
01244
01245 delete dir->rootItem;
01246 dir->rootItem = 0;
01247 dir->lstItems->clear();
01248 dir->redirect( newUrl );
01249 itemsInUse.insert( newUrl.url(), dir );
01250 urlsCurrentlyListed.insert( newUrl.url(), listers );
01251
01252 if ( holders )
01253 urlsCurrentlyHeld.insert( newUrl.url(), holders );
01254 else
01255 {
01256 #ifdef DEBUG_CACHE
01257 printDebug();
01258 #endif
01259 return;
01260 }
01261 }
01262
01263
01264 job->disconnect( this );
01265
01266 connect( job, SIGNAL(entries( KIO::Job *, const KIO::UDSEntryList & )),
01267 this, SLOT(slotUpdateEntries( KIO::Job *, const KIO::UDSEntryList & )) );
01268 connect( job, SIGNAL(result( KIO::Job * )),
01269 this, SLOT(slotUpdateResult( KIO::Job * )) );
01270
01271
01272
01273 #ifdef DEBUG_CACHE
01274 printDebug();
01275 #endif
01276 }
01277
01278 void KDirListerCache::renameDir( const KURL &oldUrl, const KURL &newUrl )
01279 {
01280 kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl;
01281 QString oldUrlStr = oldUrl.url(-1);
01282 QString newUrlStr = newUrl.url(-1);
01283
01284
01285
01286
01287
01288
01289 QDictIterator<DirItem> itu( itemsInUse );
01290 bool goNext;
01291 while ( itu.current() )
01292 {
01293 goNext = true;
01294 DirItem *dir = itu.current();
01295 KURL oldDirUrl ( itu.currentKey() );
01296
01297
01298 if ( oldUrl.isParentOf( oldDirUrl ) )
01299 {
01300
01301 QString relPath = oldDirUrl.path().mid( oldUrl.path().length() );
01302
01303 KURL newDirUrl( newUrl );
01304 if ( !relPath.isEmpty() )
01305 newDirUrl.addPath( relPath );
01306
01307
01308
01309 dir->redirect( newDirUrl );
01310 itemsInUse.remove( itu.currentKey() );
01311 itemsInUse.insert( newDirUrl.url(-1), dir );
01312 goNext = false;
01313 if ( dir->lstItems )
01314 {
01315
01316 KFileItemListIterator kit( *dir->lstItems );
01317 for ( ; kit.current(); ++kit )
01318 {
01319 KURL oldItemUrl = (*kit)->url();
01320 QString oldItemUrlStr( oldItemUrl.url(-1) );
01321 KURL newItemUrl( oldItemUrl );
01322 newItemUrl.setPath( newDirUrl.path() );
01323 newItemUrl.addPath( oldItemUrl.fileName() );
01324 kdDebug(7004) << "KDirListerCache::renameDir renaming " << oldItemUrlStr << " to " << newItemUrl.url() << endl;
01325 (*kit)->setURL( newItemUrl );
01326 }
01327 }
01328 emitRedirections( oldDirUrl, newDirUrl );
01329 }
01330 if ( goNext )
01331 ++itu;
01332 }
01333
01334
01335
01336 removeDirFromCache( oldUrl );
01337
01338 }
01339
01340 void KDirListerCache::emitRedirections( const KURL &oldUrl, const KURL &url )
01341 {
01342 kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << url.prettyURL() << endl;
01343 QString oldUrlStr = oldUrl.url(-1);
01344 QString urlStr = url.url(-1);
01345
01346 KIO::ListJob *job = jobForUrl( oldUrlStr );
01347 if ( job )
01348 killJob( job );
01349
01350
01351 QPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrlStr );
01352 if ( listers )
01353 {
01354
01355 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01356 {
01357 if ( job )
01358 kdl->jobDone( job );
01359
01360 emit kdl->canceled( oldUrl );
01361 }
01362
01363 urlsCurrentlyListed.insert( urlStr, listers );
01364 }
01365
01366
01367
01368 QPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrlStr );
01369 if ( holders )
01370 {
01371 if ( job )
01372 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
01373 kdl->jobDone( job );
01374
01375 urlsCurrentlyHeld.insert( urlStr, holders );
01376 }
01377
01378 if ( listers )
01379 {
01380 updateDirectory( url );
01381
01382
01383 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01384 emit kdl->started( url );
01385 }
01386
01387 if ( holders )
01388 {
01389
01390 for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
01391 {
01392 *kdl->d->lstDirs.find( oldUrl ) = url;
01393
01394 if ( kdl->d->lstDirs.count() == 1 )
01395 emit kdl->redirection( url );
01396
01397 emit kdl->redirection( oldUrl, url );
01398 }
01399 }
01400 }
01401
01402 void KDirListerCache::removeDirFromCache( const KURL& dir )
01403 {
01404 kdDebug(7004) << "KDirListerCache::removeDirFromCache " << dir.prettyURL() << endl;
01405 QCacheIterator<DirItem> itc( itemsCached );
01406 while ( itc.current() )
01407 {
01408 if ( dir.isParentOf( KURL( itc.currentKey() ) ) )
01409 itemsCached.remove( itc.currentKey() );
01410 else
01411 ++itc;
01412 }
01413 }
01414
01415 void KDirListerCache::slotUpdateEntries( KIO::Job* job, const KIO::UDSEntryList& list )
01416 {
01417 jobs[static_cast<KIO::ListJob*>(job)] += list;
01418 }
01419
01420 void KDirListerCache::slotUpdateResult( KIO::Job * j )
01421 {
01422 Q_ASSERT( j );
01423 KIO::ListJob *job = static_cast<KIO::ListJob *>( j );
01424
01425 KURL jobUrl = joburl( job );
01426 jobUrl.adjustPath(-1);
01427 QString jobUrlStr = jobUrl.url();
01428
01429 kdDebug(7004) << k_funcinfo << "finished update " << jobUrl << endl;
01430
01431 KDirLister *kdl;
01432
01433 QPtrList<KDirLister> *listers = urlsCurrentlyHeld[jobUrlStr];
01434 QPtrList<KDirLister> *tmpLst = urlsCurrentlyListed.take( jobUrlStr );
01435
01436 if ( tmpLst )
01437 {
01438 if ( listers )
01439 for ( kdl = tmpLst->first(); kdl; kdl = tmpLst->next() )
01440 {
01441 Q_ASSERT( listers->containsRef( kdl ) == 0 );
01442 listers->append( kdl );
01443 }
01444 else
01445 {
01446 listers = tmpLst;
01447 urlsCurrentlyHeld.insert( jobUrlStr, listers );
01448 }
01449 }
01450
01451
01452 Q_ASSERT( listers );
01453
01454 if ( job->error() )
01455 {
01456 for ( kdl = listers->first(); kdl; kdl = listers->next() )
01457 {
01458 kdl->jobDone( job );
01459
01460
01461
01462
01463 emit kdl->canceled( jobUrl );
01464 if ( kdl->numJobs() == 0 )
01465 {
01466 kdl->d->complete = true;
01467 emit kdl->canceled();
01468 }
01469 }
01470
01471 jobs.remove( job );
01472
01473
01474
01475 processPendingUpdates();
01476 return;
01477 }
01478
01479 DirItem *dir = itemsInUse[jobUrlStr];
01480 dir->complete = true;
01481
01482
01483
01484 bool delayedMimeTypes = true;
01485 for ( kdl = listers->first(); kdl; kdl = listers->next() )
01486 delayedMimeTypes &= kdl->d->delayedMimeTypes;
01487
01488
01489 QDict<KFileItem> fileItems( 9973 );
01490
01491 KFileItemListIterator kit ( *(dir->lstItems) );
01492
01493
01494 for ( ; kit.current(); ++kit )
01495 {
01496 (*kit)->unmark();
01497 fileItems.insert( (*kit)->url().url(), *kit );
01498 }
01499
01500 static const QString& dot = KGlobal::staticQString(".");
01501 static const QString& dotdot = KGlobal::staticQString("..");
01502
01503 KFileItem *item = 0, *tmp;
01504
01505 QValueList<KIO::UDSEntry> buf = jobs[job];
01506 QValueListIterator<KIO::UDSEntry> it = buf.begin();
01507 for ( ; it != buf.end(); ++it )
01508 {
01509
01510 if ( !item )
01511 item = new KFileItem( *it, jobUrl, delayedMimeTypes, true );
01512 else
01513 item->setUDSEntry( *it, jobUrl, delayedMimeTypes, true );
01514
01515
01516 QString name = item->name();
01517 Q_ASSERT( !name.isEmpty() );
01518
01519
01520
01521 if ( name.isEmpty() || name == dotdot )
01522 continue;
01523
01524 if ( name == dot )
01525 {
01526
01527
01528 if ( !dir->rootItem )
01529 {
01530 dir->rootItem = item;
01531 item = 0;
01532
01533 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01534 if ( !kdl->d->rootFileItem && kdl->d->url == jobUrl )
01535 kdl->d->rootFileItem = dir->rootItem;
01536 }
01537
01538 continue;
01539 }
01540
01541
01542 if ( (tmp = fileItems[item->url().url()]) )
01543 {
01544 tmp->mark();
01545
01546
01547 if ( !tmp->cmp( *item ) )
01548 {
01549 for ( kdl = listers->first(); kdl; kdl = listers->next() )
01550 kdl->aboutToRefreshItem( tmp );
01551
01552
01553 tmp->assign( *item );
01554
01555 for ( kdl = listers->first(); kdl; kdl = listers->next() )
01556 kdl->addRefreshItem( tmp );
01557 }
01558 }
01559 else
01560 {
01561
01562
01563 item->mark();
01564 dir->lstItems->append( item );
01565
01566 for ( kdl = listers->first(); kdl; kdl = listers->next() )
01567 kdl->addNewItem( item );
01568
01569
01570 item = 0;
01571 }
01572 }
01573
01574 if ( item )
01575 delete item;
01576
01577 jobs.remove( job );
01578
01579 deleteUnmarkedItems( listers, dir->lstItems );
01580
01581 for ( kdl = listers->first(); kdl; kdl = listers->next() )
01582 {
01583 kdl->emitItems();
01584
01585 kdl->jobDone( job );
01586
01587 emit kdl->completed( jobUrl );
01588 if ( kdl->numJobs() == 0 )
01589 {
01590 kdl->d->complete = true;
01591 emit kdl->completed();
01592 }
01593 }
01594
01595
01596
01597 processPendingUpdates();
01598 }
01599
01600
01601
01602 KIO::ListJob *KDirListerCache::jobForUrl( const QString& url, KIO::ListJob *not_job )
01603 {
01604 KIO::ListJob *job;
01605 QMap< KIO::ListJob *, QValueList<KIO::UDSEntry> >::Iterator it = jobs.begin();
01606 while ( it != jobs.end() )
01607 {
01608 job = it.key();
01609 if ( joburl( job ).url(-1) == url && job != not_job )
01610 return job;
01611 ++it;
01612 }
01613 return 0;
01614 }
01615
01616 const KURL& KDirListerCache::joburl( KIO::ListJob *job )
01617 {
01618 if ( job->redirectionURL().isValid() )
01619 return job->redirectionURL();
01620 else
01621 return job->url();
01622 }
01623
01624 void KDirListerCache::killJob( KIO::ListJob *job )
01625 {
01626 jobs.remove( job );
01627 job->disconnect( this );
01628 job->kill();
01629 }
01630
01631 void KDirListerCache::deleteUnmarkedItems( QPtrList<KDirLister> *listers, KFileItemList *lstItems )
01632 {
01633
01634 KFileItem* item;
01635 lstItems->first();
01636 while ( (item = lstItems->current()) )
01637 if ( !item->isMarked() )
01638 {
01639
01640 for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
01641 kdl->emitDeleteItem( item );
01642
01643 if ( item->isDir() )
01644 deleteDir( item->url() );
01645
01646
01647 lstItems->take();
01648 delete item;
01649 }
01650 else
01651 lstItems->next();
01652 }
01653
01654 void KDirListerCache::deleteDir( const KURL& dirUrl )
01655 {
01656
01657
01658
01659
01660
01661 QDictIterator<DirItem> itu( itemsInUse );
01662 while ( itu.current() )
01663 {
01664 KURL deletedUrl( itu.currentKey() );
01665 if ( dirUrl.isParentOf( deletedUrl ) )
01666 {
01667
01668
01669 QPtrList<KDirLister> *kdls = urlsCurrentlyListed[deletedUrl.url()];
01670 if ( kdls )
01671 {
01672
01673 kdls = new QPtrList<KDirLister>( *kdls );
01674 for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() )
01675 stop( kdl, deletedUrl );
01676
01677 delete kdls;
01678 }
01679
01680
01681
01682
01683 kdls = urlsCurrentlyHeld[deletedUrl.url()];
01684 if ( kdls )
01685 {
01686
01687 kdls = new QPtrList<KDirLister>( *kdls );
01688
01689 for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() )
01690 {
01691
01692 if ( kdl->d->url == deletedUrl )
01693 {
01694
01695 if ( kdl->d->rootFileItem )
01696 emit kdl->deleteItem( kdl->d->rootFileItem );
01697 forgetDirs( kdl );
01698 kdl->d->rootFileItem = 0;
01699 }
01700 else
01701 {
01702 bool treeview = kdl->d->lstDirs.count() > 1;
01703 if ( !treeview )
01704 emit kdl->clear();
01705
01706 forgetDirs( kdl, deletedUrl, treeview );
01707 }
01708 }
01709
01710 delete kdls;
01711 }
01712
01713
01714
01715
01716 DirItem *dir = itemsInUse.take( deletedUrl.url() );
01717 Q_ASSERT( !dir );
01718 if ( !dir )
01719 ++itu;
01720 }
01721 else
01722 ++itu;
01723 }
01724
01725
01726 removeDirFromCache( dirUrl );
01727 }
01728
01729 void KDirListerCache::processPendingUpdates()
01730 {
01731
01732 }
01733
01734 #ifndef NDEBUG
01735 void KDirListerCache::printDebug()
01736 {
01737 kdDebug(7004) << "Items in use: " << endl;
01738 QDictIterator<DirItem> itu( itemsInUse );
01739 for ( ; itu.current() ; ++itu ) {
01740 kdDebug(7004) << " " << itu.currentKey() << " URL: " << itu.current()->url
01741 << " rootItem: " << ( itu.current()->rootItem ? itu.current()->rootItem->url() : KURL() )
01742 << " autoUpdates refcount: " << itu.current()->autoUpdates
01743 << " complete: " << itu.current()->complete
01744 << ( itu.current()->lstItems ? QString(" with %1 items.").arg(itu.current()->lstItems->count()) : QString(" lstItems=NULL") ) << endl;
01745 }
01746
01747 kdDebug(7004) << "urlsCurrentlyHeld: " << endl;
01748 QDictIterator< QPtrList<KDirLister> > it( urlsCurrentlyHeld );
01749 for ( ; it.current() ; ++it )
01750 {
01751 QString list;
01752 for ( QPtrListIterator<KDirLister> listit( *it.current() ); listit.current(); ++listit )
01753 list += " 0x" + QString::number( (long)listit.current(), 16 );
01754 kdDebug(7004) << " " << it.currentKey() << " " << it.current()->count() << " listers: " << list << endl;
01755 }
01756
01757 kdDebug(7004) << "urlsCurrentlyListed: " << endl;
01758 QDictIterator< QPtrList<KDirLister> > it2( urlsCurrentlyListed );
01759 for ( ; it2.current() ; ++it2 )
01760 {
01761 QString list;
01762 for ( QPtrListIterator<KDirLister> listit( *it2.current() ); listit.current(); ++listit )
01763 list += " 0x" + QString::number( (long)listit.current(), 16 );
01764 kdDebug(7004) << " " << it2.currentKey() << " " << it2.current()->count() << " listers: " << list << endl;
01765 }
01766
01767 QMap< KIO::ListJob *, QValueList<KIO::UDSEntry> >::Iterator jit = jobs.begin();
01768 kdDebug(7004) << "Jobs: " << endl;
01769 for ( ; jit != jobs.end() ; ++jit )
01770 kdDebug(7004) << " " << jit.key() << " listing " << joburl( jit.key() ).prettyURL() << ": " << (*jit).count() << " entries." << endl;
01771
01772 kdDebug(7004) << "Items in cache: " << endl;
01773 QCacheIterator<DirItem> itc( itemsCached );
01774 for ( ; itc.current() ; ++itc )
01775 kdDebug(7004) << " " << itc.currentKey() << " rootItem: "
01776 << ( itc.current()->rootItem ? itc.current()->rootItem->url().prettyURL() : QString("NULL") )
01777 << ( itc.current()->lstItems ? QString(" with %1 items.").arg(itc.current()->lstItems->count()) : QString(" lstItems=NULL") ) << endl;
01778 }
01779 #endif
01780
01781
01782
01783
01784 KDirLister::KDirLister( bool _delayedMimeTypes )
01785 {
01786 kdDebug(7003) << "+KDirLister" << endl;
01787
01788 d = new KDirListerPrivate;
01789
01790 d->complete = true;
01791 d->delayedMimeTypes = _delayedMimeTypes;
01792
01793 setAutoUpdate( true );
01794 setDirOnlyMode( false );
01795 setShowingDotFiles( false );
01796
01797 setAutoErrorHandlingEnabled( true, 0 );
01798 }
01799
01800 KDirLister::~KDirLister()
01801 {
01802 kdDebug(7003) << "-KDirLister" << endl;
01803
01804 if ( KDirListerCache::exists() )
01805 {
01806
01807 stop();
01808 s_pCache->forgetDirs( this );
01809 }
01810
01811 delete d;
01812 }
01813
01814 bool KDirLister::openURL( const KURL& _url, bool _keep, bool _reload )
01815 {
01816 if ( !validURL( _url ) )
01817 return false;
01818
01819 kdDebug(7003) << k_funcinfo << _url.prettyURL()
01820 << " keep=" << _keep << " reload=" << _reload << endl;
01821
01822
01823 if ( d->changes != NONE && _keep )
01824 emitChanges();
01825
01826 d->changes = NONE;
01827
01828 s_pCache->listDir( this, _url, _keep, _reload );
01829
01830 return true;
01831 }
01832
01833 void KDirLister::stop()
01834 {
01835 kdDebug(7003) << k_funcinfo << endl;
01836 s_pCache->stop( this );
01837 }
01838
01839 void KDirLister::stop( const KURL& _url )
01840 {
01841 kdDebug(7003) << k_funcinfo << _url.prettyURL() << endl;
01842 s_pCache->stop( this, _url );
01843 }
01844
01845 bool KDirLister::autoUpdate() const
01846 {
01847 return d->autoUpdate;
01848 }
01849
01850 void KDirLister::setAutoUpdate( bool _enable )
01851 {
01852 if ( d->autoUpdate == _enable )
01853 return;
01854
01855 d->autoUpdate = _enable;
01856 s_pCache->setAutoUpdate( this, _enable );
01857 }
01858
01859 bool KDirLister::showingDotFiles() const
01860 {
01861 return d->isShowingDotFiles;
01862 }
01863
01864 void KDirLister::setShowingDotFiles( bool _showDotFiles )
01865 {
01866 if ( d->isShowingDotFiles == _showDotFiles )
01867 return;
01868
01869 d->isShowingDotFiles = _showDotFiles;
01870 d->changes ^= DOT_FILES;
01871 }
01872
01873 bool KDirLister::dirOnlyMode() const
01874 {
01875 return d->dirOnlyMode;
01876 }
01877
01878 void KDirLister::setDirOnlyMode( bool _dirsOnly )
01879 {
01880 if ( d->dirOnlyMode == _dirsOnly )
01881 return;
01882
01883 d->dirOnlyMode = _dirsOnly;
01884 d->changes ^= DIR_ONLY_MODE;
01885 }
01886
01887 bool KDirLister::autoErrorHandlingEnabled() const
01888 {
01889 return d->autoErrorHandling;
01890 }
01891
01892 void KDirLister::setAutoErrorHandlingEnabled( bool enable, QWidget* parent )
01893 {
01894 d->autoErrorHandling = enable;
01895 d->errorParent = parent;
01896 }
01897
01898 const KURL& KDirLister::url() const
01899 {
01900 return d->url;
01901 }
01902
01903 const KURL::List& KDirLister::directories() const
01904 {
01905 return d->lstDirs;
01906 }
01907
01908 void KDirLister::emitChanges()
01909 {
01910 if ( d->changes == NONE )
01911 return;
01912
01913 static const QString& dot = KGlobal::staticQString(".");
01914 static const QString& dotdot = KGlobal::staticQString("..");
01915
01916 for ( KURL::List::Iterator it = d->lstDirs.begin();
01917 it != d->lstDirs.end(); ++it )
01918 {
01919 KFileItemListIterator kit( *s_pCache->itemsForDir( *it ) );
01920 for ( ; kit.current(); ++kit )
01921 {
01922 if ( (*kit)->text() == dot || (*kit)->text() == dotdot )
01923 continue;
01924
01925 bool oldMime = true, newMime = true;
01926
01927 if ( d->changes & MIME_FILTER )
01928 {
01929 oldMime = doMimeFilter( (*kit)->mimetype(), d->oldMimeFilter )
01930 && doMimeExcludeFilter( (*kit)->mimetype(), d->oldMimeExcludeFilter );
01931 newMime = doMimeFilter( (*kit)->mimetype(), d->mimeFilter )
01932 && doMimeExcludeFilter( (*kit)->mimetype(), d->mimeExcludeFilter );
01933
01934 if ( oldMime && !newMime )
01935 {
01936 emit deleteItem( *kit );
01937 continue;
01938 }
01939 }
01940
01941 if ( d->changes & DIR_ONLY_MODE )
01942 {
01943
01944 if ( d->dirOnlyMode )
01945 {
01946 if ( !(*kit)->isDir() )
01947 emit deleteItem( *kit );
01948 }
01949 else if ( !(*kit)->isDir() )
01950 addNewItem( *kit );
01951
01952 continue;
01953 }
01954
01955 if ( (*kit)->isHidden() )
01956 {
01957 if ( d->changes & DOT_FILES )
01958 {
01959
01960 if ( d->isShowingDotFiles )
01961 addNewItem( *kit );
01962 else
01963 emit deleteItem( *kit );
01964
01965 continue;
01966 }
01967 }
01968 else if ( d->changes & NAME_FILTER )
01969 {
01970 bool oldName = (*kit)->isDir() ||
01971 d->oldFilters.isEmpty() ||
01972 doNameFilter( (*kit)->text(), d->oldFilters );
01973
01974 bool newName = (*kit)->isDir() ||
01975 d->lstFilters.isEmpty() ||
01976 doNameFilter( (*kit)->text(), d->lstFilters );
01977
01978 if ( oldName && !newName )
01979 {
01980 emit deleteItem( *kit );
01981 continue;
01982 }
01983 else if ( !oldName && newName )
01984 addNewItem( *kit );
01985 }
01986
01987 if ( (d->changes & MIME_FILTER) && !oldMime && newMime )
01988 addNewItem( *kit );
01989 }
01990
01991 emitItems();
01992 }
01993
01994 d->changes = NONE;
01995 }
01996
01997 void KDirLister::updateDirectory( const KURL& _u )
01998 {
01999 s_pCache->updateDirectory( _u );
02000 }
02001
02002 bool KDirLister::isFinished() const
02003 {
02004 return d->complete;
02005 }
02006
02007 KFileItem *KDirLister::rootItem() const
02008 {
02009 return d->rootFileItem;
02010 }
02011
02012 KFileItem *KDirLister::findByURL( const KURL& _url ) const
02013 {
02014 return s_pCache->findByURL( this, _url );
02015 }
02016
02017 KFileItem *KDirLister::findByName( const QString& _name ) const
02018 {
02019 return s_pCache->findByName( this, _name );
02020 }
02021
02022 #ifndef KDE_NO_COMPAT
02023 KFileItem *KDirLister::find( const KURL& _url ) const
02024 {
02025 return findByURL( _url );
02026 }
02027 #endif
02028
02029
02030
02031
02032 void KDirLister::setNameFilter( const QString& nameFilter )
02033 {
02034 if ( !(d->changes & NAME_FILTER) )
02035 {
02036 d->oldFilters = d->lstFilters;
02037 d->lstFilters.setAutoDelete( false );
02038 }
02039
02040 d->lstFilters.clear();
02041 d->lstFilters.setAutoDelete( true );
02042
02043 d->nameFilter = nameFilter;
02044
02045
02046 QStringList list = QStringList::split( ' ', nameFilter );
02047 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
02048 d->lstFilters.append( new QRegExp(*it, false, true ) );
02049
02050 d->changes |= NAME_FILTER;
02051 }
02052
02053 const QString& KDirLister::nameFilter() const
02054 {
02055 return d->nameFilter;
02056 }
02057
02058 void KDirLister::setMimeFilter( const QStringList& mimeFilter )
02059 {
02060 if ( !(d->changes & MIME_FILTER) )
02061 d->oldMimeFilter = d->mimeFilter;
02062
02063 if ( mimeFilter.find("all/allfiles") != mimeFilter.end() ||
02064 mimeFilter.find("all/all") != mimeFilter.end() )
02065 d->mimeFilter.clear();
02066 else
02067 d->mimeFilter = mimeFilter;
02068
02069 d->changes |= MIME_FILTER;
02070 }
02071
02072 void KDirLister::setMimeExcludeFilter( const QStringList& mimeExcludeFilter )
02073 {
02074 if ( !(d->changes & MIME_FILTER) )
02075 d->oldMimeExcludeFilter = d->mimeExcludeFilter;
02076
02077 d->mimeExcludeFilter = mimeExcludeFilter;
02078 d->changes |= MIME_FILTER;
02079 }
02080
02081
02082 void KDirLister::clearMimeFilter()
02083 {
02084 if ( !(d->changes & MIME_FILTER) )
02085 {
02086 d->oldMimeFilter = d->mimeFilter;
02087 d->oldMimeExcludeFilter = d->mimeExcludeFilter;
02088 }
02089 d->mimeFilter.clear();
02090 d->mimeExcludeFilter.clear();
02091 d->changes |= MIME_FILTER;
02092 }
02093
02094 const QStringList& KDirLister::mimeFilters() const
02095 {
02096 return d->mimeFilter;
02097 }
02098
02099 bool KDirLister::matchesFilter( const QString& name ) const
02100 {
02101 return doNameFilter( name, d->lstFilters );
02102 }
02103
02104 bool KDirLister::matchesMimeFilter( const QString& mime ) const
02105 {
02106 return doMimeFilter( mime, d->mimeFilter ) && doMimeExcludeFilter(mime,d->mimeExcludeFilter);
02107 }
02108
02109
02110
02111 bool KDirLister::matchesFilter( const KFileItem *item ) const
02112 {
02113 Q_ASSERT( item );
02114 static const QString& dotdot = KGlobal::staticQString("..");
02115
02116 if ( item->text() == dotdot )
02117 return false;
02118
02119 if ( !d->isShowingDotFiles && item->isHidden() )
02120 return false;
02121
02122 if ( item->isDir() || d->lstFilters.isEmpty() )
02123 return true;
02124
02125 return matchesFilter( item->text() );
02126 }
02127
02128 bool KDirLister::matchesMimeFilter( const KFileItem *item ) const
02129 {
02130 Q_ASSERT( item );
02131
02132 if ( d->mimeFilter.isEmpty() && d->mimeExcludeFilter.isEmpty() )
02133 return true;
02134 return matchesMimeFilter( item->mimetype() );
02135 }
02136
02137 bool KDirLister::doNameFilter( const QString& name, const QPtrList<QRegExp>& filters ) const
02138 {
02139 for ( QPtrListIterator<QRegExp> it( filters ); it.current(); ++it )
02140 if ( it.current()->exactMatch( name ) )
02141 return true;
02142
02143 return false;
02144 }
02145
02146 bool KDirLister::doMimeFilter( const QString& mime, const QStringList& filters ) const
02147 {
02148 if ( filters.isEmpty() )
02149 return true;
02150
02151 KMimeType::Ptr mimeptr = KMimeType::mimeType(mime);
02152
02153 QStringList::ConstIterator it = filters.begin();
02154 for ( ; it != filters.end(); ++it )
02155 if ( mimeptr->is(*it) )
02156 return true;
02157
02158
02159
02160 return false;
02161 }
02162
02163 bool KDirLister::doMimeExcludeFilter( const QString& mime, const QStringList& filters ) const
02164 {
02165 if ( filters.isEmpty() )
02166 return true;
02167
02168 QStringList::ConstIterator it = filters.begin();
02169 for ( ; it != filters.end(); ++it )
02170 if ( (*it) == mime )
02171 return false;
02172
02173 return true;
02174 }
02175
02176
02177 bool KDirLister::validURL( const KURL& _url ) const
02178 {
02179 if ( !_url.isValid() )
02180 {
02181 if ( d->autoErrorHandling )
02182 {
02183 QString tmp = i18n("Malformed URL\n%1").arg( _url.prettyURL() );
02184 KMessageBox::error( d->errorParent, tmp );
02185 }
02186 return false;
02187 }
02188
02189
02190
02191 return true;
02192 }
02193
02194 void KDirLister::handleError( KIO::Job *job )
02195 {
02196 if ( d->autoErrorHandling )
02197 job->showErrorDialog( d->errorParent );
02198 }
02199
02200
02201
02202
02203 void KDirLister::addNewItem( const KFileItem *item )
02204 {
02205 if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) )
02206 return;
02207
02208 if ( matchesMimeFilter( item ) )
02209 {
02210 if ( !d->lstNewItems )
02211 d->lstNewItems = new KFileItemList;
02212
02213 d->lstNewItems->append( item );
02214 }
02215 else
02216 {
02217 if ( !d->lstMimeFilteredItems )
02218 d->lstMimeFilteredItems = new KFileItemList;
02219
02220 d->lstMimeFilteredItems->append( item );
02221 }
02222 }
02223
02224 void KDirLister::addNewItems( const KFileItemList& items )
02225 {
02226
02227
02228
02229
02230 for ( KFileItemListIterator kit( items ); kit.current(); ++kit )
02231 addNewItem( *kit );
02232 }
02233
02234 void KDirLister::aboutToRefreshItem( const KFileItem *item )
02235 {
02236
02237 if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) )
02238 d->refreshItemWasFiltered = true;
02239 else if ( !matchesMimeFilter( item ) )
02240 d->refreshItemWasFiltered = true;
02241 else
02242 d->refreshItemWasFiltered = false;
02243 }
02244
02245 void KDirLister::addRefreshItem( const KFileItem *item )
02246 {
02247 bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item );
02248
02249 if ( !isExcluded && matchesMimeFilter( item ) )
02250 {
02251 if ( d->refreshItemWasFiltered )
02252 {
02253 if ( !d->lstNewItems )
02254 d->lstNewItems = new KFileItemList;
02255
02256 d->lstNewItems->append( item );
02257 }
02258 else
02259 {
02260 if ( !d->lstRefreshItems )
02261 d->lstRefreshItems = new KFileItemList;
02262
02263 d->lstRefreshItems->append( item );
02264 }
02265 }
02266 else if ( !d->refreshItemWasFiltered )
02267 {
02268 if ( !d->lstRemoveItems )
02269 d->lstRemoveItems = new KFileItemList;
02270
02271
02272
02273 d->lstRemoveItems->append( item );
02274 }
02275 }
02276
02277 void KDirLister::emitItems()
02278 {
02279 KFileItemList *tmpNew = d->lstNewItems;
02280 d->lstNewItems = 0;
02281
02282 KFileItemList *tmpMime = d->lstMimeFilteredItems;
02283 d->lstMimeFilteredItems = 0;
02284
02285 KFileItemList *tmpRefresh = d->lstRefreshItems;
02286 d->lstRefreshItems = 0;
02287
02288 KFileItemList *tmpRemove = d->lstRemoveItems;
02289 d->lstRemoveItems = 0;
02290
02291 if ( tmpNew )
02292 {
02293 emit newItems( *tmpNew );
02294 delete tmpNew;
02295 }
02296
02297 if ( tmpMime )
02298 {
02299 emit itemsFilteredByMime( *tmpMime );
02300 delete tmpMime;
02301 }
02302
02303 if ( tmpRefresh )
02304 {
02305 emit refreshItems( *tmpRefresh );
02306 delete tmpRefresh;
02307 }
02308
02309 if ( tmpRemove )
02310 {
02311 for ( KFileItem *tmp = tmpRemove->first(); tmp; tmp = tmpRemove->next() )
02312 emit deleteItem( tmp );
02313 delete tmpRemove;
02314 }
02315 }
02316
02317 void KDirLister::emitDeleteItem( KFileItem *item )
02318 {
02319 if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) )
02320 return;
02321 if ( matchesMimeFilter( item ) )
02322 emit deleteItem( item );
02323 }
02324
02325
02326
02327
02328 void KDirLister::slotInfoMessage( KIO::Job *, const QString& message )
02329 {
02330 emit infoMessage( message );
02331 }
02332
02333 void KDirLister::slotPercent( KIO::Job *job, unsigned long pcnt )
02334 {
02335 d->jobData[static_cast<KIO::ListJob *>(job)].percent = pcnt;
02336
02337 int result = 0;
02338
02339 KIO::filesize_t size = 0;
02340
02341 QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02342 while ( dataIt != d->jobData.end() )
02343 {
02344 result += (*dataIt).percent * (*dataIt).totalSize;
02345 size += (*dataIt).totalSize;
02346 ++dataIt;
02347 }
02348
02349 if ( size != 0 )
02350 result /= size;
02351 else
02352 result = 100;
02353 emit percent( result );
02354 }
02355
02356 void KDirLister::slotTotalSize( KIO::Job *job, KIO::filesize_t size )
02357 {
02358 d->jobData[static_cast<KIO::ListJob *>(job)].totalSize = size;
02359
02360 KIO::filesize_t result = 0;
02361 QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02362 while ( dataIt != d->jobData.end() )
02363 {
02364 result += (*dataIt).totalSize;
02365 ++dataIt;
02366 }
02367
02368 emit totalSize( result );
02369 }
02370
02371 void KDirLister::slotProcessedSize( KIO::Job *job, KIO::filesize_t size )
02372 {
02373 d->jobData[static_cast<KIO::ListJob *>(job)].processedSize = size;
02374
02375 KIO::filesize_t result = 0;
02376 QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02377 while ( dataIt != d->jobData.end() )
02378 {
02379 result += (*dataIt).processedSize;
02380 ++dataIt;
02381 }
02382
02383 emit processedSize( result );
02384 }
02385
02386 void KDirLister::slotSpeed( KIO::Job *job, unsigned long spd )
02387 {
02388 d->jobData[static_cast<KIO::ListJob *>(job)].speed = spd;
02389
02390 int result = 0;
02391 QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02392 while ( dataIt != d->jobData.end() )
02393 {
02394 result += (*dataIt).speed;
02395 ++dataIt;
02396 }
02397
02398 emit speed( result );
02399 }
02400
02401 uint KDirLister::numJobs()
02402 {
02403 return d->jobData.count();
02404 }
02405
02406 void KDirLister::jobDone( KIO::ListJob *job )
02407 {
02408 d->jobData.remove( job );
02409 }
02410
02411 void KDirLister::jobStarted( KIO::ListJob *job )
02412 {
02413 KDirListerPrivate::JobData jobData;
02414 jobData.speed = 0;
02415 jobData.percent = 0;
02416 jobData.processedSize = 0;
02417 jobData.totalSize = 0;
02418
02419 d->jobData.insert( job, jobData );
02420 d->complete = false;
02421 }
02422
02423 void KDirLister::connectJob( KIO::ListJob *job )
02424 {
02425 connect( job, SIGNAL(infoMessage( KIO::Job *, const QString& )),
02426 this, SLOT(slotInfoMessage( KIO::Job *, const QString& )) );
02427 connect( job, SIGNAL(percent( KIO::Job *, unsigned long )),
02428 this, SLOT(slotPercent( KIO::Job *, unsigned long )) );
02429 connect( job, SIGNAL(totalSize( KIO::Job *, KIO::filesize_t )),
02430 this, SLOT(slotTotalSize( KIO::Job *, KIO::filesize_t )) );
02431 connect( job, SIGNAL(processedSize( KIO::Job *, KIO::filesize_t )),
02432 this, SLOT(slotProcessedSize( KIO::Job *, KIO::filesize_t )) );
02433 connect( job, SIGNAL(speed( KIO::Job *, unsigned long )),
02434 this, SLOT(slotSpeed( KIO::Job *, unsigned long )) );
02435 }
02436
02437 void KDirLister::setMainWindow( QWidget *window )
02438 {
02439 d->window = window;
02440 }
02441
02442 QWidget *KDirLister::mainWindow()
02443 {
02444 return d->window;
02445 }
02446
02447 KFileItemList KDirLister::items( WhichItems which ) const
02448 {
02449 return itemsForDir( url(), which );
02450 }
02451
02452 KFileItemList KDirLister::itemsForDir( const KURL& dir, WhichItems which ) const
02453 {
02454 KFileItemList result;
02455 KFileItemList *allItems = s_pCache->itemsForDir( dir );
02456 if ( !allItems )
02457 return result;
02458
02459 if ( which == AllItems )
02460 result = *allItems;
02461 else
02462 {
02463 for ( KFileItemListIterator kit( *allItems ); kit.current(); ++kit )
02464 {
02465 KFileItem *item = *kit;
02466 bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item );
02467 if ( !isExcluded && matchesMimeFilter( item ) )
02468 result.append( item );
02469 }
02470 }
02471
02472 return result;
02473 }
02474
02475
02476
02477 void KDirLister::virtual_hook( int, void * )
02478 { }
02479
02480 #include "kdirlister.moc"
02481 #include "kdirlister_p.moc"