26 #include <QtCore/QRegExp>
54 connect( &pendingUpdateTimer, SIGNAL(
timeout()),
this, SLOT(processPendingUpdates()) );
55 pendingUpdateTimer.setSingleShot(
true );
58 this, SLOT(slotFileDirty(
QString)) );
60 this, SLOT(slotFileCreated(
QString)) );
62 this, SLOT(slotFileDeleted(
QString)) );
66 connect(kdirnotify, SIGNAL(FilesAdded(
QString)), SLOT(slotFilesAdded(
QString)));
72 qAddPostRoutine(kDirListerCache.destroy);
79 qDeleteAll(itemsInUse);
83 directoryData.clear();
92 bool _keep,
bool _reload )
115 resolved = QFileInfo(local).canonicalFilePath();
116 if (local != resolved)
117 canonicalUrls[resolved].append(urlStr);
124 if (!validUrl(lister, _url)) {
125 kDebug(7004) << lister <<
"url=" << _url <<
"not a valid url";
142 }
else if (lister->d->
lstDirs.contains(_url)) {
149 lister->d->
lstDirs.removeAll(_url);
154 if (lister->d->
url == _url)
160 lister->d->
lstDirs.append(_url);
162 if (lister->d->
url.isEmpty() || !_keep)
163 lister->d->
url = _url;
165 DirItem *itemU = itemsInUse.value(urlStr);
175 DirItem *itemFromCache = 0;
176 if (itemU || (!_reload && (itemFromCache = itemsCached.take(urlStr)) ) ) {
178 kDebug(7004) <<
"Entry already in use:" << _url;
181 kDebug(7004) <<
"Entry in cache:" << _url;
182 itemsInUse.insert(urlStr, itemFromCache);
183 itemU = itemFromCache;
186 itemU->incAutoUpdate();
188 if (itemFromCache && itemFromCache->watchedWhileInCache) {
189 itemFromCache->watchedWhileInCache =
false;;
190 itemFromCache->decAutoUpdate();
202 kDebug(7004) <<
"Reloading directory:" << _url;
203 itemsCached.remove(urlStr);
205 kDebug(7004) <<
"Listing directory:" << _url;
208 itemU =
new DirItem(_url, resolved);
209 itemsInUse.insert(urlStr, itemU);
211 itemU->incAutoUpdate();
231 connect(job, SIGNAL(result(
KJob*)),
232 this, SLOT(slotResult(
KJob*)));
263 if (!itemU->lstItems.isEmpty()) {
264 kDebug() <<
"Listing" << itemU->lstItems.count() <<
"cached items soon";
290 m_lister(lister), m_url(url),
291 m_reload(reload), m_emitCompleted(true)
295 kWarning(7004) <<
"Lister" << lister <<
"has a cached items job already for" <<
url;
307 kDirListerCache->emitItemsFromCache(
this, m_lister, m_url, m_reload, m_emitCompleted);
314 kDirListerCache->forgetCachedItemsJob(
this, m_lister, m_url);
315 if (!property(
"_kdlc_silent").toBool()) {
316 emit m_lister->canceled(m_url);
317 emit m_lister->canceled();
329 DirItem *itemU = kDirListerCache->itemsInUse.value(urlStr);
331 kWarning(7004) <<
"Can't find item for directory" << urlStr <<
"anymore";
335 _reload = _reload || !itemU->complete;
340 if (!items.isEmpty()) {
347 forgetCachedItemsJob(cachedItemsJob, lister, _url);
353 if (_emitCompleted) {
387 bool KDirListerCache::validUrl(
const KDirLister *lister,
const KUrl&
url )
const
389 if ( !url.isValid() )
420 Q_FOREACH(
const KUrl& url, urls) {
421 stopListingUrl(lister, url, silent);
425 QHash<QString,KDirListerCacheDirectoryData>::iterator dirit = directoryData.begin();
426 const QHash<QString,KDirListerCacheDirectoryData>::iterator dirend = directoryData.end();
427 for( ; dirit != dirend ; ++dirit ) {
430 kDebug(7004) <<
"ERROR: found lister" << lister <<
"in list - for" << dirit.key();
444 if (cachedItemsJob) {
446 cachedItemsJob->setProperty(
"_kdlc_silent",
true);
448 cachedItemsJob->
kill();
452 kDebug(7004) << lister <<
" url=" <<
url;
454 QHash<QString,KDirListerCacheDirectoryData>::iterator dirit = directoryData.find(urlStr);
455 if (dirit == directoryData.end())
462 stopListJob(urlStr, silent);
475 void KDirListerCache::stopListJob(
const QString& url,
bool silent)
490 job->setProperty(
"_kdlc_silent",
true);
500 for ( KUrl::List::const_iterator it = lister->d->
lstDirs.constBegin();
501 it != lister->d->
lstDirs.constEnd(); ++it ) {
502 DirItem* dirItem = itemsInUse.value((*it).url());
505 dirItem->incAutoUpdate();
507 dirItem->decAutoUpdate();
515 emit lister->
clear();
524 for ( KUrl::List::const_iterator it = lstDirsCopy.begin();
525 it != lstDirsCopy.end(); ++it ) {
526 forgetDirs( lister, *it,
false );
534 if (possibleMountPoints.isEmpty())
538 const bool supermount = mp->mountType() ==
"supermount";
543 return mp->mountOptions().contains(
"noauto");
555 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
556 if (dit == directoryData.end())
566 DirItem *item = itemsInUse.value(urlStr);
568 bool insertIntoCache =
false;
572 directoryData.erase(dit);
573 itemsInUse.remove( urlStr );
578 kDebug(7004) <<
"Killing update job for " << urlStr;
584 if ( lister->d->
numJobs() == 0 ) {
591 lister->d->
lstDirs.removeAll( url );
592 emit lister->
clear( url );
595 insertIntoCache = item->complete;
596 if (insertIntoCache) {
606 const bool isLocal = item->url.isLocalFile();
607 bool isManuallyMounted =
false;
608 bool containsManuallyMounted =
false;
610 isManuallyMounted =
manually_mounted( item->url.toLocalFile(), possibleMountPoints );
611 if ( !isManuallyMounted ) {
615 KFileItemList::const_iterator kit = item->lstItems.constBegin();
616 KFileItemList::const_iterator kend = item->lstItems.constEnd();
617 for ( ; kit != kend && !containsManuallyMounted; ++kit )
618 if ( (*kit).isDir() &&
manually_mounted((*kit).url().toLocalFile(), possibleMountPoints) )
619 containsManuallyMounted =
true;
623 if ( isManuallyMounted || containsManuallyMounted )
625 kDebug(7004) <<
"Not adding a watch on " << item->url <<
" because it " <<
626 ( isManuallyMounted ?
"is manually mounted" :
"contains a manually mounted subdir" );
627 item->complete =
false;
629 item->incAutoUpdate();
630 item->watchedWhileInCache =
true;
641 item->decAutoUpdate();
644 if (item && insertIntoCache) {
645 kDebug(7004) << lister <<
"item moved into cache:" <<
url;
646 itemsCached.insert(urlStr, item);
655 if (!checkUpdate(urlStr)) {
658 if (!pendingUpdateTimer.isActive())
659 pendingUpdateTimer.start(500);
695 if (cachedItemsJob) {
697 cachedItemsJob->
done();
698 delete cachedItemsJob;
708 if (!(listers.isEmpty() || killed)) {
709 kWarning() <<
"The unexpected happened.";
710 kWarning() <<
"listers for" << _dir <<
"=" << listers;
719 Q_ASSERT( listers.isEmpty() || killed );
726 connect( job, SIGNAL(result(
KJob*)),
727 this, SLOT(slotUpdateResult(
KJob*)) );
729 kDebug(7004) <<
"update started in" << _dir;
735 if ( !holders.isEmpty() ) {
740 if ( first && kdl->d->
window ) {
742 job->ui()->setWindow( kdl->d->
window );
747 job->ui()->setWindow( window );
756 bool KDirListerCache::checkUpdate(
const QString& _dir )
758 if ( !itemsInUse.contains(_dir) )
760 DirItem *item = itemsCached[_dir];
761 if ( item && item->complete )
765 item->complete =
false;
766 item->watchedWhileInCache =
false;
767 item->decAutoUpdate();
790 KDirListerCache::DirItem *KDirListerCache::dirItemForUrl(
const KUrl&
dir)
const
793 DirItem *item = itemsInUse.value(urlStr);
795 item = itemsCached[urlStr];
801 DirItem *item = dirItemForUrl(dir);
802 return item ? &item->lstItems : 0;
809 for (KUrl::List::const_iterator it = lister->d->
lstDirs.constBegin();
810 it != lister->d->
lstDirs.constEnd(); ++it) {
811 DirItem* dirItem = itemsInUse.value((*it).url());
813 const KFileItem item = dirItem->lstItems.findByName(_name);
829 DirItem* dirItem = dirItemForUrl(parentDir);
832 if (!lister || lister->d->
lstDirs.contains(parentDir)) {
833 KFileItemList::iterator it = dirItem->lstItems.begin();
834 const KFileItemList::iterator
end = dirItem->lstItems.end();
835 for (; it != end ; ++it) {
836 if ((*it).url() ==
url) {
846 dirItem = dirItemForUrl(url);
847 if (dirItem && !dirItem->rootItem.isNull() && dirItem->rootItem.url() ==
url) {
849 if (!lister || lister->d->
lstDirs.contains(url)) {
850 return &dirItem->rootItem;
884 for (KUrl::List::const_iterator it = fileList.begin(); it != fileList.end() ; ++it) {
886 DirItem* dirItem = dirItemForUrl(url);
888 deletedSubdirs.append(url);
889 if (!dirItem->rootItem.isNull()) {
890 removedItemsByDir[url.url()].append(dirItem->rootItem);
895 parentDir.setPath(parentDir.directory());
896 dirItem = dirItemForUrl(parentDir);
899 for (KFileItemList::iterator fit = dirItem->lstItems.begin(), fend = dirItem->lstItems.end(); fit != fend ; ++fit) {
900 if ((*fit).url() ==
url) {
902 removedItemsByDir[parentDir.url()].append(fileitem);
905 deletedSubdirs.append(url);
907 dirItem->lstItems.erase(fit);
914 for(; rit != removedItemsByDir.constEnd(); ++rit) {
917 DirectoryDataHash::const_iterator dit = directoryData.constFind(rit.key());
918 if (dit != directoryData.constEnd()) {
919 itemsDeleted((*dit).listersCurrentlyHolding, rit.value());
923 Q_FOREACH(
const KUrl& url, deletedSubdirs) {
934 QStringList::const_iterator it = fileList.begin();
935 for (; it != fileList.end() ; ++it) {
939 kDebug(7004) <<
"item not found for" <<
url;
945 pendingRemoteUpdates.insert(fileitem);
950 if (!dirsToUpdate.contains(dir))
951 dirsToUpdate.prepend(dir);
955 KUrl::List::const_iterator itdir = dirsToUpdate.constBegin();
956 for (; itdir != dirsToUpdate.constEnd() ; ++itdir)
961 processPendingUpdates();
968 kDebug(7004) << src <<
"->" << dst;
977 kDebug(7004) <<
"Item not found:" << oldurl;
988 if (existingDestItem) {
990 slotFilesRemoved(dst);
1001 if (!nameOnly && fileitem->
isDir()) {
1002 renameDir( src, dst );
1015 fileitem->
setName( dst.fileName() );
1020 QSet<KDirLister*> listers = emitRefreshItem( oldItem, *fileitem );
1031 QSet<KDirLister*> KDirListerCache::emitRefreshItem(
const KFileItem& oldItem,
const KFileItem& fileitem)
1036 KUrl parentDir( oldItem.
url() );
1037 parentDir.
setPath( parentDir.directory() );
1038 const QString parentDirURL = parentDir.url();
1039 DirectoryDataHash::iterator dit = directoryData.find(parentDirURL);
1040 QList<KDirLister *> listers;
1042 if (dit != directoryData.end())
1043 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1044 if (oldItem.
isDir()) {
1046 dit = directoryData.find(oldItem.
url().
url());
1047 if (dit != directoryData.end())
1048 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1050 QSet<KDirLister*> listersToRefresh;
1053 KUrl directoryUrl(oldItem.
url());
1059 directoryUrl.setPath(directoryUrl.directory());
1062 listersToRefresh.insert(kdl);
1064 return listersToRefresh;
1071 dirs << canonicalUrls.value(dir).toSet().toList();
1073 if (dirs.count() > 1)
1074 kDebug() << dir <<
"known as" << dirs;
1083 void KDirListerCache::slotFileDirty(
const QString& path )
1087 KDE_struct_stat buff;
1090 const bool isDir = S_ISDIR(buff.st_mode);
1094 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.toLocalFile())) {
1095 handleDirDirty(dir);
1098 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.directory())) {
1100 aliasUrl.addPath(url.fileName());
1101 handleFileDirty(aliasUrl);
1107 void KDirListerCache::handleDirDirty(
const KUrl& url)
1113 QMutableSetIterator<QString> pendingIt(pendingUpdates);
1114 while (pendingIt.hasNext()) {
1115 const QString updPath = pendingIt.next();
1117 if (updPath.startsWith(dirPath) &&
1118 updPath.indexOf(
'/', dirPath.length()) == -1) {
1119 kDebug(7004) <<
"forgetting about individual update to" << updPath;
1128 void KDirListerCache::handleFileDirty(
const KUrl& url)
1132 if (!existingItem) {
1140 if (!pendingUpdates.contains(filePath)) {
1142 dir.setPath(dir.directory());
1143 if (checkUpdate(dir.url())) {
1144 pendingUpdates.insert(filePath);
1145 if (!pendingUpdateTimer.isActive())
1146 pendingUpdateTimer.start(500);
1152 void KDirListerCache::slotFileCreated(
const QString& path )
1158 slotFilesAdded(fileUrl.directory());
1161 void KDirListerCache::slotFileDeleted(
const QString& path )
1166 Q_FOREACH(
KUrl url, directoriesForCanonicalPath(u.directory())) {
1168 fileUrls << url.
url();
1170 slotFilesRemoved(fileUrls);
1175 KUrl url(joburl( static_cast<KIO::ListJob *>(job) ));
1181 DirItem *dir = itemsInUse.value(urlStr);
1183 kError(7004) <<
"Internal error: job is listing" << url <<
"but itemsInUse only knows about" << itemsInUse.keys();
1188 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
1189 if (dit == directoryData.end()) {
1190 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData doesn't know about that url, only about:" << directoryData.keys();
1191 Q_ASSERT(dit != directoryData.end());
1196 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData says no listers are currently listing " << urlStr;
1209 KIO::UDSEntryList::const_iterator it = entries.begin();
1210 const KIO::UDSEntryList::const_iterator
end = entries.end();
1211 for ( ; it != end; ++it )
1215 Q_ASSERT( !name.isEmpty() );
1216 if ( name.isEmpty() )
1221 Q_ASSERT( dir->rootItem.isNull() );
1229 dir->rootItem = itemForUrl(url);
1230 if (dir->rootItem.isNull())
1231 dir->rootItem =
KFileItem( *it, url, delayedMimeTypes,
true );
1237 else if ( name !=
".." )
1239 KFileItem item( *it, url, delayedMimeTypes,
true );
1242 dir->lstItems.append( item );
1253 void KDirListerCache::slotResult(
KJob *j )
1261 runningListJobs.remove( job );
1263 KUrl jobUrl(joburl( job ));
1265 QString jobUrlStr = jobUrl.url();
1267 kDebug(7004) <<
"finished listing" << jobUrl;
1269 DirectoryDataHash::iterator dit = directoryData.find(jobUrlStr);
1270 if (dit == directoryData.end()) {
1271 kError() <<
"Nothing found in directoryData for URL" << jobUrlStr;
1275 Q_ASSERT(dit != directoryData.end());
1280 kError() <<
"OOOOPS, nothing in directoryData.listersCurrentlyListing for" << jobUrlStr;
1303 const bool silent = job->property(
"_kdlc_silent").toBool();
1318 DirItem *dir = itemsInUse.value(jobUrlStr);
1320 dir->complete =
true;
1336 processPendingUpdates();
1343 void KDirListerCache::slotRedirection(
KIO::Job *j,
const KUrl& url )
1355 if ( oldUrl == newUrl ) {
1356 kDebug(7004) <<
"New redirection url same as old, giving up.";
1358 }
else if (newUrl.isEmpty()) {
1359 kDebug(7004) <<
"New redirection url is empty, giving up.";
1363 const QString oldUrlStr = oldUrl.url();
1364 const QString newUrlStr = newUrl.url();
1366 kDebug(7004) << oldUrl <<
"->" << newUrl;
1379 DirItem *dir = itemsInUse.take(oldUrlStr);
1382 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1383 Q_ASSERT(dit != directoryData.end());
1385 directoryData.erase(dit);
1386 Q_ASSERT( !oldDirData.listersCurrentlyListing.isEmpty() );
1388 Q_ASSERT( !listers.isEmpty() );
1391 kdl->d->
redirect(oldUrlStr, newUrl,
false );
1396 const QList<KDirLister *> holders = oldDirData.listersCurrentlyHolding;
1403 kdl->d->
redirect(oldUrl, newUrl,
false );
1406 DirItem *newDir = itemsInUse.value(newUrlStr);
1408 kDebug(7004) << newUrl <<
"already in use";
1422 if ( !curListers.isEmpty() ) {
1423 kDebug(7004) <<
"and it is currently listed";
1436 curListers.append( kdl );
1438 curListers = listers;
1446 if ( !curHolders.isEmpty() ) {
1447 kDebug(7004) <<
"and it is currently held.";
1456 curHolders.append( kdl );
1458 curHolders = holders;
1464 foreach (
KDirLister *kdl, listers + holders ) {
1471 }
else if ( (newDir = itemsCached.take( newUrlStr )) ) {
1472 kDebug(7004) << newUrl <<
"is unused, but already in the cache.";
1475 itemsInUse.insert( newUrlStr, newDir );
1481 foreach (
KDirLister *kdl, listers + holders ) {
1489 kDebug(7004) << newUrl <<
"has not been listed yet.";
1492 dir->lstItems.clear();
1493 dir->redirect( newUrl );
1494 itemsInUse.insert( newUrlStr, dir );
1499 if ( holders.isEmpty() ) {
1508 job->disconnect(
this );
1512 connect( job, SIGNAL(result(
KJob*)),
1513 this, SLOT(slotUpdateResult(
KJob*)) );
1522 struct KDirListerCache::ItemInUseChange
1524 ItemInUseChange(
const QString& old,
const QString& newU, DirItem* di)
1525 : oldUrl(old), newUrl(newU), dirItem(di) {}
1531 void KDirListerCache::renameDir(
const KUrl &oldUrl,
const KUrl &newUrl )
1533 kDebug(7004) << oldUrl <<
"->" << newUrl;
1541 QLinkedList<ItemInUseChange> itemsToChange;
1542 QSet<KDirLister *> listers;
1545 QHash<QString, DirItem *>::iterator itu = itemsInUse.begin();
1546 const QHash<QString, DirItem *>::iterator ituend = itemsInUse.end();
1547 for (; itu != ituend ; ++itu) {
1548 DirItem *dir = itu.value();
1549 KUrl oldDirUrl ( itu.key() );
1554 QString relPath = oldDirUrl.path().mid( oldUrl.
path().length() );
1556 KUrl newDirUrl( newUrl );
1557 if ( !relPath.isEmpty() )
1558 newDirUrl.addPath( relPath );
1562 dir->redirect( newDirUrl );
1569 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end();
1570 kit != kend ; ++kit )
1574 const KUrl oldItemUrl ((*kit).url());
1576 KUrl newItemUrl( oldItemUrl );
1577 newItemUrl.setPath( newDirUrl.path() );
1578 newItemUrl.addPath( oldItemUrl.fileName() );
1579 kDebug(7004) <<
"renaming" << oldItemUrl <<
"to" << newItemUrl;
1580 (*kit).setUrl(newItemUrl);
1582 listers |= emitRefreshItem(oldItem, *kit);
1584 emitRedirections( oldDirUrl, newDirUrl );
1594 foreach(
const ItemInUseChange& i, itemsToChange) {
1595 itemsInUse.remove(i.oldUrl);
1596 itemsInUse.insert(i.newUrl, i.dirItem);
1601 removeDirFromCache( oldUrl );
1606 void KDirListerCache::emitRedirections(
const KUrl &oldUrl,
const KUrl &newUrl )
1608 kDebug(7004) << oldUrl <<
"->" << newUrl;
1617 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1618 if ( dit == directoryData.end() )
1620 const QList<KDirLister *> listers = (*dit).listersCurrentlyListing;
1621 const QList<KDirLister *> holders = (*dit).listersCurrentlyHolding;
1640 directoryData.erase(dit);
1642 if ( !listers.isEmpty() ) {
1652 kdl->d->
redirect(oldUrl, newUrl,
true );
1656 void KDirListerCache::removeDirFromCache(
const KUrl& dir )
1659 const QList<QString> cachedDirs = itemsCached.keys();
1660 foreach(
const QString& cachedDir, cachedDirs) {
1662 itemsCached.remove( cachedDir );
1668 runningListJobs[
static_cast<KIO::ListJob*
>(job)] += list;
1671 void KDirListerCache::slotUpdateResult(
KJob * j )
1676 KUrl jobUrl (joburl( job ));
1678 QString jobUrlStr (jobUrl.url());
1680 kDebug(7004) <<
"finished update" << jobUrl;
1690 Q_ASSERT( !listers.isEmpty() );
1692 if ( job->
error() ) {
1699 const bool silent = job->property(
"_kdlc_silent").toBool();
1703 if ( kdl->d->
numJobs() == 0 ) {
1711 runningListJobs.remove( job );
1715 processPendingUpdates();
1719 DirItem *dir = itemsInUse.value(jobUrlStr, 0);
1721 kError(7004) <<
"Internal error: itemsInUse did not contain" << jobUrlStr;
1727 dir->complete =
true;
1731 bool delayedMimeTypes =
true;
1735 QHash<QString, KFileItem*> fileItems;
1738 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end() ; kit != kend ; ++kit )
1741 fileItems.insert( (*kit).name(), &*kit );
1745 KIO::UDSEntryList::const_iterator it = buf.constBegin();
1746 const KIO::UDSEntryList::const_iterator end = buf.constEnd();
1747 for ( ; it != end; ++it )
1750 KFileItem item( *it, jobUrl, delayedMimeTypes,
true );
1752 const QString name = item.name();
1753 Q_ASSERT( !name.isEmpty() );
1757 if ( name.isEmpty() || name ==
".." )
1764 if ( dir->rootItem.isNull() )
1766 dir->rootItem = item;
1776 if (
KFileItem* tmp = fileItems.value(item.name()))
1778 QSet<KFileItem*>::iterator pru_it = pendingRemoteUpdates.find(tmp);
1779 const bool inPendingRemoteUpdates = (pru_it != pendingRemoteUpdates.end());
1782 if (!tmp->cmp( item ) || inPendingRemoteUpdates) {
1784 if (inPendingRemoteUpdates) {
1785 pendingRemoteUpdates.erase(pru_it);
1804 dir->lstItems.append( pitem );
1811 runningListJobs.remove( job );
1813 deleteUnmarkedItems( listers, dir->lstItems );
1830 processPendingUpdates();
1838 while ( it != runningListJobs.constEnd() )
1858 runningListJobs.remove( job );
1859 job->disconnect(
this );
1863 void KDirListerCache::deleteUnmarkedItems(
const QList<KDirLister *>& listers,
KFileItemList &lstItems )
1867 QMutableListIterator<KFileItem> kit(lstItems);
1868 while (kit.hasNext()) {
1872 deletedItems.append(item);
1876 if (!deletedItems.isEmpty())
1886 Q_FOREACH(
const KFileItem& item, deletedItems) {
1888 deleteDir(item.
url());
1892 void KDirListerCache::deleteDir(
const KUrl& dirUrl )
1902 QHash<QString, DirItem *>::iterator itu = itemsInUse.begin();
1903 const QHash<QString, DirItem *>::iterator ituend = itemsInUse.end();
1904 for ( ; itu != ituend; ++itu ) {
1905 const KUrl deletedUrl( itu.key() );
1907 affectedItems.append(deletedUrl);
1911 foreach(
const KUrl& deletedUrl, affectedItems) {
1912 const QString deletedUrlStr = deletedUrl.
url();
1914 DirectoryDataHash::iterator dit = directoryData.find(deletedUrlStr);
1915 if (dit != directoryData.end()) {
1917 QList<KDirLister *> listers = (*dit).listersCurrentlyListing;
1919 stopListingUrl( kdl, deletedUrl );
1924 QList<KDirLister *> holders = (*dit).listersCurrentlyHolding;
1927 if ( kdl->d->
url == deletedUrl )
1939 const bool treeview = kdl->d->
lstDirs.count() > 1;
1946 kdl->d->
lstDirs.removeAll( deletedUrl );
1948 forgetDirs( kdl, deletedUrl, treeview );
1955 int count = itemsInUse.remove( deletedUrlStr );
1956 Q_ASSERT( count == 0 );
1961 removeDirFromCache( dirUrl );
1965 void KDirListerCache::processPendingUpdates()
1967 QSet<KDirLister *> listers;
1968 foreach(
const QString& file, pendingUpdates) {
1976 listers |= emitRefreshItem( oldItem, *item );
1979 pendingUpdates.clear();
1986 void KDirListerCache::printDebug()
1988 kDebug(7004) <<
"Items in use:";
1989 QHash<QString, DirItem *>::const_iterator itu = itemsInUse.constBegin();
1990 const QHash<QString, DirItem *>::const_iterator ituend = itemsInUse.constEnd();
1991 for ( ; itu != ituend ; ++itu ) {
1992 kDebug(7004) <<
" " << itu.key() <<
"URL:" << itu.value()->url
1993 <<
"rootItem:" << ( !itu.value()->rootItem.isNull() ? itu.value()->rootItem.url() :
KUrl() )
1994 <<
"autoUpdates refcount:" << itu.value()->autoUpdates
1995 <<
"complete:" << itu.value()->complete
1996 <<
QString(
"with %1 items.").arg(itu.value()->lstItems.count());
1999 QList<KDirLister*> listersWithoutJob;
2000 kDebug(7004) <<
"Directory data:";
2001 DirectoryDataHash::const_iterator dit = directoryData.constBegin();
2002 for ( ; dit != directoryData.constEnd(); ++dit )
2005 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing )
2007 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyListing.count() <<
"listers:" <<
list;
2008 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing ) {
2011 }
else if (
KIO::ListJob* listJob = jobForUrl(dit.key())) {
2012 kDebug(7004) <<
" Lister" << listit <<
"has ListJob" << listJob;
2014 listersWithoutJob.append(listit);
2019 foreach (
KDirLister* listit, (*dit).listersCurrentlyHolding )
2021 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyHolding.count() <<
"holders:" <<
list;
2026 for ( ; jit != runningListJobs.end() ; ++jit )
2027 kDebug(7004) <<
" " << jit.key() <<
"listing" << joburl( jit.key() ) <<
":" << (*jit).count() <<
"entries.";
2029 kDebug(7004) <<
"Items in cache:";
2030 const QList<QString> cachedDirs = itemsCached.keys();
2031 foreach(
const QString& cachedDir, cachedDirs) {
2032 DirItem* dirItem = itemsCached.object(cachedDir);
2033 kDebug(7004) <<
" " << cachedDir <<
"rootItem:"
2034 << (!dirItem->rootItem.isNull() ? dirItem->rootItem.url().prettyUrl() :
QString(
"NULL") )
2035 <<
"with" << dirItem->lstItems.count() <<
"items.";
2039 Q_FOREACH(
KDirLister* listit, listersWithoutJob) {
2040 kFatal() <<
"HUH? Lister" << listit <<
"is supposed to be listing, but has no job!";
2065 if (!kDirListerCache.isDestroyed()) {
2067 kDirListerCache->forgetDirs(
this );
2081 return kDirListerCache->listDir(
this, _url, _flags & Keep, _flags &
Reload );
2086 kDirListerCache->stop(
this );
2091 kDirListerCache->stopListingUrl(
this, _url );
2105 kDirListerCache->setAutoUpdate(
this, _enable );
2176 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2181 KFileItemList::iterator kit = itemList->begin();
2182 const KFileItemList::iterator kend = itemList->end();
2183 for (; kit != kend; ++kit) {
2196 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2201 KFileItemList::iterator kit = itemList->begin();
2202 const KFileItemList::iterator kend = itemList->end();
2203 for (; kit != kend; ++kit) {
2206 if (text ==
"." || text ==
"..")
2209 if (nowVisible && !item.
isMarked())
2211 else if (!nowVisible && item.
isMarked())
2212 deletedItems.append(*kit);
2214 if (!deletedItems.isEmpty()) {
2217 Q_FOREACH(
const KFileItem& item, deletedItems)
2227 kDirListerCache->updateDirectory( _u );
2242 KFileItem *item = kDirListerCache->findByUrl(
this, _url );
2252 return kDirListerCache->findByName(
this, _name );
2268 const QStringList list = nameFilter.split(
' ', QString::SkipEmptyParts );
2269 for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
2284 if (mimeFilter.contains(QLatin1String(
"application/octet-stream")) || mimeFilter.contains(QLatin1String(
"all/allfiles")))
2327 Q_ASSERT( !item.
isNull() );
2329 if ( item.
text() ==
".." )
2343 Q_ASSERT(!item.
isNull());
2352 for ( QList<QRegExp>::const_iterator it = filters.begin(); it != filters.end(); ++it )
2353 if ( (*it).exactMatch( name ) )
2361 if ( filters.isEmpty() )
2369 QStringList::const_iterator it = filters.begin();
2370 for ( ; it != filters.end(); ++it )
2371 if ( mimeptr->
is(*it) )
2380 if ( filters.isEmpty() )
2383 QStringList::const_iterator it = filters.begin();
2384 for ( ; it != filters.end(); ++it )
2385 if ( (*it) == mime )
2402 if (!isItemVisible(item))
2407 if ( m_parent->matchesMimeFilter( item ) )
2414 Q_ASSERT( !item.
isNull() );
2415 (*lstNewItems)[directoryUrl].append( item );
2419 if ( !lstMimeFilteredItems ) {
2423 Q_ASSERT( !item.
isNull() );
2424 lstMimeFilteredItems->append( item );
2433 KFileItemList::const_iterator kit = items.begin();
2434 const KFileItemList::const_iterator kend = items.end();
2435 for ( ; kit != kend; ++kit )
2436 addNewItem(directoryUrl, *kit);
2441 const bool refreshItemWasFiltered = !isItemVisible(oldItem) ||
2442 !m_parent->matchesMimeFilter(oldItem);
2443 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2444 if ( refreshItemWasFiltered )
2446 if ( !lstNewItems ) {
2450 Q_ASSERT( !item.
isNull() );
2451 (*lstNewItems)[directoryUrl].append( item );
2455 if ( !lstRefreshItems ) {
2456 lstRefreshItems =
new QList<QPair<KFileItem,KFileItem> >;
2459 Q_ASSERT( !item.
isNull() );
2460 lstRefreshItems->append( qMakePair(oldItem, item) );
2463 else if ( !refreshItemWasFiltered )
2465 if ( !lstRemoveItems ) {
2472 Q_ASSERT(!oldItem.
isNull());
2473 lstRemoveItems->append(oldItem);
2483 lstMimeFilteredItems = 0;
2485 QList<QPair<KFileItem, KFileItem> > *tmpRefresh = lstRefreshItems;
2486 lstRefreshItems = 0;
2492 QHashIterator<KUrl, KFileItemList> it(*tmpNew);
2493 while (it.hasNext()) {
2495 emit m_parent->itemsAdded(it.key(), it.value());
2496 emit m_parent->newItems(it.value());
2503 emit m_parent->itemsFilteredByMime( *tmpMime );
2509 emit m_parent->refreshItems( *tmpRefresh );
2515 emit m_parent->itemsDeleted( *tmpRemove );
2525 return (!settings.dirOnlyMode || item.
isDir())
2526 && m_parent->matchesFilter(item);
2532 QMutableListIterator<KFileItem> it(items);
2533 while (it.hasNext()) {
2535 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2537 emit m_parent->deleteItem(item);
2542 if (!items.isEmpty())
2543 emit m_parent->itemsDeleted(items);
2550 emit m_parent->infoMessage( message );
2562 while ( dataIt != jobData.end() )
2564 result += (*dataIt).percent * (*dataIt).totalSize;
2565 size += (*dataIt).totalSize;
2573 emit m_parent->percent( result );
2582 while ( dataIt != jobData.end() )
2584 result += (*dataIt).totalSize;
2588 emit m_parent->totalSize( result );
2597 while ( dataIt != jobData.end() )
2599 result += (*dataIt).processedSize;
2603 emit m_parent->processedSize( result );
2612 while ( dataIt != jobData.end() )
2614 result += (*dataIt).speed;
2618 emit m_parent->speed( result );
2625 qDebug() << m_parent <<
"numJobs:" << jobData.count();
2626 QMapIterator<KIO::ListJob *, JobData> it(jobData);
2627 while (it.hasNext()) {
2629 qDebug() << (
void*)it.key();
2630 qDebug() << it.key();
2634 return jobData.count();
2639 jobData.remove( job );
2650 jobData.insert( job, data );
2657 m_parent, SLOT(_k_slotInfoMessage(
KJob*,
QString)) );
2658 m_parent->connect( job, SIGNAL(
percent(
KJob*,ulong)),
2659 m_parent, SLOT(_k_slotPercent(
KJob*,ulong)) );
2660 m_parent->connect( job, SIGNAL(
totalSize(
KJob*,qulonglong)),
2661 m_parent, SLOT(_k_slotTotalSize(
KJob*,qulonglong)) );
2663 m_parent, SLOT(_k_slotProcessedSize(
KJob*,qulonglong)) );
2664 m_parent->connect( job, SIGNAL(
speed(
KJob*,ulong)),
2665 m_parent, SLOT(_k_slotSpeed(
KJob*,ulong)) );
2685 KFileItemList *allItems = kDirListerCache->itemsForDir( dir );
2694 KFileItemList::const_iterator kit = allItems->constBegin();
2695 const KFileItemList::const_iterator kend = allItems->constEnd();
2696 for ( ; kit != kend; ++kit )
2700 result.append(item);
2724 rootFileItem.setUrl(newUrl);
2729 const int idx = lstDirs.indexOf( oldUrl );
2731 kWarning(7004) <<
"Unexpected redirection from" << oldUrl <<
"to" << newUrl
2732 <<
"but this dirlister is currently listing/holding" << lstDirs;
2734 lstDirs[ idx ] = newUrl;
2737 if ( lstDirs.count() == 1 ) {
2739 emit m_parent->clear();
2740 emit m_parent->redirection( newUrl );
2743 emit m_parent->clear( oldUrl );
2745 emit m_parent->redirection( oldUrl, newUrl );
2755 QMutableListIterator<KDirLister *> lister_it(listersCurrentlyListing);
2756 while (lister_it.hasNext()) {
2762 Q_ASSERT(!listersCurrentlyHolding.contains(kdl));
2763 if (!listersCurrentlyHolding.contains(kdl)) {
2764 listersCurrentlyHolding.append(kdl);
2775 return kDirListerCache->itemForUrl(url);
2778 #include "kdirlister.moc"
2779 #include "kdirlister_p.moc"