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