Add preliminary udisks eject support

Fix additional tdeioslave dirlister problems
pull/16/head
Timothy Pearson 12 years ago
parent 5d6798e9f9
commit bfc7b3bdbe

@ -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_INOTIFY "Enable inotify support for tdeio" ON )
OPTION( WITH_GAMIN "Enable FAM/GAMIN support" ${WITH_ALL_OPTIONS} ) OPTION( WITH_GAMIN "Enable FAM/GAMIN support" ${WITH_ALL_OPTIONS} )
option( WITH_UPOWER "Enable UPOWER 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_UDISKS2 "Enable UDISKS2 support" ${WITH_ALL_OPTIONS} )
OPTION( WITH_NETWORK_MANAGER_BACKEND "Enable network-manager support" OFF ) 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 ) OPTION( WITH_SUDO_TDESU_BACKEND "Use sudo as backend for tdesu (default is su)" OFF )

@ -68,18 +68,21 @@
#endif // WITH_NETWORK_MANAGER_BACKEND #endif // WITH_NETWORK_MANAGER_BACKEND
// uPower and uDisks2 integration // uPower and uDisks2 integration
#if defined(WITH_UPOWER) || defined(WITH_UDISKS2) #if defined(WITH_UPOWER) || defined(WITH_UDISKS) || defined(WITH_UDISKS2)
#include <tqdbusdata.h> #include <tqdbusdata.h>
#include <tqdbusmessage.h> #include <tqdbusmessage.h>
#include <tqdbusproxy.h> #include <tqdbusproxy.h>
#include <tqdbusvariant.h> #include <tqdbusvariant.h>
#include <tqdbusconnection.h> #include <tqdbusconnection.h>
#endif // defined(WITH_UPOWER) || defined(WITH_UDISKS2) #endif // defined(WITH_UPOWER) || defined(WITH_UDISKS) || defined(WITH_UDISKS2)
#ifdef WITH_UDISKS2 #if defined(WITH_UDISKS) || defined(WITH_UDISKS2)
#include <tqdbuserror.h> #include <tqdbuserror.h>
#include <tqdbusdatamap.h> #include <tqdbusdatamap.h>
#include <tqdbusobjectpath.h> #include <tqdbusobjectpath.h>
#endif // WITH_UDISKS2 #endif // defined(WITH_UDISKS) || defined(WITH_UDISKS2)
#if defined(WITH_UDISKS)
#include "tqdbusdatalist.h"
#endif // ddefined(WITH_UDISKS)
// BEGIN BLOCK // BEGIN BLOCK
// Copied from include/linux/genhd.h // 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<TQT_DBusData> 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) { bool ejectDriveUDisks2(TDEStorageDevice* sdevice) {
#ifdef WITH_UDISKS2 #ifdef WITH_UDISKS2
TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus);
@ -534,6 +569,16 @@ bool TDEStorageDevice::ejectDrive() {
return TRUE; return TRUE;
} }
else { else {
#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()); TQString command = TQString("eject -v '%1' 2>&1").arg(deviceNode());
FILE *exepipe = popen(command.ascii(), "r"); FILE *exepipe = popen(command.ascii(), "r");
@ -546,14 +591,17 @@ bool TDEStorageDevice::ejectDrive() {
return TRUE; return TRUE;
} }
else { else {
printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n\r", deviceNode().ascii());
return FALSE; return FALSE;
} }
} }
else { else {
printf("[tdehwlib] Failed to eject drive '%s' via 'eject' command\n\r", deviceNode().ascii());
return FALSE; return FALSE;
} }
} }
} }
}
bool TDEStorageDevice::ejectDriveMedia() { bool TDEStorageDevice::ejectDriveMedia() {
int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK); int fd = open(deviceNode().ascii(), O_RDWR | O_NONBLOCK);

@ -106,6 +106,7 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u,
_url.cleanPath(); // kill consecutive slashes _url.cleanPath(); // kill consecutive slashes
_url.adjustPath(-1); _url.adjustPath(-1);
TQString urlStr = _url.url(); TQString urlStr = _url.url();
TQString urlReferenceStr = _url.internalReferenceURL();
if ( !lister->validURL( _url ) ) { if ( !lister->validURL( _url ) ) {
return false; 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 if ( lister->d->url.isEmpty() || !_keep ) // set toplevel URL only if not set yet
lister->d->url = _url; lister->d->url = _url;
DirItem *itemU = itemsInUse[urlStr]; DirItem *itemU = itemsInUse[urlStr + ":" + urlReferenceStr];
DirItem *itemC; DirItem *itemC;
if ( !urlsCurrentlyListed[urlStr] ) if ( !urlsCurrentlyListed[urlStr + ":" + urlReferenceStr] )
{ {
// if there is an update running for _url already we get into // if there is an update running for _url already we get into
// the following case - it will just be restarted by updateDirectory(). // the following case - it will just be restarted by updateDirectory().
@ -169,8 +170,8 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u,
lister->emitItems(); lister->emitItems();
// _url is already in use, so there is already an entry in urlsCurrentlyHeld // _url is already in use, so there is already an entry in urlsCurrentlyHeld
assert( urlsCurrentlyHeld[urlStr] ); assert( urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr] );
urlsCurrentlyHeld[urlStr]->append( lister ); urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr]->append( lister );
lister->d->complete = oldState; lister->d->complete = oldState;
@ -188,7 +189,7 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u,
kdDebug(7004) << "listDir: Entry in cache: " << _url << endl; kdDebug(7004) << "listDir: Entry in cache: " << _url << endl;
itemC->decAutoUpdate(); itemC->decAutoUpdate();
itemsInUse.insert( urlStr, itemC ); itemsInUse.insert( urlStr + ":" + urlReferenceStr, itemC );
itemU = itemC; itemU = itemC;
bool oldState = lister->d->complete; bool oldState = lister->d->complete;
@ -203,10 +204,10 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u,
lister->addNewItems( *(itemC->lstItems) ); lister->addNewItems( *(itemC->lstItems) );
lister->emitItems(); lister->emitItems();
Q_ASSERT( !urlsCurrentlyHeld[urlStr] ); Q_ASSERT( !urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr] );
TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>; TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>;
list->append( lister ); list->append( lister );
urlsCurrentlyHeld.insert( urlStr, list ); urlsCurrentlyHeld.insert( urlStr + ":" + urlReferenceStr, list );
lister->d->complete = oldState; lister->d->complete = oldState;
@ -225,11 +226,11 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u,
TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>; TQPtrList<KDirLister> *list = new TQPtrList<KDirLister>;
list->append( lister ); list->append( lister );
urlsCurrentlyListed.insert( urlStr, list ); urlsCurrentlyListed.insert( urlStr + ":" + urlReferenceStr, list );
itemsCached.remove( urlStr ); itemsCached.remove( urlStr );
itemU = new DirItem( _url ); 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 // // we have a limit of MAX_JOBS_PER_LISTER concurrently running jobs
// if ( lister->numJobs() >= MAX_JOBS_PER_LISTER ) // if ( lister->numJobs() >= MAX_JOBS_PER_LISTER )
@ -271,7 +272,7 @@ bool KDirListerCache::listDir( KDirLister *lister, const KURL& _u,
emit lister->started( _url ); emit lister->started( _url );
urlsCurrentlyListed[urlStr]->append( lister ); urlsCurrentlyListed[urlStr + ":" + urlReferenceStr]->append( lister );
TDEIO::ListJob *job = jobForUrl( urlStr ); TDEIO::ListJob *job = jobForUrl( urlStr );
Q_ASSERT( job ); Q_ASSERT( job );
@ -389,21 +390,22 @@ void KDirListerCache::stop( KDirLister *lister )
void KDirListerCache::stop( KDirLister *lister, const KURL& _u ) void KDirListerCache::stop( KDirLister *lister, const KURL& _u )
{ {
TQString urlStr( _u.url(-1) ); TQString urlStr( _u.url(-1) );
TQString urlReferenceStr = _u.internalReferenceURL();
KURL _url( urlStr ); KURL _url( urlStr );
// TODO: consider to stop all the "child jobs" of _url as well // TODO: consider to stop all the "child jobs" of _url as well
kdDebug(7004) << k_funcinfo << lister << " url=" << _url << endl; kdDebug(7004) << k_funcinfo << lister << " url=" << _url << endl;
TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr + ":" + urlReferenceStr];
if ( !listers || !listers->removeRef( lister ) ) if ( !listers || !listers->removeRef( lister ) )
return; return;
// move lister to urlsCurrentlyHeld // move lister to urlsCurrentlyHeld
TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr];
if ( !holders ) if ( !holders )
{ {
holders = new TQPtrList<KDirLister>; holders = new TQPtrList<KDirLister>;
urlsCurrentlyHeld.insert( urlStr, holders ); urlsCurrentlyHeld.insert( urlStr + ":" + urlReferenceStr, holders );
} }
holders->append( lister ); holders->append( lister );
@ -421,7 +423,7 @@ void KDirListerCache::stop( KDirLister *lister, const KURL& _u )
if ( job ) if ( job )
killJob( job ); killJob( job );
urlsCurrentlyListed.remove( urlStr ); urlsCurrentlyListed.remove( urlStr + ":" + urlReferenceStr );
} }
if ( lister->numJobs() == 0 ) if ( lister->numJobs() == 0 )
@ -440,10 +442,12 @@ void KDirListerCache::setAutoUpdate( KDirLister *lister, bool enable )
for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); for ( KURL::List::Iterator it = lister->d->lstDirs.begin();
it != lister->d->lstDirs.end(); ++it ) it != lister->d->lstDirs.end(); ++it )
{ {
if ( enable ) if ( enable ) {
itemsInUse[(*it).url()]->incAutoUpdate(); itemsInUse[(*it).url() + ":" + (*it).internalReferenceURL()]->incAutoUpdate();
else }
itemsInUse[(*it).url()]->decAutoUpdate(); else {
itemsInUse[(*it).url() + ":" + (*it).internalReferenceURL()]->decAutoUpdate();
}
} }
} }
@ -469,7 +473,8 @@ void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool not
KURL url( _url ); KURL url( _url );
url.adjustPath( -1 ); url.adjustPath( -1 );
TQString urlStr = url.url(); TQString urlStr = url.url();
TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; TQString urlReferenceStr = url.internalReferenceURL();
TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr];
//Q_ASSERT( holders ); //Q_ASSERT( holders );
if ( holders ) if ( holders )
{ {
@ -482,15 +487,15 @@ void KDirListerCache::forgetDirs( KDirLister *lister, const KURL& _url, bool not
// might crash in findByName()). // might crash in findByName()).
lister->d->lstDirs.remove( lister->d->lstDirs.find( url ) ); lister->d->lstDirs.remove( lister->d->lstDirs.find( url ) );
DirItem *item = itemsInUse[urlStr]; DirItem *item = itemsInUse[urlStr + ":" + urlReferenceStr];
if ( holders && holders->isEmpty() ) if ( holders && holders->isEmpty() )
{ {
urlsCurrentlyHeld.remove( urlStr ); // this deletes the (empty) holders list urlsCurrentlyHeld.remove( urlStr + ":" + urlReferenceStr ); // this deletes the (empty) holders list
if ( !urlsCurrentlyListed[urlStr] ) if ( !urlsCurrentlyListed[urlStr + ":" + urlReferenceStr] )
{ {
// item not in use anymore -> move into cache if complete // item not in use anymore -> move into cache if complete
itemsInUse.remove( urlStr ); itemsInUse.remove( urlStr + ":" + urlReferenceStr );
// this job is a running update // this job is a running update
TDEIO::ListJob *job = jobForUrl( urlStr ); TDEIO::ListJob *job = jobForUrl( urlStr );
@ -560,7 +565,8 @@ void KDirListerCache::updateDirectory( const KURL& _dir )
kdDebug(7004) << k_funcinfo << _dir << endl; kdDebug(7004) << k_funcinfo << _dir << endl;
TQString urlStr = _dir.url(-1); TQString urlStr = _dir.url(-1);
if ( !checkUpdate( urlStr ) ) { TQString urlReferenceStr = _dir.internalReferenceURL();
if ( !checkUpdate( _dir, -1 ) ) {
return; return;
} }
@ -570,8 +576,8 @@ void KDirListerCache::updateDirectory( const KURL& _dir )
// - update a currently running listing: the listers are in urlsCurrentlyListed // - update a currently running listing: the listers are in urlsCurrentlyListed
// and urlsCurrentlyHeld // and urlsCurrentlyHeld
TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr + ":" + urlReferenceStr];
TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr]; TQPtrList<KDirLister> *holders = urlsCurrentlyHeld[urlStr + ":" + urlReferenceStr];
// restart the job for _dir if it is running already // restart the job for _dir if it is running already
bool killed = false; 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 ) if ( item && item->complete )
{ {
item->complete = false; item->complete = false;
@ -670,7 +676,8 @@ bool KDirListerCache::checkUpdate( const TQString& _dir )
KFileItemList *KDirListerCache::itemsForDir( const KURL &_dir ) const KFileItemList *KDirListerCache::itemsForDir( const KURL &_dir ) const
{ {
TQString urlStr = _dir.url(-1); TQString urlStr = _dir.url(-1);
DirItem *item = itemsInUse[ urlStr ]; TQString urlReferenceStr = _dir.internalReferenceURL();
DirItem *item = itemsInUse[ urlStr + ":" + urlReferenceStr ];
if ( !item ) { if ( !item ) {
item = itemsCached[ urlStr ]; item = itemsCached[ urlStr ];
} }
@ -684,7 +691,7 @@ KFileItem *KDirListerCache::findByName( const KDirLister *lister, const TQString
for ( KURL::List::Iterator it = lister->d->lstDirs.begin(); for ( KURL::List::Iterator it = lister->d->lstDirs.begin();
it != lister->d->lstDirs.end(); ++it ) it != lister->d->lstDirs.end(); ++it )
{ {
KFileItemListIterator kit( *itemsInUse[(*it).url()]->lstItems ); KFileItemListIterator kit( *itemsInUse[(*it).url() + ":" + (*it).internalReferenceURL()]->lstItems );
for ( ; kit.current(); ++kit ) for ( ; kit.current(); ++kit )
if ( (*kit)->name() == _name ) if ( (*kit)->name() == _name )
return (*kit); return (*kit);
@ -748,7 +755,7 @@ void KDirListerCache::FilesRemoved( const KURL::List &fileList )
// file items (see the dirtree). // file items (see the dirtree).
if ( fileitem ) if ( fileitem )
{ {
TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDir.url()]; TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDir.url() + ":" + parentDir.internalReferenceURL()];
if ( listers ) { if ( listers ) {
for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) { for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) {
kdl->emitDeleteItem( fileitem ); kdl->emitDeleteItem( fileitem );
@ -847,13 +854,14 @@ void KDirListerCache::aboutToRefreshItem( KFileItem *fileitem )
KURL parentDir( fileitem->url() ); KURL parentDir( fileitem->url() );
parentDir.setPath( parentDir.directory() ); parentDir.setPath( parentDir.directory() );
TQString parentDirURL = parentDir.url(); TQString parentDirURL = parentDir.url();
TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL]; TQString parentDirReferenceURL = parentDir.internalReferenceURL();
TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL + ":" + parentDirReferenceURL];
if ( listers ) if ( listers )
for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
kdl->aboutToRefreshItem( fileitem ); kdl->aboutToRefreshItem( fileitem );
// Also look in urlsCurrentlyListed, in case the user manages to rename during a listing // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing
listers = urlsCurrentlyListed[parentDirURL]; listers = urlsCurrentlyListed[parentDirURL + ":" + parentDirReferenceURL];
if ( listers ) if ( listers )
for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
kdl->aboutToRefreshItem( fileitem ); kdl->aboutToRefreshItem( fileitem );
@ -865,7 +873,8 @@ void KDirListerCache::emitRefreshItem( KFileItem *fileitem )
KURL parentDir( fileitem->url() ); KURL parentDir( fileitem->url() );
parentDir.setPath( parentDir.directory() ); parentDir.setPath( parentDir.directory() );
TQString parentDirURL = parentDir.url(); TQString parentDirURL = parentDir.url();
TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL]; TQString parentDirReferenceURL = parentDir.internalReferenceURL();
TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[parentDirURL + ":" + parentDirReferenceURL];
if ( listers ) if ( listers )
for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) 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 // Also look in urlsCurrentlyListed, in case the user manages to rename during a listing
listers = urlsCurrentlyListed[parentDirURL]; listers = urlsCurrentlyListed[parentDirURL + ":" + parentDirReferenceURL];
if ( listers ) if ( listers )
for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() )
{ {
@ -908,13 +917,15 @@ void KDirListerCache::slotFileDirty( const KURL& _url )
{ {
KURL dir; KURL dir;
dir.setPath( _url.path() ); dir.setPath( _url.path() );
if ( checkUpdate( dir.url(-1) ) ) { dir.setInternalReferenceURL(_url.internalReferenceURL());
if ( checkUpdate( dir, -1 ) ) {
updateDirectory( _url ); updateDirectory( _url );
} }
// the parent directory of _url.path() // the parent directory of _url.path()
dir.setPath( dir.directory() ); 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 // Nice hack to save memory: use the qt object name to store the filename
TQTimer *timer = new TQTimer( this, _url.path().utf8() ); 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<TDEIO::ListJob *>(job) ); KURL url = joburl( static_cast<TDEIO::ListJob *>(job) );
url.adjustPath(-1); url.adjustPath(-1);
TQString urlStr = url.url(); TQString urlStr = url.url();
TQString urlReferenceStr = url.internalReferenceURL();
kdDebug(7004) << k_funcinfo << "new entries for " << url << endl; kdDebug(7004) << k_funcinfo << "new entries for " << url << endl;
DirItem *dir = itemsInUse[urlStr]; DirItem *dir = itemsInUse[urlStr + ":" + urlReferenceStr];
Q_ASSERT( dir ); Q_ASSERT( dir );
TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr]; TQPtrList<KDirLister> *listers = urlsCurrentlyListed[urlStr + ":" + urlReferenceStr];
Q_ASSERT( listers ); Q_ASSERT( listers );
Q_ASSERT( !listers->isEmpty() ); Q_ASSERT( !listers->isEmpty() );
@ -1051,20 +1063,21 @@ void KDirListerCache::slotResult( TDEIO::Job *j )
KURL jobUrl = joburl( job ); KURL jobUrl = joburl( job );
jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections jobUrl.adjustPath(-1); // need remove trailing slashes again, in case of redirections
TQString jobUrlStr = jobUrl.url(); TQString jobUrlStr = jobUrl.url();
TQString jobReferenceUrlStr = jobUrl.internalReferenceURL();
kdDebug(7004) << k_funcinfo << "finished listing " << jobUrl << endl; kdDebug(7004) << k_funcinfo << "finished listing " << jobUrl << endl;
#ifdef DEBUG_CACHE #ifdef DEBUG_CACHE
printDebug(); printDebug();
#endif #endif
TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( jobUrlStr ); TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( jobUrlStr + ":" + jobReferenceUrlStr );
Q_ASSERT( listers ); Q_ASSERT( listers );
// move the directory to the held directories, do it before emitting // move the directory to the held directories, do it before emitting
// the signals to make sure it exists in KDirListerCache in case someone // the signals to make sure it exists in KDirListerCache in case someone
// calls listDir during the signal emission // calls listDir during the signal emission
Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr] ); Q_ASSERT( !urlsCurrentlyHeld[jobUrlStr + ":" + jobReferenceUrlStr] );
urlsCurrentlyHeld.insert( jobUrlStr, listers ); urlsCurrentlyHeld.insert( jobUrlStr + ":" + jobReferenceUrlStr, listers );
KDirLister *kdl; KDirLister *kdl;
@ -1084,7 +1097,7 @@ void KDirListerCache::slotResult( TDEIO::Job *j )
} }
else else
{ {
DirItem *dir = itemsInUse[jobUrlStr]; DirItem *dir = itemsInUse[jobUrlStr + ":" + jobReferenceUrlStr];
Q_ASSERT( dir ); Q_ASSERT( dir );
dir->complete = true; 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. // DF: redirection happens before listDir emits any item. Makes little sense otherwise.
// oldUrl cannot be in itemsCached because only completed items are moved there // 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 ); Q_ASSERT( dir );
TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrl.url() ); TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrl.url() + ":" + oldUrl.internalReferenceURL() );
Q_ASSERT( listers ); Q_ASSERT( listers );
Q_ASSERT( !listers->isEmpty() ); 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 // when a lister was stopped before the job emits the redirection signal, the old url will
// also be in urlsCurrentlyHeld // also be in urlsCurrentlyHeld
TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrl.url() ); TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrl.url() + ":" + oldUrl.internalReferenceURL() );
if ( holders ) if ( holders )
{ {
Q_ASSERT( !holders->isEmpty() ); 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 ) if ( newDir )
{ {
kdDebug(7004) << "slotRedirection: " << newUrl.url() << " already in use" << endl; 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 // listers of newUrl with oldJob: forget about the oldJob and use the already running one
// which will be converted to an updateJob // which will be converted to an updateJob
TQPtrList<KDirLister> *curListers = urlsCurrentlyListed[newUrl.url()]; TQPtrList<KDirLister> *curListers = urlsCurrentlyListed[newUrl.url() + ":" + newUrl.internalReferenceURL()];
if ( curListers ) if ( curListers )
{ {
kdDebug(7004) << "slotRedirection: and it is currently listed" << endl; 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 ); curListers->append( kdl );
} }
else 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 if ( oldJob ) // kill the old job, be it a list-job or an update-job
killJob( oldJob ); killJob( oldJob );
// holders of newUrl: use the already running job which will be converted to an updateJob // holders of newUrl: use the already running job which will be converted to an updateJob
TQPtrList<KDirLister> *curHolders = urlsCurrentlyHeld[newUrl.url()]; TQPtrList<KDirLister> *curHolders = urlsCurrentlyHeld[newUrl.url() + ":" + newUrl.internalReferenceURL()];
if ( curHolders ) if ( curHolders )
{ {
kdDebug(7004) << "slotRedirection: and it is currently held." << endl; 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 ); curHolders->append( kdl );
} }
else if ( holders ) 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 // 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; kdDebug(7004) << "slotRedirection: " << newUrl.url() << " is unused, but already in the cache." << endl;
delete dir; delete dir;
itemsInUse.insert( newUrl.url(), newDir ); itemsInUse.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), newDir );
urlsCurrentlyListed.insert( newUrl.url(), listers ); urlsCurrentlyListed.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), listers );
if ( holders ) if ( holders )
urlsCurrentlyHeld.insert( newUrl.url(), holders ); urlsCurrentlyHeld.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), holders );
// emit old items: listers, holders // emit old items: listers, holders
for ( KDirLister *kdl = listers->first(); kdl; kdl = listers->next() ) 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->rootItem = 0;
dir->lstItems->clear(); dir->lstItems->clear();
dir->redirect( newUrl ); dir->redirect( newUrl );
itemsInUse.insert( newUrl.url(), dir ); itemsInUse.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), dir );
urlsCurrentlyListed.insert( newUrl.url(), listers ); urlsCurrentlyListed.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), listers );
if ( holders ) if ( holders )
urlsCurrentlyHeld.insert( newUrl.url(), holders ); urlsCurrentlyHeld.insert( newUrl.url() + ":" + newUrl.internalReferenceURL(), holders );
else else
{ {
#ifdef DEBUG_CACHE #ifdef DEBUG_CACHE
@ -1376,7 +1389,9 @@ void KDirListerCache::renameDir( const KURL &oldUrl, const KURL &newUrl )
{ {
goNext = true; goNext = true;
DirItem *dir = itu.current(); 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; //kdDebug(7004) << "itemInUse: " << oldDirUrl.prettyURL() << endl;
// Check if this dir is oldUrl, or a subfolder of it // Check if this dir is oldUrl, or a subfolder of it
if ( oldUrl.isParentOf( oldDirUrl ) ) 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() ); TQString relPath = oldDirUrl.path().mid( oldUrl.path().length() );
KURL newDirUrl( newUrl ); // take new base KURL newDirUrl( newUrl ); // take new base
if ( !relPath.isEmpty() ) if ( !relPath.isEmpty() ) {
newDirUrl.addPath( relPath ); // add unchanged relative path newDirUrl.addPath( relPath ); // add unchanged relative path
}
//kdDebug(7004) << "KDirListerCache::renameDir new url=" << newDirUrl.prettyURL() << endl; //kdDebug(7004) << "KDirListerCache::renameDir new url=" << newDirUrl.prettyURL() << endl;
// Update URL in dir item and in itemsInUse // 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; kdDebug(7004) << k_funcinfo << oldUrl.prettyURL() << " -> " << url.prettyURL() << endl;
TQString oldUrlStr = oldUrl.url(-1); TQString oldUrlStr = oldUrl.url(-1);
TQString urlStr = url.url(-1); TQString urlStr = url.url(-1);
TQString oldReferenceUrlStr = oldUrl.internalReferenceURL();
TQString urlReferenceStr = url.internalReferenceURL();
TDEIO::ListJob *job = jobForUrl( oldUrlStr ); TDEIO::ListJob *job = jobForUrl( oldUrlStr );
if ( job ) if ( job )
killJob( job ); killJob( job );
// Check if we were listing this dir. Need to abort and restart with new name in that case. // Check if we were listing this dir. Need to abort and restart with new name in that case.
TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrlStr ); TQPtrList<KDirLister> *listers = urlsCurrentlyListed.take( oldUrlStr + ":" + oldReferenceUrlStr );
if ( listers ) if ( listers )
{ {
// Tell the world that the job listing the old url is dead. // 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 ); 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) // Check if we are currently displaying this directory (odds opposite wrt above)
// Update urlsCurrentlyHeld dict with new URL // Update urlsCurrentlyHeld dict with new URL
TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrlStr ); TQPtrList<KDirLister> *holders = urlsCurrentlyHeld.take( oldUrlStr + ":" + oldReferenceUrlStr );
if ( holders ) if ( holders )
{ {
if ( job ) if ( job )
for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() ) for ( KDirLister *kdl = holders->first(); kdl; kdl = holders->next() )
kdl->jobDone( job ); kdl->jobDone( job );
urlsCurrentlyHeld.insert( urlStr, holders ); urlsCurrentlyHeld.insert( urlStr + ":" + urlReferenceStr, holders );
} }
if ( listers ) if ( listers )
@ -1515,8 +1533,8 @@ void KDirListerCache::slotUpdateResult( TDEIO::Job * j )
KDirLister *kdl; KDirLister *kdl;
TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[jobUrlStr]; TQPtrList<KDirLister> *listers = urlsCurrentlyHeld[jobUrlStr + ":" + jobReferenceUrlStr];
TQPtrList<KDirLister> *tmpLst = urlsCurrentlyListed.take( jobUrlStr ); TQPtrList<KDirLister> *tmpLst = urlsCurrentlyListed.take( jobUrlStr + ":" + jobReferenceUrlStr );
if ( tmpLst ) if ( tmpLst )
{ {
@ -1529,7 +1547,7 @@ void KDirListerCache::slotUpdateResult( TDEIO::Job * j )
else else
{ {
listers = tmpLst; listers = tmpLst;
urlsCurrentlyHeld.insert( jobUrlStr, listers ); urlsCurrentlyHeld.insert( jobUrlStr + ":" + jobReferenceUrlStr, listers );
} }
} }
@ -1561,7 +1579,7 @@ void KDirListerCache::slotUpdateResult( TDEIO::Job * j )
return; return;
} }
DirItem *dir = itemsInUse[jobUrlStr]; DirItem *dir = itemsInUse[jobUrlStr + ":" + jobReferenceUrlStr];
dir->complete = true; dir->complete = true;
@ -1765,12 +1783,14 @@ void KDirListerCache::deleteDir( const KURL& dirUrl )
TQDictIterator<DirItem> itu( itemsInUse ); TQDictIterator<DirItem> itu( itemsInUse );
while ( itu.current() ) 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 ) ) if ( dirUrl.isParentOf( deletedUrl ) )
{ {
// stop all jobs for deletedUrl // stop all jobs for deletedUrl
TQPtrList<KDirLister> *kdls = urlsCurrentlyListed[deletedUrl.url()]; TQPtrList<KDirLister> *kdls = urlsCurrentlyListed[deletedUrl.url() + ":" + deletedUrl.internalReferenceURL()];
if ( kdls ) // yeah, I lack good names if ( kdls ) // yeah, I lack good names
{ {
// we need a copy because stop modifies the list // 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 // tell listers holding deletedUrl to forget about it
// this will stop running updates for deletedUrl as well // this will stop running updates for deletedUrl as well
kdls = urlsCurrentlyHeld[deletedUrl.url()]; kdls = urlsCurrentlyHeld[deletedUrl.url() + ":" + deletedUrl.internalReferenceURL()];
if ( kdls ) if ( kdls )
{ {
// we need a copy because forgetDirs modifies the list // 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 // delete the entry for deletedUrl - should not be needed, it's in
// items cached now // items cached now
DirItem *dir = itemsInUse.take( deletedUrl.url() ); DirItem *dir = itemsInUse.take( deletedUrl.url() + ":" + deletedUrl.internalReferenceURL() );
Q_ASSERT( !dir ); Q_ASSERT( !dir );
if ( !dir ) // take didn't find it - move on if ( !dir ) // take didn't find it - move on
++itu; ++itu;

@ -211,7 +211,7 @@ private:
// check if _url is held by some lister and return true, // check if _url is held by some lister and return true,
// otherwise schedule a delayed update and return false // 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 // 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 // the parent directory need to be notified, the unmarked items have to be deleted
// and removed from the cache including all the childs. // and removed from the cache including all the childs.

@ -1308,8 +1308,9 @@ void KDirWatchPrivate::slotRescan()
// like showing a message box. We don't want to keep polling during // like showing a message box. We don't want to keep polling during
// that time, otherwise the value of 'delayRemove' will be reset. // that time, otherwise the value of 'delayRemove' will be reset.
bool timerRunning = timer->isActive(); bool timerRunning = timer->isActive();
if ( timerRunning ) if ( timerRunning ) {
timer->stop(); timer->stop();
}
// We delay deletions of entries this way. // We delay deletions of entries this way.
// removeDir(), when called in slotDirty(), can cause a crash otherwise // removeDir(), when called in slotDirty(), can cause a crash otherwise
@ -1388,16 +1389,19 @@ void KDirWatchPrivate::slotRescan()
#if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY) #if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY)
// Scan parent of deleted directories for new creation // Scan parent of deleted directories for new creation
Entry* e; 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); addEntry(0, TQDir::cleanDirPath( e->path.path()+"/.."), e, true);
}
// Remove watch of parent of new created directories // 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); removeEntry(0, TQDir::cleanDirPath( e->path.path()+"/.."), e);
}
#endif #endif
if ( timerRunning ) if ( timerRunning ) {
timer->start(freq); timer->start(freq);
}
TQTimer::singleShot(0, this, TQT_SLOT(slotRemoveDelayed())); TQTimer::singleShot(0, this, TQT_SLOT(slotRemoveDelayed()));
} }

Loading…
Cancel
Save