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