diff --git a/kio/kio/forwardingslavebase.cpp b/kio/kio/forwardingslavebase.cpp index c83d5750c..17f12900a 100644 --- a/kio/kio/forwardingslavebase.cpp +++ b/kio/kio/forwardingslavebase.cpp @@ -284,6 +284,24 @@ void ForwardingSlaveBase::del(const KURL &url, bool isfile) } } +void ForwardingSlaveBase::localURL(const KURL& remoteURL) +{ + kdDebug() << "ForwardingSlaveBase::localURL: " << remoteURL << endl; + + KURL new_url; + if ( internalRewriteURL(remoteURL, new_url) ) + { + KIO::LocalURLJob *job = KIO::localURL(new_url); + connectLocalURLJob(job); + + tqApp->eventLoop()->enterLoop(); + } + else + { + // Let the slave base emit the required signals + SlaveBase::localURL(remoteURL); + } +} ////////////////////////////////////////////////////////////////////////////// @@ -343,6 +361,13 @@ void ForwardingSlaveBase::connectTransferJob(KIO::TransferJob *job) this, TQT_SLOT( slotCanResume(KIO::Job *, KIO::filesize_t) ) ); } +void ForwardingSlaveBase::connectLocalURLJob(KIO::LocalURLJob *job) +{ + connectJob(job); + connect( job, TQT_SIGNAL( localURL(KIO::Job *, const KURL&, bool) ), + this, TQT_SLOT( slotLocalURL(KIO::Job *, const KURL&, bool) ) ); +} + ////////////////////////////////////////////////////////////////////////////// void ForwardingSlaveBase::slotResult(KIO::Job *job) @@ -439,6 +464,11 @@ void ForwardingSlaveBase::slotCanResume (KIO::Job* /*job*/, KIO::filesize_t offs canResume(offset); } +void ForwardingSlaveBase::slotLocalURL(KIO::Job *, const KURL& url, bool) +{ + SlaveBase::localURL(url); +} + } #include "forwardingslavebase.moc" diff --git a/kio/kio/forwardingslavebase.h b/kio/kio/forwardingslavebase.h index a536a9f02..1e6d303ee 100644 --- a/kio/kio/forwardingslavebase.h +++ b/kio/kio/forwardingslavebase.h @@ -119,6 +119,8 @@ public: virtual void del(const KURL &url, bool isfile); + virtual void localURL(const KURL& remoteURL); + protected: /** * Rewrite an url to it's forwarded counterpart. It should return @@ -170,6 +172,7 @@ private: void connectSimpleJob(SimpleJob *job); void connectListJob(ListJob *job); void connectTransferJob(TransferJob *job); + void connectLocalURLJob(LocalURLJob *job); private slots: // KIO::Job @@ -191,6 +194,9 @@ private slots: void slotDataReq(KIO::Job *job, TQByteArray &data); void slotMimetype (KIO::Job *job, const TQString &type); void slotCanResume (KIO::Job *job, KIO::filesize_t offset); + + // KIO::LocalURLJob + void slotLocalURL(KIO::Job *, const KURL&, bool); }; } diff --git a/kio/kio/global.h b/kio/kio/global.h index 03fb61dcc..6b0408c04 100644 --- a/kio/kio/global.h +++ b/kio/kio/global.h @@ -163,7 +163,8 @@ namespace KIO CMD_MESSAGEBOXANSWER = 'S', // 83 CMD_RESUMEANSWER = 'T', // 84 CMD_CONFIG = 'U', // 85 - CMD_MULTI_GET = 'V' // 86 + CMD_MULTI_GET = 'V', // 86 + CMD_LOCALURL = 'W' // 87 // Add new ones here once a release is done, to avoid breaking binary compatibility. // Note that protocol-specific commands shouldn't be added here, but should use special. }; diff --git a/kio/kio/job.cpp b/kio/kio/job.cpp index fc1a9645f..69b363392 100644 --- a/kio/kio/job.cpp +++ b/kio/kio/job.cpp @@ -808,6 +808,40 @@ SimpleJob *KIO::unmount( const TQString& point, bool showProgressInfo ) return job; } +////////// +LocalURLJob::LocalURLJob( const KURL& url, int command, + const TQByteArray &packedArgs, bool showProgressInfo ) + : SimpleJob(url, command, packedArgs, showProgressInfo) +{ + +} + +void LocalURLJob::start(Slave *slave) +{ + connect( slave, TQT_SIGNAL( localURL(const KURL &, bool) ), + TQT_SLOT( slotLocalURL(const KURL &, bool) ) ); + + SimpleJob::start(slave); +} + +// Slave sent a response! +void LocalURLJob::slotLocalURL(const KURL &url, bool isLocal) +{ + kdDebug(7007) << "LocalURLJob::slotLocalURL(" << url << ")" << endl; + emit localURL(this, url, isLocal); +} + +void LocalURLJob::slotFinished() +{ + // Return slave to the scheduler + SimpleJob::slotFinished(); +} + +LocalURLJob *KIO::localURL( const KURL& remoteUrl ) +{ + KIO_ARGS << remoteUrl; + return new LocalURLJob(remoteUrl, CMD_LOCALURL, packedArgs, false); +} ////////// @@ -4773,5 +4807,8 @@ void CopyJob::virtual_hook( int id, void* data ) void DeleteJob::virtual_hook( int id, void* data ) { Job::virtual_hook( id, data ); } +void LocalURLJob::virtual_hook( int id, void* data ) +{ Job::virtual_hook( id, data ); } + #include "jobclasses.moc" diff --git a/kio/kio/job.h b/kio/kio/job.h index 03edb5024..fed6f82ab 100644 --- a/kio/kio/job.h +++ b/kio/kio/job.h @@ -128,6 +128,14 @@ namespace KIO { */ KIO_EXPORT SimpleJob *unmount( const TQString & point, bool showProgressInfo = true ); + /** + * Retrieve local URL if available + * + * @param remoteURL the remote URL to get the local URL for + * @return the job handling the operation. + */ + KIO_EXPORT LocalURLJob *localURL( const KURL& remoteUrl ); + /** * HTTP cache update * diff --git a/kio/kio/jobclasses.h b/kio/kio/jobclasses.h index 03ff3d452..d937e8700 100644 --- a/kio/kio/jobclasses.h +++ b/kio/kio/jobclasses.h @@ -1858,6 +1858,52 @@ namespace KIO { class DeleteJobPrivate* d; }; + /** + * A KIO job that finds a local URL + * @see KIO::localURL() + * @since R14.0.0 + */ + class KIO_EXPORT LocalURLJob : public SimpleJob { + + Q_OBJECT + + public: + /** + * Do not use this constructor to create a LocalURLJob, use KIO::localURL() instead. + * @param url the url of the file or directory to check + * @param command the command to issue + * @param packedArgs the arguments + * @param showProgressInfo true to show progress information to the user + */ + LocalURLJob(const KURL& url, int command, const TQByteArray &packedArgs, bool showProgressInfo); + + /** + * @internal + * Called by the scheduler when a @p slave gets to + * work on this job. + * @param slave the slave that starts working on this job + */ + virtual void start( Slave *slave ); + + signals: + /** + * @param job the job that emitted this signal + * @param url the local url + * @param isLocal true if the returned URL is local, false if not + */ + void localURL( KIO::Job *job, const KURL &url, bool isLocal ); + + protected slots: + void slotLocalURL( const KURL &url, bool isLocal ); + virtual void slotFinished(); + + protected: + virtual void virtual_hook( int id, void* data ); + private: + class LocalURLJobPrivate; + LocalURLJobPrivate *d; + }; + } #endif diff --git a/kio/kio/kdirlister.cpp b/kio/kio/kdirlister.cpp index a7fa515d7..0641645a6 100644 --- a/kio/kio/kdirlister.cpp +++ b/kio/kio/kdirlister.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #include "kdirlister_p.h" #include +#include KDirListerCache* KDirListerCache::s_pSelf = 0; static KStaticDeleter sd_KDirListerCache; @@ -1862,7 +1864,39 @@ bool KDirLister::openURL( const KURL& _url, bool _keep, bool _reload ) d->changes = NONE; - return s_pCache->listDir( this, _url, _keep, _reload ); + // If a local path is available, monitor that instead of the given remote URL... + KURL realURL = _url; + if (!realURL.isLocalFile()) { + KIO::LocalURLJob* localURLJob = KIO::localURL(_url); + if (localURLJob) { + connect(localURLJob, TQT_SIGNAL(localURL(KIO::Job*, const KURL&, bool)), this, TQT_SLOT(slotLocalURL(KIO::Job*, const KURL&, bool))); + connect(localURLJob, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotLocalURLKIODestroyed())); + d->localURLSlotFired = false; + while (!d->localURLSlotFired) { + tqApp->eventLoop()->processEvents(TQEventLoop::ExcludeUserInput); + usleep(1000); + } + if (d->localURLResultIsLocal) { + realURL = d->localURLResultURL; + } + } + } + + return s_pCache->listDir( this, realURL, _keep, _reload ); +} + +void KDirLister::slotLocalURL(KIO::Job *job, const KURL& url, bool isLocal) { + d->localURLSlotFired = true; + d->localURLResultURL = url; + d->localURLResultIsLocal = isLocal; +} + +void KDirLister::slotLocalURLKIODestroyed() { + if (!d->localURLSlotFired) { + d->localURLSlotFired = true; + d->localURLResultURL = KURL(); + d->localURLResultIsLocal = false; + } } void KDirLister::stop() diff --git a/kio/kio/kdirlister.h b/kio/kio/kdirlister.h index cd657f47a..2271b2a70 100644 --- a/kio/kio/kdirlister.h +++ b/kio/kio/kdirlister.h @@ -609,6 +609,8 @@ private slots: void slotTotalSize( KIO::Job *, KIO::filesize_t ); void slotProcessedSize( KIO::Job *, KIO::filesize_t ); void slotSpeed( KIO::Job *, unsigned long ); + void slotLocalURL( KIO::Job *, const KURL&, bool ); + void slotLocalURLKIODestroyed( ); private: void jobStarted( KIO::ListJob * ); diff --git a/kio/kio/kdirlister_p.h b/kio/kio/kdirlister_p.h index a98521905..047c83148 100644 --- a/kio/kio/kdirlister_p.h +++ b/kio/kio/kdirlister_p.h @@ -111,6 +111,10 @@ public: TQPtrList lstFilters, oldFilters; TQStringList mimeFilter, oldMimeFilter; TQStringList mimeExcludeFilter, oldMimeExcludeFilter; + + bool localURLSlotFired; + KURL localURLResultURL; + bool localURLResultIsLocal; }; /** diff --git a/kio/kio/slavebase.cpp b/kio/kio/slavebase.cpp index c237bd490..d0734105c 100644 --- a/kio/kio/slavebase.cpp +++ b/kio/kio/slavebase.cpp @@ -809,6 +809,23 @@ void SlaveBase::reparseConfiguration() { } +void SlaveBase::localURL(const KURL& remoteURL) +{ + bool local = remoteURL.isLocalFile(); + TQ_INT8 islocal; + KURL retURL; + if (local) { + islocal = true; + retURL = remoteURL; + } + else { + islocal = false; + retURL = remoteURL; + } + KIO_DATA << islocal << retURL; + m_pConnection->send( INF_LOCALURL, data ); +} + bool SlaveBase::dispatch() { assert( m_pConnection ); @@ -1130,6 +1147,11 @@ void SlaveBase::dispatch( int command, const TQByteArray &data ) case CMD_MULTI_GET: multiGet( data ); break; + case CMD_LOCALURL: + { + stream >> url; + localURL( url ); + } break; default: // Some command we don't understand. // Just ignore it, it may come from some future version of KDE. diff --git a/kio/kio/slavebase.h b/kio/kio/slavebase.h index 82370ce56..b6e48d5b6 100644 --- a/kio/kio/slavebase.h +++ b/kio/kio/slavebase.h @@ -515,6 +515,12 @@ public: */ virtual void reparseConfiguration(); + /** + * For use with for ForwardingSlaveBase + * Returns the local URL of the given remote URL if possible + * @since R14.0.0 + */ + virtual void localURL( const KURL& remoteURL ); /** * @return timeout value for connecting to remote host. diff --git a/kio/kio/slaveinterface.cpp b/kio/kio/slaveinterface.cpp index 62c64d566..05036cf8a 100644 --- a/kio/kio/slaveinterface.cpp +++ b/kio/kio/slaveinterface.cpp @@ -375,6 +375,13 @@ bool SlaveInterface::dispatch( int _cmd, const TQByteArray &rawdata ) metaData(meta_data); break; } + case INF_LOCALURL: { + TQ_INT8 islocal; + KURL url; + stream >> islocal >> url; + emit localURL( url, islocal ); + break; + } case MSG_NET_REQUEST: { TQString host; TQString slaveid; diff --git a/kio/kio/slaveinterface.h b/kio/kio/slaveinterface.h index d5b680f63..9d278adfc 100644 --- a/kio/kio/slaveinterface.h +++ b/kio/kio/slaveinterface.h @@ -54,7 +54,8 @@ class SlaveInterfacePrivate; INF_INFOMESSAGE, INF_META_DATA, INF_NETWORK_STATUS, - INF_MESSAGEBOX + INF_MESSAGEBOX, + INF_LOCALURL // add new ones here once a release is done, to avoid breaking binary compatibility }; @@ -136,6 +137,7 @@ signals: void totalSize( KIO::filesize_t ) ; void processedSize( KIO::filesize_t ) ; void redirection( const KURL& ) ; + void localURL( const KURL&, bool ) ; void speed( unsigned long ) ; void errorPage() ;