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 if (!itemU->lstItems.isEmpty()) {
264 kDebug() <<
"Listing" << itemU->lstItems.count() <<
"cached items soon";
282 if (job->
url() == url)
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()) {
325 const QString urlStr = _url.
url();
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) {
370 const QString urlStr = _url.
url();
387 bool KDirListerCache::validUrl(
const KDirLister *lister,
const KUrl&
url )
const 389 if ( !url.isValid() )
403 QString tmp =
i18n(
"URL cannot be listed\n%1", url.
prettyUrl() );
420 Q_FOREACH(
const KUrl& url, urls) {
421 stopListingUrl(lister, url, silent);
427 for( ; dirit != dirend ; ++dirit ) {
430 kDebug(7004) <<
"ERROR: found lister" << lister <<
"in list - for" << dirit.key();
441 const QString urlStr = url.
url();
444 if (cachedItemsJob) {
446 cachedItemsJob->setProperty(
"_kdlc_silent",
true);
448 cachedItemsJob->
kill();
452 kDebug(7004) << lister <<
" url=" <<
url;
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");
553 const QString urlStr = url.
url();
555 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
556 if (dit == directoryData.end())
566 DirItem *item = itemsInUse.value(urlStr);
568 bool insertIntoCache =
false;
572 directoryData.erase(dit);
573 itemsInUse.remove( urlStr );
578 kDebug(7004) <<
"Killing update job for " << urlStr;
584 if ( lister->d->
numJobs() == 0 ) {
591 lister->d->
lstDirs.removeAll( url );
592 emit lister->
clear( url );
595 insertIntoCache = item->complete;
596 if (insertIntoCache) {
606 const bool isLocal = item->url.isLocalFile();
607 bool isManuallyMounted =
false;
608 bool containsManuallyMounted =
false;
610 isManuallyMounted =
manually_mounted( item->url.toLocalFile(), possibleMountPoints );
611 if ( !isManuallyMounted ) {
615 KFileItemList::const_iterator kit = item->lstItems.constBegin();
616 KFileItemList::const_iterator kend = item->lstItems.constEnd();
617 for ( ; kit != kend && !containsManuallyMounted; ++kit )
618 if ( (*kit).isDir() &&
manually_mounted((*kit).url().toLocalFile(), possibleMountPoints) )
619 containsManuallyMounted =
true;
623 if ( isManuallyMounted || containsManuallyMounted )
625 kDebug(7004) <<
"Not adding a watch on " << item->url <<
" because it " <<
626 ( isManuallyMounted ?
"is manually mounted" :
"contains a manually mounted subdir" );
627 item->complete =
false;
629 item->incAutoUpdate();
630 item->watchedWhileInCache =
true;
641 item->decAutoUpdate();
644 if (item && insertIntoCache) {
645 kDebug(7004) << lister <<
"item moved into cache:" <<
url;
646 itemsCached.insert(urlStr, item);
655 if (!checkUpdate(urlStr)) {
658 if (!pendingUpdateTimer.isActive())
659 pendingUpdateTimer.start(500);
695 if (cachedItemsJob) {
697 cachedItemsJob->
done();
698 delete cachedItemsJob;
708 if (!(listers.isEmpty() || killed)) {
709 kWarning() <<
"The unexpected happened.";
710 kWarning() <<
"listers for" << _dir <<
"=" << listers;
719 Q_ASSERT( listers.isEmpty() || killed );
727 this, SLOT(slotUpdateResult(
KJob*)) );
729 kDebug(7004) <<
"update started in" << _dir;
735 if ( !holders.isEmpty() ) {
740 if ( first && kdl->d->
window ) {
742 job->ui()->setWindow( kdl->d->
window );
747 job->ui()->setWindow( window );
756 bool KDirListerCache::checkUpdate(
const QString& _dir )
758 if ( !itemsInUse.contains(_dir) )
760 DirItem *item = itemsCached[_dir];
761 if ( item && item->complete )
765 item->complete =
false;
766 item->watchedWhileInCache =
false;
767 item->decAutoUpdate();
790 KDirListerCache::DirItem *KDirListerCache::dirItemForUrl(
const KUrl&
dir)
const 793 DirItem *item = itemsInUse.value(urlStr);
795 item = itemsCached[urlStr];
801 DirItem *item = dirItemForUrl(dir);
802 return item ? &item->lstItems : 0;
809 for (KUrl::List::const_iterator it = lister->d->
lstDirs.constBegin();
810 it != lister->d->
lstDirs.constEnd(); ++it) {
811 DirItem* dirItem = itemsInUse.value((*it).url());
813 const KFileItem item = dirItem->lstItems.findByName(_name);
829 DirItem* dirItem = dirItemForUrl(parentDir);
832 if (!lister || lister->d->
lstDirs.contains(parentDir)) {
833 KFileItemList::iterator it = dirItem->lstItems.begin();
834 const KFileItemList::iterator
end = dirItem->lstItems.end();
835 for (; it != end ; ++it) {
836 if ((*it).url() ==
url) {
846 dirItem = dirItemForUrl(url);
847 if (dirItem && !dirItem->rootItem.isNull() && dirItem->rootItem.url() ==
url) {
849 if (!lister || lister->d->
lstDirs.contains(url)) {
850 return &dirItem->rootItem;
862 Q_FOREACH(
const QString& u, directoriesForCanonicalPath(urlDir.
toLocalFile())) {
884 for (KUrl::List::const_iterator it = fileList.begin(); it != fileList.end() ; ++it) {
886 DirItem* dirItem = dirItemForUrl(url);
888 deletedSubdirs.append(url);
889 if (!dirItem->rootItem.isNull()) {
890 removedItemsByDir[url.
url()].append(dirItem->rootItem);
896 dirItem = dirItemForUrl(parentDir);
899 for (KFileItemList::iterator fit = dirItem->lstItems.begin(), fend = dirItem->lstItems.end(); fit != fend ; ++fit) {
900 if ((*fit).url() ==
url) {
902 removedItemsByDir[parentDir.
url()].append(fileitem);
905 deletedSubdirs.append(url);
907 dirItem->lstItems.erase(fit);
914 for(; rit != removedItemsByDir.constEnd(); ++rit) {
917 DirectoryDataHash::const_iterator dit = directoryData.constFind(rit.key());
918 if (dit != directoryData.constEnd()) {
919 itemsDeleted((*dit).listersCurrentlyHolding, rit.value());
923 Q_FOREACH(
const KUrl& url, deletedSubdirs) {
934 QStringList::const_iterator it = fileList.begin();
935 for (; it != fileList.end() ; ++it) {
939 kDebug(7004) <<
"item not found for" <<
url;
945 pendingRemoteUpdates.insert(fileitem);
950 if (!dirsToUpdate.contains(dir))
951 dirsToUpdate.prepend(dir);
955 KUrl::List::const_iterator itdir = dirsToUpdate.constBegin();
956 for (; itdir != dirsToUpdate.constEnd() ; ++itdir)
961 processPendingUpdates();
968 kDebug(7004) << src <<
"->" << dst;
977 kDebug(7004) <<
"Item not found:" << oldurl;
988 if (existingDestItem) {
990 slotFilesRemoved(dst);
1001 if (!nameOnly && fileitem->
isDir()) {
1002 renameDir( src, dst );
1012 slotFilesChanged( QStringList() << src.
url() );
1015 fileitem->
setName( dst.fileName() );
1036 KUrl parentDir( oldItem.
url() );
1037 parentDir.
setPath( parentDir.directory() );
1038 const QString parentDirURL = parentDir.url();
1039 DirectoryDataHash::iterator dit = directoryData.find(parentDirURL);
1042 if (dit != directoryData.end())
1043 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1044 if (oldItem.
isDir()) {
1046 dit = directoryData.find(oldItem.
url().
url());
1047 if (dit != directoryData.end())
1048 listers += (*dit).listersCurrentlyHolding + (*dit).listersCurrentlyListing;
1053 KUrl directoryUrl(oldItem.
url());
1059 directoryUrl.setPath(directoryUrl.directory());
1062 listersToRefresh.insert(kdl);
1064 return listersToRefresh;
1067 QStringList KDirListerCache::directoriesForCanonicalPath(
const QString& dir)
const 1071 dirs << canonicalUrls.value(dir).toSet().toList();
1073 if (dirs.count() > 1)
1074 kDebug() << dir <<
"known as" << dirs;
1083 void KDirListerCache::slotFileDirty(
const QString& path )
1094 isDir = item.
isDir();
1096 KDE_struct_stat buff;
1097 kDebug(7004) <<
"Doing stat on:" << path;
1100 isDir = S_ISDIR(buff.st_mode);
1104 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.
toLocalFile())) {
1105 handleDirDirty(dir);
1108 Q_FOREACH(
const QString& dir, directoriesForCanonicalPath(url.
directory())) {
1111 handleFileDirty(aliasUrl);
1117 void KDirListerCache::handleDirDirty(
const KUrl& url)
1123 QMutableSetIterator<QString> pendingIt(pendingUpdates);
1124 while (pendingIt.hasNext()) {
1125 const QString updPath = pendingIt.next();
1127 if (updPath.startsWith(dirPath) &&
1128 updPath.indexOf(
'/', dirPath.length()) == -1) {
1129 kDebug(7004) <<
"forgetting about individual update to" << updPath;
1138 void KDirListerCache::handleFileDirty(
const KUrl& url)
1142 if (!existingItem) {
1150 if (!pendingUpdates.contains(filePath)) {
1153 if (checkUpdate(dir.
url())) {
1154 pendingUpdates.insert(filePath);
1155 if (!pendingUpdateTimer.isActive())
1156 pendingUpdateTimer.start(500);
1162 void KDirListerCache::slotFileCreated(
const QString& path )
1171 void KDirListerCache::slotFileDeleted(
const QString& path )
1175 QStringList fileUrls;
1176 Q_FOREACH(
KUrl url, directoriesForCanonicalPath(u.
directory())) {
1178 fileUrls << url.
url();
1180 slotFilesRemoved(fileUrls);
1185 KUrl url(joburl( static_cast<KIO::ListJob *>(job) ));
1187 QString urlStr = url.
url();
1191 DirItem *dir = itemsInUse.value(urlStr);
1193 kError(7004) <<
"Internal error: job is listing" << url <<
"but itemsInUse only knows about" << itemsInUse.keys();
1198 DirectoryDataHash::iterator dit = directoryData.find(urlStr);
1199 if (dit == directoryData.end()) {
1200 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData doesn't know about that url, only about:" << directoryData.keys();
1201 Q_ASSERT(dit != directoryData.end());
1206 kError(7004) <<
"Internal error: job is listing" << url <<
"but directoryData says no listers are currently listing " << urlStr;
1219 KIO::UDSEntryList::const_iterator it = entries.begin();
1220 const KIO::UDSEntryList::const_iterator
end = entries.end();
1221 for ( ; it != end; ++it )
1225 Q_ASSERT( !name.isEmpty() );
1226 if ( name.isEmpty() )
1231 Q_ASSERT( dir->rootItem.isNull() );
1239 dir->rootItem = itemForUrl(url);
1240 if (dir->rootItem.isNull())
1241 dir->rootItem =
KFileItem( *it, url, delayedMimeTypes,
true );
1247 else if ( name !=
".." )
1249 KFileItem item( *it, url, delayedMimeTypes,
true );
1252 dir->lstItems.append( item );
1263 void KDirListerCache::slotResult(
KJob *j )
1271 runningListJobs.remove( job );
1273 KUrl jobUrl(joburl( job ));
1275 QString jobUrlStr = jobUrl.
url();
1277 kDebug(7004) <<
"finished listing" << jobUrl;
1279 DirectoryDataHash::iterator dit = directoryData.find(jobUrlStr);
1280 if (dit == directoryData.end()) {
1281 kError() <<
"Nothing found in directoryData for URL" << jobUrlStr;
1285 Q_ASSERT(dit != directoryData.end());
1290 kError() <<
"OOOOPS, nothing in directoryData.listersCurrentlyListing for" << jobUrlStr;
1313 const bool silent = job->property(
"_kdlc_silent").toBool();
1328 DirItem *dir = itemsInUse.value(jobUrlStr);
1330 dir->complete =
true;
1346 processPendingUpdates();
1353 void KDirListerCache::slotRedirection(
KIO::Job *j,
const KUrl& url )
1365 if ( oldUrl == newUrl ) {
1366 kDebug(7004) <<
"New redirection url same as old, giving up.";
1368 }
else if (newUrl.isEmpty()) {
1369 kDebug(7004) <<
"New redirection url is empty, giving up.";
1373 const QString oldUrlStr = oldUrl.url();
1374 const QString newUrlStr = newUrl.url();
1376 kDebug(7004) << oldUrl <<
"->" << newUrl;
1389 DirItem *dir = itemsInUse.take(oldUrlStr);
1392 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1393 Q_ASSERT(dit != directoryData.end());
1395 directoryData.erase(dit);
1396 Q_ASSERT( !oldDirData.listersCurrentlyListing.isEmpty() );
1398 Q_ASSERT( !listers.isEmpty() );
1401 kdl->d->
redirect(oldUrlStr, newUrl,
false );
1413 kdl->d->
redirect(oldUrl, newUrl,
false );
1416 DirItem *newDir = itemsInUse.value(newUrlStr);
1418 kDebug(7004) << newUrl <<
"already in use";
1432 if ( !curListers.isEmpty() ) {
1433 kDebug(7004) <<
"and it is currently listed";
1446 curListers.append( kdl );
1448 curListers = listers;
1456 if ( !curHolders.isEmpty() ) {
1457 kDebug(7004) <<
"and it is currently held.";
1466 curHolders.append( kdl );
1468 curHolders = holders;
1474 foreach (
KDirLister *kdl, listers + holders ) {
1481 }
else if ( (newDir = itemsCached.take( newUrlStr )) ) {
1482 kDebug(7004) << newUrl <<
"is unused, but already in the cache.";
1485 itemsInUse.insert( newUrlStr, newDir );
1491 foreach (
KDirLister *kdl, listers + holders ) {
1499 kDebug(7004) << newUrl <<
"has not been listed yet.";
1502 dir->lstItems.clear();
1503 dir->redirect( newUrl );
1504 itemsInUse.insert( newUrlStr, dir );
1509 if ( holders.isEmpty() ) {
1518 job->disconnect(
this );
1523 this, SLOT(slotUpdateResult(
KJob*)) );
1532 struct KDirListerCache::ItemInUseChange
1534 ItemInUseChange(
const QString& old,
const QString& newU, DirItem* di)
1535 : oldUrl(old), newUrl(newU), dirItem(di) {}
1541 void KDirListerCache::renameDir(
const KUrl &oldUrl,
const KUrl &newUrl )
1543 kDebug(7004) << oldUrl <<
"->" << newUrl;
1551 QLinkedList<ItemInUseChange> itemsToChange;
1557 for (; itu != ituend ; ++itu) {
1558 DirItem *dir = itu.value();
1559 KUrl oldDirUrl ( itu.key() );
1564 QString relPath = oldDirUrl.
path().mid( oldUrl.
path().length() );
1566 KUrl newDirUrl( newUrl );
1567 if ( !relPath.isEmpty() )
1572 dir->redirect( newDirUrl );
1579 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end();
1580 kit != kend ; ++kit )
1584 const KUrl oldItemUrl ((*kit).url());
1586 KUrl newItemUrl( oldItemUrl );
1587 newItemUrl.setPath( newDirUrl.
path() );
1588 newItemUrl.addPath( oldItemUrl.fileName() );
1589 kDebug(7004) <<
"renaming" << oldItemUrl <<
"to" << newItemUrl;
1590 (*kit).setUrl(newItemUrl);
1592 listers |= emitRefreshItem(oldItem, *kit);
1594 emitRedirections( oldDirUrl, newDirUrl );
1604 foreach(
const ItemInUseChange& i, itemsToChange) {
1605 itemsInUse.remove(i.oldUrl);
1606 itemsInUse.insert(i.newUrl, i.dirItem);
1611 removeDirFromCache( oldUrl );
1616 void KDirListerCache::emitRedirections(
const KUrl &oldUrl,
const KUrl &newUrl )
1618 kDebug(7004) << oldUrl <<
"->" << newUrl;
1627 DirectoryDataHash::iterator dit = directoryData.find(oldUrlStr);
1628 if ( dit == directoryData.end() )
1650 directoryData.erase(dit);
1652 if ( !listers.isEmpty() ) {
1662 kdl->d->
redirect(oldUrl, newUrl,
true );
1666 void KDirListerCache::removeDirFromCache(
const KUrl& dir )
1670 foreach(
const QString& cachedDir, cachedDirs) {
1672 itemsCached.remove( cachedDir );
1678 runningListJobs[
static_cast<KIO::ListJob*
>(job)] += list;
1681 void KDirListerCache::slotUpdateResult(
KJob * j )
1686 KUrl jobUrl (joburl( job ));
1688 QString jobUrlStr (jobUrl.
url());
1690 kDebug(7004) <<
"finished update" << jobUrl;
1700 Q_ASSERT( !listers.isEmpty() );
1702 if ( job->
error() ) {
1709 const bool silent = job->property(
"_kdlc_silent").toBool();
1713 if ( kdl->d->
numJobs() == 0 ) {
1721 runningListJobs.remove( job );
1725 processPendingUpdates();
1729 DirItem *dir = itemsInUse.value(jobUrlStr, 0);
1731 kError(7004) <<
"Internal error: itemsInUse did not contain" << jobUrlStr;
1737 dir->complete =
true;
1748 for ( KFileItemList::iterator kit = dir->lstItems.begin(), kend = dir->lstItems.end() ; kit != kend ; ++kit )
1751 fileItems.insert( (*kit).name(), &*kit );
1755 KIO::UDSEntryList::const_iterator it = buf.constBegin();
1756 const KIO::UDSEntryList::const_iterator
end = buf.constEnd();
1757 for ( ; it != end; ++it )
1760 KFileItem item( *it, jobUrl, delayedMimeTypes,
true );
1763 Q_ASSERT( !name.isEmpty() );
1767 if ( name.isEmpty() || name ==
".." )
1774 if ( dir->rootItem.isNull() )
1776 dir->rootItem = item;
1789 const bool inPendingRemoteUpdates = (pru_it != pendingRemoteUpdates.end());
1792 if (!tmp->cmp( item ) || inPendingRemoteUpdates) {
1794 if (inPendingRemoteUpdates) {
1795 pendingRemoteUpdates.erase(pru_it);
1814 dir->lstItems.append( pitem );
1821 runningListJobs.remove( job );
1823 deleteUnmarkedItems( listers, dir->lstItems );
1840 processPendingUpdates();
1848 while ( it != runningListJobs.constEnd() )
1868 runningListJobs.remove( job );
1869 job->disconnect(
this );
1877 QMutableListIterator<KFileItem> kit(lstItems);
1878 while (kit.hasNext()) {
1882 deletedItems.append(item);
1886 if (!deletedItems.isEmpty())
1896 Q_FOREACH(
const KFileItem& item, deletedItems) {
1898 deleteDir(item.
url());
1902 void KDirListerCache::deleteDir(
const KUrl& dirUrl )
1914 for ( ; itu != ituend; ++itu ) {
1915 const KUrl deletedUrl( itu.key() );
1917 affectedItems.append(deletedUrl);
1921 foreach(
const KUrl& deletedUrl, affectedItems) {
1922 const QString deletedUrlStr = deletedUrl.
url();
1924 DirectoryDataHash::iterator dit = directoryData.find(deletedUrlStr);
1925 if (dit != directoryData.end()) {
1929 stopListingUrl( kdl, deletedUrl );
1937 if ( kdl->d->
url == deletedUrl )
1949 const bool treeview = kdl->d->
lstDirs.count() > 1;
1956 kdl->d->
lstDirs.removeAll( deletedUrl );
1958 forgetDirs( kdl, deletedUrl, treeview );
1965 int count = itemsInUse.remove( deletedUrlStr );
1966 Q_ASSERT( count == 0 );
1971 removeDirFromCache( dirUrl );
1975 void KDirListerCache::processPendingUpdates()
1978 foreach(
const QString& file, pendingUpdates) {
1986 listers |= emitRefreshItem( oldItem, *item );
1989 pendingUpdates.clear();
1996 void KDirListerCache::printDebug()
1998 kDebug(7004) <<
"Items in use:";
2001 for ( ; itu != ituend ; ++itu ) {
2002 kDebug(7004) <<
" " << itu.key() <<
"URL:" << itu.value()->url
2003 <<
"rootItem:" << ( !itu.value()->rootItem.isNull() ? itu.value()->rootItem.url() :
KUrl() )
2004 <<
"autoUpdates refcount:" << itu.value()->autoUpdates
2005 <<
"complete:" << itu.value()->complete
2006 << QString(
"with %1 items.").arg(itu.value()->lstItems.count());
2010 kDebug(7004) <<
"Directory data:";
2011 DirectoryDataHash::const_iterator dit = directoryData.constBegin();
2012 for ( ; dit != directoryData.constEnd(); ++dit )
2015 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing )
2017 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyListing.count() <<
"listers:" <<
list;
2018 foreach (
KDirLister* listit, (*dit).listersCurrentlyListing ) {
2021 }
else if (
KIO::ListJob* listJob = jobForUrl(dit.key())) {
2022 kDebug(7004) <<
" Lister" << listit <<
"has ListJob" << listJob;
2024 listersWithoutJob.append(listit);
2029 foreach (
KDirLister* listit, (*dit).listersCurrentlyHolding )
2031 kDebug(7004) <<
" " << dit.key() << (*dit).listersCurrentlyHolding.count() <<
"holders:" <<
list;
2036 for ( ; jit != runningListJobs.end() ; ++jit )
2037 kDebug(7004) <<
" " << jit.key() <<
"listing" << joburl( jit.key() ) <<
":" << (*jit).count() <<
"entries.";
2039 kDebug(7004) <<
"Items in cache:";
2041 foreach(
const QString& cachedDir, cachedDirs) {
2042 DirItem* dirItem = itemsCached.object(cachedDir);
2043 kDebug(7004) <<
" " << cachedDir <<
"rootItem:" 2044 << (!dirItem->rootItem.isNull() ? dirItem->rootItem.url().prettyUrl() : QString(
"NULL") )
2045 <<
"with" << dirItem->lstItems.count() <<
"items.";
2049 Q_FOREACH(
KDirLister* listit, listersWithoutJob) {
2050 kFatal() <<
"HUH? Lister" << listit <<
"is supposed to be listing, but has no job!";
2075 if (!kDirListerCache.isDestroyed()) {
2077 kDirListerCache->forgetDirs(
this );
2091 return kDirListerCache->listDir(
this, _url, _flags & Keep, _flags &
Reload );
2096 kDirListerCache->stop(
this );
2101 kDirListerCache->stopListingUrl(
this, _url );
2115 kDirListerCache->setAutoUpdate(
this, _enable );
2174 if (!hasPendingChanges)
2179 hasPendingChanges =
false;
2182 settings = oldSettings;
2185 Q_FOREACH(
const KUrl& dir, lstDirs) {
2186 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2191 KFileItemList::iterator kit = itemList->begin();
2192 const KFileItemList::iterator kend = itemList->end();
2193 for (; kit != kend; ++kit) {
2194 if (isItemVisible(*kit) && m_parent->matchesMimeFilter(*kit))
2201 settings = newSettings;
2203 Q_FOREACH(
const KUrl& dir, lstDirs) {
2206 KFileItemList* itemList = kDirListerCache->itemsForDir(dir);
2211 KFileItemList::iterator kit = itemList->begin();
2212 const KFileItemList::iterator kend = itemList->end();
2213 for (; kit != kend; ++kit) {
2215 const QString text = item.
text();
2216 if (text ==
"." || text ==
"..")
2218 const bool nowVisible = isItemVisible(item) && m_parent->matchesMimeFilter(item);
2219 if (nowVisible && !item.
isMarked())
2220 addNewItem(dir, item);
2221 else if (!nowVisible && item.
isMarked())
2222 deletedItems.append(*kit);
2224 if (!deletedItems.isEmpty()) {
2225 emit m_parent->itemsDeleted(deletedItems);
2227 Q_FOREACH(
const KFileItem& item, deletedItems)
2228 emit m_parent->deleteItem(item);
2232 oldSettings = settings;
2237 kDirListerCache->updateDirectory( _u );
2252 KFileItem *item = kDirListerCache->findByUrl(
this, _url );
2262 return kDirListerCache->findByName(
this, _name );
2278 const QStringList list = nameFilter.split(
' ', QString::SkipEmptyParts );
2279 for (QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
2294 if (mimeFilter.contains(QLatin1String(
"application/octet-stream")) || mimeFilter.contains(QLatin1String(
"all/allfiles")))
2337 Q_ASSERT( !item.
isNull() );
2339 if ( item.
text() ==
".." )
2353 Q_ASSERT(!item.
isNull());
2363 if ( (*it).exactMatch( name ) )
2371 if ( filters.isEmpty() )
2379 QStringList::const_iterator it = filters.begin();
2380 for ( ; it != filters.end(); ++it )
2381 if ( mimeptr->
is(*it) )
2390 if ( filters.isEmpty() )
2393 QStringList::const_iterator it = filters.begin();
2394 for ( ; it != filters.end(); ++it )
2395 if ( (*it) == mime )
2412 if (!isItemVisible(item))
2417 if ( m_parent->matchesMimeFilter( item ) )
2424 Q_ASSERT( !item.
isNull() );
2425 (*lstNewItems)[directoryUrl].append( item );
2429 if ( !lstMimeFilteredItems ) {
2433 Q_ASSERT( !item.
isNull() );
2434 lstMimeFilteredItems->append( item );
2443 KFileItemList::const_iterator kit = items.begin();
2444 const KFileItemList::const_iterator kend = items.end();
2445 for ( ; kit != kend; ++kit )
2446 addNewItem(directoryUrl, *kit);
2451 const bool refreshItemWasFiltered = !isItemVisible(oldItem) ||
2452 !m_parent->matchesMimeFilter(oldItem);
2453 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2454 if ( refreshItemWasFiltered )
2456 if ( !lstNewItems ) {
2460 Q_ASSERT( !item.
isNull() );
2461 (*lstNewItems)[directoryUrl].append( item );
2465 if ( !lstRefreshItems ) {
2469 Q_ASSERT( !item.
isNull() );
2470 lstRefreshItems->append( qMakePair(oldItem, item) );
2473 else if ( !refreshItemWasFiltered )
2475 if ( !lstRemoveItems ) {
2482 Q_ASSERT(!oldItem.
isNull());
2483 lstRemoveItems->append(oldItem);
2493 lstMimeFilteredItems = 0;
2496 lstRefreshItems = 0;
2502 QHashIterator<KUrl, KFileItemList> it(*tmpNew);
2503 while (it.hasNext()) {
2505 emit m_parent->itemsAdded(it.key(), it.value());
2506 emit m_parent->newItems(it.value());
2513 emit m_parent->itemsFilteredByMime( *tmpMime );
2519 emit m_parent->refreshItems( *tmpRefresh );
2525 emit m_parent->itemsDeleted( *tmpRemove );
2535 return (!settings.dirOnlyMode || item.
isDir())
2536 && m_parent->matchesFilter(item);
2542 QMutableListIterator<KFileItem> it(items);
2543 while (it.hasNext()) {
2545 if (isItemVisible(item) && m_parent->matchesMimeFilter(item)) {
2547 emit m_parent->deleteItem(item);
2552 if (!items.isEmpty())
2553 emit m_parent->itemsDeleted(items);
2560 emit m_parent->infoMessage( message );
2572 while ( dataIt != jobData.end() )
2574 result += (*dataIt).percent * (*dataIt).totalSize;
2575 size += (*dataIt).totalSize;
2583 emit m_parent->percent( result );
2592 while ( dataIt != jobData.end() )
2594 result += (*dataIt).totalSize;
2598 emit m_parent->totalSize( result );
2607 while ( dataIt != jobData.end() )
2609 result += (*dataIt).processedSize;
2613 emit m_parent->processedSize( result );
2622 while ( dataIt != jobData.end() )
2624 result += (*dataIt).speed;
2628 emit m_parent->speed( result );
2635 qDebug() << m_parent <<
"numJobs:" << jobData.count();
2636 QMapIterator<KIO::ListJob *, JobData> it(jobData);
2637 while (it.hasNext()) {
2639 qDebug() << (
void*)it.key();
2640 qDebug() << it.key();
2644 return jobData.count();
2649 jobData.remove( job );
2660 jobData.insert( job, data );
2667 m_parent, SLOT(_k_slotInfoMessage(
KJob*,QString)) );
2668 m_parent->connect( job, SIGNAL(
percent(
KJob*,ulong)),
2669 m_parent, SLOT(_k_slotPercent(
KJob*,ulong)) );
2670 m_parent->connect( job, SIGNAL(
totalSize(
KJob*,qulonglong)),
2671 m_parent, SLOT(_k_slotTotalSize(
KJob*,qulonglong)) );
2673 m_parent, SLOT(_k_slotProcessedSize(
KJob*,qulonglong)) );
2674 m_parent->connect( job, SIGNAL(
speed(
KJob*,ulong)),
2675 m_parent, SLOT(_k_slotSpeed(
KJob*,ulong)) );
2695 KFileItemList *allItems = kDirListerCache->itemsForDir( dir );
2704 KFileItemList::const_iterator kit = allItems->constBegin();
2705 const KFileItemList::const_iterator kend = allItems->constEnd();
2706 for ( ; kit != kend; ++kit )
2710 result.append(item);
2734 rootFileItem.setUrl(newUrl);
2739 const int idx = lstDirs.indexOf( oldUrl );
2741 kWarning(7004) <<
"Unexpected redirection from" << oldUrl <<
"to" << newUrl
2742 <<
"but this dirlister is currently listing/holding" << lstDirs;
2744 lstDirs[ idx ] = newUrl;
2747 if ( lstDirs.count() == 1 ) {
2749 emit m_parent->clear();
2750 emit m_parent->redirection( newUrl );
2753 emit m_parent->clear( oldUrl );
2755 emit m_parent->redirection( oldUrl, newUrl );
2765 QMutableListIterator<KDirLister *> lister_it(listersCurrentlyListing);
2766 while (lister_it.hasNext()) {
2772 Q_ASSERT(!listersCurrentlyHolding.contains(kdl));
2773 if (!listersCurrentlyHolding.contains(kdl)) {
2774 listersCurrentlyHolding.append(kdl);
2785 return kDirListerCache->itemForUrl(url);
2788 #include "kdirlister.moc" 2789 #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.
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).
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)
void mark()
Marks the item.
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 *)
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.