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