From bfc7b3bdbe73a4da9387b239614a433031d75256 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 17 Apr 2013 21:33:37 -0500 Subject: [PATCH] Add preliminary udisks eject support Fix additional tdeioslave dirlister problems --- CMakeLists.txt | 1 + tdecore/tdehardwaredevices.cpp | 82 +++++++++++++---- tdeio/tdeio/kdirlister.cpp | 164 ++++++++++++++++++--------------- tdeio/tdeio/kdirlister_p.h | 2 +- tdeio/tdeio/kdirwatch.cpp | 12 ++- 5 files changed, 167 insertions(+), 94 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ca0a31b4d..0eabf0270 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ OPTION( WITH_GCC_VISIBILITY "Enable fvisibility and fvisibility-inlines-hidden" OPTION( WITH_INOTIFY "Enable inotify support for tdeio" ON ) OPTION( WITH_GAMIN "Enable FAM/GAMIN support" ${WITH_ALL_OPTIONS} ) option( WITH_UPOWER "Enable UPOWER support" ${WITH_ALL_OPTIONS} ) +option( WITH_UDISKS "Enable UDISKS support" ${WITH_ALL_OPTIONS} ) option( WITH_UDISKS2 "Enable UDISKS2 support" ${WITH_ALL_OPTIONS} ) OPTION( WITH_NETWORK_MANAGER_BACKEND "Enable network-manager support" OFF ) OPTION( WITH_SUDO_TDESU_BACKEND "Use sudo as backend for tdesu (default is su)" OFF ) diff --git a/tdecore/tdehardwaredevices.cpp b/tdecore/tdehardwaredevices.cpp index 1f185985e..473d17312 100644 --- a/tdecore/tdehardwaredevices.cpp +++ b/tdecore/tdehardwaredevices.cpp @@ -68,18 +68,21 @@ #endif // WITH_NETWORK_MANAGER_BACKEND // uPower and uDisks2 integration -#if defined(WITH_UPOWER) || defined(WITH_UDISKS2) +#if defined(WITH_UPOWER) || defined(WITH_UDISKS) || defined(WITH_UDISKS2) #include #include #include #include #include -#endif // defined(WITH_UPOWER) || defined(WITH_UDISKS2) -#ifdef WITH_UDISKS2 +#endif // defined(WITH_UPOWER) || defined(WITH_UDISKS) || defined(WITH_UDISKS2) +#if defined(WITH_UDISKS) || defined(WITH_UDISKS2) #include #include #include -#endif // WITH_UDISKS2 +#endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2) +#if defined(WITH_UDISKS) + #include "tqdbusdatalist.h" +#endif // ddefined(WITH_UDISKS) // BEGIN BLOCK // Copied from include/linux/genhd.h @@ -454,6 +457,38 @@ bool TDEStorageDevice::lockDriveMedia(bool lock) { } } +bool ejectDriveUDisks(TDEStorageDevice* sdevice) { +#ifdef WITH_UDISKS + TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); + if (dbusConn.isConnected()) { + TQString blockDeviceString = sdevice->deviceNode(); + blockDeviceString.replace("/dev/", ""); + blockDeviceString = "/org/freedesktop/UDisks/devices/" + blockDeviceString; + + // Eject the drive! + TQT_DBusError error; + TQT_DBusProxy driveControl("org.freedesktop.UDisks", blockDeviceString, "org.freedesktop.UDisks.Device", dbusConn); + TQValueList params; + TQT_DBusDataList options; + params << TQT_DBusData::fromList(options); + TQT_DBusMessage reply = driveControl.sendWithReply("DriveEject", params, &error); + if (error.isValid()) { + // Error! + printf("[ERROR] %s\n\r", error.name().ascii()); fflush(stdout); + return FALSE; + } + else { + return TRUE; + } + } + else { + return FALSE; + } +#else // WITH_UDISKS + return FALSE; +#endif // WITH_UDISKS +} + bool ejectDriveUDisks2(TDEStorageDevice* sdevice) { #ifdef WITH_UDISKS2 TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); @@ -534,24 +569,37 @@ bool TDEStorageDevice::ejectDrive() { return TRUE; } else { - TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode()); - - FILE *exepipe = popen(command.ascii(), "r"); - if (exepipe) { - TQString pmount_output; - char buffer[8092]; - pmount_output = fgets(buffer, sizeof(buffer), exepipe); - int retcode = pclose(exepipe); - if (retcode == 0) { - return TRUE; +#ifdef WITH_UDISKS2 + printf("[tdehwlib] Failed to eject drive '%s' via udisks2, falling back to alternate mechanism\n\r", deviceNode().ascii()); +#endif // WITH_UDISKS2 + if (ejectDriveUDisks(this)) { + return TRUE; + } + else { +#ifdef WITH_UDISKS + printf("[tdehwlib] Failed to eject drive '%s' via udisks, falling back to alternate mechanism\n\r", deviceNode().ascii()); +#endif // WITH_UDISKS + TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode()); + + FILE *exepipe = popen(command.ascii(), "r"); + if (exepipe) { + TQString pmount_output; + char buffer[8092]; + pmount_output = fgets(buffer, sizeof(buffer), exepipe); + int retcode = pclose(exepipe); + if (retcode == 0) { + return TRUE; + } + else { + printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n\r", deviceNode().ascii()); + return FALSE; + } } else { + printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n\r", deviceNode().ascii()); return FALSE; } } - else { - return FALSE; - } } } diff --git a/tdeio/tdeio/kdirlister.cpp b/tdeio/tdeio/kdirlister.cpp index fe423742a..8df6755f1 100644 --- a/tdeio/tdeio/kdirlister.cpp +++ b/tdeio/tdeio/kdirlister.cpp @@ -106,6 +106,7 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, _url.cleanPath(); // kill consecutive slashes _url.adjustPath(-1); TQString urlStr = _url.url(); + TQString urlReferenceStr = _url.internalReferenceURL(); if ( !lister->validURL( _url ) ) { return false; @@ -144,10 +145,10 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, if ( lister->d->url.isEmpty() || !_keep ) // set toplevel URL only if not set yet lister->d->url = _url; - DirItem *itemU = itemsInUse[urlStr]; + DirItem *itemU = itemsInUse[urlStr + ":" + urlReferenceStr]; DirItem *itemC; - if ( !urlsCurrentlyListed[urlStr] ) + if ( !urlsCurrentlyListed[urlStr + ":" + urlReferenceStr] ) { // if there is an update running for _url already we get into // the following case - it will just be restarted by updateDirectory(). @@ -169,8 +170,8 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, lister->emitItems(); // _url is already in use, so there is already an entry in urlsCurrentlyHeld - assert( urlsCurrentlyHeld[urlStr] ); - urlsCurrentlyHeld[urlStr]->append( lister ); + assert( urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr] ); + urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr]->append( lister ); lister->d->complete = oldState; @@ -188,7 +189,7 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, kdDebug(7004) << "listDir: Entry in cache: " << _url << endl; itemC->decAutoUpdate(); - itemsInUse.insert( urlStr, itemC ); + itemsInUse.insert( urlStr + ":" + urlReferenceStr, itemC ); itemU = itemC; bool oldState = lister->d->complete; @@ -203,10 +204,10 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, lister->addNewItems( *(itemC->lstItems) ); lister->emitItems(); - Q_ASSERT( !urlsCurrentlyHeld[urlStr] ); + Q_ASSERT( !urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr] ); TQPtrList *list = new TQPtrList; list->append( lister ); - urlsCurrentlyHeld.insert( urlStr, list ); + urlsCurrentlyHeld.insert( urlStr + ":" + urlReferenceStr, list ); lister->d->complete = oldState; @@ -225,11 +226,11 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, TQPtrList *list = new TQPtrList; list->append( lister ); - urlsCurrentlyListed.insert( urlStr, list ); + urlsCurrentlyListed.insert( urlStr + ":" + urlReferenceStr, list ); itemsCached.remove( urlStr ); itemU = new DirItem( _url ); - itemsInUse.insert( urlStr, itemU ); + itemsInUse.insert( urlStr + ":" + urlReferenceStr, itemU ); // // we have a limit of MAX_JOBS_PER_LISTER concurrently running jobs // if ( lister->numJobs() >= MAX_JOBS_PER_LISTER ) @@ -271,7 +272,7 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u, emit lister->started( _url ); - urlsCurrentlyListed[urlStr]->append( lister ); + urlsCurrentlyListed[urlStr + ":" + urlReferenceStr]->append( lister ); TDEIO::ListJob *job = jobForUrl( urlStr ); Q_ASSERT( job ); @@ -389,21 +390,22 @@ void KDirListerCache::stop( KDirLister *lister ) void KDirListerCache::stop( KDirLister *lister, const KURL& _u ) { TQString urlStr( _u.url(-1) ); + TQString urlReferenceStr = _u.internalReferenceURL(); KURL _url( urlStr ); // TODO: consider to stop all the "child jobs" of _url as well kdDebug(7004) << k_funcinfo << lister << " url=" << _url << endl; - TQPtrList *listers = urlsCurrentlyListed[urlStr]; + TQPtrList *listers = urlsCurrentlyListed[urlStr + ":" + urlReferenceStr]; if ( !listers || !listers->removeRef( lister ) ) return; // move lister to urlsCurrentlyHeld - TQPtrList *holders = urlsCurrentlyHeld[urlStr]; + TQPtrList *holders = urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr]; if ( !holders ) { holders = new TQPtrList; - urlsCurrentlyHeld.insert( urlStr, holders ); + urlsCurrentlyHeld.insert( urlStr + ":" + urlReferenceStr, holders ); } holders->append( lister ); @@ -421,7 +423,7 @@ void KDirListerCache::stop( KDirLister *lister, const KURL& _u ) if ( job ) killJob( job ); - urlsCurrentlyListed.remove( urlStr ); + urlsCurrentlyListed.remove( urlStr + ":" + urlReferenceStr ); } if ( lister->numJobs() == 0 ) @@ -440,10 +442,12 @@ void KDirListerCache::setAutoUpdate( KDirLister *lister, bool enable ) for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); it != lister->d->lstDirs.end(); ++it ) { - if ( enable ) - itemsInUse[(*it).url()]->incAutoUpdate(); - else - itemsInUse[(*it).url()]->decAutoUpdate(); + if ( enable ) { + itemsInUse[(*it).url() + ":" + (*it).internalReferenceURL()]->incAutoUpdate(); + } + else { + itemsInUse[(*it).url() + ":" + (*it).internalReferenceURL()]->decAutoUpdate(); + } } } @@ -469,7 +473,8 @@ void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool not KURL url( _url ); url.adjustPath( -1 ); TQString urlStr = url.url(); - TQPtrList *holders = urlsCurrentlyHeld[urlStr]; + TQString urlReferenceStr = url.internalReferenceURL(); + TQPtrList *holders = urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr]; //Q_ASSERT( holders ); if ( holders ) { @@ -482,15 +487,15 @@ void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool not // might crash in findByName()). lister->d->lstDirs.remove( lister->d->lstDirs.find( url ) ); - DirItem *item = itemsInUse[urlStr]; + DirItem *item = itemsInUse[urlStr + ":" + urlReferenceStr]; if ( holders && holders->isEmpty() ) { - urlsCurrentlyHeld.remove( urlStr ); // this deletes the (empty) holders list - if ( !urlsCurrentlyListed[urlStr] ) + urlsCurrentlyHeld.remove( urlStr + ":" + urlReferenceStr ); // this deletes the (empty) holders list + if ( !urlsCurrentlyListed[urlStr + ":" + urlReferenceStr] ) { // item not in use anymore -> move into cache if complete - itemsInUse.remove( urlStr ); + itemsInUse.remove( urlStr + ":" + urlReferenceStr ); // this job is a running update TDEIO::ListJob *job = jobForUrl( urlStr ); @@ -560,7 +565,8 @@ void KDirListerCache::updateDirectory( const KURL& _dir ) kdDebug(7004) << k_funcinfo << _dir << endl; TQString urlStr = _dir.url(-1); - if ( !checkUpdate( urlStr ) ) { + TQString urlReferenceStr = _dir.internalReferenceURL(); + if ( !checkUpdate( _dir, -1 ) ) { return; } @@ -570,8 +576,8 @@ void KDirListerCache::updateDirectory( const KURL& _dir ) // - update a currently running listing: the listers are in urlsCurrentlyListed // and urlsCurrentlyHeld - TQPtrList *listers = urlsCurrentlyListed[urlStr]; - TQPtrList *holders = urlsCurrentlyHeld[urlStr]; + TQPtrList *listers = urlsCurrentlyListed[urlStr + ":" + urlReferenceStr]; + TQPtrList *holders = urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr]; // restart the job for _dir if it is running already bool killed = false; @@ -646,11 +652,11 @@ void KDirListerCache::updateDirectory( const KURL& _dir ) } } -bool KDirListerCache::checkUpdate( const TQString& _dir ) +bool KDirListerCache::checkUpdate( const KURL& _dir, int truncationMode ) { - if ( !itemsInUse[_dir] ) + if ( !itemsInUse[_dir.url(truncationMode) + ":" + _dir.internalReferenceURL()] ) { - DirItem *item = itemsCached[_dir]; + DirItem *item = itemsCached[_dir.url(truncationMode)]; if ( item && item->complete ) { item->complete = false; @@ -670,7 +676,8 @@ bool KDirListerCache::checkUpdate( const TQString& _dir ) KFileItemList *KDirListerCache::itemsForDir( const KURL &_dir ) const { TQString urlStr = _dir.url(-1); - DirItem *item = itemsInUse[ urlStr ]; + TQString urlReferenceStr = _dir.internalReferenceURL(); + DirItem *item = itemsInUse[ urlStr + ":" + urlReferenceStr ]; if ( !item ) { item = itemsCached[ urlStr ]; } @@ -684,7 +691,7 @@ KFileItem *KDirListerCache::findByName( const KDirLister *lister, const TQString for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); it != lister->d->lstDirs.end(); ++it ) { - KFileItemListIterator kit( *itemsInUse[(*it).url()]->lstItems ); + KFileItemListIterator kit( *itemsInUse[(*it).url() + ":" + (*it).internalReferenceURL()]->lstItems ); for ( ; kit.current(); ++kit ) if ( (*kit)->name() == _name ) return (*kit); @@ -748,7 +755,7 @@ void KDirListerCache::FilesRemoved( const KURL::List &fileList ) // file items (see the dirtree). if ( fileitem ) { - TQPtrList *listers = urlsCurrentlyHeld[parentDir.url()]; + TQPtrList *listers = urlsCurrentlyHeld[parentDir.url() + ":" + parentDir.internalReferenceURL()]; if ( listers ) { for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) { kdl->emitDeleteItem( fileitem ); @@ -847,13 +854,14 @@ void KDirListerCache::aboutToRefreshItem( KFileItem *fileitem ) KURL parentDir( fileitem->url() ); parentDir.setPath( parentDir.directory() ); TQString parentDirURL = parentDir.url(); - TQPtrList *listers = urlsCurrentlyHeld[parentDirURL]; + TQString parentDirReferenceURL = parentDir.internalReferenceURL(); + TQPtrList *listers = urlsCurrentlyHeld[parentDirURL + ":" + parentDirReferenceURL]; if ( listers ) for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) kdl->aboutToRefreshItem( fileitem ); // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing - listers = urlsCurrentlyListed[parentDirURL]; + listers = urlsCurrentlyListed[parentDirURL + ":" + parentDirReferenceURL]; if ( listers ) for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) kdl->aboutToRefreshItem( fileitem ); @@ -865,7 +873,8 @@ void KDirListerCache::emitRefreshItem( KFileItem *fileitem ) KURL parentDir( fileitem->url() ); parentDir.setPath( parentDir.directory() ); TQString parentDirURL = parentDir.url(); - TQPtrList *listers = urlsCurrentlyHeld[parentDirURL]; + TQString parentDirReferenceURL = parentDir.internalReferenceURL(); + TQPtrList *listers = urlsCurrentlyHeld[parentDirURL + ":" + parentDirReferenceURL]; if ( listers ) for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) { @@ -874,7 +883,7 @@ void KDirListerCache::emitRefreshItem( KFileItem *fileitem ) } // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing - listers = urlsCurrentlyListed[parentDirURL]; + listers = urlsCurrentlyListed[parentDirURL + ":" + parentDirReferenceURL]; if ( listers ) for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) { @@ -908,13 +917,15 @@ void KDirListerCache::slotFileDirty( const KURL& _url ) { KURL dir; dir.setPath( _url.path() ); - if ( checkUpdate( dir.url(-1) ) ) { + dir.setInternalReferenceURL(_url.internalReferenceURL()); + if ( checkUpdate( dir, -1 ) ) { updateDirectory( _url ); } // the parent directory of _url.path() dir.setPath( dir.directory() ); - if ( checkUpdate( dir.url() ) ) + dir.setInternalReferenceURL(_url.internalReferenceURL()); + if ( checkUpdate( dir ) ) { // Nice hack to save memory: use the qt object name to store the filename TQTimer *timer = new TQTimer( this, _url.path().utf8() ); @@ -971,13 +982,14 @@ void KDirListerCache::slotEntries( TDEIO::Job *job, const TDEIO::UDSEntryList &e KURL url = joburl( static_cast(job) ); url.adjustPath(-1); TQString urlStr = url.url(); + TQString urlReferenceStr = url.internalReferenceURL(); kdDebug(7004) << k_funcinfo << "new entries for " << url << endl; - DirItem *dir = itemsInUse[urlStr]; + DirItem *dir = itemsInUse[urlStr + ":" + urlReferenceStr]; Q_ASSERT( dir ); - TQPtrList *listers = urlsCurrentlyListed[urlStr]; + TQPtrList *listers = urlsCurrentlyListed[urlStr + ":" + urlReferenceStr]; Q_ASSERT( listers ); Q_ASSERT( !listers->isEmpty() ); @@ -1051,20 +1063,21 @@ void KDirListerCache::slotResult( TDEIO::Job *j ) KURL jobUrl = joburl( job ); jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections TQString jobUrlStr = jobUrl.url(); + TQString jobReferenceUrlStr = jobUrl.internalReferenceURL(); kdDebug(7004) << k_funcinfo << "finished listing " << jobUrl << endl; #ifdef DEBUG_CACHE printDebug(); #endif - TQPtrList *listers = urlsCurrentlyListed.take( jobUrlStr ); + TQPtrList *listers = urlsCurrentlyListed.take( jobUrlStr + ":" + jobReferenceUrlStr ); Q_ASSERT( listers ); // move the directory to the held directories, do it before emitting // the signals to make sure it exists in KDirListerCache in case someone // calls listDir during the signal emission - Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr] ); - urlsCurrentlyHeld.insert( jobUrlStr, listers ); + Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr + ":" + jobReferenceUrlStr] ); + urlsCurrentlyHeld.insert( jobUrlStr + ":" + jobReferenceUrlStr, listers ); KDirLister *kdl; @@ -1084,7 +1097,7 @@ void KDirListerCache::slotResult( TDEIO::Job *j ) } else { - DirItem *dir = itemsInUse[jobUrlStr]; + DirItem *dir = itemsInUse[jobUrlStr + ":" + jobReferenceUrlStr]; Q_ASSERT( dir ); dir->complete = true; @@ -1138,10 +1151,10 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) // DF: redirection happens before listDir emits any item. Makes little sense otherwise. // oldUrl cannot be in itemsCached because only completed items are moved there - DirItem *dir = itemsInUse.take( oldUrl.url() ); + DirItem *dir = itemsInUse.take( oldUrl.url() + ":" + oldUrl.internalReferenceURL() ); Q_ASSERT( dir ); - TQPtrList *listers = urlsCurrentlyListed.take( oldUrl.url() ); + TQPtrList *listers = urlsCurrentlyListed.take( oldUrl.url() + ":" + oldUrl.internalReferenceURL() ); Q_ASSERT( listers ); Q_ASSERT( !listers->isEmpty() ); @@ -1171,7 +1184,7 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) // when a lister was stopped before the job emits the redirection signal, the old url will // also be in urlsCurrentlyHeld - TQPtrList *holders = urlsCurrentlyHeld.take( oldUrl.url() ); + TQPtrList *holders = urlsCurrentlyHeld.take( oldUrl.url() + ":" + oldUrl.internalReferenceURL() ); if ( holders ) { Q_ASSERT( !holders->isEmpty() ); @@ -1207,7 +1220,7 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) } } - DirItem *newDir = itemsInUse[newUrl.url()]; + DirItem *newDir = itemsInUse[newUrl.url() + ":" + newUrl.internalReferenceURL()]; if ( newDir ) { kdDebug(7004) << "slotRedirection: " << newUrl.url() << " already in use" << endl; @@ -1221,7 +1234,7 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) // listers of newUrl with oldJob: forget about the oldJob and use the already running one // which will be converted to an updateJob - TQPtrList *curListers = urlsCurrentlyListed[newUrl.url()]; + TQPtrList *curListers = urlsCurrentlyListed[newUrl.url() + ":" + newUrl.internalReferenceURL()]; if ( curListers ) { kdDebug(7004) << "slotRedirection: and it is currently listed" << endl; @@ -1241,13 +1254,13 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) curListers->append( kdl ); } else - urlsCurrentlyListed.insert( newUrl.url(), listers ); + urlsCurrentlyListed.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), listers ); if ( oldJob ) // kill the old job, be it a list-job or an update-job killJob( oldJob ); // holders of newUrl: use the already running job which will be converted to an updateJob - TQPtrList *curHolders = urlsCurrentlyHeld[newUrl.url()]; + TQPtrList *curHolders = urlsCurrentlyHeld[newUrl.url() + ":" + newUrl.internalReferenceURL()]; if ( curHolders ) { kdDebug(7004) << "slotRedirection: and it is currently held." << endl; @@ -1264,7 +1277,7 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) curHolders->append( kdl ); } else if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); + urlsCurrentlyHeld.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), holders ); // emit old items: listers, holders. NOT: newUrlListers/newUrlHolders, they already have them listed @@ -1295,10 +1308,10 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) kdDebug(7004) << "slotRedirection: " << newUrl.url() << " is unused, but already in the cache." << endl; delete dir; - itemsInUse.insert( newUrl.url(), newDir ); - urlsCurrentlyListed.insert( newUrl.url(), listers ); + itemsInUse.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), newDir ); + urlsCurrentlyListed.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), listers ); if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); + urlsCurrentlyHeld.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), holders ); // emit old items: listers, holders for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) @@ -1330,11 +1343,11 @@ void KDirListerCache::slotRedirection( TDEIO::Job *j, const KURL& url ) dir->rootItem = 0; dir->lstItems->clear(); dir->redirect( newUrl ); - itemsInUse.insert( newUrl.url(), dir ); - urlsCurrentlyListed.insert( newUrl.url(), listers ); + itemsInUse.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), dir ); + urlsCurrentlyListed.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), listers ); if ( holders ) - urlsCurrentlyHeld.insert( newUrl.url(), holders ); + urlsCurrentlyHeld.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), holders ); else { #ifdef DEBUG_CACHE @@ -1376,7 +1389,9 @@ void KDirListerCache::renameDir( const KURL &oldUrl, const KURL &newUrl ) { goNext = true; DirItem *dir = itu.current(); - KURL oldDirUrl ( itu.currentKey() ); + TQString oldDirURLIndep = itu.currentKey(); + oldDirURLIndep.truncate(oldDirURLIndep.length() - (dir->url.internalReferenceURL().length()+strlen(":"))); + KURL oldDirUrl ( oldDirURLIndep ); //kdDebug(7004) << "itemInUse: " << oldDirUrl.prettyURL() << endl; // Check if this dir is oldUrl, or a subfolder of it if ( oldUrl.isParentOf( oldDirUrl ) ) @@ -1385,8 +1400,9 @@ void KDirListerCache::renameDir( const KURL &oldUrl, const KURL &newUrl ) TQString relPath = oldDirUrl.path().mid( oldUrl.path().length() ); KURL newDirUrl( newUrl ); // take new base - if ( !relPath.isEmpty() ) + if ( !relPath.isEmpty() ) { newDirUrl.addPath( relPath ); // add unchanged relative path + } //kdDebug(7004) << "KDirListerCache::renameDir new url=" << newDirUrl.prettyURL() << endl; // Update URL in dir item and in itemsInUse @@ -1426,13 +1442,15 @@ void KDirListerCache::emitRedirections( const KURL &oldUrl, const KURL &url ) kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << url.prettyURL() << endl; TQString oldUrlStr = oldUrl.url(-1); TQString urlStr = url.url(-1); + TQString oldReferenceUrlStr = oldUrl.internalReferenceURL(); + TQString urlReferenceStr = url.internalReferenceURL(); TDEIO::ListJob *job = jobForUrl( oldUrlStr ); if ( job ) killJob( job ); // Check if we were listing this dir. Need to abort and restart with new name in that case. - TQPtrList *listers = urlsCurrentlyListed.take( oldUrlStr ); + TQPtrList *listers = urlsCurrentlyListed.take( oldUrlStr + ":" + oldReferenceUrlStr ); if ( listers ) { // Tell the world that the job listing the old url is dead. @@ -1444,19 +1462,19 @@ void KDirListerCache::emitRedirections( const KURL &oldUrl, const KURL &url ) emit kdl->canceled( oldUrl ); } - urlsCurrentlyListed.insert( urlStr, listers ); + urlsCurrentlyListed.insert( urlStr + ":" + urlReferenceStr, listers ); } // Check if we are currently displaying this directory (odds opposite wrt above) // Update urlsCurrentlyHeld dict with new URL - TQPtrList *holders = urlsCurrentlyHeld.take( oldUrlStr ); + TQPtrList *holders = urlsCurrentlyHeld.take( oldUrlStr + ":" + oldReferenceUrlStr ); if ( holders ) { if ( job ) for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) kdl->jobDone( job ); - urlsCurrentlyHeld.insert( urlStr, holders ); + urlsCurrentlyHeld.insert( urlStr + ":" + urlReferenceStr, holders ); } if ( listers ) @@ -1515,8 +1533,8 @@ void KDirListerCache::slotUpdateResult( TDEIO::Job * j ) KDirLister *kdl; - TQPtrList *listers = urlsCurrentlyHeld[jobUrlStr]; - TQPtrList *tmpLst = urlsCurrentlyListed.take( jobUrlStr ); + TQPtrList *listers = urlsCurrentlyHeld[jobUrlStr + ":" + jobReferenceUrlStr]; + TQPtrList *tmpLst = urlsCurrentlyListed.take( jobUrlStr + ":" + jobReferenceUrlStr ); if ( tmpLst ) { @@ -1529,7 +1547,7 @@ void KDirListerCache::slotUpdateResult( TDEIO::Job * j ) else { listers = tmpLst; - urlsCurrentlyHeld.insert( jobUrlStr, listers ); + urlsCurrentlyHeld.insert( jobUrlStr + ":" + jobReferenceUrlStr, listers ); } } @@ -1561,7 +1579,7 @@ void KDirListerCache::slotUpdateResult( TDEIO::Job * j ) return; } - DirItem *dir = itemsInUse[jobUrlStr]; + DirItem *dir = itemsInUse[jobUrlStr + ":" + jobReferenceUrlStr]; dir->complete = true; @@ -1765,12 +1783,14 @@ void KDirListerCache::deleteDir( const KURL& dirUrl ) TQDictIterator itu( itemsInUse ); while ( itu.current() ) { - KURL deletedUrl( itu.currentKey() ); + TQString deletedUrlIndep = itu.currentKey(); + deletedUrlIndep.truncate(deletedUrlIndep.length() - ((*itu)->url.internalReferenceURL().length()+strlen(":"))); + KURL deletedUrl( deletedUrlIndep ); if ( dirUrl.isParentOf( deletedUrl ) ) { // stop all jobs for deletedUrl - TQPtrList *kdls = urlsCurrentlyListed[deletedUrl.url()]; + TQPtrList *kdls = urlsCurrentlyListed[deletedUrl.url() + ":" + deletedUrl.internalReferenceURL()]; if ( kdls ) // yeah, I lack good names { // we need a copy because stop modifies the list @@ -1784,7 +1804,7 @@ void KDirListerCache::deleteDir( const KURL& dirUrl ) // tell listers holding deletedUrl to forget about it // this will stop running updates for deletedUrl as well - kdls = urlsCurrentlyHeld[deletedUrl.url()]; + kdls = urlsCurrentlyHeld[deletedUrl.url() + ":" + deletedUrl.internalReferenceURL()]; if ( kdls ) { // we need a copy because forgetDirs modifies the list @@ -1817,7 +1837,7 @@ void KDirListerCache::deleteDir( const KURL& dirUrl ) // delete the entry for deletedUrl - should not be needed, it's in // items cached now - DirItem *dir = itemsInUse.take( deletedUrl.url() ); + DirItem *dir = itemsInUse.take( deletedUrl.url() + ":" + deletedUrl.internalReferenceURL() ); Q_ASSERT( !dir ); if ( !dir ) // take didn't find it - move on ++itu; diff --git a/tdeio/tdeio/kdirlister_p.h b/tdeio/tdeio/kdirlister_p.h index 0953ed205..0e1bfa259 100644 --- a/tdeio/tdeio/kdirlister_p.h +++ b/tdeio/tdeio/kdirlister_p.h @@ -211,7 +211,7 @@ private: // check if _url is held by some lister and return true, // otherwise schedule a delayed update and return false - bool checkUpdate( const TQString& _url ); + bool checkUpdate( const KURL& _url, int truncationMode = 0 ); // when there were items deleted from the filesystem all the listers holding // the parent directory need to be notified, the unmarked items have to be deleted // and removed from the cache including all the childs. diff --git a/tdeio/tdeio/kdirwatch.cpp b/tdeio/tdeio/kdirwatch.cpp index 3f6a13272..da1f61540 100644 --- a/tdeio/tdeio/kdirwatch.cpp +++ b/tdeio/tdeio/kdirwatch.cpp @@ -1308,8 +1308,9 @@ void KDirWatchPrivate::slotRescan() // like showing a message box. We don't want to keep polling during // that time, otherwise the value of 'delayRemove' will be reset. bool timerRunning = timer->isActive(); - if ( timerRunning ) + if ( timerRunning ) { timer->stop(); + } // We delay deletions of entries this way. // removeDir(), when called in slotDirty(), can cause a crash otherwise @@ -1388,16 +1389,19 @@ void KDirWatchPrivate::slotRescan() #if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY) // Scan parent of deleted directories for new creation Entry* e; - for(e=dList.first();e;e=dList.next()) + for(e=dList.first();e;e=dList.next()) { addEntry(0, TQDir::cleanDirPath( e->path.path()+"/.."), e, true); + } // Remove watch of parent of new created directories - for(e=cList.first();e;e=cList.next()) + for(e=cList.first();e;e=cList.next()) { removeEntry(0, TQDir::cleanDirPath( e->path.path()+"/.."), e); + } #endif - if ( timerRunning ) + if ( timerRunning ) { timer->start(freq); + } TQTimer::singleShot(0, this, TQT_SLOT(slotRemoveDelayed())); }