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
01211
01212
for (
KDirLister *kdl = listers->
first(); kdl; kdl = listers->
next() )
01213 {
01214
if ( !kdl->
d->rootFileItem && kdl->
d->url == newUrl )
01215 kdl->
d->rootFileItem = newDir->rootItem;
01216
01217 kdl->
addNewItems( *(newDir->lstItems) );
01218 kdl->
emitItems();
01219 }
01220
01221
if ( holders )
01222 {
01223
for (
KDirLister *kdl = holders->
first(); kdl; kdl = holders->
next() )
01224 {
01225
if ( !kdl->
d->rootFileItem && kdl->
d->url == newUrl )
01226 kdl->
d->rootFileItem = newDir->rootItem;
01227
01228 kdl->
addNewItems( *(newDir->lstItems) );
01229 kdl->
emitItems();
01230 }
01231 }
01232 }
01233
else
01234 {
01235
kdDebug(7004) <<
"slotRedirection: " << newUrl.
url() <<
" has not been listed yet." <<
endl;
01236
01237
delete dir->rootItem;
01238 dir->rootItem = 0;
01239 dir->lstItems->clear();
01240 dir->redirect( newUrl );
01241 itemsInUse.insert( newUrl.
url(), dir );
01242 urlsCurrentlyListed.
insert( newUrl.
url(), listers );
01243
01244
if ( holders )
01245 urlsCurrentlyHeld.
insert( newUrl.
url(), holders );
01246
else
01247 {
01248
#ifdef DEBUG_CACHE
01249
printDebug();
01250
#endif
01251
return;
01252 }
01253 }
01254
01255
01256 job->
disconnect(
this );
01257
01258 connect( job, SIGNAL(entries(
KIO::Job *,
const KIO::UDSEntryList & )),
01259
this, SLOT(slotUpdateEntries(
KIO::Job *,
const KIO::UDSEntryList & )) );
01260 connect( job, SIGNAL(result(
KIO::Job * )),
01261
this, SLOT(slotUpdateResult(
KIO::Job * )) );
01262
01263
01264
01265
#ifdef DEBUG_CACHE
01266
printDebug();
01267
#endif
01268
}
01269
01270
void KDirListerCache::renameDir(
const KURL &oldUrl,
const KURL &newUrl )
01271 {
01272
kdDebug(7004) <<
k_funcinfo << oldUrl.
prettyURL() <<
" -> " << newUrl.
prettyURL() <<
endl;
01273
QString oldUrlStr = oldUrl.
url(-1);
01274
QString newUrlStr = newUrl.
url(-1);
01275
01276
01277
01278
01279
01280
01281
QDictIterator<DirItem> itu( itemsInUse );
01282
bool goNext;
01283
while ( itu.
current() )
01284 {
01285 goNext =
true;
01286 DirItem *dir = itu.
current();
01287
KURL oldDirUrl ( itu.
currentKey() );
01288
01289
01290
if ( oldUrl.
isParentOf( oldDirUrl ) )
01291 {
01292
01293
QString relPath = oldDirUrl.
path().
mid( oldUrl.
path().
length() );
01294
01295
KURL newDirUrl( newUrl );
01296
if ( !relPath.
isEmpty() )
01297 newDirUrl.
addPath( relPath );
01298
01299
01300
01301 dir->redirect( newDirUrl );
01302 itemsInUse.remove( itu.
currentKey() );
01303 itemsInUse.insert( newDirUrl.
url(-1), dir );
01304 goNext =
false;
01305
if ( dir->lstItems )
01306 {
01307
01308
KFileItemListIterator kit( *dir->lstItems );
01309
for ( ; kit.
current(); ++kit )
01310 {
01311
KURL oldItemUrl = (*kit)->url();
01312
QString oldItemUrlStr( oldItemUrl.
url(-1) );
01313
KURL newItemUrl( oldItemUrl );
01314 newItemUrl.
setPath( newDirUrl.
path() );
01315 newItemUrl.
addPath( oldItemUrl.
fileName() );
01316
kdDebug(7004) <<
"KDirListerCache::renameDir renaming " << oldItemUrlStr <<
" to " << newItemUrl.
url() <<
endl;
01317 (*kit)->setURL( newItemUrl );
01318 }
01319 }
01320 emitRedirections( oldDirUrl, newDirUrl );
01321 }
01322
if ( goNext )
01323 ++itu;
01324 }
01325
01326
01327
01328 removeDirFromCache( oldUrl );
01329
01330 }
01331
01332
void KDirListerCache::emitRedirections(
const KURL &oldUrl,
const KURL &url )
01333 {
01334
kdDebug(7004) <<
k_funcinfo << oldUrl.
prettyURL() <<
" -> " << url.
prettyURL() <<
endl;
01335
QString oldUrlStr = oldUrl.
url(-1);
01336
QString urlStr = url.
url(-1);
01337
01338
KIO::ListJob *job = jobForUrl( oldUrlStr );
01339
if ( job )
01340 killJob( job );
01341
01342
01343 QPtrList<KDirLister> *listers = urlsCurrentlyListed.
take( oldUrlStr );
01344
if ( listers )
01345 {
01346
01347
for (
KDirLister *kdl = listers->
first(); kdl; kdl = listers->
next() )
01348 {
01349
if ( job )
01350 kdl->
jobDone( job );
01351
01352 emit kdl->
canceled( oldUrl );
01353 }
01354
01355 urlsCurrentlyListed.
insert( urlStr, listers );
01356 }
01357
01358
01359
01360 QPtrList<KDirLister> *holders = urlsCurrentlyHeld.
take( oldUrlStr );
01361
if ( holders )
01362 {
01363
if ( job )
01364
for (
KDirLister *kdl = holders->
first(); kdl; kdl = holders->
next() )
01365 kdl->
jobDone( job );
01366
01367 urlsCurrentlyHeld.
insert( urlStr, holders );
01368 }
01369
01370
if ( listers )
01371 {
01372 updateDirectory( url );
01373
01374
01375
for (
KDirLister *kdl = listers->
first(); kdl; kdl = listers->
next() )
01376 emit kdl->
started( url );
01377 }
01378
01379
if ( holders )
01380 {
01381
01382
for (
KDirLister *kdl = holders->
first(); kdl; kdl = holders->
next() )
01383 {
01384 *kdl->
d->lstDirs.find( oldUrl ) = url;
01385
01386
if ( kdl->
d->lstDirs.count() == 1 )
01387 emit kdl->
redirection( url );
01388
01389 emit kdl->
redirection( oldUrl, url );
01390 }
01391 }
01392 }
01393
01394
void KDirListerCache::removeDirFromCache(
const KURL& dir )
01395 {
01396
kdDebug(7004) <<
"KDirListerCache::removeDirFromCache " << dir.
prettyURL() <<
endl;
01397
QCacheIterator<DirItem> itc( itemsCached );
01398
while ( itc.
current() )
01399 {
01400
if ( dir.
isParentOf(
KURL( itc.
currentKey() ) ) )
01401 itemsCached.remove( itc.
currentKey() );
01402
else
01403 ++itc;
01404 }
01405 }
01406
01407
void KDirListerCache::slotUpdateEntries(
KIO::Job* job,
const KIO::UDSEntryList& list )
01408 {
01409 jobs[static_cast<KIO::ListJob*>(job)] += list;
01410 }
01411
01412
void KDirListerCache::slotUpdateResult(
KIO::Job * j )
01413 {
01414 Q_ASSERT( j );
01415
KIO::ListJob *job = static_cast<KIO::ListJob *>( j );
01416
01417
KURL jobUrl = joburl( job );
01418 jobUrl.
adjustPath(-1);
01419
QString jobUrlStr = jobUrl.
url();
01420
01421
kdDebug(7004) <<
k_funcinfo <<
"finished update " << jobUrl <<
endl;
01422
01423
KDirLister *kdl;
01424
01425 QPtrList<KDirLister> *listers = urlsCurrentlyHeld[jobUrlStr];
01426 QPtrList<KDirLister> *tmpLst = urlsCurrentlyListed.
take( jobUrlStr );
01427
01428
if ( tmpLst )
01429 {
01430
if ( listers )
01431
for ( kdl = tmpLst->
first(); kdl; kdl = tmpLst->
next() )
01432 {
01433 Q_ASSERT( listers->
containsRef( kdl ) == 0 );
01434 listers->
append( kdl );
01435 }
01436
else
01437 {
01438 listers = tmpLst;
01439 urlsCurrentlyHeld.
insert( jobUrlStr, listers );
01440 }
01441 }
01442
01443
01444 Q_ASSERT( listers );
01445
01446
if ( job->
error() )
01447 {
01448
for ( kdl = listers->
first(); kdl; kdl = listers->
next() )
01449 {
01450 kdl->
jobDone( job );
01451
01452
01453
01454
01455 emit kdl->
canceled( jobUrl );
01456
if ( kdl->
numJobs() == 0 )
01457 {
01458 kdl->
d->complete =
true;
01459 emit kdl->
canceled();
01460 }
01461 }
01462
01463 jobs.remove( job );
01464
01465
01466
01467 processPendingUpdates();
01468
return;
01469 }
01470
01471 DirItem *dir = itemsInUse[jobUrlStr];
01472 dir->complete =
true;
01473
01474
01475
01476
bool delayedMimeTypes =
true;
01477
for ( kdl = listers->
first(); kdl; kdl = listers->
next() )
01478 delayedMimeTypes &= kdl->
d->delayedMimeTypes;
01479
01480
01481
QDict<KFileItem> fileItems( 9973 );
01482
01483
KFileItemListIterator kit ( *(dir->lstItems) );
01484
01485
01486
for ( ; kit.
current(); ++kit )
01487 {
01488 (*kit)->unmark();
01489 fileItems.
insert( (*kit)->url().url(), *kit );
01490 }
01491
01492
static const QString& dot =
KGlobal::staticQString(
".");
01493
static const QString& dotdot =
KGlobal::staticQString(
"..");
01494
01495
KFileItem *item = 0, *tmp;
01496
01497
QValueList<KIO::UDSEntry> buf = jobs[job];
01498
QValueListIterator<KIO::UDSEntry> it = buf.
begin();
01499
for ( ; it != buf.
end(); ++it )
01500 {
01501
01502
if ( !item )
01503 item =
new KFileItem( *it, jobUrl, delayedMimeTypes,
true );
01504
else
01505 item->
setUDSEntry( *it, jobUrl, delayedMimeTypes,
true );
01506
01507
01508
QString name = item->
name();
01509 Q_ASSERT( !
name.
isEmpty() );
01510
01511
01512
01513
if (
name.
isEmpty() ||
name == dotdot )
01514
continue;
01515
01516
if (
name == dot )
01517 {
01518
01519
01520
if ( !dir->rootItem )
01521 {
01522 dir->rootItem = item;
01523 item = 0;
01524
01525
for (
KDirLister *kdl = listers->
first(); kdl; kdl = listers->
next() )
01526
if ( !kdl->
d->rootFileItem && kdl->
d->url == jobUrl )
01527 kdl->
d->rootFileItem = dir->rootItem;
01528 }
01529
01530
continue;
01531 }
01532
01533
01534
if ( (tmp = fileItems[item->
url().
url()]) )
01535 {
01536 tmp->
mark();
01537
01538
01539
if ( !tmp->
cmp( *item ) )
01540 {
01541
for ( kdl = listers->
first(); kdl; kdl = listers->
next() )
01542 kdl->
aboutToRefreshItem( tmp );
01543
01544
01545 tmp->
assign( *item );
01546
01547
for ( kdl = listers->
first(); kdl; kdl = listers->
next() )
01548 kdl->
addRefreshItem( tmp );
01549 }
01550 }
01551
else
01552 {
01553
01554
01555 item->
mark();
01556 dir->lstItems->append( item );
01557
01558
for ( kdl = listers->
first(); kdl; kdl = listers->
next() )
01559 kdl->
addNewItem( item );
01560
01561
01562 item = 0;
01563 }
01564 }
01565
01566
if ( item )
01567
delete item;
01568
01569 jobs.
remove( job );
01570
01571 deleteUnmarkedItems( listers, dir->lstItems );
01572
01573
for ( kdl = listers->
first(); kdl; kdl = listers->
next() )
01574 {
01575 kdl->
emitItems();
01576
01577 kdl->
jobDone( job );
01578
01579 emit kdl->
completed( jobUrl );
01580
if ( kdl->
numJobs() == 0 )
01581 {
01582 kdl->
d->complete =
true;
01583 emit kdl->
completed();
01584 }
01585 }
01586
01587
01588
01589 processPendingUpdates();
01590 }
01591
01592
01593
01594
KIO::ListJob *KDirListerCache::jobForUrl(
const QString& url,
KIO::ListJob *not_job )
01595 {
01596
KIO::ListJob *job;
01597
QMap< KIO::ListJob *, QValueList<KIO::UDSEntry> >::Iterator it = jobs.begin();
01598
while ( it != jobs.
end() )
01599 {
01600 job = it.key();
01601
if ( joburl( job ).
url(-1) == url && job != not_job )
01602
return job;
01603 ++it;
01604 }
01605
return 0;
01606 }
01607
01608
const KURL& KDirListerCache::joburl(
KIO::ListJob *job )
01609 {
01610
if ( job->
redirectionURL().
isValid() )
01611
return job->
redirectionURL();
01612
else
01613
return job->
url();
01614 }
01615
01616
void KDirListerCache::killJob(
KIO::ListJob *job )
01617 {
01618 jobs.remove( job );
01619 job->
disconnect(
this );
01620 job->
kill();
01621 }
01622
01623
void KDirListerCache::deleteUnmarkedItems( QPtrList<KDirLister> *listers,
KFileItemList *lstItems )
01624 {
01625
01626
KFileItem* item;
01627 lstItems->
first();
01628
while ( (item = lstItems->
current()) )
01629
if ( !item->
isMarked() )
01630 {
01631
01632
for (
KDirLister *kdl = listers->
first(); kdl; kdl = listers->
next() )
01633 kdl->
emitDeleteItem( item );
01634
01635
if ( item->
isDir() )
01636 deleteDir( item->
url() );
01637
01638
01639 lstItems->
take();
01640
delete item;
01641 }
01642
else
01643 lstItems->
next();
01644 }
01645
01646
void KDirListerCache::deleteDir(
const KURL& dirUrl )
01647 {
01648
01649
01650
01651
01652
01653
QDictIterator<DirItem> itu( itemsInUse );
01654
while ( itu.
current() )
01655 {
01656
KURL deletedUrl( itu.
currentKey() );
01657
if ( dirUrl.
isParentOf( deletedUrl ) )
01658 {
01659
01660
01661 QPtrList<KDirLister> *kdls = urlsCurrentlyListed[deletedUrl.
url()];
01662
if ( kdls )
01663 {
01664
01665 kdls =
new QPtrList<KDirLister>( *kdls );
01666
for (
KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() )
01667 stop( kdl, deletedUrl );
01668
01669
delete kdls;
01670 }
01671
01672
01673
01674
01675 kdls = urlsCurrentlyHeld[deletedUrl.
url()];
01676
if ( kdls )
01677 {
01678
01679 kdls =
new QPtrList<KDirLister>( *kdls );
01680
01681
for (
KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() )
01682 {
01683
01684
if ( kdl->
d->url == deletedUrl )
01685 {
01686
01687
if ( kdl->
d->rootFileItem )
01688 emit kdl->
deleteItem( kdl->
d->rootFileItem );
01689 forgetDirs( kdl );
01690 kdl->
d->rootFileItem = 0;
01691 }
01692
else
01693 {
01694
bool treeview = kdl->
d->lstDirs.count() > 1;
01695
if ( !treeview )
01696 {
01697 emit kdl->
clear();
01698 kdl->
d->lstDirs.clear();
01699 }
01700
else
01701 kdl->
d->lstDirs.remove( kdl->
d->lstDirs.find( deletedUrl ) );
01702
01703 forgetDirs( kdl, deletedUrl, treeview );
01704 }
01705 }
01706
01707
delete kdls;
01708 }
01709
01710
01711
01712
01713 DirItem *dir = itemsInUse.take( deletedUrl.
url() );
01714 Q_ASSERT( !dir );
01715
if ( !dir )
01716 ++itu;
01717 }
01718
else
01719 ++itu;
01720 }
01721
01722
01723 removeDirFromCache( dirUrl );
01724 }
01725
01726
void KDirListerCache::processPendingUpdates()
01727 {
01728
01729 }
01730
01731
#ifndef NDEBUG
01732
void KDirListerCache::printDebug()
01733 {
01734
kdDebug(7004) <<
"Items in use: " <<
endl;
01735
QDictIterator<DirItem> itu( itemsInUse );
01736
for ( ; itu.
current() ; ++itu ) {
01737
kdDebug(7004) <<
" " << itu.
currentKey() <<
" URL: " << itu.
current()->url
01738 <<
" rootItem: " << ( itu.
current()->rootItem ? itu.
current()->rootItem->url() :
KURL() )
01739 << " autoUpdates refcount: " << itu.current()->autoUpdates
01740 << " complete: " << itu.current()->complete
01741 << ( itu.current()->lstItems ?
QString(" with %1 items.").arg(itu.current()->lstItems->count()) :
QString(" lstItems=NULL") ) <<
endl;
01742 }
01743
01744
kdDebug(7004) <<
"urlsCurrentlyHeld: " <<
endl;
01745
QDictIterator< QPtrList<KDirLister> > it( urlsCurrentlyHeld );
01746
for ( ; it.
current() ; ++it )
01747 {
01748
QString list;
01749
for (
QPtrListIterator<KDirLister> listit( *it.
current() ); listit.
current(); ++listit )
01750 list +=
" 0x" +
QString::number( (
long)listit.
current(), 16 );
01751
kdDebug(7004) <<
" " << it.
currentKey() <<
" " << it.
current()->count() <<
" listers: " << list <<
endl;
01752 }
01753
01754
kdDebug(7004) <<
"urlsCurrentlyListed: " <<
endl;
01755
QDictIterator< QPtrList<KDirLister> > it2( urlsCurrentlyListed );
01756
for ( ; it2.
current() ; ++it2 )
01757 {
01758
QString list;
01759
for (
QPtrListIterator<KDirLister> listit( *it2.
current() ); listit.
current(); ++listit )
01760 list +=
" 0x" +
QString::number( (
long)listit.
current(), 16 );
01761
kdDebug(7004) <<
" " << it2.
currentKey() <<
" " << it2.
current()->count() <<
" listers: " << list <<
endl;
01762 }
01763
01764
QMap< KIO::ListJob *, QValueList<KIO::UDSEntry> >::Iterator jit = jobs.begin();
01765
kdDebug(7004) <<
"Jobs: " <<
endl;
01766
for ( ; jit != jobs.
end() ; ++jit )
01767
kdDebug(7004) <<
" " << jit.key() <<
" listing " << joburl( jit.key() ).
prettyURL() <<
": " << (*jit).count() <<
" entries." <<
endl;
01768
01769
kdDebug(7004) <<
"Items in cache: " <<
endl;
01770
QCacheIterator<DirItem> itc( itemsCached );
01771
for ( ; itc.
current() ; ++itc )
01772
kdDebug(7004) <<
" " << itc.
currentKey() <<
" rootItem: "
01773 << ( itc.
current()->rootItem ? itc.
current()->rootItem->url().prettyURL() :
QString("NULL") )
01774 << ( itc.current()->lstItems ?
QString(" with %1 items.").arg(itc.current()->lstItems->count()) :
QString(" lstItems=NULL") ) <<
endl;
01775 }
01776
#endif
01777
01778
01779
01780
01781 KDirLister::KDirLister(
bool _delayedMimeTypes )
01782 {
01783
kdDebug(7003) <<
"+KDirLister" <<
endl;
01784
01785 d =
new KDirListerPrivate;
01786
01787 d->complete =
true;
01788 d->delayedMimeTypes = _delayedMimeTypes;
01789
01790
setAutoUpdate(
true );
01791
setDirOnlyMode(
false );
01792
setShowingDotFiles(
false );
01793
01794
setAutoErrorHandlingEnabled(
true, 0 );
01795 }
01796
01797 KDirLister::~KDirLister()
01798 {
01799
kdDebug(7003) <<
"-KDirLister" <<
endl;
01800
01801
01802
stop();
01803 s_pCache->forgetDirs(
this );
01804
01805
delete d;
01806 }
01807
01808 bool KDirLister::openURL(
const KURL& _url,
bool _keep,
bool _reload )
01809 {
01810
if ( !
validURL( _url ) )
01811
return false;
01812
01813
kdDebug(7003) <<
k_funcinfo << _url.
prettyURL()
01814 <<
" keep=" << _keep <<
" reload=" << _reload <<
endl;
01815
01816
01817
if ( d->changes != NONE && _keep )
01818
emitChanges();
01819
01820 d->changes = NONE;
01821
01822 s_pCache->listDir(
this, _url, _keep, _reload );
01823
01824
return true;
01825 }
01826
01827 void KDirLister::stop()
01828 {
01829
kdDebug(7003) <<
k_funcinfo <<
endl;
01830 s_pCache->stop(
this );
01831 }
01832
01833 void KDirLister::stop(
const KURL& _url )
01834 {
01835
kdDebug(7003) <<
k_funcinfo << _url.
prettyURL() <<
endl;
01836 s_pCache->stop(
this, _url );
01837 }
01838
01839
bool KDirLister::autoUpdate()
const
01840
{
01841
return d->autoUpdate;
01842 }
01843
01844 void KDirLister::setAutoUpdate(
bool _enable )
01845 {
01846
if ( d->autoUpdate == _enable )
01847
return;
01848
01849 d->autoUpdate = _enable;
01850 s_pCache->setAutoUpdate(
this, _enable );
01851 }
01852
01853
bool KDirLister::showingDotFiles()
const
01854
{
01855
return d->isShowingDotFiles;
01856 }
01857
01858 void KDirLister::setShowingDotFiles(
bool _showDotFiles )
01859 {
01860
if ( d->isShowingDotFiles == _showDotFiles )
01861
return;
01862
01863 d->isShowingDotFiles = _showDotFiles;
01864 d->changes ^= DOT_FILES;
01865 }
01866
01867
bool KDirLister::dirOnlyMode()
const
01868
{
01869
return d->dirOnlyMode;
01870 }
01871
01872 void KDirLister::setDirOnlyMode(
bool _dirsOnly )
01873 {
01874
if ( d->dirOnlyMode == _dirsOnly )
01875
return;
01876
01877 d->dirOnlyMode = _dirsOnly;
01878 d->changes ^= DIR_ONLY_MODE;
01879 }
01880
01881
bool KDirLister::autoErrorHandlingEnabled()
const
01882
{
01883
return d->autoErrorHandling;
01884 }
01885
01886 void KDirLister::setAutoErrorHandlingEnabled(
bool enable,
QWidget* parent )
01887 {
01888 d->autoErrorHandling = enable;
01889 d->errorParent = parent;
01890 }
01891
01892 const KURL&
KDirLister::url()
const
01893
{
01894
return d->url;
01895 }
01896
01897 const KURL::List&
KDirLister::directories()
const
01898
{
01899
return d->lstDirs;
01900 }
01901
01902 void KDirLister::emitChanges()
01903 {
01904
if ( d->changes == NONE )
01905
return;
01906
01907
static const QString& dot = KGlobal::staticQString(
".");
01908
static const QString& dotdot = KGlobal::staticQString(
"..");
01909
01910
for ( KURL::List::Iterator it = d->lstDirs.begin();
01911 it != d->lstDirs.end(); ++it )
01912 {
01913
KFileItemListIterator kit( *s_pCache->itemsForDir( *it ) );
01914
for ( ; kit.
current(); ++kit )
01915 {
01916
if ( (*kit)->text() == dot || (*kit)->text() == dotdot )
01917
continue;
01918
01919
bool oldMime =
true, newMime =
true;
01920
01921
if ( d->changes & MIME_FILTER )
01922 {
01923 oldMime =
doMimeFilter( (*kit)->mimetype(), d->oldMimeFilter )
01924 && doMimeExcludeFilter( (*kit)->mimetype(), d->oldMimeExcludeFilter );
01925 newMime = doMimeFilter( (*kit)->mimetype(), d->mimeFilter )
01926 && doMimeExcludeFilter( (*kit)->mimetype(), d->mimeExcludeFilter );
01927
01928
if ( oldMime && !newMime )
01929 {
01930 emit
deleteItem( *kit );
01931
continue;
01932 }
01933 }
01934
01935
if ( d->changes & DIR_ONLY_MODE )
01936 {
01937
01938
if ( d->dirOnlyMode )
01939 {
01940
if ( !(*kit)->isDir() )
01941 emit
deleteItem( *kit );
01942 }
01943
else if ( !(*kit)->isDir() )
01944 addNewItem( *kit );
01945
01946
continue;
01947 }
01948
01949
if ( (*kit)->isHidden() )
01950 {
01951
if ( d->changes & DOT_FILES )
01952 {
01953
01954
if ( d->isShowingDotFiles )
01955 addNewItem( *kit );
01956
else
01957 emit
deleteItem( *kit );
01958
01959
continue;
01960 }
01961 }
01962
else if ( d->changes & NAME_FILTER )
01963 {
01964
bool oldName = (*kit)->isDir() ||
01965 d->oldFilters.isEmpty() ||
01966
doNameFilter( (*kit)->text(), d->oldFilters );
01967
01968
bool newName = (*kit)->isDir() ||
01969 d->lstFilters.isEmpty() ||
01970
doNameFilter( (*kit)->text(), d->lstFilters );
01971
01972
if ( oldName && !newName )
01973 {
01974 emit
deleteItem( *kit );
01975
continue;
01976 }
01977
else if ( !oldName && newName )
01978 addNewItem( *kit );
01979 }
01980
01981
if ( (d->changes & MIME_FILTER) && !oldMime && newMime )
01982 addNewItem( *kit );
01983 }
01984
01985 emitItems();
01986 }
01987
01988 d->changes = NONE;
01989 }
01990
01991 void KDirLister::updateDirectory(
const KURL& _u )
01992 {
01993 s_pCache->updateDirectory( _u );
01994 }
01995
01996 bool KDirLister::isFinished()
const
01997
{
01998
return d->complete;
01999 }
02000
02001 KFileItem *
KDirLister::rootItem()
const
02002
{
02003
return d->rootFileItem;
02004 }
02005
02006 KFileItem *
KDirLister::findByURL(
const KURL& _url )
const
02007
{
02008
return s_pCache->findByURL(
this, _url );
02009 }
02010
02011 KFileItem *
KDirLister::findByName(
const QString& _name )
const
02012
{
02013
return s_pCache->findByName(
this, _name );
02014 }
02015
02016
#ifndef KDE_NO_COMPAT
02017
KFileItem *KDirLister::find(
const KURL& _url )
const
02018
{
02019
return findByURL( _url );
02020 }
02021
#endif
02022
02023
02024
02025
02026 void KDirLister::setNameFilter(
const QString& nameFilter )
02027 {
02028
if ( !(d->changes & NAME_FILTER) )
02029 {
02030 d->oldFilters = d->lstFilters;
02031 d->lstFilters.setAutoDelete(
false );
02032 }
02033
02034 d->lstFilters.clear();
02035 d->lstFilters.setAutoDelete(
true );
02036
02037 d->nameFilter = nameFilter;
02038
02039
02040
QStringList list = QStringList::split(
' ', nameFilter );
02041
for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
02042 d->lstFilters.append(
new QRegExp(*it,
false,
true ) );
02043
02044 d->changes |= NAME_FILTER;
02045 }
02046
02047
const QString&
KDirLister::nameFilter()
const
02048
{
02049
return d->nameFilter;
02050 }
02051
02052 void KDirLister::setMimeFilter(
const QStringList& mimeFilter )
02053 {
02054
if ( !(d->changes & MIME_FILTER) )
02055 d->oldMimeFilter = d->mimeFilter;
02056
02057
if ( mimeFilter.find(
"all/allfiles") != mimeFilter.end() ||
02058 mimeFilter.find(
"all/all") != mimeFilter.end() )
02059 d->mimeFilter.clear();
02060
else
02061 d->mimeFilter = mimeFilter;
02062
02063 d->changes |= MIME_FILTER;
02064 }
02065
02066 void KDirLister::setMimeExcludeFilter(
const QStringList& mimeExcludeFilter )
02067 {
02068
if ( !(d->changes & MIME_FILTER) )
02069 d->oldMimeExcludeFilter = d->mimeExcludeFilter;
02070
02071 d->mimeExcludeFilter = mimeExcludeFilter;
02072 d->changes |= MIME_FILTER;
02073 }
02074
02075
02076 void KDirLister::clearMimeFilter()
02077 {
02078
if ( !(d->changes & MIME_FILTER) )
02079 {
02080 d->oldMimeFilter = d->mimeFilter;
02081 d->oldMimeExcludeFilter = d->mimeExcludeFilter;
02082 }
02083 d->mimeFilter.clear();
02084 d->mimeExcludeFilter.clear();
02085 d->changes |= MIME_FILTER;
02086 }
02087
02088 const QStringList&
KDirLister::mimeFilters()
const
02089
{
02090
return d->mimeFilter;
02091 }
02092
02093 bool KDirLister::matchesFilter(
const QString& name )
const
02094
{
02095
return doNameFilter( name, d->lstFilters );
02096 }
02097
02098 bool KDirLister::matchesMimeFilter(
const QString& mime )
const
02099
{
02100
return doMimeFilter( mime, d->mimeFilter ) && doMimeExcludeFilter(mime,d->mimeExcludeFilter);
02101 }
02102
02103
02104
02105 bool KDirLister::matchesFilter(
const KFileItem *item )
const
02106
{
02107 Q_ASSERT( item );
02108
static const QString& dotdot = KGlobal::staticQString(
"..");
02109
02110
if ( item->
text() == dotdot )
02111
return false;
02112
02113
if ( !d->isShowingDotFiles && item->
text()[0] ==
'.' )
02114
return false;
02115
02116
if ( item->
isDir() || d->lstFilters.isEmpty() )
02117
return true;
02118
02119
return matchesFilter( item->
text() );
02120 }
02121
02122 bool KDirLister::matchesMimeFilter(
const KFileItem *item )
const
02123
{
02124 Q_ASSERT( item );
02125
02126
if ( d->mimeFilter.isEmpty() && d->mimeExcludeFilter.isEmpty() )
02127
return true;
02128
return matchesMimeFilter( item->
mimetype() );
02129 }
02130
02131 bool KDirLister::doNameFilter(
const QString& name,
const QPtrList<QRegExp>& filters )
const
02132
{
02133
for (
QPtrListIterator<QRegExp> it( filters ); it.
current(); ++it )
02134
if ( it.
current()->exactMatch( name ) )
02135
return true;
02136
02137
return false;
02138 }
02139
02140 bool KDirLister::doMimeFilter(
const QString& mime,
const QStringList& filters )
const
02141
{
02142
if ( filters.isEmpty() )
02143
return true;
02144
02145
KMimeType::Ptr mimeptr = KMimeType::mimeType(mime);
02146
02147 QStringList::ConstIterator it = filters.begin();
02148
for ( ; it != filters.end(); ++it )
02149
if ( mimeptr->is(*it) )
02150
return true;
02151
02152
02153
02154
return false;
02155 }
02156
02157
bool KDirLister::doMimeExcludeFilter(
const QString& mime,
const QStringList& filters )
const
02158
{
02159
if ( filters.isEmpty() )
02160
return true;
02161
02162 QStringList::ConstIterator it = filters.begin();
02163
for ( ; it != filters.end(); ++it )
02164
if ( (*it) == mime )
02165
return false;
02166
02167
return true;
02168 }
02169
02170
02171 bool KDirLister::validURL(
const KURL& _url )
const
02172
{
02173
if ( !_url.
isValid() )
02174 {
02175
if ( d->autoErrorHandling )
02176 {
02177
QString tmp = i18n(
"Malformed URL\n%1").arg( _url.
prettyURL() );
02178 KMessageBox::error( d->errorParent, tmp );
02179 }
02180
return false;
02181 }
02182
02183
02184
02185
return true;
02186 }
02187
02188 void KDirLister::handleError(
KIO::Job *job )
02189 {
02190
if ( d->autoErrorHandling )
02191 job->
showErrorDialog( d->errorParent );
02192 }
02193
02194
02195
02196
02197
void KDirLister::addNewItem(
const KFileItem *item )
02198 {
02199
bool isNameFilterMatch = (d->dirOnlyMode && !item->
isDir()) || !matchesFilter( item );
02200
02201
if ( isNameFilterMatch )
02202
return;
02203
02204
bool isMimeFilterMatch = !matchesMimeFilter( item );
02205
02206
if ( !isNameFilterMatch && !isMimeFilterMatch )
02207 {
02208
if ( !d->lstNewItems )
02209 d->lstNewItems =
new KFileItemList;
02210
02211 d->lstNewItems->append( item );
02212 }
02213
else
02214 {
02215
if ( !d->lstMimeFilteredItems )
02216 d->lstMimeFilteredItems =
new KFileItemList;
02217
02218 d->lstMimeFilteredItems->append( item );
02219 }
02220 }
02221
02222
void KDirLister::addNewItems(
const KFileItemList& items )
02223 {
02224
02225
for (
KFileItemListIterator kit( items ); kit.
current(); ++kit )
02226 addNewItem( *kit );
02227 }
02228
02229
void KDirLister::aboutToRefreshItem(
const KFileItem *item )
02230 {
02231
bool isNameFilterMatch = (d->dirOnlyMode && !item->
isDir()) || !
matchesFilter( item );
02232
bool isMimeFilterMatch = !
matchesMimeFilter( item );
02233
02234
if ( !isNameFilterMatch && !isMimeFilterMatch )
02235 d->refreshItemWasFiltered =
false;
02236
else
02237 d->refreshItemWasFiltered =
true;
02238 }
02239
02240
void KDirLister::addRefreshItem(
const KFileItem *item )
02241 {
02242
bool isNameFilterMatch = (d->dirOnlyMode && !item->
isDir()) || !
matchesFilter( item );
02243
bool isMimeFilterMatch = !
matchesMimeFilter( item );
02244
02245
if ( !isNameFilterMatch && !isMimeFilterMatch )
02246 {
02247
if ( d->refreshItemWasFiltered )
02248 {
02249
if ( !d->lstNewItems )
02250 d->lstNewItems =
new KFileItemList;
02251
02252 d->lstNewItems->append( item );
02253 }
02254
else
02255 {
02256
if ( !d->lstRefreshItems )
02257 d->lstRefreshItems =
new KFileItemList;
02258
02259 d->lstRefreshItems->append( item );
02260 }
02261 }
02262
else if ( !d->refreshItemWasFiltered )
02263 {
02264
if ( !d->lstRemoveItems )
02265 d->lstRemoveItems =
new KFileItemList;
02266
02267
02268
02269 d->lstRemoveItems->append( item );
02270 }
02271 }
02272
02273
void KDirLister::emitItems()
02274 {
02275
KFileItemList *tmpNew = d->lstNewItems;
02276 d->lstNewItems = 0;
02277
02278
KFileItemList *tmpMime = d->lstMimeFilteredItems;
02279 d->lstMimeFilteredItems = 0;
02280
02281
KFileItemList *tmpRefresh = d->lstRefreshItems;
02282 d->lstRefreshItems = 0;
02283
02284
KFileItemList *tmpRemove = d->lstRemoveItems;
02285 d->lstRemoveItems = 0;
02286
02287
if ( tmpNew )
02288 {
02289 emit
newItems( *tmpNew );
02290
delete tmpNew;
02291 }
02292
02293
if ( tmpMime )
02294 {
02295 emit
itemsFilteredByMime( *tmpMime );
02296
delete tmpMime;
02297 }
02298
02299
if ( tmpRefresh )
02300 {
02301 emit
refreshItems( *tmpRefresh );
02302
delete tmpRefresh;
02303 }
02304
02305
if ( tmpRemove )
02306 {
02307
for (
KFileItem *tmp = tmpRemove->
first(); tmp; tmp = tmpRemove->
next() )
02308 emit
deleteItem( tmp );
02309
delete tmpRemove;
02310 }
02311 }
02312
02313
void KDirLister::emitDeleteItem(
KFileItem *item )
02314 {
02315
bool isNameFilterMatch = (d->dirOnlyMode && !item->
isDir()) || !
matchesFilter( item );
02316
bool isMimeFilterMatch = !
matchesMimeFilter( item );
02317
02318
if ( !isNameFilterMatch && !isMimeFilterMatch )
02319 emit
deleteItem( item );
02320 }
02321
02322
02323
02324
02325
void KDirLister::slotInfoMessage(
KIO::Job *,
const QString& message )
02326 {
02327 emit
infoMessage( message );
02328 }
02329
02330
void KDirLister::slotPercent(
KIO::Job *job,
unsigned long pcnt )
02331 {
02332 d->jobData[static_cast<KIO::ListJob *>(job)].percent = pcnt;
02333
02334
int result = 0;
02335
02336 KIO::filesize_t size = 0;
02337
02338
QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02339
while ( dataIt != d->jobData.end() )
02340 {
02341 result += (*dataIt).percent * (*dataIt).totalSize;
02342 size += (*dataIt).totalSize;
02343 ++dataIt;
02344 }
02345
02346
if ( size != 0 )
02347 result /= size;
02348
else
02349 result = 100;
02350 emit
percent( result );
02351 }
02352
02353
void KDirLister::slotTotalSize(
KIO::Job *job, KIO::filesize_t size )
02354 {
02355 d->jobData[static_cast<KIO::ListJob *>(job)].totalSize = size;
02356
02357 KIO::filesize_t result = 0;
02358
QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02359
while ( dataIt != d->jobData.end() )
02360 {
02361 result += (*dataIt).totalSize;
02362 ++dataIt;
02363 }
02364
02365 emit
totalSize( result );
02366 }
02367
02368
void KDirLister::slotProcessedSize(
KIO::Job *job, KIO::filesize_t size )
02369 {
02370 d->jobData[static_cast<KIO::ListJob *>(job)].processedSize = size;
02371
02372 KIO::filesize_t result = 0;
02373
QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02374
while ( dataIt != d->jobData.end() )
02375 {
02376 result += (*dataIt).processedSize;
02377 ++dataIt;
02378 }
02379
02380 emit
processedSize( result );
02381 }
02382
02383
void KDirLister::slotSpeed(
KIO::Job *job,
unsigned long spd )
02384 {
02385 d->jobData[static_cast<KIO::ListJob *>(job)].speed = spd;
02386
02387
int result = 0;
02388
QMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
02389
while ( dataIt != d->jobData.end() )
02390 {
02391 result += (*dataIt).speed;
02392 ++dataIt;
02393 }
02394
02395 emit
speed( result );
02396 }
02397
02398 uint KDirLister::numJobs()
02399 {
02400
return d->jobData.count();
02401 }
02402
02403
void KDirLister::jobDone(
KIO::ListJob *job )
02404 {
02405 d->jobData.remove( job );
02406 }
02407
02408
void KDirLister::jobStarted(
KIO::ListJob *job )
02409 {
02410 KDirListerPrivate::JobData jobData;
02411 jobData.speed = 0;
02412 jobData.percent = 0;
02413 jobData.processedSize = 0;
02414 jobData.totalSize = 0;
02415
02416 d->jobData.insert( job, jobData );
02417 d->complete =
false;
02418 }
02419
02420
void KDirLister::connectJob(
KIO::ListJob *job )
02421 {
02422
connect( job, SIGNAL(
infoMessage(
KIO::Job *,
const QString& )),
02423
this, SLOT(slotInfoMessage(
KIO::Job *,
const QString& )) );
02424
connect( job, SIGNAL(
percent(
KIO::Job *,
unsigned long )),
02425
this, SLOT(slotPercent(
KIO::Job *,
unsigned long )) );
02426
connect( job, SIGNAL(
totalSize(
KIO::Job *, KIO::filesize_t )),
02427
this, SLOT(slotTotalSize(
KIO::Job *, KIO::filesize_t )) );
02428
connect( job, SIGNAL(
processedSize(
KIO::Job *, KIO::filesize_t )),
02429
this, SLOT(slotProcessedSize(
KIO::Job *, KIO::filesize_t )) );
02430
connect( job, SIGNAL(
speed(
KIO::Job *,
unsigned long )),
02431
this, SLOT(slotSpeed(
KIO::Job *,
unsigned long )) );
02432 }
02433
02434 void KDirLister::setMainWindow(
QWidget *window )
02435 {
02436 d->window = window;
02437 }
02438
02439 QWidget *
KDirLister::mainWindow()
02440 {
02441
return d->window;
02442 }
02443
02444 KFileItemList KDirLister::items( WhichItems which )
const
02445
{
02446
return itemsForDir(
url(), which );
02447 }
02448
02449 KFileItemList KDirLister::itemsForDir(
const KURL& dir, WhichItems which )
const
02450
{
02451
KFileItemList result;
02452
KFileItemList *allItems = s_pCache->itemsForDir( dir );
02453
if ( !allItems )
02454
return result;
02455
02456
if ( which == AllItems )
02457 result = *allItems;
02458
else
02459 {
02460
for (
KFileItemListIterator kit( *allItems ); kit.
current(); ++kit )
02461 {
02462
KFileItem *item = *kit;
02463
bool isNameFilterMatch = (d->dirOnlyMode && !item->
isDir()) ||
02464 !
matchesFilter( item );
02465
bool isMimeFilterMatch = !
matchesMimeFilter( item );
02466
02467
if ( !isNameFilterMatch && !isMimeFilterMatch )
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"