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 ) )
689 if (cachedItemsJob) {
691 cachedItemsJob->
done();
692 delete cachedItemsJob;
702 if (!(listers.isEmpty() || killed)) {
703 kWarning() <<
"The unexpected happened.";
704 kWarning() <<
"listers for" << _dir <<
"=" << listers;
713 Q_ASSERT( listers.isEmpty() || killed );
720 connect( job, SIGNAL(result(
KJob*)),
721 this, SLOT(slotUpdateResult(
KJob*)) );
723 kDebug(7004) <<
"update started in" << _dir;
729 if ( !holders.isEmpty() ) {
734 if ( first && kdl->d->
window ) {
736 job->ui()->setWindow( kdl->d->
window );
741 job->ui()->setWindow( window );
750 bool KDirListerCache::checkUpdate(
const QString& _dir )
752 if ( !itemsInUse.contains(_dir) )
754 DirItem *item = itemsCached[_dir];
755 if ( item && item->complete )
759 item->complete =
false;
760 item->watchedWhileInCache =
false;
761 item->decAutoUpdate();
784 KDirListerCache::DirItem *KDirListerCache::dirItemForUrl(
const KUrl&
dir)
const
787 DirItem *item = itemsInUse.value(urlStr);
789 item = itemsCached[urlStr];
795 DirItem *item = dirItemForUrl(dir);
796 return item ? &item->lstItems : 0;
803 for (KUrl::List::const_iterator it = lister->d->
lstDirs.constBegin();
804 it != lister->d->
lstDirs.constEnd(); ++it) {
805 DirItem* dirItem = itemsInUse.value((*it).url());
807 const KFileItem item = dirItem->lstItems.findByName(_name);
823 DirItem* dirItem = dirItemForUrl(parentDir);
826 if (!lister || lister->d->
lstDirs.contains(parentDir)) {
827 KFileItemList::iterator it = dirItem->lstItems.begin();
828 const KFileItemList::iterator
end = dirItem->lstItems.end();
829 for (; it != end ; ++it) {
830 if ((*it).url() ==
url) {
840 dirItem = dirItemForUrl(url);
841 if (dirItem && !dirItem->rootItem.isNull() && dirItem->rootItem.url() ==
url) {
843 if (!lister || lister->d->
lstDirs.contains(url)) {
844 return &dirItem->rootItem;
878 for (KUrl::List::const_iterator it = fileList.begin(); it != fileList.end() ; ++it) {
880 DirItem* dirItem = dirItemForUrl(url);
882 deletedSubdirs.append(url);
883 if (!dirItem->rootItem.isNull()) {
884 removedItemsByDir[url.url()].append(dirItem->rootItem);
889 parentDir.setPath(parentDir.directory());
890 dirItem = dirItemForUrl(parentDir);
893 for (KFileItemList::iterator fit = dirItem->lstItems.begin(), fend = dirItem->lstItems.end(); fit != fend ; ++fit) {
894 if ((*fit).url() ==
url) {
896 removedItemsByDir[parentDir.url()].append(fileitem);
899 deletedSubdirs.append(url);
901 dirItem->lstItems.erase(fit);
908 for(; rit != removedItemsByDir.constEnd(); ++rit) {
911 DirectoryDataHash::const_iterator dit = directoryData.constFind(rit.key());
912 if (dit != directoryData.constEnd()) {
913 itemsDeleted((*dit).listersCurrentlyHolding, rit.value());
917 Q_FOREACH(
const KUrl& url, deletedSubdirs) {
928 QStringList::const_iterator it = fileList.begin();
929 for (; it != fileList.end() ; ++it) {
933 kDebug(7004) <<
"item not found for" <<
url;
939 pendingRemoteUpdates.insert(fileitem);
944 if (!dirsToUpdate.contains(dir))
945 dirsToUpdate.prepend(dir);
949 KUrl::List::const_iterator itdir = dirsToUpdate.constBegin();
950 for (; itdir != dirsToUpdate.constEnd() ; ++itdir)
955 processPendingUpdates();
962 kDebug(7004) << src <<
"->" << dst;
971 kDebug(7004) <<
"Item not found:" << oldurl;
982 if (existingDestItem) {
984 slotFilesRemoved(dst);
995 if (!nameOnly && fileitem->
isDir()) {
996 renameDir( src, dst );
1009 fileitem->
setName( dst.fileName() );
1014 QSet<KDirLister*> listers = emitRefreshItem( oldItem, *fileitem );
1025 QSet<KDirLister*> KDirListerCache::emitRefreshItem(
const KFileItem& oldItem,
const KFileItem& fileitem)
1030 KUrl parentDir( oldItem.
url() );
1031 parentDir.
setPath( parentDir.directory() );
1032 const QString parentDirURL = parentDir.url();
1033 DirectoryDataHash::iterator dit = directoryData.find(parentDirURL);
1034 QList<KDirLister *> listers;
1036 if (dit != directoryData.end())
1037 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1038 if (oldItem.
isDir()) {
1040 dit = directoryData.find(oldItem.
url().
url());
1041 if (dit != directoryData.end())
1042 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1044 QSet<KDirLister*> listersToRefresh;
1047 KUrl directoryUrl(oldItem.
url());
1053 directoryUrl.setPath(directoryUrl.directory());
1056 listersToRefresh.insert(kdl);
1058 return listersToRefresh;
1065 dirs << canonicalUrls.value(dir).toSet().toList();
1067 if (dirs.count() > 1)
1068 kDebug() << dir <<
"known as" << dirs;
1077 void KDirListerCache::slotFileDirty(
const QString& path )
1081 KDE_struct_stat buff;
1084 const bool isDir = S_ISDIR(buff.st_mode);
1088 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.toLocalFile())) {
1089 handleDirDirty(dir);
1092 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.directory())) {
1094 aliasUrl.addPath(url.fileName());
1095 handleFileDirty(aliasUrl);
1101 void KDirListerCache::handleDirDirty(
const KUrl& url)
1107 QMutableSetIterator<QString> pendingIt(pendingUpdates);
1108 while (pendingIt.hasNext()) {
1109 const QString updPath = pendingIt.next();
1111 if (updPath.startsWith(dirPath) &&
1112 updPath.indexOf(
'/', dirPath.length()) == -1) {
1113 kDebug(7004) <<
"forgetting about individual update to" << updPath;
1122 void KDirListerCache::handleFileDirty(
const KUrl& url)
1126 if (!existingItem) {
1134 if (!pendingUpdates.contains(filePath)) {
1136 dir.setPath(dir.directory());
1137 if (checkUpdate(dir.url())) {
1138 pendingUpdates.insert(filePath);
1139 if (!pendingUpdateTimer.isActive())
1140 pendingUpdateTimer.start(500);
1146 void KDirListerCache::slotFileCreated(
const QString& path )
1152 slotFilesAdded(fileUrl.directory());
1155 void KDirListerCache::slotFileDeleted(
const QString& path )
1160 Q_FOREACH(
KUrl url, directoriesForCanonicalPath(u.directory())) {
1162 fileUrls << url.
url();
1164 slotFilesRemoved(fileUrls);
1169 KUrl url(joburl( static_cast<KIO::ListJob *>(job) ));
1175 DirItem *dir = itemsInUse.value(urlStr);
1177 kError(7004) <<
"Internal error: job is listing" << url <<
"but itemsInUse only knows about" << itemsInUse.keys();
1182 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
1183 if (dit == directoryData.end()) {
1184 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData doesn't know about that url, only about:" << directoryData.keys();
1185 Q_ASSERT(dit != directoryData.end());
1190 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData says no listers are currently listing " << urlStr;
1203 KIO::UDSEntryList::const_iterator it = entries.begin();
1204 const KIO::UDSEntryList::const_iterator
end = entries.end();
1205 for ( ; it != end; ++it )
1209 Q_ASSERT( !name.isEmpty() );
1210 if ( name.isEmpty() )
1215 Q_ASSERT( dir->rootItem.isNull() );
1223 dir->rootItem = itemForUrl(url);
1224 if (dir->rootItem.isNull())
1225 dir->rootItem =
KFileItem( *it, url, delayedMimeTypes,
true );
1231 else if ( name !=
".." )
1233 KFileItem item( *it, url, delayedMimeTypes,
true );
1236 dir->lstItems.append( item );
1247 void KDirListerCache::slotResult(
KJob *j )
1255 runningListJobs.remove( job );
1257 KUrl jobUrl(joburl( job ));
1259 QString jobUrlStr = jobUrl.url();
1261 kDebug(7004) <<
"finished listing" << jobUrl;
1263 DirectoryDataHash::iterator dit = directoryData.find(jobUrlStr);
1264 if (dit == directoryData.end()) {
1265 kError() <<
"Nothing found in directoryData for URL" << jobUrlStr;
1269 Q_ASSERT(dit != directoryData.end());
1274 kError() <<
"OOOOPS, nothing in directoryData.listersCurrentlyListing for" << jobUrlStr;
1297 const bool silent = job->property(
"_kdlc_silent").toBool();
1312 DirItem *dir = itemsInUse.value(jobUrlStr);
1314 dir->complete =
true;
1330 processPendingUpdates();
1337 void KDirListerCache::slotRedirection(
KIO::Job *j,
const KUrl& url )
1349 if ( oldUrl == newUrl ) {
1350 kDebug(7004) <<
"New redirection url same as old, giving up.";
1352 }
else if (newUrl.isEmpty()) {
1353 kDebug(7004) <<
"New redirection url is empty, giving up.";
1357 const QString oldUrlStr = oldUrl.url();
1358 const QString newUrlStr = newUrl.url();
1360 kDebug(7004) << oldUrl <<
"->" << newUrl;
1373 DirItem *dir = itemsInUse.take(oldUrlStr);
1376 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1377 Q_ASSERT(dit != directoryData.end());
1379 directoryData.erase(dit);
1380 Q_ASSERT( !oldDirData.listersCurrentlyListing.isEmpty() );
1382 Q_ASSERT( !listers.isEmpty() );
1385 kdl->d->
redirect(oldUrlStr, newUrl,
false );
1390 const QList<KDirLister *> holders = oldDirData.listersCurrentlyHolding;
1397 kdl->d->
redirect(oldUrl, newUrl,
false );
1400 DirItem *newDir = itemsInUse.value(newUrlStr);
1402 kDebug(7004) << newUrl <<
"already in use";
1416 if ( !curListers.isEmpty() ) {
1417 kDebug(7004) <<
"and it is currently listed";
1430 curListers.append( kdl );
1432 curListers = listers;
1440 if ( !curHolders.isEmpty() ) {
1441 kDebug(7004) <<
"and it is currently held.";
1450 curHolders.append( kdl );
1452 curHolders = holders;
1458 foreach (
KDirLister *kdl, listers + holders ) {
1465 }
else if ( (newDir = itemsCached.take( newUrlStr )) ) {
1466 kDebug(7004) << newUrl <<
"is unused, but already in the cache.";
1469 itemsInUse.insert( newUrlStr, newDir );
1475 foreach (
KDirLister *kdl, listers + holders ) {
1483 kDebug(7004) << newUrl <<
"has not been listed yet.";
1486 dir->lstItems.clear();
1487 dir->redirect( newUrl );
1488 itemsInUse.insert( newUrlStr, dir );
1493 if ( holders.isEmpty() ) {
1502 job->disconnect(
this );
1506 connect( job, SIGNAL(result(
KJob*)),
1507 this, SLOT(slotUpdateResult(
KJob*)) );
1516 struct KDirListerCache::ItemInUseChange
1518 ItemInUseChange(
const QString& old,
const QString& newU, DirItem* di)
1519 : oldUrl(old), newUrl(newU), dirItem(di) {}
1525 void KDirListerCache::renameDir(
const KUrl &oldUrl,
const KUrl &newUrl )
1527 kDebug(7004) << oldUrl <<
"->" << newUrl;
1535 QLinkedList<ItemInUseChange> itemsToChange;
1536 QSet<KDirLister *> listers;
1539 QHash<QString, DirItem *>::iterator itu = itemsInUse.begin();
1540 const QHash<QString, DirItem *>::iterator ituend = itemsInUse.end();
1541 for (; itu != ituend ; ++itu) {
1542 DirItem *dir = itu.value();
1543 KUrl oldDirUrl ( itu.key() );
1548 QString relPath = oldDirUrl.path().mid( oldUrl.
path().length() );
1550 KUrl newDirUrl( newUrl );
1551 if ( !relPath.isEmpty() )
1552 newDirUrl.addPath( relPath );
1556 dir->redirect( newDirUrl );
1563 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end();
1564 kit != kend ; ++kit )
1568 const KUrl oldItemUrl ((*kit).url());
1570 KUrl newItemUrl( oldItemUrl );
1571 newItemUrl.setPath( newDirUrl.path() );
1572 newItemUrl.addPath( oldItemUrl.fileName() );
1573 kDebug(7004) <<
"renaming" << oldItemUrl <<
"to" << newItemUrl;
1574 (*kit).setUrl(newItemUrl);
1576 listers |= emitRefreshItem(oldItem, *kit);
1578 emitRedirections( oldDirUrl, newDirUrl );
1588 foreach(
const ItemInUseChange& i, itemsToChange) {
1589 itemsInUse.remove(i.oldUrl);
1590 itemsInUse.insert(i.newUrl, i.dirItem);
1595 removeDirFromCache( oldUrl );
1600 void KDirListerCache::emitRedirections(
const KUrl &oldUrl,
const KUrl &newUrl )
1602 kDebug(7004) << oldUrl <<
"->" << newUrl;
1611 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1612 if ( dit == directoryData.end() )
1614 const QList<KDirLister *> listers = (*dit).listersCurrentlyListing;
1615 const QList<KDirLister *> holders = (*dit).listersCurrentlyHolding;
1634 directoryData.erase(dit);
1636 if ( !listers.isEmpty() ) {
1646 kdl->d->
redirect(oldUrl, newUrl,
true );
1650 void KDirListerCache::removeDirFromCache(
const KUrl& dir )
1653 const QList<QString> cachedDirs = itemsCached.keys();
1654 foreach(
const QString& cachedDir, cachedDirs) {
1656 itemsCached.remove( cachedDir );
1662 runningListJobs[
static_cast<KIO::ListJob*
>(job)] += list;
1665 void KDirListerCache::slotUpdateResult(
KJob * j )
1670 KUrl jobUrl (joburl( job ));
1672 QString jobUrlStr (jobUrl.url());
1674 kDebug(7004) <<
"finished update" << jobUrl;
1684 Q_ASSERT( !listers.isEmpty() );
1686 if ( job->
error() ) {
1693 const bool silent = job->property(
"_kdlc_silent").toBool();
1697 if ( kdl->d->
numJobs() == 0 ) {
1705 runningListJobs.remove( job );
1709 processPendingUpdates();
1713 DirItem *dir = itemsInUse.value(jobUrlStr, 0);
1715 kError(7004) <<
"Internal error: itemsInUse did not contain" << jobUrlStr;
1721 dir->complete =
true;
1725 bool delayedMimeTypes =
true;
1729 QHash<QString, KFileItem*> fileItems;
1732 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end() ; kit != kend ; ++kit )
1735 fileItems.insert( (*kit).name(), &*kit );
1739 KIO::UDSEntryList::const_iterator it = buf.constBegin();
1740 const KIO::UDSEntryList::const_iterator end = buf.constEnd();
1741 for ( ; it != end; ++it )
1744 KFileItem item( *it, jobUrl, delayedMimeTypes,
true );
1746 const QString name = item.name();
1747 Q_ASSERT( !name.isEmpty() );
1751 if ( name.isEmpty() || name ==
".." )
1758 if ( dir->rootItem.isNull() )
1760 dir->rootItem = item;
1770 if (
KFileItem* tmp = fileItems.value(item.name()))
1772 QSet<KFileItem*>::iterator pru_it = pendingRemoteUpdates.find(tmp);
1773 const bool inPendingRemoteUpdates = (pru_it != pendingRemoteUpdates.end());
1776 if (!tmp->cmp( item ) || inPendingRemoteUpdates) {
1778 if (inPendingRemoteUpdates) {
1779 pendingRemoteUpdates.erase(pru_it);
1798 dir->lstItems.append( pitem );
1805 runningListJobs.remove( job );
1807 deleteUnmarkedItems( listers, dir->lstItems );
1824 processPendingUpdates();
1832 while ( it != runningListJobs.constEnd() )
1852 runningListJobs.remove( job );
1853 job->disconnect(
this );
1857 void KDirListerCache::deleteUnmarkedItems(
const QList<KDirLister *>& listers,
KFileItemList &lstItems )
1861 QMutableListIterator<KFileItem> kit(lstItems);
1862 while (kit.hasNext()) {
1866 deletedItems.append(item);
1870 if (!deletedItems.isEmpty())
1880 Q_FOREACH(
const KFileItem& item, deletedItems) {
1882 deleteDir(item.
url());
1886 void KDirListerCache::deleteDir(
const KUrl& dirUrl )
1896 QHash<QString, DirItem *>::iterator itu = itemsInUse.begin();
1897 const QHash<QString, DirItem *>::iterator ituend = itemsInUse.end();
1898 for ( ; itu != ituend; ++itu ) {
1899 const KUrl deletedUrl( itu.key() );
1901 affectedItems.append(deletedUrl);
1905 foreach(
const KUrl& deletedUrl, affectedItems) {
1906 const QString deletedUrlStr = deletedUrl.
url();
1908 DirectoryDataHash::iterator dit = directoryData.find(deletedUrlStr);
1909 if (dit != directoryData.end()) {
1911 QList<KDirLister *> listers = (*dit).listersCurrentlyListing;
1913 stopListingUrl( kdl, deletedUrl );
1918 QList<KDirLister *> holders = (*dit).listersCurrentlyHolding;
1921 if ( kdl->d->
url == deletedUrl )
1933 const bool treeview = kdl->d->
lstDirs.count() > 1;
1940 kdl->d->
lstDirs.removeAll( deletedUrl );
1942 forgetDirs( kdl, deletedUrl, treeview );
1949 int count = itemsInUse.remove( deletedUrlStr );
1950 Q_ASSERT( count == 0 );
1955 removeDirFromCache( dirUrl );
1959 void KDirListerCache::processPendingUpdates()
1961 QSet<KDirLister *> listers;
1962 foreach(
const QString& file, pendingUpdates) {
1970 listers |= emitRefreshItem( oldItem, *item );
1973 pendingUpdates.clear();
1980 void KDirListerCache::printDebug()
1982 kDebug(7004) <<
"Items in use:";
1983 QHash<QString, DirItem *>::const_iterator itu = itemsInUse.constBegin();
1984 const QHash<QString, DirItem *>::const_iterator ituend = itemsInUse.constEnd();
1985 for ( ; itu != ituend ; ++itu ) {
1986 kDebug(7004) <<
" " << itu.key() <<
"URL:" << itu.value()->url
1987 <<
"rootItem:" << ( !itu.value()->rootItem.isNull() ? itu.value()->rootItem.url() :
KUrl() )
1988 <<
"autoUpdates refcount:" << itu.value()->autoUpdates
1989 <<
"complete:" << itu.value()->complete
1990 <<
QString(
"with %1 items.").arg(itu.value()->lstItems.count());
1993 QList<KDirLister*> listersWithoutJob;
1994 kDebug(7004) <<
"Directory data:";
1995 DirectoryDataHash::const_iterator dit = directoryData.constBegin();
1996 for ( ; dit != directoryData.constEnd(); ++dit )
1999 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing )
2001 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyListing.count() <<
"listers:" <<
list;
2002 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing ) {
2005 }
else if (
KIO::ListJob* listJob = jobForUrl(dit.key())) {
2006 kDebug(7004) <<
" Lister" << listit <<
"has ListJob" << listJob;
2008 listersWithoutJob.append(listit);
2013 foreach (
KDirLister* listit, (*dit).listersCurrentlyHolding )
2015 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyHolding.count() <<
"holders:" <<
list;
2020 for ( ; jit != runningListJobs.end() ; ++jit )
2021 kDebug(7004) <<
" " << jit.key() <<
"listing" << joburl( jit.key() ) <<
":" << (*jit).count() <<
"entries.";
2023 kDebug(7004) <<
"Items in cache:";
2024 const QList<QString> cachedDirs = itemsCached.keys();
2025 foreach(
const QString& cachedDir, cachedDirs) {
2026 DirItem* dirItem = itemsCached.object(cachedDir);
2027 kDebug(7004) <<
" " << cachedDir <<
"rootItem:"
2028 << (!dirItem->rootItem.isNull() ? dirItem->rootItem.url().prettyUrl() :
QString(
"NULL") )
2029 <<
"with" << dirItem->lstItems.count() <<
"items.";
2033 Q_FOREACH(
KDirLister* listit, listersWithoutJob) {
2034 kFatal() <<
"HUH? Lister" << listit <<
"is supposed to be listing, but has no job!";
2059 if (!kDirListerCache.isDestroyed()) {
2061 kDirListerCache->forgetDirs(
this );
2075 return kDirListerCache->listDir(
this, _url, _flags & Keep, _flags &
Reload );
2080 kDirListerCache->stop(
this );
2085 kDirListerCache->stopListingUrl(
this, _url );
2099 kDirListerCache->setAutoUpdate(
this, _enable );
2170 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2175 KFileItemList::iterator kit = itemList->begin();
2176 const KFileItemList::iterator kend = itemList->end();
2177 for (; kit != kend; ++kit) {
2190 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2195 KFileItemList::iterator kit = itemList->begin();
2196 const KFileItemList::iterator kend = itemList->end();
2197 for (; kit != kend; ++kit) {
2200 if (text ==
"." || text ==
"..")
2203 if (nowVisible && !item.
isMarked())
2205 else if (!nowVisible && item.
isMarked())
2206 deletedItems.append(*kit);
2208 if (!deletedItems.isEmpty()) {
2211 Q_FOREACH(
const KFileItem& item, deletedItems)
2221 kDirListerCache->updateDirectory( _u );
2236 KFileItem *item = kDirListerCache->findByUrl(
this, _url );
2246 return kDirListerCache->findByName(
this, _name );
2262 const QStringList list = nameFilter.split(
' ', QString::SkipEmptyParts );
2263 for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
2278 if (mimeFilter.contains(QLatin1String(
"application/octet-stream")) || mimeFilter.contains(QLatin1String(
"all/allfiles")))
2321 Q_ASSERT( !item.
isNull() );
2323 if ( item.
text() ==
".." )
2337 Q_ASSERT(!item.
isNull());
2346 for ( QList<QRegExp>::const_iterator it = filters.begin(); it != filters.end(); ++it )
2347 if ( (*it).exactMatch( name ) )
2355 if ( filters.isEmpty() )
2363 QStringList::const_iterator it = filters.begin();
2364 for ( ; it != filters.end(); ++it )
2365 if ( mimeptr->
is(*it) )
2374 if ( filters.isEmpty() )
2377 QStringList::const_iterator it = filters.begin();
2378 for ( ; it != filters.end(); ++it )
2379 if ( (*it) == mime )
2396 if (!isItemVisible(item))
2401 if ( m_parent->matchesMimeFilter( item ) )
2408 Q_ASSERT( !item.
isNull() );
2409 (*lstNewItems)[directoryUrl].append( item );
2413 if ( !lstMimeFilteredItems ) {
2417 Q_ASSERT( !item.
isNull() );
2418 lstMimeFilteredItems->append( item );
2427 KFileItemList::const_iterator kit = items.begin();
2428 const KFileItemList::const_iterator kend = items.end();
2429 for ( ; kit != kend; ++kit )
2430 addNewItem(directoryUrl, *kit);
2435 const bool refreshItemWasFiltered = !isItemVisible(oldItem) ||
2436 !m_parent->matchesMimeFilter(oldItem);
2437 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2438 if ( refreshItemWasFiltered )
2440 if ( !lstNewItems ) {
2444 Q_ASSERT( !item.
isNull() );
2445 (*lstNewItems)[directoryUrl].append( item );
2449 if ( !lstRefreshItems ) {
2450 lstRefreshItems =
new QList<QPair<KFileItem,KFileItem> >;
2453 Q_ASSERT( !item.
isNull() );
2454 lstRefreshItems->append( qMakePair(oldItem, item) );
2457 else if ( !refreshItemWasFiltered )
2459 if ( !lstRemoveItems ) {
2466 Q_ASSERT(!oldItem.
isNull());
2467 lstRemoveItems->append(oldItem);
2477 lstMimeFilteredItems = 0;
2479 QList<QPair<KFileItem, KFileItem> > *tmpRefresh = lstRefreshItems;
2480 lstRefreshItems = 0;
2486 QHashIterator<KUrl, KFileItemList> it(*tmpNew);
2487 while (it.hasNext()) {
2489 emit m_parent->itemsAdded(it.key(), it.value());
2490 emit m_parent->newItems(it.value());
2497 emit m_parent->itemsFilteredByMime( *tmpMime );
2503 emit m_parent->refreshItems( *tmpRefresh );
2509 emit m_parent->itemsDeleted( *tmpRemove );
2519 return (!settings.dirOnlyMode || item.
isDir())
2520 && m_parent->matchesFilter(item);
2526 QMutableListIterator<KFileItem> it(items);
2527 while (it.hasNext()) {
2529 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2531 emit m_parent->deleteItem(item);
2536 if (!items.isEmpty())
2537 emit m_parent->itemsDeleted(items);
2544 emit m_parent->infoMessage( message );
2556 while ( dataIt != jobData.end() )
2558 result += (*dataIt).percent * (*dataIt).totalSize;
2559 size += (*dataIt).totalSize;
2567 emit m_parent->percent( result );
2576 while ( dataIt != jobData.end() )
2578 result += (*dataIt).totalSize;
2582 emit m_parent->totalSize( result );
2591 while ( dataIt != jobData.end() )
2593 result += (*dataIt).processedSize;
2597 emit m_parent->processedSize( result );
2606 while ( dataIt != jobData.end() )
2608 result += (*dataIt).speed;
2612 emit m_parent->speed( result );
2619 qDebug() << m_parent <<
"numJobs:" << jobData.count();
2620 QMapIterator<KIO::ListJob *, JobData> it(jobData);
2621 while (it.hasNext()) {
2623 qDebug() << (
void*)it.key();
2624 qDebug() << it.key();
2628 return jobData.count();
2633 jobData.remove( job );
2644 jobData.insert( job, data );
2651 m_parent, SLOT(_k_slotInfoMessage(
KJob*,
QString)) );
2652 m_parent->connect( job, SIGNAL(
percent(
KJob*,ulong)),
2653 m_parent, SLOT(_k_slotPercent(
KJob*,ulong)) );
2654 m_parent->connect( job, SIGNAL(
totalSize(
KJob*,qulonglong)),
2655 m_parent, SLOT(_k_slotTotalSize(
KJob*,qulonglong)) );
2657 m_parent, SLOT(_k_slotProcessedSize(
KJob*,qulonglong)) );
2658 m_parent->connect( job, SIGNAL(
speed(
KJob*,ulong)),
2659 m_parent, SLOT(_k_slotSpeed(
KJob*,ulong)) );
2679 KFileItemList *allItems = kDirListerCache->itemsForDir( dir );
2688 KFileItemList::const_iterator kit = allItems->constBegin();
2689 const KFileItemList::const_iterator kend = allItems->constEnd();
2690 for ( ; kit != kend; ++kit )
2694 result.append(item);
2718 rootFileItem.setUrl(newUrl);
2723 const int idx = lstDirs.indexOf( oldUrl );
2725 kWarning(7004) <<
"Unexpected redirection from" << oldUrl <<
"to" << newUrl
2726 <<
"but this dirlister is currently listing/holding" << lstDirs;
2728 lstDirs[ idx ] = newUrl;
2731 if ( lstDirs.count() == 1 ) {
2733 emit m_parent->clear();
2734 emit m_parent->redirection( newUrl );
2737 emit m_parent->clear( oldUrl );
2739 emit m_parent->redirection( oldUrl, newUrl );
2749 QMutableListIterator<KDirLister *> lister_it(listersCurrentlyListing);
2750 while (lister_it.hasNext()) {
2756 Q_ASSERT(!listersCurrentlyHolding.contains(kdl));
2757 if (!listersCurrentlyHolding.contains(kdl)) {
2758 listersCurrentlyHolding.append(kdl);
2769 return kDirListerCache->itemForUrl(url);
2772 #include "kdirlister.moc"
2773 #include "kdirlister_p.moc"