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 );
535 const bool supermount = mp->mountType() ==
"supermount";
540 return mp->mountOptions().contains(
"noauto");
552 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
553 if (dit == directoryData.end())
563 DirItem *item = itemsInUse.value(urlStr);
565 bool insertIntoCache =
false;
569 directoryData.erase(dit);
570 itemsInUse.remove( urlStr );
575 kDebug(7004) <<
"Killing update job for " << urlStr;
581 if ( lister->d->
numJobs() == 0 ) {
588 lister->d->
lstDirs.removeAll( url );
589 emit lister->
clear( url );
592 insertIntoCache = item->complete;
593 if (insertIntoCache) {
603 const bool isLocal = item->url.isLocalFile();
604 bool isManuallyMounted =
false;
605 bool containsManuallyMounted =
false;
607 isManuallyMounted =
manually_mounted( item->url.toLocalFile(), possibleMountPoints );
608 if ( !isManuallyMounted ) {
612 KFileItemList::const_iterator kit = item->lstItems.constBegin();
613 KFileItemList::const_iterator kend = item->lstItems.constEnd();
614 for ( ; kit != kend && !containsManuallyMounted; ++kit )
615 if ( (*kit).isDir() &&
manually_mounted((*kit).url().toLocalFile(), possibleMountPoints) )
616 containsManuallyMounted =
true;
620 if ( isManuallyMounted || containsManuallyMounted )
622 kDebug(7004) <<
"Not adding a watch on " << item->url <<
" because it " <<
623 ( isManuallyMounted ?
"is manually mounted" :
"contains a manually mounted subdir" );
624 item->complete =
false;
626 item->incAutoUpdate();
627 item->watchedWhileInCache =
true;
638 item->decAutoUpdate();
641 if (item && insertIntoCache) {
642 kDebug(7004) << lister <<
"item moved into cache:" <<
url;
643 itemsCached.insert(urlStr, item);
652 if ( !checkUpdate( urlStr ) )
686 if (cachedItemsJob) {
688 cachedItemsJob->
done();
689 delete cachedItemsJob;
699 if (!(listers.isEmpty() || killed)) {
700 kWarning() <<
"The unexpected happened.";
701 kWarning() <<
"listers for" << _dir <<
"=" << listers;
710 Q_ASSERT( listers.isEmpty() || killed );
717 connect( job, SIGNAL(result(
KJob*)),
718 this, SLOT(slotUpdateResult(
KJob*)) );
720 kDebug(7004) <<
"update started in" << _dir;
726 if ( !holders.isEmpty() ) {
731 if ( first && kdl->d->
window ) {
733 job->ui()->setWindow( kdl->d->
window );
738 job->ui()->setWindow( window );
747 bool KDirListerCache::checkUpdate(
const QString& _dir )
749 if ( !itemsInUse.contains(_dir) )
751 DirItem *item = itemsCached[_dir];
752 if ( item && item->complete )
756 item->complete =
false;
757 item->watchedWhileInCache =
false;
758 item->decAutoUpdate();
781 KDirListerCache::DirItem *KDirListerCache::dirItemForUrl(
const KUrl&
dir)
const
784 DirItem *item = itemsInUse.value(urlStr);
786 item = itemsCached[urlStr];
792 DirItem *item = dirItemForUrl(dir);
793 return item ? &item->lstItems : 0;
800 for (KUrl::List::const_iterator it = lister->d->
lstDirs.constBegin();
801 it != lister->d->
lstDirs.constEnd(); ++it) {
802 DirItem* dirItem = itemsInUse.value((*it).url());
804 const KFileItem item = dirItem->lstItems.findByName(_name);
820 DirItem* dirItem = dirItemForUrl(parentDir);
823 if (!lister || lister->d->
lstDirs.contains(parentDir)) {
824 KFileItemList::iterator it = dirItem->lstItems.begin();
825 const KFileItemList::iterator
end = dirItem->lstItems.end();
826 for (; it != end ; ++it) {
827 if ((*it).url() ==
url) {
837 dirItem = dirItemForUrl(url);
838 if (dirItem && !dirItem->rootItem.isNull() && dirItem->rootItem.url() ==
url) {
840 if (!lister || lister->d->
lstDirs.contains(url)) {
841 return &dirItem->rootItem;
875 for (KUrl::List::const_iterator it = fileList.begin(); it != fileList.end() ; ++it) {
877 DirItem* dirItem = dirItemForUrl(url);
879 deletedSubdirs.append(url);
880 if (!dirItem->rootItem.isNull()) {
881 removedItemsByDir[url.url()].append(dirItem->rootItem);
886 parentDir.setPath(parentDir.directory());
887 dirItem = dirItemForUrl(parentDir);
890 for (KFileItemList::iterator fit = dirItem->lstItems.begin(), fend = dirItem->lstItems.end(); fit != fend ; ++fit) {
891 if ((*fit).url() ==
url) {
893 removedItemsByDir[parentDir.url()].append(fileitem);
896 deletedSubdirs.append(url);
898 dirItem->lstItems.erase(fit);
905 for(; rit != removedItemsByDir.constEnd(); ++rit) {
908 DirectoryDataHash::const_iterator dit = directoryData.constFind(rit.key());
909 if (dit != directoryData.constEnd()) {
910 itemsDeleted((*dit).listersCurrentlyHolding, rit.value());
914 Q_FOREACH(
const KUrl& url, deletedSubdirs) {
925 QStringList::const_iterator it = fileList.begin();
926 for (; it != fileList.end() ; ++it) {
930 kDebug(7004) <<
"item not found for" <<
url;
936 pendingRemoteUpdates.insert(fileitem);
941 if (!dirsToUpdate.contains(dir))
942 dirsToUpdate.prepend(dir);
946 KUrl::List::const_iterator itdir = dirsToUpdate.constBegin();
947 for (; itdir != dirsToUpdate.constEnd() ; ++itdir)
952 processPendingUpdates();
959 kDebug(7004) << src <<
"->" << dst;
968 kDebug(7004) <<
"Item not found:" << oldurl;
979 if (existingDestItem) {
981 slotFilesRemoved(dst);
992 if (!nameOnly && fileitem->
isDir()) {
993 renameDir( src, dst );
1006 fileitem->
setName( dst.fileName() );
1011 QSet<KDirLister*> listers = emitRefreshItem( oldItem, *fileitem );
1022 QSet<KDirLister*> KDirListerCache::emitRefreshItem(
const KFileItem& oldItem,
const KFileItem& fileitem)
1027 KUrl parentDir( oldItem.
url() );
1028 parentDir.
setPath( parentDir.directory() );
1029 const QString parentDirURL = parentDir.url();
1030 DirectoryDataHash::iterator dit = directoryData.find(parentDirURL);
1031 QList<KDirLister *> listers;
1033 if (dit != directoryData.end())
1034 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1035 if (oldItem.
isDir()) {
1037 dit = directoryData.find(oldItem.
url().
url());
1038 if (dit != directoryData.end())
1039 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1041 QSet<KDirLister*> listersToRefresh;
1044 KUrl directoryUrl(oldItem.
url());
1050 directoryUrl.setPath(directoryUrl.directory());
1053 listersToRefresh.insert(kdl);
1055 return listersToRefresh;
1062 dirs << canonicalUrls.value(dir).toSet().toList();
1064 if (dirs.count() > 1)
1065 kDebug() << dir <<
"known as" << dirs;
1074 void KDirListerCache::slotFileDirty(
const QString& path )
1078 KDE_struct_stat buff;
1081 const bool isDir = S_ISDIR(buff.st_mode);
1085 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.toLocalFile())) {
1086 handleDirDirty(dir);
1089 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.directory())) {
1091 aliasUrl.addPath(url.fileName());
1092 handleFileDirty(aliasUrl);
1098 void KDirListerCache::handleDirDirty(
const KUrl& url)
1104 QMutableSetIterator<QString> pendingIt(pendingUpdates);
1105 while (pendingIt.hasNext()) {
1106 const QString updPath = pendingIt.next();
1108 if (updPath.startsWith(dirPath) &&
1109 updPath.indexOf(
'/', dirPath.length()) == -1) {
1110 kDebug(7004) <<
"forgetting about individual update to" << updPath;
1119 void KDirListerCache::handleFileDirty(
const KUrl& url)
1123 if (!existingItem) {
1131 if (!pendingUpdates.contains(filePath)) {
1133 dir.setPath(dir.directory());
1134 if (checkUpdate(dir.url())) {
1135 pendingUpdates.insert(filePath);
1136 if (!pendingUpdateTimer.isActive())
1137 pendingUpdateTimer.start(500);
1143 void KDirListerCache::slotFileCreated(
const QString& path )
1149 slotFilesAdded(fileUrl.directory());
1152 void KDirListerCache::slotFileDeleted(
const QString& path )
1157 Q_FOREACH(
KUrl url, directoriesForCanonicalPath(u.directory())) {
1159 fileUrls << url.
url();
1161 slotFilesRemoved(fileUrls);
1166 KUrl url(joburl( static_cast<KIO::ListJob *>(job) ));
1172 DirItem *dir = itemsInUse.value(urlStr);
1174 kError(7004) <<
"Internal error: job is listing" << url <<
"but itemsInUse only knows about" << itemsInUse.keys();
1179 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
1180 if (dit == directoryData.end()) {
1181 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData doesn't know about that url, only about:" << directoryData.keys();
1182 Q_ASSERT(dit != directoryData.end());
1187 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData says no listers are currently listing " << urlStr;
1200 KIO::UDSEntryList::const_iterator it = entries.begin();
1201 const KIO::UDSEntryList::const_iterator
end = entries.end();
1202 for ( ; it != end; ++it )
1206 Q_ASSERT( !name.isEmpty() );
1207 if ( name.isEmpty() )
1212 Q_ASSERT( dir->rootItem.isNull() );
1220 dir->rootItem = itemForUrl(url);
1221 if (dir->rootItem.isNull())
1222 dir->rootItem =
KFileItem( *it, url, delayedMimeTypes,
true );
1228 else if ( name !=
".." )
1230 KFileItem item( *it, url, delayedMimeTypes,
true );
1233 dir->lstItems.append( item );
1244 void KDirListerCache::slotResult(
KJob *j )
1252 runningListJobs.remove( job );
1254 KUrl jobUrl(joburl( job ));
1256 QString jobUrlStr = jobUrl.url();
1258 kDebug(7004) <<
"finished listing" << jobUrl;
1260 DirectoryDataHash::iterator dit = directoryData.find(jobUrlStr);
1261 if (dit == directoryData.end()) {
1262 kError() <<
"Nothing found in directoryData for URL" << jobUrlStr;
1266 Q_ASSERT(dit != directoryData.end());
1271 kError() <<
"OOOOPS, nothing in directoryData.listersCurrentlyListing for" << jobUrlStr;
1294 const bool silent = job->property(
"_kdlc_silent").toBool();
1309 DirItem *dir = itemsInUse.value(jobUrlStr);
1311 dir->complete =
true;
1327 processPendingUpdates();
1334 void KDirListerCache::slotRedirection(
KIO::Job *j,
const KUrl& url )
1346 if ( oldUrl == newUrl ) {
1347 kDebug(7004) <<
"New redirection url same as old, giving up.";
1349 }
else if (newUrl.isEmpty()) {
1350 kDebug(7004) <<
"New redirection url is empty, giving up.";
1354 const QString oldUrlStr = oldUrl.url();
1355 const QString newUrlStr = newUrl.url();
1357 kDebug(7004) << oldUrl <<
"->" << newUrl;
1370 DirItem *dir = itemsInUse.take(oldUrlStr);
1373 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1374 Q_ASSERT(dit != directoryData.end());
1376 directoryData.erase(dit);
1377 Q_ASSERT( !oldDirData.listersCurrentlyListing.isEmpty() );
1379 Q_ASSERT( !listers.isEmpty() );
1382 kdl->d->
redirect(oldUrlStr, newUrl,
false );
1387 const QList<KDirLister *> holders = oldDirData.listersCurrentlyHolding;
1394 kdl->d->
redirect(oldUrl, newUrl,
false );
1397 DirItem *newDir = itemsInUse.value(newUrlStr);
1399 kDebug(7004) << newUrl <<
"already in use";
1413 if ( !curListers.isEmpty() ) {
1414 kDebug(7004) <<
"and it is currently listed";
1427 curListers.append( kdl );
1429 curListers = listers;
1437 if ( !curHolders.isEmpty() ) {
1438 kDebug(7004) <<
"and it is currently held.";
1447 curHolders.append( kdl );
1449 curHolders = holders;
1455 foreach (
KDirLister *kdl, listers + holders ) {
1462 }
else if ( (newDir = itemsCached.take( newUrlStr )) ) {
1463 kDebug(7004) << newUrl <<
"is unused, but already in the cache.";
1466 itemsInUse.insert( newUrlStr, newDir );
1472 foreach (
KDirLister *kdl, listers + holders ) {
1480 kDebug(7004) << newUrl <<
"has not been listed yet.";
1483 dir->lstItems.clear();
1484 dir->redirect( newUrl );
1485 itemsInUse.insert( newUrlStr, dir );
1490 if ( holders.isEmpty() ) {
1499 job->disconnect(
this );
1503 connect( job, SIGNAL(result(
KJob*)),
1504 this, SLOT(slotUpdateResult(
KJob*)) );
1513 struct KDirListerCache::ItemInUseChange
1515 ItemInUseChange(
const QString& old,
const QString& newU, DirItem* di)
1516 : oldUrl(old), newUrl(newU), dirItem(di) {}
1522 void KDirListerCache::renameDir(
const KUrl &oldUrl,
const KUrl &newUrl )
1524 kDebug(7004) << oldUrl <<
"->" << newUrl;
1532 QLinkedList<ItemInUseChange> itemsToChange;
1533 QSet<KDirLister *> listers;
1536 QHash<QString, DirItem *>::iterator itu = itemsInUse.begin();
1537 const QHash<QString, DirItem *>::iterator ituend = itemsInUse.end();
1538 for (; itu != ituend ; ++itu) {
1539 DirItem *dir = itu.value();
1540 KUrl oldDirUrl ( itu.key() );
1545 QString relPath = oldDirUrl.path().mid( oldUrl.
path().length() );
1547 KUrl newDirUrl( newUrl );
1548 if ( !relPath.isEmpty() )
1549 newDirUrl.addPath( relPath );
1553 dir->redirect( newDirUrl );
1560 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end();
1561 kit != kend ; ++kit )
1565 const KUrl oldItemUrl ((*kit).url());
1567 KUrl newItemUrl( oldItemUrl );
1568 newItemUrl.setPath( newDirUrl.path() );
1569 newItemUrl.addPath( oldItemUrl.fileName() );
1570 kDebug(7004) <<
"renaming" << oldItemUrl <<
"to" << newItemUrl;
1571 (*kit).setUrl(newItemUrl);
1573 listers |= emitRefreshItem(oldItem, *kit);
1575 emitRedirections( oldDirUrl, newDirUrl );
1585 foreach(
const ItemInUseChange& i, itemsToChange) {
1586 itemsInUse.remove(i.oldUrl);
1587 itemsInUse.insert(i.newUrl, i.dirItem);
1592 removeDirFromCache( oldUrl );
1597 void KDirListerCache::emitRedirections(
const KUrl &oldUrl,
const KUrl &newUrl )
1599 kDebug(7004) << oldUrl <<
"->" << newUrl;
1608 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1609 if ( dit == directoryData.end() )
1611 const QList<KDirLister *> listers = (*dit).listersCurrentlyListing;
1612 const QList<KDirLister *> holders = (*dit).listersCurrentlyHolding;
1631 directoryData.erase(dit);
1633 if ( !listers.isEmpty() ) {
1643 kdl->d->
redirect(oldUrl, newUrl,
true );
1647 void KDirListerCache::removeDirFromCache(
const KUrl& dir )
1650 const QList<QString> cachedDirs = itemsCached.keys();
1651 foreach(
const QString& cachedDir, cachedDirs) {
1653 itemsCached.remove( cachedDir );
1659 runningListJobs[
static_cast<KIO::ListJob*
>(job)] += list;
1662 void KDirListerCache::slotUpdateResult(
KJob * j )
1667 KUrl jobUrl (joburl( job ));
1669 QString jobUrlStr (jobUrl.url());
1671 kDebug(7004) <<
"finished update" << jobUrl;
1681 Q_ASSERT( !listers.isEmpty() );
1683 if ( job->
error() ) {
1690 const bool silent = job->property(
"_kdlc_silent").toBool();
1694 if ( kdl->d->
numJobs() == 0 ) {
1702 runningListJobs.remove( job );
1706 processPendingUpdates();
1710 DirItem *dir = itemsInUse.value(jobUrlStr, 0);
1712 kError(7004) <<
"Internal error: itemsInUse did not contain" << jobUrlStr;
1718 dir->complete =
true;
1722 bool delayedMimeTypes =
true;
1726 QHash<QString, KFileItem*> fileItems;
1729 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end() ; kit != kend ; ++kit )
1732 fileItems.insert( (*kit).name(), &*kit );
1736 KIO::UDSEntryList::const_iterator it = buf.constBegin();
1737 const KIO::UDSEntryList::const_iterator end = buf.constEnd();
1738 for ( ; it != end; ++it )
1741 KFileItem item( *it, jobUrl, delayedMimeTypes,
true );
1743 const QString name = item.name();
1744 Q_ASSERT( !name.isEmpty() );
1748 if ( name.isEmpty() || name ==
".." )
1755 if ( dir->rootItem.isNull() )
1757 dir->rootItem = item;
1767 if (
KFileItem* tmp = fileItems.value(item.name()))
1769 QSet<KFileItem*>::iterator pru_it = pendingRemoteUpdates.find(tmp);
1770 const bool inPendingRemoteUpdates = (pru_it != pendingRemoteUpdates.end());
1773 if (!tmp->cmp( item ) || inPendingRemoteUpdates) {
1775 if (inPendingRemoteUpdates) {
1776 pendingRemoteUpdates.erase(pru_it);
1795 dir->lstItems.append( pitem );
1802 runningListJobs.remove( job );
1804 deleteUnmarkedItems( listers, dir->lstItems );
1821 processPendingUpdates();
1829 while ( it != runningListJobs.constEnd() )
1849 runningListJobs.remove( job );
1850 job->disconnect(
this );
1854 void KDirListerCache::deleteUnmarkedItems(
const QList<KDirLister *>& listers,
KFileItemList &lstItems )
1858 QMutableListIterator<KFileItem> kit(lstItems);
1859 while (kit.hasNext()) {
1863 deletedItems.append(item);
1867 if (!deletedItems.isEmpty())
1877 Q_FOREACH(
const KFileItem& item, deletedItems) {
1879 deleteDir(item.
url());
1883 void KDirListerCache::deleteDir(
const KUrl& dirUrl )
1893 QHash<QString, DirItem *>::iterator itu = itemsInUse.begin();
1894 const QHash<QString, DirItem *>::iterator ituend = itemsInUse.end();
1895 for ( ; itu != ituend; ++itu ) {
1896 const KUrl deletedUrl( itu.key() );
1898 affectedItems.append(deletedUrl);
1902 foreach(
const KUrl& deletedUrl, affectedItems) {
1903 const QString deletedUrlStr = deletedUrl.
url();
1905 DirectoryDataHash::iterator dit = directoryData.find(deletedUrlStr);
1906 if (dit != directoryData.end()) {
1908 QList<KDirLister *> listers = (*dit).listersCurrentlyListing;
1910 stopListingUrl( kdl, deletedUrl );
1915 QList<KDirLister *> holders = (*dit).listersCurrentlyHolding;
1918 if ( kdl->d->
url == deletedUrl )
1930 const bool treeview = kdl->d->
lstDirs.count() > 1;
1937 kdl->d->
lstDirs.removeAll( deletedUrl );
1939 forgetDirs( kdl, deletedUrl, treeview );
1946 int count = itemsInUse.remove( deletedUrlStr );
1947 Q_ASSERT( count == 0 );
1952 removeDirFromCache( dirUrl );
1956 void KDirListerCache::processPendingUpdates()
1958 QSet<KDirLister *> listers;
1959 foreach(
const QString& file, pendingUpdates) {
1967 listers |= emitRefreshItem( oldItem, *item );
1970 pendingUpdates.clear();
1977 void KDirListerCache::printDebug()
1979 kDebug(7004) <<
"Items in use:";
1980 QHash<QString, DirItem *>::const_iterator itu = itemsInUse.constBegin();
1981 const QHash<QString, DirItem *>::const_iterator ituend = itemsInUse.constEnd();
1982 for ( ; itu != ituend ; ++itu ) {
1983 kDebug(7004) <<
" " << itu.key() <<
"URL:" << itu.value()->url
1984 <<
"rootItem:" << ( !itu.value()->rootItem.isNull() ? itu.value()->rootItem.url() :
KUrl() )
1985 <<
"autoUpdates refcount:" << itu.value()->autoUpdates
1986 <<
"complete:" << itu.value()->complete
1987 <<
QString(
"with %1 items.").arg(itu.value()->lstItems.count());
1990 QList<KDirLister*> listersWithoutJob;
1991 kDebug(7004) <<
"Directory data:";
1992 DirectoryDataHash::const_iterator dit = directoryData.constBegin();
1993 for ( ; dit != directoryData.constEnd(); ++dit )
1996 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing )
1998 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyListing.count() <<
"listers:" <<
list;
1999 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing ) {
2002 }
else if (
KIO::ListJob* listJob = jobForUrl(dit.key())) {
2003 kDebug(7004) <<
" Lister" << listit <<
"has ListJob" << listJob;
2005 listersWithoutJob.append(listit);
2010 foreach (
KDirLister* listit, (*dit).listersCurrentlyHolding )
2012 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyHolding.count() <<
"holders:" <<
list;
2017 for ( ; jit != runningListJobs.end() ; ++jit )
2018 kDebug(7004) <<
" " << jit.key() <<
"listing" << joburl( jit.key() ) <<
":" << (*jit).count() <<
"entries.";
2020 kDebug(7004) <<
"Items in cache:";
2021 const QList<QString> cachedDirs = itemsCached.keys();
2022 foreach(
const QString& cachedDir, cachedDirs) {
2023 DirItem* dirItem = itemsCached.object(cachedDir);
2024 kDebug(7004) <<
" " << cachedDir <<
"rootItem:"
2025 << (!dirItem->rootItem.isNull() ? dirItem->rootItem.url().prettyUrl() :
QString(
"NULL") )
2026 <<
"with" << dirItem->lstItems.count() <<
"items.";
2030 Q_FOREACH(
KDirLister* listit, listersWithoutJob) {
2031 kFatal() <<
"HUH? Lister" << listit <<
"is supposed to be listing, but has no job!";
2056 if (!kDirListerCache.isDestroyed()) {
2058 kDirListerCache->forgetDirs(
this );
2072 return kDirListerCache->listDir(
this, _url, _flags & Keep, _flags &
Reload );
2077 kDirListerCache->stop(
this );
2082 kDirListerCache->stopListingUrl(
this, _url );
2096 kDirListerCache->setAutoUpdate(
this, _enable );
2167 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2172 KFileItemList::iterator kit = itemList->begin();
2173 const KFileItemList::iterator kend = itemList->end();
2174 for (; kit != kend; ++kit) {
2187 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2192 KFileItemList::iterator kit = itemList->begin();
2193 const KFileItemList::iterator kend = itemList->end();
2194 for (; kit != kend; ++kit) {
2197 if (text ==
"." || text ==
"..")
2200 if (nowVisible && !item.
isMarked())
2202 else if (!nowVisible && item.
isMarked())
2203 deletedItems.append(*kit);
2205 if (!deletedItems.isEmpty()) {
2208 Q_FOREACH(
const KFileItem& item, deletedItems)
2218 kDirListerCache->updateDirectory( _u );
2233 KFileItem *item = kDirListerCache->findByUrl(
this, _url );
2243 return kDirListerCache->findByName(
this, _name );
2259 const QStringList list = nameFilter.split(
' ', QString::SkipEmptyParts );
2260 for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
2275 if (mimeFilter.contains(QLatin1String(
"application/octet-stream")) || mimeFilter.contains(QLatin1String(
"all/allfiles")))
2318 Q_ASSERT( !item.
isNull() );
2320 if ( item.
text() ==
".." )
2334 Q_ASSERT(!item.
isNull());
2343 for ( QList<QRegExp>::const_iterator it = filters.begin(); it != filters.end(); ++it )
2344 if ( (*it).exactMatch( name ) )
2352 if ( filters.isEmpty() )
2360 QStringList::const_iterator it = filters.begin();
2361 for ( ; it != filters.end(); ++it )
2362 if ( mimeptr->
is(*it) )
2371 if ( filters.isEmpty() )
2374 QStringList::const_iterator it = filters.begin();
2375 for ( ; it != filters.end(); ++it )
2376 if ( (*it) == mime )
2393 if (!isItemVisible(item))
2398 if ( m_parent->matchesMimeFilter( item ) )
2405 Q_ASSERT( !item.
isNull() );
2406 (*lstNewItems)[directoryUrl].append( item );
2410 if ( !lstMimeFilteredItems ) {
2414 Q_ASSERT( !item.
isNull() );
2415 lstMimeFilteredItems->append( item );
2424 KFileItemList::const_iterator kit = items.begin();
2425 const KFileItemList::const_iterator kend = items.end();
2426 for ( ; kit != kend; ++kit )
2427 addNewItem(directoryUrl, *kit);
2432 const bool refreshItemWasFiltered = !isItemVisible(oldItem) ||
2433 !m_parent->matchesMimeFilter(oldItem);
2434 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2435 if ( refreshItemWasFiltered )
2437 if ( !lstNewItems ) {
2441 Q_ASSERT( !item.
isNull() );
2442 (*lstNewItems)[directoryUrl].append( item );
2446 if ( !lstRefreshItems ) {
2447 lstRefreshItems =
new QList<QPair<KFileItem,KFileItem> >;
2450 Q_ASSERT( !item.
isNull() );
2451 lstRefreshItems->append( qMakePair(oldItem, item) );
2454 else if ( !refreshItemWasFiltered )
2456 if ( !lstRemoveItems ) {
2463 Q_ASSERT(!oldItem.
isNull());
2464 lstRemoveItems->append(oldItem);
2474 lstMimeFilteredItems = 0;
2476 QList<QPair<KFileItem, KFileItem> > *tmpRefresh = lstRefreshItems;
2477 lstRefreshItems = 0;
2483 QHashIterator<KUrl, KFileItemList> it(*tmpNew);
2484 while (it.hasNext()) {
2486 emit m_parent->itemsAdded(it.key(), it.value());
2487 emit m_parent->newItems(it.value());
2494 emit m_parent->itemsFilteredByMime( *tmpMime );
2500 emit m_parent->refreshItems( *tmpRefresh );
2506 emit m_parent->itemsDeleted( *tmpRemove );
2516 return (!settings.dirOnlyMode || item.
isDir())
2517 && m_parent->matchesFilter(item);
2523 QMutableListIterator<KFileItem> it(items);
2524 while (it.hasNext()) {
2526 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2528 emit m_parent->deleteItem(item);
2533 if (!items.isEmpty())
2534 emit m_parent->itemsDeleted(items);
2541 emit m_parent->infoMessage( message );
2553 while ( dataIt != jobData.end() )
2555 result += (*dataIt).percent * (*dataIt).totalSize;
2556 size += (*dataIt).totalSize;
2564 emit m_parent->percent( result );
2573 while ( dataIt != jobData.end() )
2575 result += (*dataIt).totalSize;
2579 emit m_parent->totalSize( result );
2588 while ( dataIt != jobData.end() )
2590 result += (*dataIt).processedSize;
2594 emit m_parent->processedSize( result );
2603 while ( dataIt != jobData.end() )
2605 result += (*dataIt).speed;
2609 emit m_parent->speed( result );
2616 qDebug() << m_parent <<
"numJobs:" << jobData.count();
2617 QMapIterator<KIO::ListJob *, JobData> it(jobData);
2618 while (it.hasNext()) {
2620 qDebug() << (
void*)it.key();
2621 qDebug() << it.key();
2625 return jobData.count();
2630 jobData.remove( job );
2641 jobData.insert( job, data );
2648 m_parent, SLOT(_k_slotInfoMessage(
KJob*,
QString)) );
2649 m_parent->connect( job, SIGNAL(
percent(
KJob*,ulong)),
2650 m_parent, SLOT(_k_slotPercent(
KJob*,ulong)) );
2651 m_parent->connect( job, SIGNAL(
totalSize(
KJob*,qulonglong)),
2652 m_parent, SLOT(_k_slotTotalSize(
KJob*,qulonglong)) );
2654 m_parent, SLOT(_k_slotProcessedSize(
KJob*,qulonglong)) );
2655 m_parent->connect( job, SIGNAL(
speed(
KJob*,ulong)),
2656 m_parent, SLOT(_k_slotSpeed(
KJob*,ulong)) );
2676 KFileItemList *allItems = kDirListerCache->itemsForDir( dir );
2685 KFileItemList::const_iterator kit = allItems->constBegin();
2686 const KFileItemList::const_iterator kend = allItems->constEnd();
2687 for ( ; kit != kend; ++kit )
2691 result.append(item);
2717 const int idx = lstDirs.indexOf( oldUrl );
2719 kWarning(7004) <<
"Unexpected redirection from" << oldUrl <<
"to" << newUrl
2720 <<
"but this dirlister is currently listing/holding" << lstDirs;
2722 lstDirs[ idx ] = newUrl;
2725 if ( lstDirs.count() == 1 ) {
2727 emit m_parent->clear();
2728 emit m_parent->redirection( newUrl );
2731 emit m_parent->clear( oldUrl );
2733 emit m_parent->redirection( oldUrl, newUrl );
2743 QMutableListIterator<KDirLister *> lister_it(listersCurrentlyListing);
2744 while (lister_it.hasNext()) {
2750 Q_ASSERT(!listersCurrentlyHolding.contains(kdl));
2751 if (!listersCurrentlyHolding.contains(kdl)) {
2752 listersCurrentlyHolding.append(kdl);
2763 return kDirListerCache->itemForUrl(url);
2766 #include "kdirlister.moc"
2767 #include "kdirlister_p.moc"