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)) );
64 kdirnotify =
new org::kde::KDirNotify(QString(), QString(), QDBusConnection::sessionBus(),
this);
65 connect(kdirnotify, SIGNAL(FileRenamed(QString,QString)), SLOT(slotFileRenamed(QString,QString)));
66 connect(kdirnotify, SIGNAL(FilesAdded(QString)), SLOT(slotFilesAdded(QString)));
67 connect(kdirnotify, SIGNAL(FilesChanged(QStringList)), SLOT(slotFilesChanged(QStringList)));
68 connect(kdirnotify, SIGNAL(FilesRemoved(QStringList)), SLOT(slotFilesRemoved(QStringList)));
72 qAddPostRoutine(kDirListerCache.destroy);
79 qDeleteAll(itemsInUse);
83 directoryData.clear();
92 bool _keep,
bool _reload )
101 _url.setHost(QString());
109 const QString urlStr = _url.
url();
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 kDebug(7004) <<
"Listing" << itemU->lstItems.count() <<
"cached items soon";
292 m_lister(lister), m_url(
url),
293 m_reload(
reload), m_emitCompleted(true)
297 kWarning(7004) <<
"Lister" << lister <<
"has a cached items job already for" <<
url;
309 kDirListerCache->emitItemsFromCache(
this, m_lister, m_url, m_reload, m_emitCompleted);
316 kDirListerCache->forgetCachedItemsJob(
this, m_lister, m_url);
317 if (!property(
"_kdlc_silent").toBool()) {
318 emit m_lister->canceled(m_url);
319 emit m_lister->canceled();
327 const QString urlStr = _url.
url();
331 DirItem *itemU = kDirListerCache->itemsInUse.value(urlStr);
333 kWarning(7004) <<
"Can't find item for directory" << urlStr <<
"anymore";
337 _reload = _reload || !itemU->complete;
342 if (!
items.isEmpty()) {
349 forgetCachedItemsJob(cachedItemsJob, lister, _url);
355 if (_emitCompleted) {
372 const QString urlStr = _url.
url();
389 bool KDirListerCache::validUrl(
const KDirLister *lister,
const KUrl&
url )
const 391 if ( !
url.isValid() )
422 Q_FOREACH(
const KUrl&
url, urls) {
423 stopListingUrl(lister,
url, silent);
429 for( ; dirit != dirend ; ++dirit ) {
432 kDebug(7004) <<
"ERROR: found lister" << lister <<
"in list - for" << dirit.key();
443 const QString urlStr =
url.
url();
446 if (cachedItemsJob) {
448 cachedItemsJob->setProperty(
"_kdlc_silent",
true);
450 cachedItemsJob->
kill();
454 kDebug(7004) << lister <<
" url=" <<
url;
457 if (dirit == directoryData.end())
464 stopListJob(urlStr, silent);
477 void KDirListerCache::stopListJob(
const QString&
url,
bool silent)
492 job->setProperty(
"_kdlc_silent",
true);
502 for ( KUrl::List::const_iterator it = lister->d->
lstDirs.constBegin();
503 it != lister->d->
lstDirs.constEnd(); ++it ) {
504 DirItem* dirItem = itemsInUse.value((*it).url());
507 dirItem->incAutoUpdate();
509 dirItem->decAutoUpdate();
517 emit lister->
clear();
526 for ( KUrl::List::const_iterator it = lstDirsCopy.begin();
527 it != lstDirsCopy.end(); ++it ) {
528 forgetDirs( lister, *it,
false );
536 if (possibleMountPoints.isEmpty())
540 const bool supermount = mp->mountType() ==
"supermount";
545 return mp->mountOptions().contains(
"noauto");
555 const QString urlStr =
url.
url();
557 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
558 if (dit == directoryData.end())
568 DirItem *item = itemsInUse.value(urlStr);
570 bool insertIntoCache =
false;
574 directoryData.erase(dit);
575 itemsInUse.remove( urlStr );
580 kDebug(7004) <<
"Killing update job for " << urlStr;
586 if ( lister->d->
numJobs() == 0 ) {
597 insertIntoCache = item->complete;
598 if (insertIntoCache) {
608 const bool isLocal = item->url.isLocalFile();
609 bool isManuallyMounted =
false;
610 bool containsManuallyMounted =
false;
612 isManuallyMounted =
manually_mounted( item->url.toLocalFile(), possibleMountPoints );
613 if ( !isManuallyMounted ) {
617 KFileItemList::const_iterator kit = item->lstItems.constBegin();
618 KFileItemList::const_iterator kend = item->lstItems.constEnd();
619 for ( ; kit != kend && !containsManuallyMounted; ++kit )
620 if ( (*kit).isDir() &&
manually_mounted((*kit).url().toLocalFile(), possibleMountPoints) )
621 containsManuallyMounted =
true;
625 if ( isManuallyMounted || containsManuallyMounted )
627 kDebug(7004) <<
"Not adding a watch on " << item->url <<
" because it " <<
628 ( isManuallyMounted ?
"is manually mounted" :
"contains a manually mounted subdir" );
629 item->complete =
false;
631 item->incAutoUpdate();
632 item->watchedWhileInCache =
true;
643 item->decAutoUpdate();
646 if (item && insertIntoCache) {
647 kDebug(7004) << lister <<
"item moved into cache:" <<
url;
648 itemsCached.insert(urlStr, item);
657 if (!checkUpdate(urlStr)) {
660 if (!pendingUpdateTimer.isActive())
661 pendingUpdateTimer.start(500);
697 if (cachedItemsJob) {
699 cachedItemsJob->
done();
700 delete cachedItemsJob;
710 if (!(listers.isEmpty() || killed)) {
711 kWarning() <<
"The unexpected happened.";
712 kWarning() <<
"listers for" << _dir <<
"=" << listers;
721 Q_ASSERT( listers.isEmpty() || killed );
728 connect( job, SIGNAL(result(
KJob*)),
729 this, SLOT(slotUpdateResult(
KJob*)) );
731 kDebug(7004) <<
"update started in" << _dir;
737 if ( !holders.isEmpty() ) {
742 if ( first && kdl->d->
window ) {
744 job->ui()->setWindow( kdl->d->
window );
749 job->ui()->setWindow(
window );
758 bool KDirListerCache::checkUpdate(
const QString& _dir )
760 if ( !itemsInUse.contains(_dir) )
762 DirItem *item = itemsCached[_dir];
763 if ( item && item->complete )
767 item->complete =
false;
768 item->watchedWhileInCache =
false;
769 item->decAutoUpdate();
792 KDirListerCache::DirItem *KDirListerCache::dirItemForUrl(
const KUrl&
dir)
const 795 DirItem *item = itemsInUse.value(urlStr);
797 item = itemsCached[urlStr];
803 DirItem *item = dirItemForUrl(
dir);
804 return item ? &item->lstItems : 0;
811 for (KUrl::List::const_iterator it = lister->d->
lstDirs.constBegin();
812 it != lister->d->
lstDirs.constEnd(); ++it) {
813 DirItem* dirItem = itemsInUse.value((*it).url());
815 const KFileItem item = dirItem->lstItems.findByName(_name);
831 DirItem* dirItem = dirItemForUrl(parentDir);
834 if (!lister || lister->d->
lstDirs.contains(parentDir)) {
835 KFileItemList::iterator it = dirItem->lstItems.begin();
836 const KFileItemList::iterator
end = dirItem->lstItems.end();
837 for (; it !=
end ; ++it) {
838 if ((*it).url() ==
url) {
848 dirItem = dirItemForUrl(
url);
849 if (dirItem && !dirItem->rootItem.isNull() && dirItem->rootItem.url() ==
url) {
851 if (!lister || lister->d->
lstDirs.contains(
url)) {
852 return &dirItem->rootItem;
864 Q_FOREACH(
const QString& u, directoriesForCanonicalPath(urlDir.
toLocalFile())) {
886 for (KUrl::List::const_iterator it = fileList.begin(); it != fileList.end() ; ++it) {
888 DirItem* dirItem = dirItemForUrl(
url);
890 deletedSubdirs.append(
url);
891 if (!dirItem->rootItem.isNull()) {
892 removedItemsByDir[
url.
url()].append(dirItem->rootItem);
897 parentDir.setPath(parentDir.directory());
898 dirItem = dirItemForUrl(parentDir);
901 for (KFileItemList::iterator fit = dirItem->lstItems.begin(), fend = dirItem->lstItems.end(); fit != fend ; ++fit) {
902 if ((*fit).url() ==
url) {
904 removedItemsByDir[parentDir.url()].append(fileitem);
907 deletedSubdirs.append(
url);
909 dirItem->lstItems.erase(fit);
916 for(; rit != removedItemsByDir.constEnd(); ++rit) {
919 DirectoryDataHash::const_iterator dit = directoryData.constFind(rit.key());
920 if (dit != directoryData.constEnd()) {
921 itemsDeleted((*dit).listersCurrentlyHolding, rit.value());
925 Q_FOREACH(
const KUrl&
url, deletedSubdirs) {
936 QStringList::const_iterator it = fileList.begin();
937 for (; it != fileList.end() ; ++it) {
941 kDebug(7004) <<
"item not found for" <<
url;
947 pendingRemoteUpdates.insert(fileitem);
951 dir.setPath(
dir.directory());
952 if (!dirsToUpdate.contains(
dir))
953 dirsToUpdate.prepend(
dir);
957 KUrl::List::const_iterator itdir = dirsToUpdate.constBegin();
958 for (; itdir != dirsToUpdate.constEnd() ; ++itdir)
963 processPendingUpdates();
970 kDebug(7004) << src <<
"->" << dst;
979 kDebug(7004) <<
"Item not found:" << oldurl;
990 if (existingDestItem) {
992 slotFilesRemoved(dst);
1003 if (!nameOnly && fileitem->
isDir()) {
1004 renameDir( src, dst );
1014 slotFilesChanged( QStringList() << src.
url() );
1017 fileitem->
setName( dst.fileName() );
1038 KUrl parentDir( oldItem.
url() );
1039 parentDir.
setPath( parentDir.directory() );
1040 const QString parentDirURL = parentDir.url();
1041 DirectoryDataHash::iterator dit = directoryData.find(parentDirURL);
1044 if (dit != directoryData.end())
1045 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1046 if (oldItem.
isDir()) {
1048 dit = directoryData.find(oldItem.
url().
url());
1049 if (dit != directoryData.end())
1050 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1055 KUrl directoryUrl(oldItem.
url());
1061 directoryUrl.setPath(directoryUrl.directory());
1064 listersToRefresh.insert(kdl);
1066 return listersToRefresh;
1069 QStringList KDirListerCache::directoriesForCanonicalPath(
const QString&
dir)
const 1073 dirs << canonicalUrls.value(
dir).toSet().toList();
1075 if (
dirs.count() > 1)
1085 void KDirListerCache::slotFileDirty(
const QString& path )
1096 isDir = item.
isDir();
1098 KDE_struct_stat buff;
1099 kDebug(7004) <<
"Doing stat on:" << path;
1102 isDir = S_ISDIR(buff.st_mode);
1107 handleDirDirty(
dir);
1110 Q_FOREACH(
const QString&
dir, directoriesForCanonicalPath(
url.
directory())) {
1113 handleFileDirty(aliasUrl);
1119 void KDirListerCache::handleDirDirty(
const KUrl&
url)
1125 QMutableSetIterator<QString> pendingIt(pendingUpdates);
1126 while (pendingIt.hasNext()) {
1127 const QString updPath = pendingIt.next();
1129 if (updPath.startsWith(dirPath) &&
1130 updPath.indexOf(
'/', dirPath.length()) == -1) {
1131 kDebug(7004) <<
"forgetting about individual update to" << updPath;
1140 void KDirListerCache::handleFileDirty(
const KUrl&
url)
1144 if (!existingItem) {
1152 if (!pendingUpdates.contains(filePath)) {
1154 dir.setPath(
dir.directory());
1155 if (checkUpdate(
dir.url())) {
1156 pendingUpdates.insert(filePath);
1157 if (!pendingUpdateTimer.isActive())
1158 pendingUpdateTimer.start(500);
1164 void KDirListerCache::slotFileCreated(
const QString& path )
1170 slotFilesAdded(fileUrl.directory());
1173 void KDirListerCache::slotFileDeleted(
const QString& path )
1177 QStringList fileUrls;
1178 Q_FOREACH(
KUrl url, directoriesForCanonicalPath(u.directory())) {
1182 slotFilesRemoved(fileUrls);
1187 KUrl url(joburl( static_cast<KIO::ListJob *>(job) ));
1189 QString urlStr =
url.
url();
1193 DirItem *
dir = itemsInUse.value(urlStr);
1195 kError(7004) <<
"Internal error: job is listing" <<
url <<
"but itemsInUse only knows about" << itemsInUse.keys();
1200 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
1201 if (dit == directoryData.end()) {
1202 kError(7004) <<
"Internal error: job is listing" <<
url <<
"but directoryData doesn't know about that url, only about:" << directoryData.keys();
1203 Q_ASSERT(dit != directoryData.end());
1208 kError(7004) <<
"Internal error: job is listing" <<
url <<
"but directoryData says no listers are currently listing " << urlStr;
1221 KIO::UDSEntryList::const_iterator it = entries.begin();
1222 const KIO::UDSEntryList::const_iterator
end = entries.end();
1223 for ( ; it !=
end; ++it )
1227 Q_ASSERT( !
name.isEmpty() );
1228 if (
name.isEmpty() )
1233 Q_ASSERT(
dir->rootItem.isNull() );
1241 dir->rootItem = itemForUrl(
url);
1242 if (
dir->rootItem.isNull())
1249 else if ( name !=
".." )
1254 dir->lstItems.append( item );
1265 void KDirListerCache::slotResult(
KJob *j )
1273 runningListJobs.remove( job );
1275 KUrl jobUrl(joburl( job ));
1277 QString jobUrlStr = jobUrl.url();
1279 kDebug(7004) <<
"finished listing" << jobUrl;
1281 DirectoryDataHash::iterator dit = directoryData.find(jobUrlStr);
1282 if (dit == directoryData.end()) {
1283 kError() <<
"Nothing found in directoryData for URL" << jobUrlStr;
1287 Q_ASSERT(dit != directoryData.end());
1292 kError() <<
"OOOOPS, nothing in directoryData.listersCurrentlyListing for" << jobUrlStr;
1315 const bool silent = job->property(
"_kdlc_silent").toBool();
1330 DirItem *
dir = itemsInUse.value(jobUrlStr);
1332 dir->complete =
true;
1348 processPendingUpdates();
1367 if ( oldUrl == newUrl ) {
1368 kDebug(7004) <<
"New redirection url same as old, giving up.";
1370 }
else if (newUrl.isEmpty()) {
1371 kDebug(7004) <<
"New redirection url is empty, giving up.";
1375 const QString oldUrlStr = oldUrl.url();
1376 const QString newUrlStr = newUrl.url();
1378 kDebug(7004) << oldUrl <<
"->" << newUrl;
1391 DirItem *
dir = itemsInUse.take(oldUrlStr);
1394 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1395 Q_ASSERT(dit != directoryData.end());
1397 directoryData.erase(dit);
1398 Q_ASSERT( !oldDirData.listersCurrentlyListing.isEmpty() );
1400 Q_ASSERT( !listers.isEmpty() );
1403 kdl->d->
redirect(oldUrlStr, newUrl,
false );
1415 kdl->d->
redirect(oldUrl, newUrl,
false );
1418 DirItem *newDir = itemsInUse.value(newUrlStr);
1420 kDebug(7004) << newUrl <<
"already in use";
1434 if ( !curListers.isEmpty() ) {
1435 kDebug(7004) <<
"and it is currently listed";
1448 curListers.append( kdl );
1450 curListers = listers;
1458 if ( !curHolders.isEmpty() ) {
1459 kDebug(7004) <<
"and it is currently held.";
1468 curHolders.append( kdl );
1470 curHolders = holders;
1476 foreach (
KDirLister *kdl, listers + holders ) {
1483 }
else if ( (newDir = itemsCached.take( newUrlStr )) ) {
1484 kDebug(7004) << newUrl <<
"is unused, but already in the cache.";
1487 itemsInUse.insert( newUrlStr, newDir );
1493 foreach (
KDirLister *kdl, listers + holders ) {
1501 kDebug(7004) << newUrl <<
"has not been listed yet.";
1504 dir->lstItems.clear();
1505 dir->redirect( newUrl );
1506 itemsInUse.insert( newUrlStr,
dir );
1511 if ( holders.isEmpty() ) {
1520 job->disconnect(
this );
1524 connect( job, SIGNAL(result(
KJob*)),
1525 this, SLOT(slotUpdateResult(
KJob*)) );
1534 struct KDirListerCache::ItemInUseChange
1536 ItemInUseChange(
const QString& old,
const QString& newU, DirItem* di)
1537 : oldUrl(old), newUrl(newU), dirItem(di) {}
1543 void KDirListerCache::renameDir(
const KUrl &oldUrl,
const KUrl &newUrl )
1545 kDebug(7004) << oldUrl <<
"->" << newUrl;
1553 QLinkedList<ItemInUseChange> itemsToChange;
1559 for (; itu != ituend ; ++itu) {
1560 DirItem *
dir = itu.value();
1561 KUrl oldDirUrl ( itu.key() );
1566 QString relPath = oldDirUrl.
path().mid( oldUrl.
path().length() );
1568 KUrl newDirUrl( newUrl );
1569 if ( !relPath.isEmpty() )
1570 newDirUrl.addPath( relPath );
1574 dir->redirect( newDirUrl );
1581 for ( KFileItemList::iterator kit =
dir->lstItems.begin(), kend =
dir->lstItems.end();
1582 kit != kend ; ++kit )
1586 const KUrl oldItemUrl ((*kit).url());
1588 KUrl newItemUrl( oldItemUrl );
1589 newItemUrl.setPath( newDirUrl.path() );
1590 newItemUrl.addPath( oldItemUrl.fileName() );
1591 kDebug(7004) <<
"renaming" << oldItemUrl <<
"to" << newItemUrl;
1592 (*kit).setUrl(newItemUrl);
1594 listers |= emitRefreshItem(oldItem, *kit);
1605 foreach(
const ItemInUseChange& i, itemsToChange) {
1606 itemsInUse.remove(i.oldUrl);
1607 itemsInUse.insert(i.newUrl, i.dirItem);
1610 foreach(
const ItemInUseChange& i, itemsToChange) {
1611 emitRedirections(i.oldUrl, i.newUrl);
1616 removeDirFromCache( oldUrl );
1621 void KDirListerCache::emitRedirections(
const KUrl &oldUrl,
const KUrl &newUrl )
1623 kDebug(7004) << oldUrl <<
"->" << newUrl;
1632 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1633 if ( dit == directoryData.end() )
1655 directoryData.erase(dit);
1657 if ( !listers.isEmpty() ) {
1667 kdl->d->
redirect(oldUrl, newUrl,
true );
1671 void KDirListerCache::removeDirFromCache(
const KUrl&
dir )
1675 foreach(
const QString& cachedDir, cachedDirs) {
1676 if (
dir.isParentOf(
KUrl( cachedDir ) ) )
1677 itemsCached.remove( cachedDir );
1686 void KDirListerCache::slotUpdateResult(
KJob * j )
1691 KUrl jobUrl (joburl( job ));
1693 QString jobUrlStr (jobUrl.url());
1695 kDebug(7004) <<
"finished update" << jobUrl;
1705 Q_ASSERT( !listers.isEmpty() );
1707 if ( job->
error() ) {
1714 const bool silent = job->property(
"_kdlc_silent").toBool();
1718 if ( kdl->d->
numJobs() == 0 ) {
1726 runningListJobs.remove( job );
1730 processPendingUpdates();
1734 DirItem *
dir = itemsInUse.value(jobUrlStr, 0);
1736 kError(7004) <<
"Internal error: itemsInUse did not contain" << jobUrlStr;
1742 dir->complete =
true;
1753 for ( KFileItemList::iterator kit =
dir->lstItems.begin(), kend =
dir->lstItems.end() ; kit != kend ; ++kit )
1756 fileItems.insert( (*kit).name(), &*kit );
1760 KIO::UDSEntryList::const_iterator it = buf.constBegin();
1761 const KIO::UDSEntryList::const_iterator
end = buf.constEnd();
1762 for ( ; it !=
end; ++it )
1768 Q_ASSERT( !
name.isEmpty() );
1772 if (
name.isEmpty() ||
name ==
".." )
1779 if (
dir->rootItem.isNull() )
1781 dir->rootItem = item;
1794 const bool inPendingRemoteUpdates = (pru_it != pendingRemoteUpdates.end());
1797 if (!tmp->cmp( item ) || inPendingRemoteUpdates) {
1799 if (inPendingRemoteUpdates) {
1800 pendingRemoteUpdates.erase(pru_it);
1819 dir->lstItems.append( pitem );
1826 runningListJobs.remove( job );
1828 deleteUnmarkedItems( listers,
dir->lstItems );
1845 processPendingUpdates();
1853 while ( it != runningListJobs.constEnd() )
1873 runningListJobs.remove( job );
1874 job->disconnect(
this );
1882 QMutableListIterator<KFileItem> kit(lstItems);
1883 while (kit.hasNext()) {
1887 deletedItems.append(item);
1891 if (!deletedItems.isEmpty())
1901 Q_FOREACH(
const KFileItem& item, deletedItems) {
1903 deleteDir(item.
url());
1907 void KDirListerCache::deleteDir(
const KUrl& dirUrl )
1919 for ( ; itu != ituend; ++itu ) {
1920 const KUrl deletedUrl( itu.key() );
1922 affectedItems.append(deletedUrl);
1926 foreach(
const KUrl& deletedUrl, affectedItems) {
1927 const QString deletedUrlStr = deletedUrl.
url();
1929 DirectoryDataHash::iterator dit = directoryData.find(deletedUrlStr);
1930 if (dit != directoryData.end()) {
1934 stopListingUrl( kdl, deletedUrl );
1942 if ( kdl->d->
url == deletedUrl )
1954 const bool treeview = kdl->d->
lstDirs.count() > 1;
1961 kdl->d->
lstDirs.removeAll( deletedUrl );
1963 forgetDirs( kdl, deletedUrl, treeview );
1970 int count = itemsInUse.remove( deletedUrlStr );
1971 Q_ASSERT( count == 0 );
1976 removeDirFromCache( dirUrl );
1980 void KDirListerCache::processPendingUpdates()
1983 foreach(
const QString& file, pendingUpdates) {
1991 listers |= emitRefreshItem( oldItem, *item );
1994 pendingUpdates.clear();
2001 void KDirListerCache::printDebug()
2003 kDebug(7004) <<
"Items in use:";
2006 for ( ; itu != ituend ; ++itu ) {
2007 kDebug(7004) <<
" " << itu.key() <<
"URL:" << itu.value()->url
2008 <<
"rootItem:" << ( !itu.value()->rootItem.isNull() ? itu.value()->rootItem.url() :
KUrl() )
2009 <<
"autoUpdates refcount:" << itu.value()->autoUpdates
2010 <<
"complete:" << itu.value()->complete
2011 << QString(
"with %1 items.").arg(itu.value()->lstItems.count());
2015 kDebug(7004) <<
"Directory data:";
2016 DirectoryDataHash::const_iterator dit = directoryData.constBegin();
2017 for ( ; dit != directoryData.constEnd(); ++dit )
2020 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing )
2022 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyListing.count() <<
"listers:" <<
list;
2023 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing ) {
2026 }
else if (
KIO::ListJob* listJob = jobForUrl(dit.key())) {
2027 kDebug(7004) <<
" Lister" << listit <<
"has ListJob" << listJob;
2029 listersWithoutJob.append(listit);
2034 foreach (
KDirLister* listit, (*dit).listersCurrentlyHolding )
2036 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyHolding.count() <<
"holders:" <<
list;
2041 for ( ; jit != runningListJobs.end() ; ++jit )
2042 kDebug(7004) <<
" " << jit.key() <<
"listing" << joburl( jit.key() ) <<
":" << (*jit).count() <<
"entries.";
2044 kDebug(7004) <<
"Items in cache:";
2046 foreach(
const QString& cachedDir, cachedDirs) {
2047 DirItem* dirItem = itemsCached.object(cachedDir);
2048 kDebug(7004) <<
" " << cachedDir <<
"rootItem:" 2049 << (!dirItem->rootItem.isNull() ? dirItem->rootItem.url().prettyUrl() : QString(
"NULL") )
2050 <<
"with" << dirItem->lstItems.count() <<
"items.";
2054 Q_FOREACH(
KDirLister* listit, listersWithoutJob) {
2055 kFatal() <<
"HUH? Lister" << listit <<
"is supposed to be listing, but has no job!";
2080 if (!kDirListerCache.isDestroyed()) {
2082 kDirListerCache->forgetDirs(
this );
2096 return kDirListerCache->listDir(
this, _url, _flags &
Keep, _flags &
Reload );
2101 kDirListerCache->stop(
this );
2106 kDirListerCache->stopListingUrl(
this, _url );
2120 kDirListerCache->setAutoUpdate(
this, _enable );
2196 KFileItemList::iterator kit = itemList->begin();
2197 const KFileItemList::iterator kend = itemList->end();
2198 for (; kit != kend; ++kit) {
2216 KFileItemList::iterator kit = itemList->begin();
2217 const KFileItemList::iterator kend = itemList->end();
2218 for (; kit != kend; ++kit) {
2220 const QString text = item.
text();
2221 if (text ==
"." || text ==
"..")
2224 if (nowVisible && !item.
isMarked())
2226 else if (!nowVisible && item.
isMarked())
2227 deletedItems.append(*kit);
2229 if (!deletedItems.isEmpty()) {
2232 Q_FOREACH(
const KFileItem& item, deletedItems)
2242 kDirListerCache->updateDirectory( _u );
2257 KFileItem *item = kDirListerCache->findByUrl(
this, _url );
2267 return kDirListerCache->findByName(
this, _name );
2283 const QStringList
list =
nameFilter.split(
' ', QString::SkipEmptyParts );
2284 for (QStringList::const_iterator it =
list.begin(); it !=
list.end(); ++it)
2299 if (
mimeFilter.contains(QLatin1String(
"application/octet-stream")) ||
mimeFilter.contains(QLatin1String(
"all/allfiles")))
2342 Q_ASSERT( !item.
isNull() );
2344 if ( item.
text() ==
".." )
2358 Q_ASSERT(!item.
isNull());
2368 if ( (*it).exactMatch(
name ) )
2376 if ( filters.isEmpty() )
2384 QStringList::const_iterator it = filters.begin();
2385 for ( ; it != filters.end(); ++it )
2386 if ( mimeptr->
is(*it) )
2395 if ( filters.isEmpty() )
2398 QStringList::const_iterator it = filters.begin();
2399 for ( ; it != filters.end(); ++it )
2400 if ( (*it) == mime )
2417 if (!isItemVisible(item))
2422 if ( m_parent->matchesMimeFilter( item ) )
2429 Q_ASSERT( !item.
isNull() );
2430 (*lstNewItems)[directoryUrl].append( item );
2434 if ( !lstMimeFilteredItems ) {
2438 Q_ASSERT( !item.
isNull() );
2439 lstMimeFilteredItems->append( item );
2448 KFileItemList::const_iterator kit =
items.begin();
2449 const KFileItemList::const_iterator kend =
items.end();
2450 for ( ; kit != kend; ++kit )
2451 addNewItem(directoryUrl, *kit);
2456 const bool refreshItemWasFiltered = !isItemVisible(oldItem) ||
2457 !m_parent->matchesMimeFilter(oldItem);
2458 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2459 if ( refreshItemWasFiltered )
2461 if ( !lstNewItems ) {
2465 Q_ASSERT( !item.
isNull() );
2466 (*lstNewItems)[directoryUrl].append( item );
2470 if ( !lstRefreshItems ) {
2474 Q_ASSERT( !item.
isNull() );
2475 lstRefreshItems->append( qMakePair(oldItem, item) );
2478 else if ( !refreshItemWasFiltered )
2480 if ( !lstRemoveItems ) {
2487 Q_ASSERT(!oldItem.
isNull());
2488 lstRemoveItems->append(oldItem);
2498 lstMimeFilteredItems = 0;
2501 lstRefreshItems = 0;
2507 QHashIterator<KUrl, KFileItemList> it(*tmpNew);
2508 while (it.hasNext()) {
2510 emit m_parent->itemsAdded(it.key(), it.value());
2511 emit m_parent->newItems(it.value());
2518 emit m_parent->itemsFilteredByMime( *tmpMime );
2524 emit m_parent->refreshItems( *tmpRefresh );
2530 emit m_parent->itemsDeleted( *tmpRemove );
2540 return (!settings.dirOnlyMode || item.
isDir())
2541 && m_parent->matchesFilter(item);
2547 QMutableListIterator<KFileItem> it(
items);
2548 while (it.hasNext()) {
2550 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2552 emit m_parent->deleteItem(item);
2557 if (!
items.isEmpty())
2558 emit m_parent->itemsDeleted(
items);
2565 emit m_parent->infoMessage(
message );
2577 while ( dataIt != jobData.end() )
2579 result += (*dataIt).percent * (*dataIt).totalSize;
2580 size += (*dataIt).totalSize;
2588 emit m_parent->percent( result );
2597 while ( dataIt != jobData.end() )
2599 result += (*dataIt).totalSize;
2603 emit m_parent->totalSize( result );
2612 while ( dataIt != jobData.end() )
2614 result += (*dataIt).processedSize;
2618 emit m_parent->processedSize( result );
2627 while ( dataIt != jobData.end() )
2629 result += (*dataIt).speed;
2633 emit m_parent->speed( result );
2640 qDebug() << m_parent <<
"numJobs:" << jobData.count();
2641 QMapIterator<KIO::ListJob *, JobData> it(jobData);
2642 while (it.hasNext()) {
2644 qDebug() << (
void*)it.key();
2645 qDebug() << it.key();
2649 return jobData.count();
2654 jobData.remove( job );
2665 jobData.insert( job, data );
2672 m_parent, SLOT(_k_slotInfoMessage(
KJob*,QString)) );
2673 m_parent->connect( job, SIGNAL(
percent(
KJob*,ulong)),
2674 m_parent, SLOT(_k_slotPercent(
KJob*,ulong)) );
2675 m_parent->connect( job, SIGNAL(
totalSize(
KJob*,qulonglong)),
2676 m_parent, SLOT(_k_slotTotalSize(
KJob*,qulonglong)) );
2678 m_parent, SLOT(_k_slotProcessedSize(
KJob*,qulonglong)) );
2679 m_parent->connect( job, SIGNAL(
speed(
KJob*,ulong)),
2680 m_parent, SLOT(_k_slotSpeed(
KJob*,ulong)) );
2709 KFileItemList::const_iterator kit = allItems->constBegin();
2710 const KFileItemList::const_iterator kend = allItems->constEnd();
2711 for ( ; kit != kend; ++kit )
2715 result.append(item);
2739 rootFileItem.setUrl(newUrl);
2744 const int idx = lstDirs.indexOf( oldUrl );
2746 kWarning(7004) <<
"Unexpected redirection from" << oldUrl <<
"to" << newUrl
2747 <<
"but this dirlister is currently listing/holding" << lstDirs;
2749 lstDirs[ idx ] = newUrl;
2752 if ( lstDirs.count() == 1 ) {
2754 emit m_parent->clear();
2755 emit m_parent->redirection( newUrl );
2758 emit m_parent->clear( oldUrl );
2760 emit m_parent->redirection( oldUrl, newUrl );
2770 QMutableListIterator<KDirLister *> lister_it(listersCurrentlyListing);
2771 while (lister_it.hasNext()) {
2777 Q_ASSERT(!listersCurrentlyHolding.contains(kdl));
2778 if (!listersCurrentlyHolding.contains(kdl)) {
2779 listersCurrentlyHolding.append(kdl);
2790 return kDirListerCache->itemForUrl(
url);
2793 #include "kdirlister.moc" 2794 #include "kdirlister_p.moc" virtual void setWindow(QWidget *window)
Associate this job with a window given by window.
An alternative URL (If different from the caption).
void slotFilesRemoved(const QStringList &fileList)
Notify that files have been deleted.
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
QString name(bool lowerCase=false) const
Return the name of the file item (without a path).
QString i18n(const char *text)
bool kill(KillVerbosity verbosity=Quietly)
QString stringValue(uint field) const
QString nameFilter() const
Returns the current name filter, as set via setNameFilter()
void percent(int percent)
Progress signal showing the overall progress of the KDirLister.
virtual ~KDirLister()
Destroy the directory lister.
void adjustPath(AdjustPathOption trailing)
QT_MOC_COMPAT void deleteItem(const KFileItem &_fileItem)
Signals that an item has been deleted.
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
KFileItem findByName(const KDirLister *lister, const QString &_name) const
qulonglong filesize_t
64-bit file size
bool isLocalFile() const
Returns true if the file is a local file.
bool isMarked() const
Used when updating a directory.
static KDirWatch * self()
virtual void setShowingDotFiles(bool _showDotFiles)
Changes the "is viewing dot files" setting.
KFileItem * findByUrl(const KDirLister *lister, const KUrl &url) const
void _k_slotInfoMessage(KJob *, const QString &)
virtual void setAutoUpdate(bool enable)
Enable/disable automatic directory updating, when a directory changes (using KDirWatch).
FilterSettings oldSettings
bool dirOnlyMode() const
Checks whether the KDirLister only lists directories or all files.
A ListJob is allows you to get the get the content of a directory.
bool matchesMimeFilter(const QString &mime) const
Checks whether mime matches a filter in the list of mime types.
#define K_GLOBAL_STATIC(TYPE, NAME)
virtual void handleError(KIO::Job *)
Reimplement to customize error handling.
Hide progress information dialog, i.e.
bool equals(const KUrl &u, const EqualsOptions &options=0) const
Previous directories aren't forgotten (they are still watched by kdirwatch and their items are kept f...
void refresh()
Throw away and re-read (for local files) all information about the file.
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
KUrl url() const
Returns the url of the file.
int stat(const QString &path, KDE_struct_stat *buf)
const char * name(StandardAction id)
CachedItemsJob * cachedItemsJobForUrl(const KUrl &url) const
virtual bool openUrl(const KUrl &_url, OpenUrlFlags _flags=NoFlags)
Run the directory lister on the given url.
bool doMimeExcludeFilter(const QString &mimeExclude, const QStringList &filters) const
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
virtual void clearMimeFilter()
Clears the mime based filter.
bool autoUpdate() const
Checks whether KDirWatch will automatically update directories.
void setUrl(const KUrl &url)
Sets the item's URL.
static KFileItem cachedItemForUrl(const KUrl &url)
Return the KFileItem for the given URL, if we listed it recently and it's still in the cache - which ...
void setName(const QString &name)
Sets the item's name (i.e.
QStringList mimeExcludeFilter
QList< KDirLister * > listersCurrentlyListing
void forgetCachedItemsJob(KDirLister::Private::CachedItemsJob *job, KDirLister *lister, const KUrl &url)
CompareWithoutTrailingSlash
void setMainWindow(QWidget *window)
Pass the main window this object is associated with this is used for caching authentication data...
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
void stopListingUrl(KDirLister *lister, const KUrl &_url, bool silent=false)
void addNewItem(const KUrl &directoryUrl, const KFileItem &item)
static bool manually_mounted(const QString &path, const KMountPoint::List &possibleMountPoints)
void _k_slotPercent(KJob *, unsigned long)
KIO::UDSEntry entry() const
Returns the UDS entry.
void connectJob(KIO::ListJob *)
void slotFileRenamed(const QString &srcUrl, const QString &dstUrl)
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
bool isItemVisible(const KFileItem &item) const
Should this item be visible according to the current filter settings?
bool isNull() const
Return true if default-constructed.
KFileItem rootItem() const
Returns the file item of the URL.
void totalSize(KIO::filesize_t size)
Emitted when we know the size of the jobs.
virtual bool doNameFilter(const QString &name, const QList< QRegExp > &filters) const
Called by the public matchesFilter() to do the actual filtering.
void setPath(const QString &path)
ListJob * listDir(const KUrl &url, JobFlags flags=DefaultFlags, bool includeHidden=true)
List the contents of url, which is assumed to be a directory.
void stop(KDirLister *lister, bool silent=false)
QList< KDirLister * > listersCurrentlyHolding
virtual void stop()
Stop listing all directories currently being listed.
virtual void setNameFilter(const QString &filter)
Set a name filter to only list items matching this name, e.g.
void updateDirectory(const KUrl &dir)
QStringList mimeFilters() const
Returns the list of mime based filters, as set via setMimeFilter().
void addPath(const QString &txt)
void _k_slotProcessedSize(KJob *, qulonglong)
bool isHidden() const
Checks whether the file is hidden.
Indicates whether to use the cache or to reread the directory from the disk.
KFileItemList items(WhichItems which=FilteredItems) const
Returns the items listed for the current url().
long unsigned int percent
virtual void setDirOnlyMode(bool dirsOnly)
Call this to list only directories.
bool isDir() const
Returns true if this item represents a directory.
void prepareForSettingsChange()
KFileItemList itemsForDir(const KUrl &dir, WhichItems which=FilteredItems) const
Returns the items listed for the given dir.
void emitItemsDeleted(const KFileItemList &items)
CachedItemsJob(KDirLister *lister, const KUrl &url, bool reload)
void speed(int bytes_per_second)
Emitted to display information about the speed of the jobs.
QWidget * mainWindow()
Returns the main window associated with this object.
Ptr findByPath(const QString &path) const
void infoMessage(const QString &msg)
Emitted to display information about running jobs.
bool is(const QString &mimeTypeName) const
void setAutoErrorHandlingEnabled(bool enable, QWidget *parent)
Enable or disable auto error handling is enabled.
void started(const KUrl &_url)
Tell the view that we started to list _url.
bool isParentOf(const KUrl &u) const
List of KFileItems, which adds a few helper methods to QList<KFileItem>.
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
void canceled()
Tell the view that the user canceled the listing.
void completed()
Tell the view that listing is finished.
void slotFilesChanged(const QStringList &fileList)
Notify that files have been changed.
bool isFinished() const
Returns true if no io operation is currently in progress.
QList< QRegExp > lstFilters
void setDelayedMimeTypes(bool delayedMimeTypes)
Delayed mimetypes feature: If enabled, mime types will be fetched on demand, which leads to a faster ...
virtual void setMimeFilter(const QStringList &mimeList)
Set mime-based filter to only list items matching the given mimetypes.
void jobStarted(KIO::ListJob *)
KFileItem itemForUrl(const KUrl &url) const
static QString protocolClass(const QString &protocol)
void jobDone(KIO::ListJob *)
const KShortcut & reload()
void refreshMimeType()
Re-reads mimetype information.
bool listDir(KDirLister *lister, const KUrl &_url, bool _keep, bool _reload)
KJobUiDelegate * uiDelegate() const
QList< CachedItemsJob * > m_cachedItemsJobs
::OrgKdeKDirNotifyInterface KDirNotify
KIO::filesize_t totalSize
KUrl::List directories() const
Returns all URLs that are listed by this KDirLister.
KMimeType::Ptr determineMimeType() const
Returns the mimetype of the file item.
const KUrl & url() const
Returns the SimpleJob's URL.
virtual KFileItem findByUrl(const KUrl &_url) const
Find an item by its URL.
QString text() const
Returns the text of the file item.
void clear()
Signal to clear all items.
bool delayedMimeTypes() const
WhichItems
Used by items() and itemsForDir() to specify whether you want all items for a directory or just the f...
QString localPath() const
Returns the local path if isLocalFile() == true or the KIO item has a UDS_LOCAL_PATH atom...
void forgetDirs(KDirLister *lister)
void processedSize(KIO::filesize_t size)
Regularly emitted to show the progress of this KDirLister.
void redirect(const KUrl &oldUrl, const KUrl &newUrl, bool keepItems)
Redirect this dirlister from oldUrl to newUrl.
KUrl url() const
Returns the top level URL that is listed by this KDirLister.
Design of the cache: There is a single KDirListerCache for the whole process.
void setAutoUpdate(KDirLister *lister, bool enable)
virtual bool doMimeFilter(const QString &mime, const QStringList &filters) const
Called by the public matchesMimeFilter() to do the actual filtering.
QString dir(const QString &fileClass)
Returns the most recently used directory accociated with this file-class.
virtual void showErrorMessage()
bool autoErrorHandlingEnabled() const
Check whether auto error handling is enabled.
void setEmitCompleted(bool b)
void redirection(const KUrl &_url)
Signal a redirection.
static List possibleMountPoints(DetailsNeededFlags infoNeeded=BasicInfoNeeded)
KUrl::List lstDirs
List of dirs handled by this dirlister.
KFileItemList * itemsForDir(const KUrl &dir) const
Filename - as displayed in directory listings etc.
void _k_slotTotalSize(KJob *, qulonglong)
bool showingDotFiles() const
Checks whether hidden files (files beginning with a dot) will be shown.
KIO::filesize_t processedSize
void emitItemsFromCache(KDirLister::Private::CachedItemsJob *job, KDirLister *lister, const KUrl &_url, bool _reload, bool _emitCompleted)
void slotFilesAdded(const QString &urlDirectory)
Notify that files have been added in directory The receiver will list that directory again to find th...
The base class for all jobs.
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
bool matchesFilter(const QString &name) const
Checks whether name matches a filter in the list of name filters.
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
void _k_slotSpeed(KJob *, unsigned long)
static Ptr mimeType(const QString &name, FindByNameOption options=ResolveAliases)
static bool supportsListing(const KUrl &url)
Returns whether the protocol can list files/objects.
Helper class for the kiojob used to list and update a directory.
void moveListersWithoutCachedItemsJob(const KUrl &url)
virtual KFileItem findByName(const QString &name) const
Find an item by its name.
void setAutoDelete(bool autodelete)
JobUiDelegate * ui() const
Retrieves the UI delegate of this job.
void setMimeExcludeFilter(const QStringList &mimeList)
Filtering should be done with KFileFilter.
void addRefreshItem(const KUrl &directoryUrl, const KFileItem &oldItem, const KFileItem &item)
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
static QDebug kFatal(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
void itemsDeleted(const KFileItemList &items)
Signal that items have been deleted.
void addNewItems(const KUrl &directoryUrl, const KFileItemList &items)
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
const KUrl & redirectionUrl() const
Returns the ListJob's redirection URL.
virtual void emitChanges()
Actually emit the changes made with setShowingDotFiles, setDirOnlyMode, setNameFilter and setMimeFilt...
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
A KFileItem is a generic class to handle a file, local or remote.
QString number(KIO::filesize_t size)
Converts a size to a string representation Not unlike QString::number(...)
KDirLister(QObject *parent=0)
Create a directory lister.
QStringList list(const QString &fileClass)
Returns a list of directories associated with this file-class.
QString mimetype() const
Returns the mimetype of the file item.
virtual void updateDirectory(const KUrl &_dir)
Update the directory _dir.