• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kio/kio
 

kio/kio

  • kio
  • kio
kdirlister.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3  2000 Carsten Pfeiffer <pfeiffer@kde.org>
4  2001-2005 Michael Brade <brade@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "kdirlister.h"
23 
24 #include <tqregexp.h>
25 #include <tqptrlist.h>
26 #include <tqtimer.h>
27 
28 #include <kapplication.h>
29 #include <kdebug.h>
30 #include <klocale.h>
31 #include <kio/job.h>
32 #include <kmessagebox.h>
33 #include <kglobal.h>
34 #include <kglobalsettings.h>
35 #include <kstaticdeleter.h>
36 #include <kprotocolinfo.h>
37 
38 #include "kdirlister_p.h"
39 
40 #include <assert.h>
41 
42 KDirListerCache* KDirListerCache::s_pSelf = 0;
43 static KStaticDeleter<KDirListerCache> sd_KDirListerCache;
44 
45 // Enable this to get printDebug() called often, to see the contents of the cache
46 //#define DEBUG_CACHE
47 
48 // Make really sure it doesn't get activated in the final build
49 #ifdef NDEBUG
50 #undef DEBUG_CACHE
51 #endif
52 
53 KDirListerCache::KDirListerCache( int maxCount )
54  : itemsCached( maxCount )
55 {
56  kdDebug(7004) << "+KDirListerCache" << endl;
57 
58  itemsInUse.setAutoDelete( false );
59  itemsCached.setAutoDelete( true );
60  urlsCurrentlyListed.setAutoDelete( true );
61  urlsCurrentlyHeld.setAutoDelete( true );
62  pendingUpdates.setAutoDelete( true );
63 
64  connect( kdirwatch, TQT_SIGNAL( dirty( const TQString& ) ),
65  this, TQT_SLOT( slotFileDirty( const TQString& ) ) );
66  connect( kdirwatch, TQT_SIGNAL( created( const TQString& ) ),
67  this, TQT_SLOT( slotFileCreated( const TQString& ) ) );
68  connect( kdirwatch, TQT_SIGNAL( deleted( const TQString& ) ),
69  this, TQT_SLOT( slotFileDeleted( const TQString& ) ) );
70 }
71 
72 KDirListerCache::~KDirListerCache()
73 {
74  kdDebug(7004) << "-KDirListerCache" << endl;
75 
76  itemsInUse.setAutoDelete( true );
77  itemsInUse.clear();
78  itemsCached.clear();
79  urlsCurrentlyListed.clear();
80  urlsCurrentlyHeld.clear();
81 
82  if ( KDirWatch::exists() )
83  kdirwatch->disconnect( this );
84 }
85 
86 // setting _reload to true will emit the old files and
87 // call updateDirectory
88 bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u,
89  bool _keep, bool _reload )
90 {
91  // like this we don't have to worry about trailing slashes any further
92  KURL _url = _u;
93  _url.cleanPath(); // kill consecutive slashes
94  _url.adjustPath(-1);
95  TQString urlStr = _url.url();
96 
97  if ( !lister->validURL( _url ) )
98  return false;
99 
100 #ifdef DEBUG_CACHE
101  printDebug();
102 #endif
103  kdDebug(7004) << k_funcinfo << lister << " url=" << _url
104  << " keep=" << _keep << " reload=" << _reload << endl;
105 
106  if ( !_keep )
107  {
108  // stop any running jobs for lister
109  stop( lister );
110 
111  // clear our internal list for lister
112  forgetDirs( lister );
113 
114  lister->d->rootFileItem = 0;
115  }
116  else if ( lister->d->lstDirs.find( _url ) != lister->d->lstDirs.end() )
117  {
118  // stop the job listing _url for this lister
119  stop( lister, _url );
120 
121  // clear _url for lister
122  forgetDirs( lister, _url, true );
123 
124  if ( lister->d->url == _url )
125  lister->d->rootFileItem = 0;
126  }
127 
128  lister->d->lstDirs.append( _url );
129 
130  if ( lister->d->url.isEmpty() || !_keep ) // set toplevel URL only if not set yet
131  lister->d->url = _url;
132 
133  DirItem *itemU = itemsInUse[urlStr];
134  DirItem *itemC;
135 
136  if ( !urlsCurrentlyListed[urlStr] )
137  {
138  // if there is an update running for _url already we get into
139  // the following case - it will just be restarted by updateDirectory().
140 
141  if ( itemU )
142  {
143  kdDebug(7004) << "listDir: Entry already in use: " << _url << endl;
144 
145  bool oldState = lister->d->complete;
146  lister->d->complete = false;
147 
148  emit lister->started( _url );
149 
150  if ( !lister->d->rootFileItem && lister->d->url == _url )
151  lister->d->rootFileItem = itemU->rootItem;
152 
153  lister->addNewItems( *(itemU->lstItems) );
154  lister->emitItems();
155 
156  // _url is already in use, so there is already an entry in urlsCurrentlyHeld
157  assert( urlsCurrentlyHeld[urlStr] );
158  urlsCurrentlyHeld[urlStr]->append( lister );
159 
160  lister->d->complete = oldState;
161 
162  emit lister->completed( _url );
163  if ( lister->d->complete )
164  emit lister->completed();
165 
166  if ( _reload || !itemU->complete )
167  updateDirectory( _url );
168  }
169  else if ( !_reload && (itemC = itemsCached.take( urlStr )) )
170  {
171  kdDebug(7004) << "listDir: Entry in cache: " << _url << endl;
172 
173  itemC->decAutoUpdate();
174  itemsInUse.insert( urlStr, itemC );
175  itemU = itemC;
176 
177  bool oldState = lister->d->complete;
178  lister->d->complete = false;
179 
180  emit lister->started( _url );
181 
182  if ( !lister->d->rootFileItem && lister->d->url == _url )
183  lister->d->rootFileItem = itemC->rootItem;
184 
185  lister->addNewItems( *(itemC->lstItems) );
186  lister->emitItems();
187 
188  Q_ASSERT( !urlsCurrentlyHeld[urlStr] );
189  TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>;
190  list->append( lister );
191  urlsCurrentlyHeld.insert( urlStr, list );
192 
193  lister->d->complete = oldState;
194 
195  emit lister->completed( _url );
196  if ( lister->d->complete )
197  emit lister->completed();
198 
199  if ( !itemC->complete )
200  updateDirectory( _url );
201  }
202  else // dir not in cache or _reload is true
203  {
204  kdDebug(7004) << "listDir: Entry not in cache or reloaded: " << _url << endl;
205 
206  TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>;
207  list->append( lister );
208  urlsCurrentlyListed.insert( urlStr, list );
209 
210  itemsCached.remove( urlStr );
211  itemU = new DirItem( _url );
212  itemsInUse.insert( urlStr, itemU );
213 
214 // // we have a limit of MAX_JOBS_PER_LISTER concurrently running jobs
215 // if ( lister->numJobs() >= MAX_JOBS_PER_LISTER )
216 // {
217 // lstPendingUpdates.append( _url );
218 // }
219 // else
220 // {
221 
222  if ( lister->d->url == _url )
223  lister->d->rootFileItem = 0;
224 
225  KIO::ListJob* job = KIO::listDir( _url, false /* no default GUI */ );
226  jobs.insert( job, TQValueList<KIO::UDSEntry>() );
227 
228  lister->jobStarted( job );
229  lister->connectJob( job );
230 
231  if ( lister->d->window )
232  job->setWindow( lister->d->window );
233 
234  connect( job, TQT_SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList & ) ),
235  this, TQT_SLOT( slotEntries( KIO::Job *, const KIO::UDSEntryList & ) ) );
236  connect( job, TQT_SIGNAL( result( KIO::Job * ) ),
237  this, TQT_SLOT( slotResult( KIO::Job * ) ) );
238  connect( job, TQT_SIGNAL( redirection( KIO::Job *, const KURL & ) ),
239  this, TQT_SLOT( slotRedirection( KIO::Job *, const KURL & ) ) );
240 
241  emit lister->started( _url );
242 
243 // }
244  }
245  }
246  else
247  {
248  kdDebug(7004) << "listDir: Entry currently being listed: " << _url << endl;
249 
250  emit lister->started( _url );
251 
252  urlsCurrentlyListed[urlStr]->append( lister );
253 
254  KIO::ListJob *job = jobForUrl( urlStr );
255  Q_ASSERT( job );
256 
257  lister->jobStarted( job );
258  lister->connectJob( job );
259 
260  Q_ASSERT( itemU );
261 
262  if ( !lister->d->rootFileItem && lister->d->url == _url )
263  lister->d->rootFileItem = itemU->rootItem;
264 
265  lister->addNewItems( *(itemU->lstItems) );
266  lister->emitItems();
267  }
268 
269  // automatic updating of directories
270  if ( lister->d->autoUpdate )
271  itemU->incAutoUpdate();
272 
273  return true;
274 }
275 
276 bool KDirListerCache::validURL( const KDirLister *lister, const KURL& url ) const
277 {
278  if ( !url.isValid() )
279  {
280  if ( lister->d->autoErrorHandling )
281  {
282  TQString tmp = i18n("Malformed URL\n%1").arg( url.prettyURL() );
283  KMessageBox::error( lister->d->errorParent, tmp );
284  }
285  return false;
286  }
287 
288  if ( !KProtocolInfo::supportsListing( url ) )
289  {
290  if ( lister->d->autoErrorHandling )
291  {
292  // TODO: this message should be changed during next string unfreeze!
293  TQString tmp = i18n("Malformed URL\n%1").arg( url.prettyURL() );
294  KMessageBox::error( lister->d->errorParent, tmp );
295  }
296  return false;
297  }
298 
299  return true;
300 }
301 
302 void KDirListerCache::stop( KDirLister *lister )
303 {
304 #ifdef DEBUG_CACHE
305  printDebug();
306 #endif
307  kdDebug(7004) << k_funcinfo << "lister: " << lister << endl;
308  bool stopped = false;
309 
310  TQDictIterator< TQPtrList<KDirLister> > it( urlsCurrentlyListed );
311  TQPtrList<KDirLister> *listers;
312  while ( (listers = it.current()) )
313  {
314  if ( listers->findRef( lister ) > -1 )
315  {
316  // lister is listing url
317  TQString url = it.currentKey();
318 
319  //kdDebug(7004) << k_funcinfo << " found lister in list - for " << url << endl;
320  bool ret = listers->removeRef( lister );
321  Q_ASSERT( ret );
322 
323  KIO::ListJob *job = jobForUrl( url );
324  if ( job )
325  lister->jobDone( job );
326 
327  // move lister to urlsCurrentlyHeld
328  TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[url];
329  if ( !holders )
330  {
331  holders = new TQPtrList<KDirLister>;
332  urlsCurrentlyHeld.insert( url, holders );
333  }
334 
335  holders->append( lister );
336 
337  emit lister->canceled( KURL( url ) );
338 
339  //kdDebug(7004) << k_funcinfo << "remaining list: " << listers->count() << " listers" << endl;
340 
341  if ( listers->isEmpty() )
342  {
343  // kill the job since it isn't used any more
344  if ( job )
345  killJob( job );
346 
347  urlsCurrentlyListed.remove( url );
348  }
349 
350  stopped = true;
351  }
352  else
353  ++it;
354  }
355 
356  if ( stopped )
357  {
358  emit lister->canceled();
359  lister->d->complete = true;
360  }
361 
362  // this is wrong if there is still an update running!
363  //Q_ASSERT( lister->d->complete );
364 }
365 
366 void KDirListerCache::stop( KDirLister *lister, const KURL& _u )
367 {
368  TQString urlStr( _u.url(-1) );
369  KURL _url( urlStr );
370 
371  // TODO: consider to stop all the "child jobs" of _url as well
372  kdDebug(7004) << k_funcinfo << lister << " url=" << _url << endl;
373 
374  TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr];
375  if ( !listers || !listers->removeRef( lister ) )
376  return;
377 
378  // move lister to urlsCurrentlyHeld
379  TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr];
380  if ( !holders )
381  {
382  holders = new TQPtrList<KDirLister>;
383  urlsCurrentlyHeld.insert( urlStr, holders );
384  }
385 
386  holders->append( lister );
387 
388 
389  KIO::ListJob *job = jobForUrl( urlStr );
390  if ( job )
391  lister->jobDone( job );
392 
393  emit lister->canceled( _url );
394 
395  if ( listers->isEmpty() )
396  {
397  // kill the job since it isn't used any more
398  if ( job )
399  killJob( job );
400 
401  urlsCurrentlyListed.remove( urlStr );
402  }
403 
404  if ( lister->numJobs() == 0 )
405  {
406  lister->d->complete = true;
407 
408  // we killed the last job for lister
409  emit lister->canceled();
410  }
411 }
412 
413 void KDirListerCache::setAutoUpdate( KDirLister *lister, bool enable )
414 {
415  // IMPORTANT: this method does not check for the current autoUpdate state!
416 
417  for ( KURL::List::Iterator it = lister->d->lstDirs.begin();
418  it != lister->d->lstDirs.end(); ++it )
419  {
420  if ( enable )
421  itemsInUse[(*it).url()]->incAutoUpdate();
422  else
423  itemsInUse[(*it).url()]->decAutoUpdate();
424  }
425 }
426 
427 void KDirListerCache::forgetDirs( KDirLister *lister )
428 {
429  kdDebug(7004) << k_funcinfo << lister << endl;
430 
431  emit lister->clear();
432 
433  // forgetDirs() will modify lstDirs, make a copy first
434  KURL::List lstDirsCopy = lister->d->lstDirs;
435  for ( KURL::List::Iterator it = lstDirsCopy.begin();
436  it != lstDirsCopy.end(); ++it )
437  {
438  forgetDirs( lister, *it, false );
439  }
440 }
441 
442 void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool notify )
443 {
444  kdDebug(7004) << k_funcinfo << lister << " _url: " << _url << endl;
445 
446  KURL url( _url );
447  url.adjustPath( -1 );
448  TQString urlStr = url.url();
449  TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr];
450  //Q_ASSERT( holders );
451  if ( holders )
452  {
453  holders->removeRef( lister );
454  }
455 
456  // remove the dir from lister->d->lstDirs so that it doesn't contain things
457  // that itemsInUse doesn't. When emitting the canceled signals lstDirs must
458  // not contain anything that itemsInUse does not contain. (otherwise it
459  // might crash in findByName()).
460  lister->d->lstDirs.remove( lister->d->lstDirs.find( url ) );
461 
462  DirItem *item = itemsInUse[urlStr];
463 
464  if ( holders && holders->isEmpty() )
465  {
466  urlsCurrentlyHeld.remove( urlStr ); // this deletes the (empty) holders list
467  if ( !urlsCurrentlyListed[urlStr] )
468  {
469  // item not in use anymore -> move into cache if complete
470  itemsInUse.remove( urlStr );
471 
472  // this job is a running update
473  KIO::ListJob *job = jobForUrl( urlStr );
474  if ( job )
475  {
476  lister->jobDone( job );
477  killJob( job );
478  kdDebug(7004) << k_funcinfo << "Killing update job for " << urlStr << endl;
479 
480  emit lister->canceled( url );
481  if ( lister->numJobs() == 0 )
482  {
483  lister->d->complete = true;
484  emit lister->canceled();
485  }
486  }
487 
488  if ( notify )
489  emit lister->clear( url );
490 
491  if ( item && item->complete )
492  {
493  kdDebug(7004) << k_funcinfo << lister << " item moved into cache: " << url << endl;
494  itemsCached.insert( urlStr, item ); // TODO: may return false!!
495 
496  // Should we forget the dir for good, or keep a watch on it?
497  // Generally keep a watch, except when it would prevent
498  // unmounting a removable device (#37780)
499  const bool isLocal = item->url.isLocalFile();
500  const bool isManuallyMounted = isLocal && KIO::manually_mounted( item->url.path() );
501  bool containsManuallyMounted = false;
502  if ( !isManuallyMounted && item->lstItems && isLocal )
503  {
504  // Look for a manually-mounted directory inside
505  // If there's one, we can't keep a watch either, FAM would prevent unmounting the CDROM
506  // I hope this isn't too slow (manually_mounted caches the last device so most
507  // of the time this is just a stat per subdir)
508  KFileItemListIterator kit( *item->lstItems );
509  for ( ; kit.current() && !containsManuallyMounted; ++kit )
510  if ( (*kit)->isDir() && KIO::manually_mounted( (*kit)->url().path() ) )
511  containsManuallyMounted = true;
512  }
513 
514  if ( isManuallyMounted || containsManuallyMounted )
515  {
516  kdDebug(7004) << "Not adding a watch on " << item->url << " because it " <<
517  ( isManuallyMounted ? "is manually mounted" : "contains a manually mounted subdir" ) << endl;
518  item->complete = false; // set to "dirty"
519  }
520  else
521  item->incAutoUpdate(); // keep watch
522  }
523  else
524  {
525  delete item;
526  item = 0;
527  }
528  }
529  }
530 
531  if ( item && lister->d->autoUpdate )
532  item->decAutoUpdate();
533 }
534 
535 void KDirListerCache::updateDirectory( const KURL& _dir )
536 {
537  kdDebug(7004) << k_funcinfo << _dir << endl;
538 
539  TQString urlStr = _dir.url(-1);
540  if ( !checkUpdate( urlStr ) )
541  return;
542 
543  // A job can be running to
544  // - only list a new directory: the listers are in urlsCurrentlyListed
545  // - only update a directory: the listers are in urlsCurrentlyHeld
546  // - update a currently running listing: the listers are in urlsCurrentlyListed
547  // and urlsCurrentlyHeld
548 
549  TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr];
550  TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr];
551 
552  // restart the job for _dir if it is running already
553  bool killed = false;
554  TQWidget *window = 0;
555  KIO::ListJob *job = jobForUrl( urlStr );
556  if ( job )
557  {
558  window = job->window();
559 
560  killJob( job );
561  killed = true;
562 
563  if ( listers )
564  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
565  kdl->jobDone( job );
566 
567  if ( holders )
568  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
569  kdl->jobDone( job );
570  }
571  kdDebug(7004) << k_funcinfo << "Killed = " << killed << endl;
572 
573  // we don't need to emit canceled signals since we only replaced the job,
574  // the listing is continuing.
575 
576  Q_ASSERT( !listers || (listers && killed) );
577 
578  job = KIO::listDir( _dir, false /* no default GUI */ );
579  jobs.insert( job, TQValueList<KIO::UDSEntry>() );
580 
581  connect( job, TQT_SIGNAL(entries( KIO::Job *, const KIO::UDSEntryList & )),
582  this, TQT_SLOT(slotUpdateEntries( KIO::Job *, const KIO::UDSEntryList & )) );
583  connect( job, TQT_SIGNAL(result( KIO::Job * )),
584  this, TQT_SLOT(slotUpdateResult( KIO::Job * )) );
585 
586  kdDebug(7004) << k_funcinfo << "update started in " << _dir << endl;
587 
588  if ( listers )
589  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
590  kdl->jobStarted( job );
591 
592  if ( holders )
593  {
594  if ( !killed )
595  {
596  bool first = true;
597  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
598  {
599  kdl->jobStarted( job );
600  if ( first && kdl->d->window )
601  {
602  first = false;
603  job->setWindow( kdl->d->window );
604  }
605  emit kdl->started( _dir );
606  }
607  }
608  else
609  {
610  job->setWindow( window );
611 
612  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
613  kdl->jobStarted( job );
614  }
615  }
616 }
617 
618 bool KDirListerCache::checkUpdate( const TQString& _dir )
619 {
620  if ( !itemsInUse[_dir] )
621  {
622  DirItem *item = itemsCached[_dir];
623  if ( item && item->complete )
624  {
625  item->complete = false;
626  item->decAutoUpdate();
627  // Hmm, this debug output might include login/password from the _dir URL.
628  //kdDebug(7004) << k_funcinfo << "directory " << _dir << " not in use, marked dirty." << endl;
629  }
630  //else
631  //kdDebug(7004) << k_funcinfo << "aborted, directory " << _dir << " not in cache." << endl;
632 
633  return false;
634  }
635  else
636  return true;
637 }
638 
639 KFileItemList *KDirListerCache::itemsForDir( const KURL &_dir ) const
640 {
641  TQString urlStr = _dir.url(-1);
642  DirItem *item = itemsInUse[ urlStr ];
643  if ( !item )
644  item = itemsCached[ urlStr ];
645  return item ? item->lstItems : 0;
646 }
647 
648 KFileItem *KDirListerCache::findByName( const KDirLister *lister, const TQString& _name ) const
649 {
650  Q_ASSERT( lister );
651 
652  for ( KURL::List::Iterator it = lister->d->lstDirs.begin();
653  it != lister->d->lstDirs.end(); ++it )
654  {
655  KFileItemListIterator kit( *itemsInUse[(*it).url()]->lstItems );
656  for ( ; kit.current(); ++kit )
657  if ( (*kit)->name() == _name )
658  return (*kit);
659  }
660 
661  return 0L;
662 }
663 
664 KFileItem *KDirListerCache::findByURL( const KDirLister *lister, const KURL& _u ) const
665 {
666  KURL _url = _u;
667  _url.adjustPath(-1);
668 
669  KURL parentDir( _url );
670  parentDir.setPath( parentDir.directory() );
671 
672  // If lister is set, check that it contains this dir
673  if ( lister && !lister->d->lstDirs.contains( parentDir ) )
674  return 0L;
675 
676  KFileItemList *itemList = itemsForDir( parentDir );
677  if ( itemList )
678  {
679  KFileItemListIterator kit( *itemList );
680  for ( ; kit.current(); ++kit )
681  if ( (*kit)->url() == _url )
682  return (*kit);
683  }
684  return 0L;
685 }
686 
687 void KDirListerCache::FilesAdded( const KURL &dir )
688 {
689  kdDebug(7004) << k_funcinfo << dir << endl;
690  updateDirectory( dir );
691 }
692 
693 void KDirListerCache::FilesRemoved( const KURL::List &fileList )
694 {
695  kdDebug(7004) << k_funcinfo << endl;
696  KURL::List::ConstIterator it = fileList.begin();
697  for ( ; it != fileList.end() ; ++it )
698  {
699  // emit the deleteItem signal if this file was shown in any view
700  KFileItem *fileitem = 0L;
701  KURL parentDir( *it );
702  parentDir.setPath( parentDir.directory() );
703  KFileItemList *lstItems = itemsForDir( parentDir );
704  if ( lstItems )
705  {
706  KFileItem *fit = lstItems->first();
707  for ( ; fit; fit = lstItems->next() )
708  if ( fit->url() == *it ) {
709  fileitem = fit;
710  lstItems->take(); // remove fileitem from list
711  break;
712  }
713  }
714 
715  // Tell the views about it before deleting the KFileItems. They might need the subdirs'
716  // file items (see the dirtree).
717  if ( fileitem )
718  {
719  TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDir.url()];
720  if ( listers )
721  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
722  kdl->emitDeleteItem( fileitem );
723  }
724 
725  // If we found a fileitem, we can test if it's a dir. If not, we'll go to deleteDir just in case.
726  if ( !fileitem || fileitem->isDir() )
727  {
728  // in case of a dir, check if we have any known children, there's much to do in that case
729  // (stopping jobs, removing dirs from cache etc.)
730  deleteDir( *it );
731  }
732 
733  // now remove the item itself
734  delete fileitem;
735  }
736 }
737 
738 void KDirListerCache::FilesChanged( const KURL::List &fileList )
739 {
740  KURL::List dirsToUpdate;
741  kdDebug(7004) << k_funcinfo << "only half implemented" << endl;
742  KURL::List::ConstIterator it = fileList.begin();
743  for ( ; it != fileList.end() ; ++it )
744  {
745  if ( ( *it ).isLocalFile() )
746  {
747  kdDebug(7004) << "KDirListerCache::FilesChanged " << *it << endl;
748  KFileItem *fileitem = findByURL( 0, *it );
749  if ( fileitem )
750  {
751  // we need to refresh the item, because e.g. the permissions can have changed.
752  aboutToRefreshItem( fileitem );
753  fileitem->refresh();
754  emitRefreshItem( fileitem );
755  }
756  else
757  kdDebug(7004) << "item not found" << endl;
758  } else {
759  // For remote files, refresh() won't be able to figure out the new information.
760  // Let's update the dir.
761  KURL dir( *it );
762  dir.setPath( dir.directory( true ) );
763  if ( dirsToUpdate.find( dir ) == dirsToUpdate.end() )
764  dirsToUpdate.prepend( dir );
765  }
766  }
767 
768  KURL::List::ConstIterator itdir = dirsToUpdate.begin();
769  for ( ; itdir != dirsToUpdate.end() ; ++itdir )
770  updateDirectory( *itdir );
771  // ## TODO problems with current jobs listing/updating that dir
772  // ( see kde-2.2.2's kdirlister )
773 }
774 
775 void KDirListerCache::FileRenamed( const KURL &src, const KURL &dst )
776 {
777  kdDebug(7004) << k_funcinfo << src.prettyURL() << " -> " << dst.prettyURL() << endl;
778 #ifdef DEBUG_CACHE
779  printDebug();
780 #endif
781 
782  // Somehow this should only be called if src is a dir. But how could we know if it is?
783  // (Note that looking into itemsInUse isn't good enough. One could rename a subdir in a view.)
784  renameDir( src, dst );
785 
786  // Now update the KFileItem representing that file or dir (not exclusive with the above!)
787  KURL oldurl( src );
788  oldurl.adjustPath( -1 );
789  KFileItem *fileitem = findByURL( 0, oldurl );
790  if ( fileitem )
791  {
792  if ( !fileitem->isLocalFile() && !fileitem->localPath().isEmpty() ) // it uses UDS_LOCAL_PATH? ouch, needs an update then
793  FilesChanged( src );
794  else
795  {
796  aboutToRefreshItem( fileitem );
797  fileitem->setURL( dst );
798  fileitem->refreshMimeType();
799  emitRefreshItem( fileitem );
800  }
801  }
802 #ifdef DEBUG_CACHE
803  printDebug();
804 #endif
805 }
806 
807 void KDirListerCache::aboutToRefreshItem( KFileItem *fileitem )
808 {
809  // Look whether this item was shown in any view, i.e. held by any dirlister
810  KURL parentDir( fileitem->url() );
811  parentDir.setPath( parentDir.directory() );
812  TQString parentDirURL = parentDir.url();
813  TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL];
814  if ( listers )
815  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
816  kdl->aboutToRefreshItem( fileitem );
817 
818  // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing
819  listers = urlsCurrentlyListed[parentDirURL];
820  if ( listers )
821  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
822  kdl->aboutToRefreshItem( fileitem );
823 }
824 
825 void KDirListerCache::emitRefreshItem( KFileItem *fileitem )
826 {
827  // Look whether this item was shown in any view, i.e. held by any dirlister
828  KURL parentDir( fileitem->url() );
829  parentDir.setPath( parentDir.directory() );
830  TQString parentDirURL = parentDir.url();
831  TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL];
832  if ( listers )
833  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
834  {
835  kdl->addRefreshItem( fileitem );
836  kdl->emitItems();
837  }
838 
839  // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing
840  listers = urlsCurrentlyListed[parentDirURL];
841  if ( listers )
842  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
843  {
844  kdl->addRefreshItem( fileitem );
845  kdl->emitItems();
846  }
847 }
848 
849 KDirListerCache* KDirListerCache::self()
850 {
851  if ( !s_pSelf )
852  s_pSelf = sd_KDirListerCache.setObject( s_pSelf, new KDirListerCache );
853 
854  return s_pSelf;
855 }
856 
857 bool KDirListerCache::exists()
858 {
859  return s_pSelf != 0;
860 }
861 
862 
863 // private slots
864 
865 // _file can also be a directory being currently held!
866 void KDirListerCache::slotFileDirty( const TQString& _file )
867 {
868  kdDebug(7004) << k_funcinfo << _file << endl;
869 
870  if ( !pendingUpdates[_file] )
871  {
872  KURL dir;
873  dir.setPath( _file );
874  if ( checkUpdate( dir.url(-1) ) )
875  updateDirectory( dir );
876 
877  // the parent directory of _file
878  dir.setPath( dir.directory() );
879  if ( checkUpdate( dir.url() ) )
880  {
881  // Nice hack to save memory: use the qt object name to store the filename
882  TQTimer *timer = new TQTimer( this, _file.utf8() );
883  connect( timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotFileDirtyDelayed()) );
884  pendingUpdates.insert( _file, timer );
885  timer->start( 500, true );
886  }
887  }
888 }
889 
890 // delayed updating of files, FAM is flooding us with events
891 void KDirListerCache::slotFileDirtyDelayed()
892 {
893  TQString file = TQString::fromUtf8( TQT_TQOBJECT_CONST(sender())->name() );
894 
895  kdDebug(7004) << k_funcinfo << file << endl;
896 
897  // TODO: do it better: don't always create/delete the TQTimer but reuse it.
898  // Delete the timer after the parent directory is removed from the cache.
899  pendingUpdates.remove( file );
900 
901  KURL u;
902  u.setPath( file );
903  KFileItem *item = findByURL( 0, u ); // search all items
904  if ( item )
905  {
906  // we need to refresh the item, because e.g. the permissions can have changed.
907  aboutToRefreshItem( item );
908  item->refresh();
909  emitRefreshItem( item );
910  }
911 }
912 
913 void KDirListerCache::slotFileCreated( const TQString& _file )
914 {
915  kdDebug(7004) << k_funcinfo << _file << endl;
916  // XXX: how to avoid a complete rescan here?
917  KURL u;
918  u.setPath( _file );
919  u.setPath( u.directory() );
920  FilesAdded( u );
921 }
922 
923 void KDirListerCache::slotFileDeleted( const TQString& _file )
924 {
925  kdDebug(7004) << k_funcinfo << _file << endl;
926  KURL u;
927  u.setPath( _file );
928  FilesRemoved( u );
929 }
930 
931 void KDirListerCache::slotEntries( KIO::Job *job, const KIO::UDSEntryList &entries )
932 {
933  KURL url = joburl( static_cast<KIO::ListJob *>(job) );
934  url.adjustPath(-1);
935  TQString urlStr = url.url();
936 
937  kdDebug(7004) << k_funcinfo << "new entries for " << url << endl;
938 
939  DirItem *dir = itemsInUse[urlStr];
940  Q_ASSERT( dir );
941 
942  TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr];
943  Q_ASSERT( listers );
944  Q_ASSERT( !listers->isEmpty() );
945 
946  // check if anyone wants the mimetypes immediately
947  bool delayedMimeTypes = true;
948  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
949  delayedMimeTypes = delayedMimeTypes && kdl->d->delayedMimeTypes;
950 
951  // avoid creating these QStrings again and again
952  static const TQString& dot = KGlobal::staticQString(".");
953  static const TQString& dotdot = KGlobal::staticQString("..");
954 
955  KIO::UDSEntryListConstIterator it = entries.begin();
956  KIO::UDSEntryListConstIterator end = entries.end();
957 
958  for ( ; it != end; ++it )
959  {
960  TQString name;
961 
962  // find out about the name
963  KIO::UDSEntry::ConstIterator entit = (*it).begin();
964  for( ; entit != (*it).end(); ++entit )
965  if ( (*entit).m_uds == KIO::UDS_NAME )
966  {
967  name = (*entit).m_str;
968  break;
969  }
970 
971  Q_ASSERT( !name.isEmpty() );
972  if ( name.isEmpty() )
973  continue;
974 
975  if ( name == dot )
976  {
977  Q_ASSERT( !dir->rootItem );
978  dir->rootItem = new KFileItem( *it, url, delayedMimeTypes, true );
979 
980  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
981  if ( !kdl->d->rootFileItem && kdl->d->url == url )
982  kdl->d->rootFileItem = dir->rootItem;
983  }
984  else if ( name != dotdot )
985  {
986  KFileItem* item = new KFileItem( *it, url, delayedMimeTypes, true );
987  Q_ASSERT( item );
988 
989  //kdDebug(7004)<< "Adding item: " << item->url() << endl;
990  dir->lstItems->append( item );
991 
992  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
993  kdl->addNewItem( item );
994  }
995  }
996 
997  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
998  kdl->emitItems();
999 }
1000 
1001 void KDirListerCache::slotResult( KIO::Job *j )
1002 {
1003  Q_ASSERT( j );
1004  KIO::ListJob *job = static_cast<KIO::ListJob *>( j );
1005  jobs.remove( job );
1006 
1007  KURL jobUrl = joburl( job );
1008  jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections
1009  TQString jobUrlStr = jobUrl.url();
1010 
1011  kdDebug(7004) << k_funcinfo << "finished listing " << jobUrl << endl;
1012 #ifdef DEBUG_CACHE
1013  printDebug();
1014 #endif
1015 
1016  TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( jobUrlStr );
1017  Q_ASSERT( listers );
1018 
1019  // move the directory to the held directories, do it before emitting
1020  // the signals to make sure it exists in KDirListerCache in case someone
1021  // calls listDir during the signal emission
1022  Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr] );
1023  urlsCurrentlyHeld.insert( jobUrlStr, listers );
1024 
1025  KDirLister *kdl;
1026 
1027  if ( job->error() )
1028  {
1029  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1030  {
1031  kdl->jobDone( job );
1032  kdl->handleError( job );
1033  emit kdl->canceled( jobUrl );
1034  if ( kdl->numJobs() == 0 )
1035  {
1036  kdl->d->complete = true;
1037  emit kdl->canceled();
1038  }
1039  }
1040  }
1041  else
1042  {
1043  DirItem *dir = itemsInUse[jobUrlStr];
1044  Q_ASSERT( dir );
1045  dir->complete = true;
1046 
1047  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1048  {
1049  kdl->jobDone( job );
1050  emit kdl->completed( jobUrl );
1051  if ( kdl->numJobs() == 0 )
1052  {
1053  kdl->d->complete = true;
1054  emit kdl->completed();
1055  }
1056  }
1057  }
1058 
1059  // TODO: hmm, if there was an error and job is a parent of one or more
1060  // of the pending urls we should cancel it/them as well
1061  processPendingUpdates();
1062 
1063 #ifdef DEBUG_CACHE
1064  printDebug();
1065 #endif
1066 }
1067 
1068 void KDirListerCache::slotRedirection( KIO::Job *j, const KURL& url )
1069 {
1070  Q_ASSERT( j );
1071  KIO::ListJob *job = static_cast<KIO::ListJob *>( j );
1072 
1073  KURL oldUrl = job->url(); // here we really need the old url!
1074  KURL newUrl = url;
1075 
1076  // strip trailing slashes
1077  oldUrl.adjustPath(-1);
1078  newUrl.adjustPath(-1);
1079 
1080  if ( oldUrl == newUrl )
1081  {
1082  kdDebug(7004) << k_funcinfo << "New redirection url same as old, giving up." << endl;
1083  return;
1084  }
1085 
1086  kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl;
1087 
1088 #ifdef DEBUG_CACHE
1089  printDebug();
1090 #endif
1091 
1092  // I don't think there can be dirItems that are childs of oldUrl.
1093  // Am I wrong here? And even if so, we don't need to delete them, right?
1094  // DF: redirection happens before listDir emits any item. Makes little sense otherwise.
1095 
1096  // oldUrl cannot be in itemsCached because only completed items are moved there
1097  DirItem *dir = itemsInUse.take( oldUrl.url() );
1098  Q_ASSERT( dir );
1099 
1100  TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrl.url() );
1101  Q_ASSERT( listers );
1102  Q_ASSERT( !listers->isEmpty() );
1103 
1104  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1105  {
1106  // TODO: put in own method?
1107  if ( kdl->d->url.equals( oldUrl, true ) )
1108  {
1109  kdl->d->rootFileItem = 0;
1110  kdl->d->url = newUrl;
1111  }
1112 
1113  *kdl->d->lstDirs.find( oldUrl ) = newUrl;
1114 
1115  if ( kdl->d->lstDirs.count() == 1 )
1116  {
1117  emit kdl->clear();
1118  emit kdl->redirection( newUrl );
1119  emit kdl->redirection( oldUrl, newUrl );
1120  }
1121  else
1122  {
1123  emit kdl->clear( oldUrl );
1124  emit kdl->redirection( oldUrl, newUrl );
1125  }
1126  }
1127 
1128  // when a lister was stopped before the job emits the redirection signal, the old url will
1129  // also be in urlsCurrentlyHeld
1130  TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrl.url() );
1131  if ( holders )
1132  {
1133  Q_ASSERT( !holders->isEmpty() );
1134 
1135  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
1136  {
1137  kdl->jobStarted( job );
1138 
1139  // do it like when starting a new list-job that will redirect later
1140  emit kdl->started( oldUrl );
1141 
1142  // TODO: maybe don't emit started if there's an update running for newUrl already?
1143 
1144  if ( kdl->d->url.equals( oldUrl, true ) )
1145  {
1146  kdl->d->rootFileItem = 0;
1147  kdl->d->url = newUrl;
1148  }
1149 
1150  *kdl->d->lstDirs.find( oldUrl ) = newUrl;
1151 
1152  if ( kdl->d->lstDirs.count() == 1 )
1153  {
1154  emit kdl->clear();
1155  emit kdl->redirection( newUrl );
1156  emit kdl->redirection( oldUrl, newUrl );
1157  }
1158  else
1159  {
1160  emit kdl->clear( oldUrl );
1161  emit kdl->redirection( oldUrl, newUrl );
1162  }
1163  }
1164  }
1165 
1166  DirItem *newDir = itemsInUse[newUrl.url()];
1167  if ( newDir )
1168  {
1169  kdDebug(7004) << "slotRedirection: " << newUrl.url() << " already in use" << endl;
1170 
1171  // only in this case there can newUrl already be in urlsCurrentlyListed or urlsCurrentlyHeld
1172  delete dir;
1173 
1174  // get the job if one's running for newUrl already (can be a list-job or an update-job), but
1175  // do not return this 'job', which would happen because of the use of redirectionURL()
1176  KIO::ListJob *oldJob = jobForUrl( newUrl.url(), job );
1177 
1178  // listers of newUrl with oldJob: forget about the oldJob and use the already running one
1179  // which will be converted to an updateJob
1180  TQPtrList<KDirLister> *curListers = urlsCurrentlyListed[newUrl.url()];
1181  if ( curListers )
1182  {
1183  kdDebug(7004) << "slotRedirection: and it is currently listed" << endl;
1184 
1185  Q_ASSERT( oldJob ); // ?!
1186 
1187  for ( KDirLister *kdl = curListers->first(); kdl; kdl = curListers->next() ) // listers of newUrl
1188  {
1189  kdl->jobDone( oldJob );
1190 
1191  kdl->jobStarted( job );
1192  kdl->connectJob( job );
1193  }
1194 
1195  // append listers of oldUrl with newJob to listers of newUrl with oldJob
1196  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1197  curListers->append( kdl );
1198  }
1199  else
1200  urlsCurrentlyListed.insert( newUrl.url(), listers );
1201 
1202  if ( oldJob ) // kill the old job, be it a list-job or an update-job
1203  killJob( oldJob );
1204 
1205  // holders of newUrl: use the already running job which will be converted to an updateJob
1206  TQPtrList<KDirLister> *curHolders = urlsCurrentlyHeld[newUrl.url()];
1207  if ( curHolders )
1208  {
1209  kdDebug(7004) << "slotRedirection: and it is currently held." << endl;
1210 
1211  for ( KDirLister *kdl = curHolders->first(); kdl; kdl = curHolders->next() ) // holders of newUrl
1212  {
1213  kdl->jobStarted( job );
1214  emit kdl->started( newUrl );
1215  }
1216 
1217  // append holders of oldUrl to holders of newUrl
1218  if ( holders )
1219  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
1220  curHolders->append( kdl );
1221  }
1222  else if ( holders )
1223  urlsCurrentlyHeld.insert( newUrl.url(), holders );
1224 
1225 
1226  // emit old items: listers, holders. NOT: newUrlListers/newUrlHolders, they already have them listed
1227  // TODO: make this a separate method?
1228  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1229  {
1230  if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
1231  kdl->d->rootFileItem = newDir->rootItem;
1232 
1233  kdl->addNewItems( *(newDir->lstItems) );
1234  kdl->emitItems();
1235  }
1236 
1237  if ( holders )
1238  {
1239  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
1240  {
1241  if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
1242  kdl->d->rootFileItem = newDir->rootItem;
1243 
1244  kdl->addNewItems( *(newDir->lstItems) );
1245  kdl->emitItems();
1246  }
1247  }
1248  }
1249  else if ( (newDir = itemsCached.take( newUrl.url() )) )
1250  {
1251  kdDebug(7004) << "slotRedirection: " << newUrl.url() << " is unused, but already in the cache." << endl;
1252 
1253  delete dir;
1254  itemsInUse.insert( newUrl.url(), newDir );
1255  urlsCurrentlyListed.insert( newUrl.url(), listers );
1256  if ( holders )
1257  urlsCurrentlyHeld.insert( newUrl.url(), holders );
1258 
1259  // emit old items: listers, holders
1260  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1261  {
1262  if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
1263  kdl->d->rootFileItem = newDir->rootItem;
1264 
1265  kdl->addNewItems( *(newDir->lstItems) );
1266  kdl->emitItems();
1267  }
1268 
1269  if ( holders )
1270  {
1271  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
1272  {
1273  if ( !kdl->d->rootFileItem && kdl->d->url == newUrl )
1274  kdl->d->rootFileItem = newDir->rootItem;
1275 
1276  kdl->addNewItems( *(newDir->lstItems) );
1277  kdl->emitItems();
1278  }
1279  }
1280  }
1281  else
1282  {
1283  kdDebug(7004) << "slotRedirection: " << newUrl.url() << " has not been listed yet." << endl;
1284 
1285  delete dir->rootItem;
1286  dir->rootItem = 0;
1287  dir->lstItems->clear();
1288  dir->redirect( newUrl );
1289  itemsInUse.insert( newUrl.url(), dir );
1290  urlsCurrentlyListed.insert( newUrl.url(), listers );
1291 
1292  if ( holders )
1293  urlsCurrentlyHeld.insert( newUrl.url(), holders );
1294  else
1295  {
1296 #ifdef DEBUG_CACHE
1297  printDebug();
1298 #endif
1299  return; // only in this case the job doesn't need to be converted,
1300  }
1301  }
1302 
1303  // make the job an update job
1304  job->disconnect( this );
1305 
1306  connect( job, TQT_SIGNAL(entries( KIO::Job *, const KIO::UDSEntryList & )),
1307  this, TQT_SLOT(slotUpdateEntries( KIO::Job *, const KIO::UDSEntryList & )) );
1308  connect( job, TQT_SIGNAL(result( KIO::Job * )),
1309  this, TQT_SLOT(slotUpdateResult( KIO::Job * )) );
1310 
1311  // FIXME: autoUpdate-Counts!!
1312 
1313 #ifdef DEBUG_CACHE
1314  printDebug();
1315 #endif
1316 }
1317 
1318 void KDirListerCache::renameDir( const KURL &oldUrl, const KURL &newUrl )
1319 {
1320  kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << newUrl.prettyURL() << endl;
1321  TQString oldUrlStr = oldUrl.url(-1);
1322  TQString newUrlStr = newUrl.url(-1);
1323 
1324  // Not enough. Also need to look at any child dir, even sub-sub-sub-dir.
1325  //DirItem *dir = itemsInUse.take( oldUrlStr );
1326  //emitRedirections( oldUrl, url );
1327 
1328  // Look at all dirs being listed/shown
1329  TQDictIterator<DirItem> itu( itemsInUse );
1330  bool goNext;
1331  while ( itu.current() )
1332  {
1333  goNext = true;
1334  DirItem *dir = itu.current();
1335  KURL oldDirUrl ( itu.currentKey() );
1336  //kdDebug(7004) << "itemInUse: " << oldDirUrl.prettyURL() << endl;
1337  // Check if this dir is oldUrl, or a subfolder of it
1338  if ( oldUrl.isParentOf( oldDirUrl ) )
1339  {
1340  // TODO should use KURL::cleanpath like isParentOf does
1341  TQString relPath = oldDirUrl.path().mid( oldUrl.path().length() );
1342 
1343  KURL newDirUrl( newUrl ); // take new base
1344  if ( !relPath.isEmpty() )
1345  newDirUrl.addPath( relPath ); // add unchanged relative path
1346  //kdDebug(7004) << "KDirListerCache::renameDir new url=" << newDirUrl.prettyURL() << endl;
1347 
1348  // Update URL in dir item and in itemsInUse
1349  dir->redirect( newDirUrl );
1350  itemsInUse.remove( itu.currentKey() ); // implies ++itu
1351  itemsInUse.insert( newDirUrl.url(-1), dir );
1352  goNext = false; // because of the implied ++itu above
1353  if ( dir->lstItems )
1354  {
1355  // Rename all items under that dir
1356  KFileItemListIterator kit( *dir->lstItems );
1357  for ( ; kit.current(); ++kit )
1358  {
1359  KURL oldItemUrl = (*kit)->url();
1360  TQString oldItemUrlStr( oldItemUrl.url(-1) );
1361  KURL newItemUrl( oldItemUrl );
1362  newItemUrl.setPath( newDirUrl.path() );
1363  newItemUrl.addPath( oldItemUrl.fileName() );
1364  kdDebug(7004) << "KDirListerCache::renameDir renaming " << oldItemUrlStr << " to " << newItemUrl.url() << endl;
1365  (*kit)->setURL( newItemUrl );
1366  }
1367  }
1368  emitRedirections( oldDirUrl, newDirUrl );
1369  }
1370  if ( goNext )
1371  ++itu;
1372  }
1373 
1374  // Is oldUrl a directory in the cache?
1375  // Remove any child of oldUrl from the cache - even if the renamed dir itself isn't in it!
1376  removeDirFromCache( oldUrl );
1377  // TODO rename, instead.
1378 }
1379 
1380 void KDirListerCache::emitRedirections( const KURL &oldUrl, const KURL &url )
1381 {
1382  kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << url.prettyURL() << endl;
1383  TQString oldUrlStr = oldUrl.url(-1);
1384  TQString urlStr = url.url(-1);
1385 
1386  KIO::ListJob *job = jobForUrl( oldUrlStr );
1387  if ( job )
1388  killJob( job );
1389 
1390  // Check if we were listing this dir. Need to abort and restart with new name in that case.
1391  TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrlStr );
1392  if ( listers )
1393  {
1394  // Tell the world that the job listing the old url is dead.
1395  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1396  {
1397  if ( job )
1398  kdl->jobDone( job );
1399 
1400  emit kdl->canceled( oldUrl );
1401  }
1402 
1403  urlsCurrentlyListed.insert( urlStr, listers );
1404  }
1405 
1406  // Check if we are currently displaying this directory (odds opposite wrt above)
1407  // Update urlsCurrentlyHeld dict with new URL
1408  TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrlStr );
1409  if ( holders )
1410  {
1411  if ( job )
1412  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
1413  kdl->jobDone( job );
1414 
1415  urlsCurrentlyHeld.insert( urlStr, holders );
1416  }
1417 
1418  if ( listers )
1419  {
1420  updateDirectory( url );
1421 
1422  // Tell the world about the new url
1423  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1424  emit kdl->started( url );
1425  }
1426 
1427  if ( holders )
1428  {
1429  // And notify the dirlisters of the redirection
1430  for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
1431  {
1432  *kdl->d->lstDirs.find( oldUrl ) = url;
1433 
1434  if ( kdl->d->lstDirs.count() == 1 )
1435  emit kdl->redirection( url );
1436 
1437  emit kdl->redirection( oldUrl, url );
1438  }
1439  }
1440 }
1441 
1442 void KDirListerCache::removeDirFromCache( const KURL& dir )
1443 {
1444  kdDebug(7004) << "KDirListerCache::removeDirFromCache " << dir.prettyURL() << endl;
1445  TQCacheIterator<DirItem> itc( itemsCached );
1446  while ( itc.current() )
1447  {
1448  if ( dir.isParentOf( KURL( itc.currentKey() ) ) )
1449  itemsCached.remove( itc.currentKey() );
1450  else
1451  ++itc;
1452  }
1453 }
1454 
1455 void KDirListerCache::slotUpdateEntries( KIO::Job* job, const KIO::UDSEntryList& list )
1456 {
1457  jobs[static_cast<KIO::ListJob*>(job)] += list;
1458 }
1459 
1460 void KDirListerCache::slotUpdateResult( KIO::Job * j )
1461 {
1462  Q_ASSERT( j );
1463  KIO::ListJob *job = static_cast<KIO::ListJob *>( j );
1464 
1465  KURL jobUrl = joburl( job );
1466  jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections
1467  TQString jobUrlStr = jobUrl.url();
1468 
1469  kdDebug(7004) << k_funcinfo << "finished update " << jobUrl << endl;
1470 
1471  KDirLister *kdl;
1472 
1473  TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[jobUrlStr];
1474  TQPtrList<KDirLister> *tmpLst = urlsCurrentlyListed.take( jobUrlStr );
1475 
1476  if ( tmpLst )
1477  {
1478  if ( listers )
1479  for ( kdl = tmpLst->first(); kdl; kdl = tmpLst->next() )
1480  {
1481  Q_ASSERT( listers->containsRef( kdl ) == 0 );
1482  listers->append( kdl );
1483  }
1484  else
1485  {
1486  listers = tmpLst;
1487  urlsCurrentlyHeld.insert( jobUrlStr, listers );
1488  }
1489  }
1490 
1491  // once we are updating dirs that are only in the cache this will fail!
1492  Q_ASSERT( listers );
1493 
1494  if ( job->error() )
1495  {
1496  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1497  {
1498  kdl->jobDone( job );
1499 
1500  //don't bother the user
1501  //kdl->handleError( job );
1502 
1503  emit kdl->canceled( jobUrl );
1504  if ( kdl->numJobs() == 0 )
1505  {
1506  kdl->d->complete = true;
1507  emit kdl->canceled();
1508  }
1509  }
1510 
1511  jobs.remove( job );
1512 
1513  // TODO: if job is a parent of one or more
1514  // of the pending urls we should cancel them
1515  processPendingUpdates();
1516  return;
1517  }
1518 
1519  DirItem *dir = itemsInUse[jobUrlStr];
1520  dir->complete = true;
1521 
1522 
1523  // check if anyone wants the mimetypes immediately
1524  bool delayedMimeTypes = true;
1525  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1526  delayedMimeTypes = delayedMimeTypes && kdl->d->delayedMimeTypes;
1527 
1528  // should be enough to get reasonable speed in most cases
1529  TQDict<KFileItem> fileItems( 9973 );
1530 
1531  KFileItemListIterator kit ( *(dir->lstItems) );
1532 
1533  // Unmark all items in url
1534  for ( ; kit.current(); ++kit )
1535  {
1536  (*kit)->unmark();
1537  fileItems.insert( (*kit)->url().url(), *kit );
1538  }
1539 
1540  static const TQString& dot = KGlobal::staticQString(".");
1541  static const TQString& dotdot = KGlobal::staticQString("..");
1542 
1543  KFileItem *item = 0, *tmp;
1544 
1545  TQValueList<KIO::UDSEntry> buf = jobs[job];
1546  TQValueListIterator<KIO::UDSEntry> it = buf.begin();
1547  for ( ; it != buf.end(); ++it )
1548  {
1549  // Form the complete url
1550  if ( !item )
1551  item = new KFileItem( *it, jobUrl, delayedMimeTypes, true );
1552  else
1553  item->setUDSEntry( *it, jobUrl, delayedMimeTypes, true );
1554 
1555  // Find out about the name
1556  TQString name = item->name();
1557  Q_ASSERT( !name.isEmpty() );
1558 
1559  // we duplicate the check for dotdot here, to avoid iterating over
1560  // all items again and checking in matchesFilter() that way.
1561  if ( name.isEmpty() || name == dotdot )
1562  continue;
1563 
1564  if ( name == dot )
1565  {
1566  // if the update was started before finishing the original listing
1567  // there is no root item yet
1568  if ( !dir->rootItem )
1569  {
1570  dir->rootItem = item;
1571  item = 0;
1572 
1573  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1574  if ( !kdl->d->rootFileItem && kdl->d->url == jobUrl )
1575  kdl->d->rootFileItem = dir->rootItem;
1576  }
1577 
1578  continue;
1579  }
1580 
1581  // Find this item
1582  if ( (tmp = fileItems[item->url().url()]) )
1583  {
1584  tmp->mark();
1585 
1586  // check if something changed for this file
1587  if ( !tmp->cmp( *item ) )
1588  {
1589  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1590  kdl->aboutToRefreshItem( tmp );
1591 
1592  //kdDebug(7004) << "slotUpdateResult: file changed: " << tmp->name() << endl;
1593  tmp->assign( *item );
1594 
1595  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1596  kdl->addRefreshItem( tmp );
1597  }
1598  }
1599  else // this is a new file
1600  {
1601  //kdDebug(7004) << "slotUpdateResult: new file: " << name << endl;
1602 
1603  item->mark();
1604  dir->lstItems->append( item );
1605 
1606  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1607  kdl->addNewItem( item );
1608 
1609  // item used, we need a new one for the next iteration
1610  item = 0;
1611  }
1612  }
1613 
1614  if ( item )
1615  delete item;
1616 
1617  jobs.remove( job );
1618 
1619  deleteUnmarkedItems( listers, dir->lstItems );
1620 
1621  for ( kdl = listers->first(); kdl; kdl = listers->next() )
1622  {
1623  kdl->emitItems();
1624 
1625  kdl->jobDone( job );
1626 
1627  emit kdl->completed( jobUrl );
1628  if ( kdl->numJobs() == 0 )
1629  {
1630  kdl->d->complete = true;
1631  emit kdl->completed();
1632  }
1633  }
1634 
1635  // TODO: hmm, if there was an error and job is a parent of one or more
1636  // of the pending urls we should cancel it/them as well
1637  processPendingUpdates();
1638 }
1639 
1640 // private
1641 
1642 KIO::ListJob *KDirListerCache::jobForUrl( const TQString& url, KIO::ListJob *not_job )
1643 {
1644  KIO::ListJob *job;
1645  TQMap< KIO::ListJob *, TQValueList<KIO::UDSEntry> >::Iterator it = jobs.begin();
1646  while ( it != jobs.end() )
1647  {
1648  job = it.key();
1649  if ( joburl( job ).url(-1) == url && job != not_job )
1650  return job;
1651  ++it;
1652  }
1653  return 0;
1654 }
1655 
1656 const KURL& KDirListerCache::joburl( KIO::ListJob *job )
1657 {
1658  if ( job->redirectionURL().isValid() )
1659  return job->redirectionURL();
1660  else
1661  return job->url();
1662 }
1663 
1664 void KDirListerCache::killJob( KIO::ListJob *job )
1665 {
1666  jobs.remove( job );
1667  job->disconnect( this );
1668  job->kill();
1669 }
1670 
1671 void KDirListerCache::deleteUnmarkedItems( TQPtrList<KDirLister> *listers, KFileItemList *lstItems )
1672 {
1673  // Find all unmarked items and delete them
1674  KFileItem* item;
1675  lstItems->first();
1676  while ( (item = lstItems->current()) )
1677  if ( !item->isMarked() )
1678  {
1679  //kdDebug() << k_funcinfo << item->name() << endl;
1680  for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
1681  kdl->emitDeleteItem( item );
1682 
1683  if ( item->isDir() )
1684  deleteDir( item->url() );
1685 
1686  // finally actually delete the item
1687  lstItems->take();
1688  delete item;
1689  }
1690  else
1691  lstItems->next();
1692 }
1693 
1694 void KDirListerCache::deleteDir( const KURL& dirUrl )
1695 {
1696  //kdDebug() << k_funcinfo << dirUrl.prettyURL() << endl;
1697  // unregister and remove the childs of the deleted item.
1698  // Idea: tell all the KDirListers that they should forget the dir
1699  // and then remove it from the cache.
1700 
1701  TQDictIterator<DirItem> itu( itemsInUse );
1702  while ( itu.current() )
1703  {
1704  KURL deletedUrl( itu.currentKey() );
1705  if ( dirUrl.isParentOf( deletedUrl ) )
1706  {
1707  // stop all jobs for deletedUrl
1708 
1709  TQPtrList<KDirLister> *kdls = urlsCurrentlyListed[deletedUrl.url()];
1710  if ( kdls ) // yeah, I lack good names
1711  {
1712  // we need a copy because stop modifies the list
1713  kdls = new TQPtrList<KDirLister>( *kdls );
1714  for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() )
1715  stop( kdl, deletedUrl );
1716 
1717  delete kdls;
1718  }
1719 
1720  // tell listers holding deletedUrl to forget about it
1721  // this will stop running updates for deletedUrl as well
1722 
1723  kdls = urlsCurrentlyHeld[deletedUrl.url()];
1724  if ( kdls )
1725  {
1726  // we need a copy because forgetDirs modifies the list
1727  kdls = new TQPtrList<KDirLister>( *kdls );
1728 
1729  for ( KDirLister *kdl = kdls->first(); kdl; kdl = kdls->next() )
1730  {
1731  // lister's root is the deleted item
1732  if ( kdl->d->url == deletedUrl )
1733  {
1734  // tell the view first. It might need the subdirs' items (which forgetDirs will delete)
1735  if ( kdl->d->rootFileItem )
1736  emit kdl->deleteItem( kdl->d->rootFileItem );
1737  forgetDirs( kdl );
1738  kdl->d->rootFileItem = 0;
1739  }
1740  else
1741  {
1742  bool treeview = kdl->d->lstDirs.count() > 1;
1743  if ( !treeview )
1744  emit kdl->clear();
1745 
1746  forgetDirs( kdl, deletedUrl, treeview );
1747  }
1748  }
1749 
1750  delete kdls;
1751  }
1752 
1753  // delete the entry for deletedUrl - should not be needed, it's in
1754  // items cached now
1755 
1756  DirItem *dir = itemsInUse.take( deletedUrl.url() );
1757  Q_ASSERT( !dir );
1758  if ( !dir ) // take didn't find it - move on
1759  ++itu;
1760  }
1761  else
1762  ++itu;
1763  }
1764 
1765  // remove the children from the cache
1766  removeDirFromCache( dirUrl );
1767 }
1768 
1769 void KDirListerCache::processPendingUpdates()
1770 {
1771  // TODO
1772 }
1773 
1774 #ifndef NDEBUG
1775 void KDirListerCache::printDebug()
1776 {
1777  kdDebug(7004) << "Items in use: " << endl;
1778  TQDictIterator<DirItem> itu( itemsInUse );
1779  for ( ; itu.current() ; ++itu ) {
1780  kdDebug(7004) << " " << itu.currentKey() << " URL: " << itu.current()->url
1781  << " rootItem: " << ( itu.current()->rootItem ? itu.current()->rootItem->url() : KURL() )
1782  << " autoUpdates refcount: " << itu.current()->autoUpdates
1783  << " complete: " << itu.current()->complete
1784  << ( itu.current()->lstItems ? TQString(" with %1 items.").arg(itu.current()->lstItems->count()) : TQString(" lstItems=NULL") ) << endl;
1785  }
1786 
1787  kdDebug(7004) << "urlsCurrentlyHeld: " << endl;
1788  TQDictIterator< TQPtrList<KDirLister> > it( urlsCurrentlyHeld );
1789  for ( ; it.current() ; ++it )
1790  {
1791  TQString list;
1792  for ( TQPtrListIterator<KDirLister> listit( *it.current() ); listit.current(); ++listit )
1793  list += " 0x" + TQString::number( (long)listit.current(), 16 );
1794  kdDebug(7004) << " " << it.currentKey() << " " << it.current()->count() << " listers: " << list << endl;
1795  }
1796 
1797  kdDebug(7004) << "urlsCurrentlyListed: " << endl;
1798  TQDictIterator< TQPtrList<KDirLister> > it2( urlsCurrentlyListed );
1799  for ( ; it2.current() ; ++it2 )
1800  {
1801  TQString list;
1802  for ( TQPtrListIterator<KDirLister> listit( *it2.current() ); listit.current(); ++listit )
1803  list += " 0x" + TQString::number( (long)listit.current(), 16 );
1804  kdDebug(7004) << " " << it2.currentKey() << " " << it2.current()->count() << " listers: " << list << endl;
1805  }
1806 
1807  TQMap< KIO::ListJob *, TQValueList<KIO::UDSEntry> >::Iterator jit = jobs.begin();
1808  kdDebug(7004) << "Jobs: " << endl;
1809  for ( ; jit != jobs.end() ; ++jit )
1810  kdDebug(7004) << " " << jit.key() << " listing " << joburl( jit.key() ).prettyURL() << ": " << (*jit).count() << " entries." << endl;
1811 
1812  kdDebug(7004) << "Items in cache: " << endl;
1813  TQCacheIterator<DirItem> itc( itemsCached );
1814  for ( ; itc.current() ; ++itc )
1815  kdDebug(7004) << " " << itc.currentKey() << " rootItem: "
1816  << ( itc.current()->rootItem ? itc.current()->rootItem->url().prettyURL() : TQString("NULL") )
1817  << ( itc.current()->lstItems ? TQString(" with %1 items.").arg(itc.current()->lstItems->count()) : TQString(" lstItems=NULL") ) << endl;
1818 }
1819 #endif
1820 
1821 /*********************** -- The new KDirLister -- ************************/
1822 
1823 
1824 KDirLister::KDirLister( bool _delayedMimeTypes )
1825 {
1826  kdDebug(7003) << "+KDirLister" << endl;
1827 
1828  d = new KDirListerPrivate;
1829 
1830  d->complete = true;
1831  d->delayedMimeTypes = _delayedMimeTypes;
1832 
1833  setAutoUpdate( true );
1834  setDirOnlyMode( false );
1835  setShowingDotFiles( false );
1836 
1837  setAutoErrorHandlingEnabled( true, 0 );
1838 }
1839 
1840 KDirLister::~KDirLister()
1841 {
1842  kdDebug(7003) << "-KDirLister" << endl;
1843 
1844  if ( KDirListerCache::exists() )
1845  {
1846  // Stop all running jobs
1847  stop();
1848  s_pCache->forgetDirs( this );
1849  }
1850 
1851  delete d;
1852 }
1853 
1854 bool KDirLister::openURL( const KURL& _url, bool _keep, bool _reload )
1855 {
1856  kdDebug(7003) << k_funcinfo << _url.prettyURL()
1857  << " keep=" << _keep << " reload=" << _reload << endl;
1858 
1859  // emit the current changes made to avoid an inconsistent treeview
1860  if ( d->changes != NONE && _keep )
1861  emitChanges();
1862 
1863  d->changes = NONE;
1864 
1865  return s_pCache->listDir( this, _url, _keep, _reload );
1866 }
1867 
1868 void KDirLister::stop()
1869 {
1870  kdDebug(7003) << k_funcinfo << endl;
1871  s_pCache->stop( this );
1872 }
1873 
1874 void KDirLister::stop( const KURL& _url )
1875 {
1876  kdDebug(7003) << k_funcinfo << _url.prettyURL() << endl;
1877  s_pCache->stop( this, _url );
1878 }
1879 
1880 bool KDirLister::autoUpdate() const
1881 {
1882  return d->autoUpdate;
1883 }
1884 
1885 void KDirLister::setAutoUpdate( bool _enable )
1886 {
1887  if ( d->autoUpdate == _enable )
1888  return;
1889 
1890  d->autoUpdate = _enable;
1891  s_pCache->setAutoUpdate( this, _enable );
1892 }
1893 
1894 bool KDirLister::showingDotFiles() const
1895 {
1896  return d->isShowingDotFiles;
1897 }
1898 
1899 void KDirLister::setShowingDotFiles( bool _showDotFiles )
1900 {
1901  if ( d->isShowingDotFiles == _showDotFiles )
1902  return;
1903 
1904  d->isShowingDotFiles = _showDotFiles;
1905  d->changes ^= DOT_FILES;
1906 }
1907 
1908 bool KDirLister::dirOnlyMode() const
1909 {
1910  return d->dirOnlyMode;
1911 }
1912 
1913 void KDirLister::setDirOnlyMode( bool _dirsOnly )
1914 {
1915  if ( d->dirOnlyMode == _dirsOnly )
1916  return;
1917 
1918  d->dirOnlyMode = _dirsOnly;
1919  d->changes ^= DIR_ONLY_MODE;
1920 }
1921 
1922 bool KDirLister::autoErrorHandlingEnabled() const
1923 {
1924  return d->autoErrorHandling;
1925 }
1926 
1927 void KDirLister::setAutoErrorHandlingEnabled( bool enable, TQWidget* parent )
1928 {
1929  d->autoErrorHandling = enable;
1930  d->errorParent = parent;
1931 }
1932 
1933 const KURL& KDirLister::url() const
1934 {
1935  return d->url;
1936 }
1937 
1938 const KURL::List& KDirLister::directories() const
1939 {
1940  return d->lstDirs;
1941 }
1942 
1943 void KDirLister::emitChanges()
1944 {
1945  if ( d->changes == NONE )
1946  return;
1947 
1948  static const TQString& dot = KGlobal::staticQString(".");
1949  static const TQString& dotdot = KGlobal::staticQString("..");
1950 
1951  for ( KURL::List::Iterator it = d->lstDirs.begin();
1952  it != d->lstDirs.end(); ++it )
1953  {
1954  KFileItemListIterator kit( *s_pCache->itemsForDir( *it ) );
1955  for ( ; kit.current(); ++kit )
1956  {
1957  if ( (*kit)->text() == dot || (*kit)->text() == dotdot )
1958  continue;
1959 
1960  bool oldMime = true, newMime = true;
1961 
1962  if ( d->changes & MIME_FILTER )
1963  {
1964  oldMime = doMimeFilter( (*kit)->mimetype(), d->oldMimeFilter )
1965  && doMimeExcludeFilter( (*kit)->mimetype(), d->oldMimeExcludeFilter );
1966  newMime = doMimeFilter( (*kit)->mimetype(), d->mimeFilter )
1967  && doMimeExcludeFilter( (*kit)->mimetype(), d->mimeExcludeFilter );
1968 
1969  if ( oldMime && !newMime )
1970  {
1971  emit deleteItem( *kit );
1972  continue;
1973  }
1974  }
1975 
1976  if ( d->changes & DIR_ONLY_MODE )
1977  {
1978  // the lister switched to dirOnlyMode
1979  if ( d->dirOnlyMode )
1980  {
1981  if ( !(*kit)->isDir() )
1982  emit deleteItem( *kit );
1983  }
1984  else if ( !(*kit)->isDir() )
1985  addNewItem( *kit );
1986 
1987  continue;
1988  }
1989 
1990  if ( (*kit)->isHidden() )
1991  {
1992  if ( d->changes & DOT_FILES )
1993  {
1994  // the lister switched to dot files mode
1995  if ( d->isShowingDotFiles )
1996  addNewItem( *kit );
1997  else
1998  emit deleteItem( *kit );
1999 
2000  continue;
2001  }
2002  }
2003  else if ( d->changes & NAME_FILTER )
2004  {
2005  bool oldName = (*kit)->isDir() ||
2006  d->oldFilters.isEmpty() ||
2007  doNameFilter( (*kit)->text(), d->oldFilters );
2008 
2009  bool newName = (*kit)->isDir() ||
2010  d->lstFilters.isEmpty() ||
2011  doNameFilter( (*kit)->text(), d->lstFilters );
2012 
2013  if ( oldName && !newName )
2014  {
2015  emit deleteItem( *kit );
2016  continue;
2017  }
2018  else if ( !oldName && newName )
2019  addNewItem( *kit );
2020  }
2021 
2022  if ( (d->changes & MIME_FILTER) && !oldMime && newMime )
2023  addNewItem( *kit );
2024  }
2025 
2026  emitItems();
2027  }
2028 
2029  d->changes = NONE;
2030 }
2031 
2032 void KDirLister::updateDirectory( const KURL& _u )
2033 {
2034  s_pCache->updateDirectory( _u );
2035 }
2036 
2037 bool KDirLister::isFinished() const
2038 {
2039  return d->complete;
2040 }
2041 
2042 KFileItem *KDirLister::rootItem() const
2043 {
2044  return d->rootFileItem;
2045 }
2046 
2047 KFileItem *KDirLister::findByURL( const KURL& _url ) const
2048 {
2049  return s_pCache->findByURL( this, _url );
2050 }
2051 
2052 KFileItem *KDirLister::findByName( const TQString& _name ) const
2053 {
2054  return s_pCache->findByName( this, _name );
2055 }
2056 
2057 #ifndef KDE_NO_COMPAT
2058 KFileItem *KDirLister::find( const KURL& _url ) const
2059 {
2060  return findByURL( _url );
2061 }
2062 #endif
2063 
2064 
2065 // ================ public filter methods ================ //
2066 
2067 void KDirLister::setNameFilter( const TQString& nameFilter )
2068 {
2069  if ( !(d->changes & NAME_FILTER) )
2070  {
2071  d->oldFilters = d->lstFilters;
2072  d->lstFilters.setAutoDelete( false );
2073  }
2074 
2075  d->lstFilters.clear();
2076  d->lstFilters.setAutoDelete( true );
2077 
2078  d->nameFilter = nameFilter;
2079 
2080  // Split on white space
2081  TQStringList list = TQStringList::split( ' ', nameFilter );
2082  for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
2083  d->lstFilters.append( new TQRegExp(*it, false, true ) );
2084 
2085  d->changes |= NAME_FILTER;
2086 }
2087 
2088 const TQString& KDirLister::nameFilter() const
2089 {
2090  return d->nameFilter;
2091 }
2092 
2093 void KDirLister::setMimeFilter( const TQStringList& mimeFilter )
2094 {
2095  if ( !(d->changes & MIME_FILTER) )
2096  d->oldMimeFilter = d->mimeFilter;
2097 
2098  if ( mimeFilter.find("all/allfiles") != mimeFilter.end() ||
2099  mimeFilter.find("all/all") != mimeFilter.end() )
2100  d->mimeFilter.clear();
2101  else
2102  d->mimeFilter = mimeFilter;
2103 
2104  d->changes |= MIME_FILTER;
2105 }
2106 
2107 void KDirLister::setMimeExcludeFilter( const TQStringList& mimeExcludeFilter )
2108 {
2109  if ( !(d->changes & MIME_FILTER) )
2110  d->oldMimeExcludeFilter = d->mimeExcludeFilter;
2111 
2112  d->mimeExcludeFilter = mimeExcludeFilter;
2113  d->changes |= MIME_FILTER;
2114 }
2115 
2116 
2117 void KDirLister::clearMimeFilter()
2118 {
2119  if ( !(d->changes & MIME_FILTER) )
2120  {
2121  d->oldMimeFilter = d->mimeFilter;
2122  d->oldMimeExcludeFilter = d->mimeExcludeFilter;
2123  }
2124  d->mimeFilter.clear();
2125  d->mimeExcludeFilter.clear();
2126  d->changes |= MIME_FILTER;
2127 }
2128 
2129 const TQStringList& KDirLister::mimeFilters() const
2130 {
2131  return d->mimeFilter;
2132 }
2133 
2134 bool KDirLister::matchesFilter( const TQString& name ) const
2135 {
2136  return doNameFilter( name, d->lstFilters );
2137 }
2138 
2139 bool KDirLister::matchesMimeFilter( const TQString& mime ) const
2140 {
2141  return doMimeFilter( mime, d->mimeFilter ) && doMimeExcludeFilter(mime,d->mimeExcludeFilter);
2142 }
2143 
2144 // ================ protected methods ================ //
2145 
2146 bool KDirLister::matchesFilter( const KFileItem *item ) const
2147 {
2148  Q_ASSERT( item );
2149  static const TQString& dotdot = KGlobal::staticQString("..");
2150 
2151  if ( item->text() == dotdot )
2152  return false;
2153 
2154  if ( !d->isShowingDotFiles && item->isHidden() )
2155  return false;
2156 
2157  if ( item->isDir() || d->lstFilters.isEmpty() )
2158  return true;
2159 
2160  return matchesFilter( item->text() );
2161 }
2162 
2163 bool KDirLister::matchesMimeFilter( const KFileItem *item ) const
2164 {
2165  Q_ASSERT( item );
2166  // Don't lose time determining the mimetype if there is no filter
2167  if ( d->mimeFilter.isEmpty() && d->mimeExcludeFilter.isEmpty() )
2168  return true;
2169  return matchesMimeFilter( item->mimetype() );
2170 }
2171 
2172 bool KDirLister::doNameFilter( const TQString& name, const TQPtrList<TQRegExp>& filters ) const
2173 {
2174  for ( TQPtrListIterator<TQRegExp> it( filters ); it.current(); ++it )
2175  if ( it.current()->exactMatch( name ) )
2176  return true;
2177 
2178  return false;
2179 }
2180 
2181 bool KDirLister::doMimeFilter( const TQString& mime, const TQStringList& filters ) const
2182 {
2183  if ( filters.isEmpty() )
2184  return true;
2185 
2186  KMimeType::Ptr mimeptr = KMimeType::mimeType(mime);
2187  //kdDebug(7004) << "doMimeFilter: investigating: "<<mimeptr->name()<<endl;
2188  TQStringList::ConstIterator it = filters.begin();
2189  for ( ; it != filters.end(); ++it )
2190  if ( mimeptr->is(*it) )
2191  return true;
2192  //else kdDebug(7004) << "doMimeFilter: compared without result to "<<*it<<endl;
2193 
2194 
2195  return false;
2196 }
2197 
2198 bool KDirLister::doMimeExcludeFilter( const TQString& mime, const TQStringList& filters ) const
2199 {
2200  if ( filters.isEmpty() )
2201  return true;
2202 
2203  TQStringList::ConstIterator it = filters.begin();
2204  for ( ; it != filters.end(); ++it )
2205  if ( (*it) == mime )
2206  return false;
2207 
2208  return true;
2209 }
2210 
2211 
2212 bool KDirLister::validURL( const KURL& _url ) const
2213 {
2214  return s_pCache->validURL( this, _url );
2215 }
2216 
2217 void KDirLister::handleError( KIO::Job *job )
2218 {
2219  if ( d->autoErrorHandling )
2220  job->showErrorDialog( d->errorParent );
2221 }
2222 
2223 
2224 // ================= private methods ================= //
2225 
2226 void KDirLister::addNewItem( const KFileItem *item )
2227 {
2228  if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) )
2229  return; // No reason to continue... bailing out here prevents a mimetype scan.
2230 
2231  if ( matchesMimeFilter( item ) )
2232  {
2233  if ( !d->lstNewItems )
2234  d->lstNewItems = new KFileItemList;
2235 
2236  d->lstNewItems->append( item ); // items not filtered
2237  }
2238  else
2239  {
2240  if ( !d->lstMimeFilteredItems )
2241  d->lstMimeFilteredItems = new KFileItemList;
2242 
2243  d->lstMimeFilteredItems->append( item ); // only filtered by mime
2244  }
2245 }
2246 
2247 void KDirLister::addNewItems( const KFileItemList& items )
2248 {
2249  // TODO: make this faster - test if we have a filter at all first
2250  // DF: was this profiled? The matchesFoo() functions should be fast, w/o filters...
2251  // Of course if there is no filter and we can do a range-insertion instead of a loop, that might be good.
2252  // But that's for Qt4, not possible with TQPtrList.
2253  for ( KFileItemListIterator kit( items ); kit.current(); ++kit )
2254  addNewItem( *kit );
2255 }
2256 
2257 void KDirLister::aboutToRefreshItem( const KFileItem *item )
2258 {
2259  // The code here follows the logic in addNewItem
2260  if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) )
2261  d->refreshItemWasFiltered = true;
2262  else if ( !matchesMimeFilter( item ) )
2263  d->refreshItemWasFiltered = true;
2264  else
2265  d->refreshItemWasFiltered = false;
2266 }
2267 
2268 void KDirLister::addRefreshItem( const KFileItem *item )
2269 {
2270  bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item );
2271 
2272  if ( !isExcluded && matchesMimeFilter( item ) )
2273  {
2274  if ( d->refreshItemWasFiltered )
2275  {
2276  if ( !d->lstNewItems )
2277  d->lstNewItems = new KFileItemList;
2278 
2279  d->lstNewItems->append( item );
2280  }
2281  else
2282  {
2283  if ( !d->lstRefreshItems )
2284  d->lstRefreshItems = new KFileItemList;
2285 
2286  d->lstRefreshItems->append( item );
2287  }
2288  }
2289  else if ( !d->refreshItemWasFiltered )
2290  {
2291  if ( !d->lstRemoveItems )
2292  d->lstRemoveItems = new KFileItemList;
2293 
2294  // notify the user that the mimetype of a file changed that doesn't match
2295  // a filter or does match an exclude filter
2296  d->lstRemoveItems->append( item );
2297  }
2298 }
2299 
2300 void KDirLister::emitItems()
2301 {
2302  KFileItemList *tmpNew = d->lstNewItems;
2303  d->lstNewItems = 0;
2304 
2305  KFileItemList *tmpMime = d->lstMimeFilteredItems;
2306  d->lstMimeFilteredItems = 0;
2307 
2308  KFileItemList *tmpRefresh = d->lstRefreshItems;
2309  d->lstRefreshItems = 0;
2310 
2311  KFileItemList *tmpRemove = d->lstRemoveItems;
2312  d->lstRemoveItems = 0;
2313 
2314  if ( tmpNew )
2315  {
2316  emit newItems( *tmpNew );
2317  delete tmpNew;
2318  }
2319 
2320  if ( tmpMime )
2321  {
2322  emit itemsFilteredByMime( *tmpMime );
2323  delete tmpMime;
2324  }
2325 
2326  if ( tmpRefresh )
2327  {
2328  emit refreshItems( *tmpRefresh );
2329  delete tmpRefresh;
2330  }
2331 
2332  if ( tmpRemove )
2333  {
2334  for ( KFileItem *tmp = tmpRemove->first(); tmp; tmp = tmpRemove->next() )
2335  emit deleteItem( tmp );
2336  delete tmpRemove;
2337  }
2338 }
2339 
2340 void KDirLister::emitDeleteItem( KFileItem *item )
2341 {
2342  if ( ( d->dirOnlyMode && !item->isDir() ) || !matchesFilter( item ) )
2343  return; // No reason to continue... bailing out here prevents a mimetype scan.
2344  if ( matchesMimeFilter( item ) )
2345  emit deleteItem( item );
2346 }
2347 
2348 
2349 // ================ private slots ================ //
2350 
2351 void KDirLister::slotInfoMessage( KIO::Job *, const TQString& message )
2352 {
2353  emit infoMessage( message );
2354 }
2355 
2356 void KDirLister::slotPercent( KIO::Job *job, unsigned long pcnt )
2357 {
2358  d->jobData[static_cast<KIO::ListJob *>(job)].percent = pcnt;
2359 
2360  int result = 0;
2361 
2362  KIO::filesize_t size = 0;
2363 
2364  TQMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
2365  while ( dataIt != d->jobData.end() )
2366  {
2367  result += (*dataIt).percent * (*dataIt).totalSize;
2368  size += (*dataIt).totalSize;
2369  ++dataIt;
2370  }
2371 
2372  if ( size != 0 )
2373  result /= size;
2374  else
2375  result = 100;
2376  emit percent( result );
2377 }
2378 
2379 void KDirLister::slotTotalSize( KIO::Job *job, KIO::filesize_t size )
2380 {
2381  d->jobData[static_cast<KIO::ListJob *>(job)].totalSize = size;
2382 
2383  KIO::filesize_t result = 0;
2384  TQMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
2385  while ( dataIt != d->jobData.end() )
2386  {
2387  result += (*dataIt).totalSize;
2388  ++dataIt;
2389  }
2390 
2391  emit totalSize( result );
2392 }
2393 
2394 void KDirLister::slotProcessedSize( KIO::Job *job, KIO::filesize_t size )
2395 {
2396  d->jobData[static_cast<KIO::ListJob *>(job)].processedSize = size;
2397 
2398  KIO::filesize_t result = 0;
2399  TQMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
2400  while ( dataIt != d->jobData.end() )
2401  {
2402  result += (*dataIt).processedSize;
2403  ++dataIt;
2404  }
2405 
2406  emit processedSize( result );
2407 }
2408 
2409 void KDirLister::slotSpeed( KIO::Job *job, unsigned long spd )
2410 {
2411  d->jobData[static_cast<KIO::ListJob *>(job)].speed = spd;
2412 
2413  int result = 0;
2414  TQMap< KIO::ListJob *, KDirListerPrivate::JobData >::Iterator dataIt = d->jobData.begin();
2415  while ( dataIt != d->jobData.end() )
2416  {
2417  result += (*dataIt).speed;
2418  ++dataIt;
2419  }
2420 
2421  emit speed( result );
2422 }
2423 
2424 uint KDirLister::numJobs()
2425 {
2426  return d->jobData.count();
2427 }
2428 
2429 void KDirLister::jobDone( KIO::ListJob *job )
2430 {
2431  d->jobData.remove( job );
2432 }
2433 
2434 void KDirLister::jobStarted( KIO::ListJob *job )
2435 {
2436  KDirListerPrivate::JobData jobData;
2437  jobData.speed = 0;
2438  jobData.percent = 0;
2439  jobData.processedSize = 0;
2440  jobData.totalSize = 0;
2441 
2442  d->jobData.insert( job, jobData );
2443  d->complete = false;
2444 }
2445 
2446 void KDirLister::connectJob( KIO::ListJob *job )
2447 {
2448  connect( job, TQT_SIGNAL(infoMessage( KIO::Job *, const TQString& )),
2449  this, TQT_SLOT(slotInfoMessage( KIO::Job *, const TQString& )) );
2450  connect( job, TQT_SIGNAL(percent( KIO::Job *, unsigned long )),
2451  this, TQT_SLOT(slotPercent( KIO::Job *, unsigned long )) );
2452  connect( job, TQT_SIGNAL(totalSize( KIO::Job *, KIO::filesize_t )),
2453  this, TQT_SLOT(slotTotalSize( KIO::Job *, KIO::filesize_t )) );
2454  connect( job, TQT_SIGNAL(processedSize( KIO::Job *, KIO::filesize_t )),
2455  this, TQT_SLOT(slotProcessedSize( KIO::Job *, KIO::filesize_t )) );
2456  connect( job, TQT_SIGNAL(speed( KIO::Job *, unsigned long )),
2457  this, TQT_SLOT(slotSpeed( KIO::Job *, unsigned long )) );
2458 }
2459 
2460 void KDirLister::setMainWindow( TQWidget *window )
2461 {
2462  d->window = window;
2463 }
2464 
2465 TQWidget *KDirLister::mainWindow()
2466 {
2467  return d->window;
2468 }
2469 
2470 KFileItemList KDirLister::items( WhichItems which ) const
2471 {
2472  return itemsForDir( url(), which );
2473 }
2474 
2475 KFileItemList KDirLister::itemsForDir( const KURL& dir, WhichItems which ) const
2476 {
2477  KFileItemList result;
2478  KFileItemList *allItems = s_pCache->itemsForDir( dir );
2479  if ( !allItems )
2480  return result;
2481 
2482  if ( which == AllItems )
2483  result = *allItems; // shallow copy
2484  else // only items passing the filters
2485  {
2486  for ( KFileItemListIterator kit( *allItems ); kit.current(); ++kit )
2487  {
2488  KFileItem *item = *kit;
2489  bool isExcluded = (d->dirOnlyMode && !item->isDir()) || !matchesFilter( item );
2490  if ( !isExcluded && matchesMimeFilter( item ) )
2491  result.append( item );
2492  }
2493  }
2494 
2495  return result;
2496 }
2497 
2498 // to keep BC changes
2499 
2500 void KDirLister::virtual_hook( int, void * )
2501 { /*BASE::virtual_hook( id, data );*/ }
2502 
2503 #include "kdirlister.moc"
2504 #include "kdirlister_p.moc"
KDirLister::matchesFilter
bool matchesFilter(const TQString &name) const
Checks whether name matches a filter in the list of name filters.
Definition: kdirlister.cpp:2134
KDirLister::percent
void percent(int percent)
Progress signal showing the overall progress of the KDirLister.
KDirLister::~KDirLister
virtual ~KDirLister()
Destroy the directory lister.
Definition: kdirlister.cpp:1840
KIO::Job::window
TQWidget * window() const
Returns the window this job is associated with.
Definition: job.cpp:358
KDirLister::setMimeExcludeFilter
void setMimeExcludeFilter(const TQStringList &mimeList)
Filtering should be done with KFileFilter.
Definition: kdirlister.cpp:2107
KDirLister::setShowingDotFiles
virtual void setShowingDotFiles(bool _showDotFiles)
Changes the "is viewing dot files" setting.
Definition: kdirlister.cpp:1899
KFileItem::url
const KURL & url() const
Returns the url of the file.
Definition: kfileitem.h:113
KFileItem::isDir
bool isDir() const
Returns true if this item represents a directory.
Definition: kfileitem.cpp:734
KDirLister::mainWindow
TQWidget * mainWindow()
Returns the main window associated with this object.
Definition: kdirlister.cpp:2465
KIO::Job::showErrorDialog
void showErrorDialog(TQWidget *parent=0L)
Display a dialog box to inform the user of the error given by this job.
Definition: job.cpp:294
KDirLister::setAutoUpdate
virtual void setAutoUpdate(bool enable)
Enable/disable automatic directory updating, when a directory changes (using KDirWatch).
Definition: kdirlister.cpp:1885
KIO::ListJob
A ListJob is allows you to get the get the content of a directory.
Definition: jobclasses.h:1392
KIO::SimpleJob::url
const KURL & url() const
Returns the SimpleJob's URL.
Definition: jobclasses.h:549
KDirLister::handleError
virtual void handleError(KIO::Job *)
Reimplement to customize error handling.
Definition: kdirlister.cpp:2217
KFileItem::refresh
void refresh()
Throw away and re-read (for local files) all information about the file.
Definition: kfileitem.cpp:268
KDirLister::rootItem
KFileItem * rootItem() const
Returns the file item of the URL.
Definition: kdirlister.cpp:2042
KDirLister::clearMimeFilter
virtual void clearMimeFilter()
Clears the mime based filter.
Definition: kdirlister.cpp:2117
KFileItem::name
const TQString & name(bool lowerCase=false) const
Return the name of the file item (without a path).
Definition: kfileitem.h:298
KDirLister::doNameFilter
virtual bool doNameFilter(const TQString &name, const TQPtrList< TQRegExp > &filters) const
Called by the public matchesFilter() to do the actual filtering.
Definition: kdirlister.cpp:2172
KIO::Job::setWindow
void setWindow(TQWidget *window)
Associate this job with a window given by window.
Definition: job.cpp:352
KMimeType::mimeType
static Ptr mimeType(const TQString &_name)
Retrieve a pointer to the mime type _name or a pointer to the default mime type "application/octet-st...
Definition: kmimetype.cpp:141
KDirLister::dirOnlyMode
bool dirOnlyMode() const
Checks whether the KDirLister only lists directories or all files.
KDirLister::itemsForDir
KFileItemList itemsForDir(const KURL &dir, WhichItems which=FilteredItems) const
Returns the items listed for the given dir.
Definition: kdirlister.cpp:2475
KFileItem::mark
void mark()
Marks the item.
Definition: kfileitem.h:426
KIO::manually_mounted
KIO_EXPORT bool manually_mounted(const TQString &filename)
Checks if the path belongs to a filesystem that is manually mounted.
Definition: global.cpp:1946
KDirLister::totalSize
void totalSize(KIO::filesize_t size)
Emitted when we know the size of the jobs.
KDirLister::refreshItems
void refreshItems(const KFileItemList &items)
Signal an item to refresh (its mimetype/icon/name has changed).
KDirLister::mimeFilters
const TQStringList & mimeFilters() const
Returns the list of mime based filters, as set via setMimeFilter().
Definition: kdirlister.cpp:2129
KFileItem::isLocalFile
bool isLocalFile() const
Returns true if the file is a local file.
Definition: kfileitem.h:282
KDirLister::autoErrorHandlingEnabled
bool autoErrorHandlingEnabled() const
Check whether auto error handling is enabled.
KIO::listDir
KIO_EXPORT ListJob * listDir(const KURL &url, bool showProgressInfo=true, bool includeHidden=true)
List the contents of url, which is assumed to be a directory.
Definition: job.cpp:2152
KDirLister::stop
virtual void stop()
Stop listing all directories currently being listed.
Definition: kdirlister.cpp:1868
KIO::SimpleJob::kill
virtual void kill(bool quietly=true)
Abort job.
Definition: job.cpp:457
KDirLister::deleteItem
void deleteItem(KFileItem *_fileItem)
Signal an item to remove.
KDirLister::infoMessage
void infoMessage(const TQString &msg)
Emitted to display information about running jobs.
KDirLister::findByName
virtual KFileItem * findByName(const TQString &name) const
Find an item by its name.
Definition: kdirlister.cpp:2052
KDirLister::setDirOnlyMode
virtual void setDirOnlyMode(bool dirsOnly)
Call this to list only directories.
Definition: kdirlister.cpp:1913
KFileItem::setURL
void setURL(const KURL &url)
Sets the item's URL.
Definition: kfileitem.cpp:297
KDirLister::items
KFileItemList items(WhichItems which=FilteredItems) const
Returns the items listed for the current url().
Definition: kdirlister.cpp:2470
KDirLister::directories
const KURL::List & directories() const
Returns all URLs that are listed by this KDirLister.
Definition: kdirlister.cpp:1938
KDirLister::newItems
void newItems(const KFileItemList &items)
Signal new items.
KDirLister::speed
void speed(int bytes_per_second)
Emitted to display information about the speed of the jobs.
KDirLister::updateDirectory
virtual void updateDirectory(const KURL &_dir)
Update the directory _dir.
Definition: kdirlister.cpp:2032
KFileItem::mimetype
TQString mimetype() const
Returns the mimetype of the file item.
Definition: kfileitem.cpp:518
KDirLister::matchesMimeFilter
bool matchesMimeFilter(const TQString &mime) const
Checks whether mime matches a filter in the list of mime types.
Definition: kdirlister.cpp:2139
KIO::UDS_NAME
Filename - as displayed in directory listings etc.
Definition: global.h:334
KDirLister::setMimeFilter
virtual void setMimeFilter(const TQStringList &mimeList)
Set mime-based filter to only list items matching the given mimetypes.
Definition: kdirlister.cpp:2093
KProtocolInfo::supportsListing
static bool supportsListing(const KURL &url)
Returns whether the protocol can list files/objects.
Definition: kprotocolinfo.cpp:121
KFileItem::setUDSEntry
void setUDSEntry(const KIO::UDSEntry &entry, const KURL &url, bool determineMimeTypeOnDemand=false, bool urlIsDirectory=false)
Reinitialize KFileItem with a new UDSEntry.
Definition: kfileitem.cpp:977
KFileItem::localPath
TQString localPath() const
Returns the local path if isLocalFile() == true or the KIO item has a UDS_LOCAL_PATH atom...
Definition: kfileitem.cpp:332
KDirLister::isFinished
bool isFinished() const
Returns true if no io operation is currently in progress.
Definition: kdirlister.cpp:2037
KDirLister::canceled
void canceled()
Tell the view that the user canceled the listing.
KDirLister::completed
void completed()
Tell the view that listing is finished.
KDirLister::started
void started(const KURL &_url)
Tell the view that we started to list _url.
KDirLister::url
const KURL & url() const
Returns the top level URL that is listed by this KDirLister.
Definition: kdirlister.cpp:1933
KIO::filesize_t
TQ_ULLONG filesize_t
64-bit file size
Definition: global.h:39
KFileItem::refreshMimeType
void refreshMimeType()
Re-reads mimetype information.
Definition: kfileitem.cpp:286
KDirLister::findByURL
virtual KFileItem * findByURL(const KURL &_url) const
Find an item by its URL.
Definition: kdirlister.cpp:2047
KDirLister::showingDotFiles
bool showingDotFiles() const
Checks whether hidden files (files beginning with a dot) will be shown.
KIO::Job::error
int error() const
Returns the error code, if there has been an error.
Definition: jobclasses.h:95
KDirLister::clear
void clear()
Signal to clear all items.
KDirLister::KDirLister
KDirLister(bool _delayedMimeTypes=false)
Create a directory lister.
Definition: kdirlister.cpp:1824
KDirLister::WhichItems
WhichItems
Used by items() and itemsForDir() to specify whether you want all items for a directory or just the f...
Definition: kdirlister.h:363
KDirLister::itemsFilteredByMime
void itemsFilteredByMime(const KFileItemList &items)
Send a list of items filtered-out by mime-type.
KDirLister::processedSize
void processedSize(KIO::filesize_t size)
Regularly emitted to show the progress of this KDirLister.
KDirLister::redirection
void redirection(const KURL &_url)
Signal a redirection.
KDirLister::autoUpdate
bool autoUpdate() const
Checks whether KDirWatch will automatically update directories.
KDirLister::setAutoErrorHandlingEnabled
void setAutoErrorHandlingEnabled(bool enable, TQWidget *parent)
Enable or disable auto error handling is enabled.
Definition: kdirlister.cpp:1927
KFileItem::isMarked
bool isMarked() const
Used when updating a directory.
Definition: kfileitem.h:421
KIO::Job
The base class for all jobs.
Definition: jobclasses.h:68
KDirLister::setMainWindow
void setMainWindow(TQWidget *window)
Pass the main window this object is associated with this is used for caching authentication data...
Definition: kdirlister.cpp:2460
KFileItem::isHidden
bool isHidden() const
Checks whether the file is hidden.
Definition: kfileitem.cpp:723
KDirLister::setNameFilter
virtual void setNameFilter(const TQString &filter)
Set a name filter to only list items matching this name, e.g.
Definition: kdirlister.cpp:2067
KDirWatch::exists
static bool exists()
Returns true if there is an instance of KDirWatch.
Definition: kdirwatch.cpp:1605
KDirLister
The dir lister deals with the kiojob used to list and update a directory and has signals for the user...
Definition: kdirlister.h:55
KFileItem::text
const TQString & text() const
Returns the text of the file item.
Definition: kfileitem.h:289
KDirLister::validURL
virtual bool validURL(const KURL &) const
Checks if an url is malformed or not and displays an error message if it is and autoErrorHandling is ...
Definition: kdirlister.cpp:2212
KDirLister::nameFilter
const TQString & nameFilter() const
Returns the current name filter, as set via setNameFilter()
KIO::ListJob::redirectionURL
const KURL & redirectionURL() const
Returns the ListJob's redirection URL.
Definition: jobclasses.h:1424
KDirLister::emitChanges
virtual void emitChanges()
Actually emit the changes made with setShowingDotFiles, setDirOnlyMode, setNameFilter and setMimeFilt...
Definition: kdirlister.cpp:1943
KDirLister::doMimeFilter
virtual bool doMimeFilter(const TQString &mime, const TQStringList &filters) const
Called by the public matchesMimeFilter() to do the actual filtering.
Definition: kdirlister.cpp:2181
KFileItem
A KFileItem is a generic class to handle a file, local or remote.
Definition: kfileitem.h:41
KDirLister::openURL
virtual bool openURL(const KURL &_url, bool _keep=false, bool _reload=false)
Run the directory lister on the given url.
Definition: kdirlister.cpp:1854

kio/kio

Skip menu "kio/kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kio/kio

Skip menu "kio/kio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kio/kio by doxygen 1.8.8
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |