KIO
forwardingslavebase.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 Copyright (c) 2004 Kevin Ottens <ervin@ipsquad.net> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "forwardingslavebase.h" 00021 00022 #include "deletejob.h" 00023 #include "job.h" 00024 00025 #include <kdebug.h> 00026 #include <kmimetype.h> 00027 #include <kprotocolinfo.h> 00028 00029 #include <QtGui/QApplication> 00030 #include <QtCore/QEventLoop> 00031 00032 namespace KIO 00033 { 00034 00035 class ForwardingSlaveBasePrivate 00036 { 00037 public: 00038 ForwardingSlaveBasePrivate(QObject * eventLoopParent) : 00039 eventLoop(eventLoopParent) 00040 {} 00041 ForwardingSlaveBase *q; 00042 00043 KUrl m_processedURL; 00044 KUrl m_requestedURL; 00045 QEventLoop eventLoop; 00046 00047 bool internalRewriteUrl(const KUrl &url, KUrl &newURL); 00048 00049 void connectJob(Job *job); 00050 void connectSimpleJob(SimpleJob *job); 00051 void connectListJob(ListJob *job); 00052 void connectTransferJob(TransferJob *job); 00053 00054 void _k_slotResult(KJob *job); 00055 void _k_slotWarning(KJob *job, const QString &msg); 00056 void _k_slotInfoMessage(KJob *job, const QString &msg); 00057 void _k_slotTotalSize(KJob *job, qulonglong size); 00058 void _k_slotProcessedSize(KJob *job, qulonglong size); 00059 void _k_slotSpeed(KJob *job, unsigned long bytesPerSecond); 00060 00061 // KIO::SimpleJob subclasses 00062 void _k_slotRedirection(KIO::Job *job, const KUrl &url); 00063 00064 // KIO::ListJob 00065 void _k_slotEntries(KIO::Job *job, const KIO::UDSEntryList &entries); 00066 00067 // KIO::TransferJob 00068 void _k_slotData(KIO::Job *job, const QByteArray &data); 00069 void _k_slotDataReq(KIO::Job *job, QByteArray &data); 00070 void _k_slotMimetype (KIO::Job *job, const QString &type); 00071 void _k_slotCanResume (KIO::Job *job, KIO::filesize_t offset); 00072 }; 00073 00074 ForwardingSlaveBase::ForwardingSlaveBase(const QByteArray &protocol, 00075 const QByteArray &poolSocket, 00076 const QByteArray &appSocket) 00077 : QObject(), SlaveBase(protocol, poolSocket, appSocket), 00078 d( new ForwardingSlaveBasePrivate(this) ) 00079 { 00080 d->q = this; 00081 } 00082 00083 ForwardingSlaveBase::~ForwardingSlaveBase() 00084 { 00085 delete d; 00086 } 00087 00088 bool ForwardingSlaveBasePrivate::internalRewriteUrl(const KUrl &url, KUrl &newURL) 00089 { 00090 bool result = true; 00091 00092 if ( url.protocol() == q->mProtocol ) 00093 { 00094 result = q->rewriteUrl(url, newURL); 00095 } 00096 else 00097 { 00098 newURL = url; 00099 } 00100 00101 m_processedURL = newURL; 00102 m_requestedURL = url; 00103 return result; 00104 } 00105 00106 void ForwardingSlaveBase::prepareUDSEntry(KIO::UDSEntry &entry, 00107 bool listing) const 00108 { 00109 //kDebug() << "listing==" << listing; 00110 00111 const QString name = entry.stringValue( KIO::UDSEntry::UDS_NAME ); 00112 QString mimetype = entry.stringValue( KIO::UDSEntry::UDS_MIME_TYPE ); 00113 KUrl url; 00114 const QString urlStr = entry.stringValue( KIO::UDSEntry::UDS_URL ); 00115 const bool url_found = !urlStr.isEmpty(); 00116 if ( url_found ) 00117 { 00118 url = urlStr; 00119 KUrl new_url = d->m_requestedURL; 00120 if (listing) 00121 new_url.addPath(url.fileName()); 00122 // ## Didn't find a way to use an iterator instead of re-doing a key lookup 00123 entry.insert( KIO::UDSEntry::UDS_URL, new_url.url() ); 00124 kDebug() << "URL =" << url; 00125 kDebug() << "New URL =" << new_url; 00126 } 00127 00128 if (mimetype.isEmpty()) 00129 { 00130 KUrl new_url = d->m_processedURL; 00131 if (url_found && listing) 00132 { 00133 new_url.addPath( url.fileName() ); 00134 } 00135 else if (listing) 00136 { 00137 new_url.addPath( name ); 00138 } 00139 00140 mimetype = KMimeType::findByUrl(new_url)->name(); 00141 00142 entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, mimetype ); 00143 00144 kDebug() << "New Mimetype = " << mimetype; 00145 } 00146 00147 if ( d->m_processedURL.isLocalFile() ) 00148 { 00149 KUrl new_url = d->m_processedURL; 00150 if (listing) 00151 { 00152 new_url.addPath( name ); 00153 } 00154 00155 entry.insert( KIO::UDSEntry::UDS_LOCAL_PATH, new_url.toLocalFile() ); 00156 } 00157 } 00158 00159 KUrl ForwardingSlaveBase::processedUrl() const 00160 { 00161 return d->m_processedURL; 00162 } 00163 00164 KUrl ForwardingSlaveBase::requestedUrl() const 00165 { 00166 return d->m_requestedURL; 00167 } 00168 00169 void ForwardingSlaveBase::get(const KUrl &url) 00170 { 00171 kDebug() << url; 00172 00173 KUrl new_url; 00174 if ( d->internalRewriteUrl(url, new_url) ) 00175 { 00176 KIO::TransferJob *job = KIO::get(new_url, NoReload, HideProgressInfo); 00177 d->connectTransferJob(job); 00178 00179 d->eventLoop.exec(); 00180 } 00181 else 00182 { 00183 error(KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); 00184 } 00185 } 00186 00187 void ForwardingSlaveBase::put(const KUrl &url, int permissions, 00188 JobFlags flags) 00189 { 00190 kDebug() << url; 00191 00192 KUrl new_url; 00193 if ( d->internalRewriteUrl(url, new_url) ) 00194 { 00195 KIO::TransferJob *job = KIO::put(new_url, permissions, 00196 flags | HideProgressInfo); 00197 d->connectTransferJob(job); 00198 00199 d->eventLoop.exec(); 00200 } 00201 else 00202 { 00203 error( KIO::ERR_MALFORMED_URL, url.prettyUrl() ); 00204 } 00205 } 00206 00207 void ForwardingSlaveBase::stat(const KUrl &url) 00208 { 00209 kDebug() << url; 00210 00211 KUrl new_url; 00212 if ( d->internalRewriteUrl(url, new_url) ) 00213 { 00214 KIO::SimpleJob *job = KIO::stat(new_url, KIO::HideProgressInfo); 00215 d->connectSimpleJob(job); 00216 00217 d->eventLoop.exec(); 00218 } 00219 else 00220 { 00221 error(KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); 00222 } 00223 } 00224 00225 void ForwardingSlaveBase::mimetype(const KUrl &url) 00226 { 00227 kDebug() << url; 00228 00229 KUrl new_url; 00230 if ( d->internalRewriteUrl(url, new_url) ) 00231 { 00232 KIO::TransferJob *job = KIO::mimetype(new_url, KIO::HideProgressInfo); 00233 d->connectTransferJob(job); 00234 00235 d->eventLoop.exec(); 00236 } 00237 else 00238 { 00239 error(KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); 00240 } 00241 } 00242 00243 void ForwardingSlaveBase::listDir(const KUrl &url) 00244 { 00245 kDebug() << url; 00246 00247 KUrl new_url; 00248 if ( d->internalRewriteUrl(url, new_url) ) 00249 { 00250 KIO::ListJob *job = KIO::listDir(new_url, KIO::HideProgressInfo); 00251 d->connectListJob(job); 00252 00253 d->eventLoop.exec(); 00254 } 00255 else 00256 { 00257 error(KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); 00258 } 00259 } 00260 00261 void ForwardingSlaveBase::mkdir(const KUrl &url, int permissions) 00262 { 00263 kDebug() << url; 00264 00265 KUrl new_url; 00266 if ( d->internalRewriteUrl(url, new_url) ) 00267 { 00268 KIO::SimpleJob *job = KIO::mkdir(new_url, permissions); 00269 d->connectSimpleJob(job); 00270 00271 d->eventLoop.exec(); 00272 } 00273 else 00274 { 00275 error( KIO::ERR_MALFORMED_URL, url.prettyUrl() ); 00276 } 00277 } 00278 00279 void ForwardingSlaveBase::rename(const KUrl &src, const KUrl &dest, 00280 JobFlags flags) 00281 { 00282 kDebug() << src << "," << dest; 00283 00284 KUrl new_src, new_dest; 00285 if( !d->internalRewriteUrl(src, new_src) ) 00286 { 00287 error(KIO::ERR_DOES_NOT_EXIST, src.prettyUrl()); 00288 } 00289 else if ( d->internalRewriteUrl(dest, new_dest) ) 00290 { 00291 KIO::Job *job = KIO::rename(new_src, new_dest, flags); 00292 d->connectJob(job); 00293 00294 d->eventLoop.exec(); 00295 } 00296 else 00297 { 00298 error( KIO::ERR_MALFORMED_URL, dest.prettyUrl() ); 00299 } 00300 } 00301 00302 void ForwardingSlaveBase::symlink(const QString &target, const KUrl &dest, 00303 JobFlags flags) 00304 { 00305 kDebug() << target << ", " << dest; 00306 00307 KUrl new_dest; 00308 if ( d->internalRewriteUrl(dest, new_dest) ) 00309 { 00310 KIO::SimpleJob *job = KIO::symlink(target, new_dest, flags & HideProgressInfo); 00311 d->connectSimpleJob(job); 00312 00313 d->eventLoop.exec(); 00314 } 00315 else 00316 { 00317 error( KIO::ERR_MALFORMED_URL, dest.prettyUrl() ); 00318 } 00319 } 00320 00321 void ForwardingSlaveBase::chmod(const KUrl &url, int permissions) 00322 { 00323 kDebug() << url; 00324 00325 KUrl new_url; 00326 if ( d->internalRewriteUrl(url, new_url) ) 00327 { 00328 KIO::SimpleJob *job = KIO::chmod(new_url, permissions); 00329 d->connectSimpleJob(job); 00330 00331 d->eventLoop.exec(); 00332 } 00333 else 00334 { 00335 error(KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); 00336 } 00337 } 00338 00339 void ForwardingSlaveBase::setModificationTime(const KUrl& url, const QDateTime& mtime) 00340 { 00341 kDebug() << url; 00342 00343 KUrl new_url; 00344 if ( d->internalRewriteUrl(url, new_url) ) 00345 { 00346 KIO::SimpleJob *job = KIO::setModificationTime(new_url, mtime); 00347 d->connectSimpleJob(job); 00348 00349 d->eventLoop.exec(); 00350 } 00351 else 00352 { 00353 error(KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); 00354 } 00355 } 00356 00357 void ForwardingSlaveBase::copy(const KUrl &src, const KUrl &dest, 00358 int permissions, JobFlags flags) 00359 { 00360 kDebug() << src << "," << dest; 00361 00362 KUrl new_src, new_dest; 00363 if ( !d->internalRewriteUrl(src, new_src) ) 00364 { 00365 error(KIO::ERR_DOES_NOT_EXIST, src.prettyUrl()); 00366 } 00367 else if( d->internalRewriteUrl(dest, new_dest) ) 00368 { 00369 // Are you sure you want to display here a ProgressInfo ??? 00370 KIO::Job *job = KIO::file_copy(new_src, new_dest, permissions, 00371 (flags & (~Overwrite) & (~HideProgressInfo)) ); 00372 d->connectJob(job); 00373 00374 d->eventLoop.exec(); 00375 } 00376 else 00377 { 00378 error( KIO::ERR_MALFORMED_URL, dest.prettyUrl() ); 00379 } 00380 } 00381 00382 void ForwardingSlaveBase::del(const KUrl &url, bool isfile) 00383 { 00384 kDebug() << url; 00385 00386 KUrl new_url; 00387 if ( d->internalRewriteUrl(url, new_url) ) 00388 { 00389 if (isfile) 00390 { 00391 KIO::DeleteJob *job = KIO::del(new_url, HideProgressInfo); 00392 d->connectJob(job); 00393 } 00394 else 00395 { 00396 KIO::SimpleJob *job = KIO::rmdir(new_url); 00397 d->connectSimpleJob(job); 00398 } 00399 00400 d->eventLoop.exec(); 00401 } 00402 else 00403 { 00404 error(KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); 00405 } 00406 } 00407 00408 00410 00411 void ForwardingSlaveBasePrivate::connectJob(KIO::Job *job) 00412 { 00413 // We will forward the warning message, no need to let the job 00414 // display it itself 00415 job->setUiDelegate( 0 ); 00416 00417 // Forward metadata (e.g. modification time for put()) 00418 job->setMetaData( q->allMetaData() ); 00419 #if 0 // debug code 00420 kDebug() << "transferring metadata:"; 00421 const MetaData md = allMetaData(); 00422 for ( MetaData::const_iterator it = md.begin(); it != md.end(); ++it ) 00423 kDebug() << it.key() << " = " << it.data(); 00424 #endif 00425 00426 q->connect( job, SIGNAL( result(KJob *) ), 00427 SLOT( _k_slotResult(KJob *) ) ); 00428 q->connect( job, SIGNAL( warning(KJob *, const QString &, const QString &) ), 00429 SLOT( _k_slotWarning(KJob *, const QString &) ) ); 00430 q->connect( job, SIGNAL( infoMessage(KJob *, const QString &, const QString &) ), 00431 SLOT( _k_slotInfoMessage(KJob *, const QString &) ) ); 00432 q->connect( job, SIGNAL( totalSize(KJob *, qulonglong) ), 00433 SLOT( _k_slotTotalSize(KJob *, qulonglong) ) ); 00434 q->connect( job, SIGNAL( processedSize(KJob *, qulonglong) ), 00435 SLOT( _k_slotProcessedSize(KJob *, qulonglong) ) ); 00436 q->connect( job, SIGNAL( speed(KJob *, unsigned long) ), 00437 SLOT( _k_slotSpeed(KJob *, unsigned long) ) ); 00438 } 00439 00440 void ForwardingSlaveBasePrivate::connectSimpleJob(KIO::SimpleJob *job) 00441 { 00442 connectJob(job); 00443 q->connect( job, SIGNAL( redirection(KIO::Job *, const KUrl &) ), 00444 SLOT( _k_slotRedirection(KIO::Job *, const KUrl &) ) ); 00445 } 00446 00447 void ForwardingSlaveBasePrivate::connectListJob(KIO::ListJob *job) 00448 { 00449 connectSimpleJob(job); 00450 q->connect( job, SIGNAL( entries(KIO::Job *, const KIO::UDSEntryList &) ), 00451 SLOT( _k_slotEntries(KIO::Job *, const KIO::UDSEntryList &) ) ); 00452 } 00453 00454 void ForwardingSlaveBasePrivate::connectTransferJob(KIO::TransferJob *job) 00455 { 00456 connectSimpleJob(job); 00457 q->connect( job, SIGNAL( data(KIO::Job *, const QByteArray &) ), 00458 SLOT( _k_slotData(KIO::Job *, const QByteArray &) ) ); 00459 q->connect( job, SIGNAL( dataReq(KIO::Job *, QByteArray &) ), 00460 SLOT( _k_slotDataReq(KIO::Job *, QByteArray &) ) ); 00461 q->connect( job, SIGNAL( mimetype(KIO::Job *, const QString &) ), 00462 SLOT( _k_slotMimetype(KIO::Job *, const QString &) ) ); 00463 q->connect( job, SIGNAL( canResume(KIO::Job *, KIO::filesize_t) ), 00464 SLOT( _k_slotCanResume(KIO::Job *, KIO::filesize_t) ) ); 00465 } 00466 00468 00469 void ForwardingSlaveBasePrivate::_k_slotResult(KJob *job) 00470 { 00471 if ( job->error() != 0) 00472 { 00473 q->error( job->error(), job->errorText() ); 00474 } 00475 else 00476 { 00477 KIO::StatJob *stat_job = qobject_cast<KIO::StatJob *>(job); 00478 if ( stat_job!=0L ) 00479 { 00480 KIO::UDSEntry entry = stat_job->statResult(); 00481 q->prepareUDSEntry(entry); 00482 q->statEntry( entry ); 00483 } 00484 q->finished(); 00485 } 00486 00487 eventLoop.exit(); 00488 } 00489 00490 void ForwardingSlaveBasePrivate::_k_slotWarning(KJob* /*job*/, const QString &msg) 00491 { 00492 q->warning(msg); 00493 } 00494 00495 void ForwardingSlaveBasePrivate::_k_slotInfoMessage(KJob* /*job*/, const QString &msg) 00496 { 00497 q->infoMessage(msg); 00498 } 00499 00500 void ForwardingSlaveBasePrivate::_k_slotTotalSize(KJob* /*job*/, qulonglong size) 00501 { 00502 q->totalSize(size); 00503 } 00504 00505 void ForwardingSlaveBasePrivate::_k_slotProcessedSize(KJob* /*job*/, qulonglong size) 00506 { 00507 q->processedSize(size); 00508 } 00509 00510 void ForwardingSlaveBasePrivate::_k_slotSpeed(KJob* /*job*/, unsigned long bytesPerSecond) 00511 { 00512 q->speed(bytesPerSecond); 00513 } 00514 00515 void ForwardingSlaveBasePrivate::_k_slotRedirection(KIO::Job *job, const KUrl &url) 00516 { 00517 q->redirection(url); 00518 00519 // We've been redirected stop everything. 00520 job->kill( KJob::Quietly ); 00521 q->finished(); 00522 00523 eventLoop.exit(); 00524 } 00525 00526 void ForwardingSlaveBasePrivate::_k_slotEntries(KIO::Job* /*job*/, 00527 const KIO::UDSEntryList &entries) 00528 { 00529 KIO::UDSEntryList final_entries = entries; 00530 00531 KIO::UDSEntryList::iterator it = final_entries.begin(); 00532 const KIO::UDSEntryList::iterator end = final_entries.end(); 00533 00534 for(; it!=end; ++it) 00535 { 00536 q->prepareUDSEntry(*it, true); 00537 } 00538 00539 q->listEntries( final_entries ); 00540 } 00541 00542 void ForwardingSlaveBasePrivate::_k_slotData(KIO::Job* /*job*/, const QByteArray &_data) 00543 { 00544 q->data(_data); 00545 } 00546 00547 void ForwardingSlaveBasePrivate::_k_slotDataReq(KIO::Job* /*job*/, QByteArray &data) 00548 { 00549 q->dataReq(); 00550 q->readData(data); 00551 } 00552 00553 void ForwardingSlaveBasePrivate::_k_slotMimetype (KIO::Job* /*job*/, const QString &type) 00554 { 00555 q->mimeType(type); 00556 } 00557 00558 void ForwardingSlaveBasePrivate::_k_slotCanResume (KIO::Job* /*job*/, KIO::filesize_t offset) 00559 { 00560 q->canResume(offset); 00561 } 00562 00563 } 00564 00565 #include "forwardingslavebase.moc" 00566
KDE 4.6 API Reference