observer.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 Matej Koss <koss@miesto.sk> 00003 David Faure <faure@kde.org> 00004 00005 $Id$ 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License version 2 as published by the Free Software Foundation. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include <assert.h> 00023 00024 #include <kdebug.h> 00025 #include <tdeapplication.h> 00026 #include <dcopclient.h> 00027 #include <kurl.h> 00028 00029 #include "jobclasses.h" 00030 #include "observer.h" 00031 00032 #include "uiserver_stub.h" 00033 00034 #include "passdlg.h" 00035 #include "slavebase.h" 00036 #include "observer_stub.h" 00037 #include <tdemessagebox.h> 00038 #include <ksslinfodlg.h> 00039 #include <ksslcertdlg.h> 00040 #include <ksslcertificate.h> 00041 #include <ksslcertchain.h> 00042 #include <tdelocale.h> 00043 00044 using namespace TDEIO; 00045 00046 template class TQIntDict<TDEIO::Job>; 00047 00048 Observer * Observer::s_pObserver = 0L; 00049 00050 const int KDEBUG_OBSERVER = 7007; // Should be 7028 00051 00052 Observer::Observer() : DCOPObject("TDEIO::Observer") 00053 { 00054 // Register app as able to receive DCOP messages 00055 if (kapp && !kapp->dcopClient()->isAttached()) 00056 { 00057 kapp->dcopClient()->attach(); 00058 } 00059 00060 if ( !kapp->dcopClient()->isApplicationRegistered( "tdeio_uiserver" ) ) 00061 { 00062 kdDebug(KDEBUG_OBSERVER) << "Starting tdeio_uiserver" << endl; 00063 TQString error; 00064 int ret = TDEApplication::startServiceByDesktopPath( "tdeio_uiserver.desktop", 00065 TQStringList(), &error ); 00066 if ( ret > 0 ) 00067 { 00068 kdError() << "Couldn't start tdeio_uiserver from tdeio_uiserver.desktop: " << error << endl; 00069 } else 00070 kdDebug(KDEBUG_OBSERVER) << "startServiceByDesktopPath returned " << ret << endl; 00071 00072 } 00073 if ( !kapp->dcopClient()->isApplicationRegistered( "tdeio_uiserver" ) ) 00074 kdDebug(KDEBUG_OBSERVER) << "The application tdeio_uiserver is STILL NOT REGISTERED" << endl; 00075 else 00076 kdDebug(KDEBUG_OBSERVER) << "tdeio_uiserver registered" << endl; 00077 00078 m_uiserver = new UIServer_stub( "tdeio_uiserver", "UIServer" ); 00079 } 00080 00081 int Observer::newJob( TDEIO::Job * job, bool showProgress ) 00082 { 00083 // Tell the UI Server about this new job, and give it the application id 00084 // at the same time 00085 int progressId = m_uiserver->newJob( kapp->dcopClient()->appId(), showProgress ); 00086 00087 // Keep the result in a dict 00088 m_dctJobs.insert( progressId, job ); 00089 00090 return progressId; 00091 } 00092 00093 void Observer::jobFinished( int progressId ) 00094 { 00095 m_uiserver->jobFinished( progressId ); 00096 m_dctJobs.remove( progressId ); 00097 } 00098 00099 void Observer::killJob( int progressId ) 00100 { 00101 TDEIO::Job * job = m_dctJobs[ progressId ]; 00102 if (!job) 00103 { 00104 kdWarning() << "Can't find job to kill ! There is no job with progressId=" << progressId << " in this process" << endl; 00105 return; 00106 } 00107 job->kill( false /* not quietly */ ); 00108 } 00109 00110 MetaData Observer::metadata( int progressId ) 00111 { 00112 TDEIO::Job * job = m_dctJobs[ progressId ]; 00113 assert(job); 00114 return job->metaData(); 00115 } 00116 00117 void Observer::slotTotalSize( TDEIO::Job* job, TDEIO::filesize_t size ) 00118 { 00119 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTotalSize " << job << " " << TDEIO::number(size) << endl; 00120 m_uiserver->totalSize64( job->progressId(), size ); 00121 } 00122 00123 void Observer::slotTotalFiles( TDEIO::Job* job, unsigned long files ) 00124 { 00125 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTotalFiles " << job << " " << files << endl; 00126 m_uiserver->totalFiles( job->progressId(), files ); 00127 } 00128 00129 void Observer::slotTotalDirs( TDEIO::Job* job, unsigned long dirs ) 00130 { 00131 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTotalDirs " << job << " " << dirs << endl; 00132 m_uiserver->totalDirs( job->progressId(), dirs ); 00133 } 00134 00135 void Observer::slotProcessedSize( TDEIO::Job* job, TDEIO::filesize_t size ) 00136 { 00137 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotProcessedSize " << job << " " << job->progressId() << " " << TDEIO::number(size) << endl; 00138 m_uiserver->processedSize64( job->progressId(), size ); 00139 } 00140 00141 void Observer::slotProcessedFiles( TDEIO::Job* job, unsigned long files ) 00142 { 00143 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotProcessedFiles " << job << " " << files << endl; 00144 m_uiserver->processedFiles( job->progressId(), files ); 00145 } 00146 00147 void Observer::slotProcessedDirs( TDEIO::Job* job, unsigned long dirs ) 00148 { 00149 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotProcessedDirs " << job << " " << dirs << endl; 00150 m_uiserver->processedDirs( job->progressId(), dirs ); 00151 } 00152 00153 void Observer::slotSpeed( TDEIO::Job* job, unsigned long speed ) 00154 { 00155 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotSpeed " << job << " " << speed << endl; 00156 m_uiserver->speed( job->progressId(), speed ); 00157 } 00158 00159 void Observer::slotPercent( TDEIO::Job* job, unsigned long percent ) 00160 { 00161 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotPercent " << job << " " << percent << endl; 00162 m_uiserver->percent( job->progressId(), percent ); 00163 } 00164 00165 void Observer::slotInfoMessage( TDEIO::Job* job, const TQString & msg ) 00166 { 00167 m_uiserver->infoMessage( job->progressId(), msg ); 00168 } 00169 00170 void Observer::slotCopying( TDEIO::Job* job, const KURL& from, const KURL& to ) 00171 { 00172 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotCopying " << job << " " << from.url() << " " << to.url() << endl; 00173 m_uiserver->copying( job->progressId(), from, to ); 00174 } 00175 00176 void Observer::slotMoving( TDEIO::Job* job, const KURL& from, const KURL& to ) 00177 { 00178 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotMoving " << job << " " << from.url() << " " << to.url() << endl; 00179 m_uiserver->moving( job->progressId(), from, to ); 00180 } 00181 00182 void Observer::slotDeleting( TDEIO::Job* job, const KURL& url ) 00183 { 00184 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotDeleting " << job << " " << url.url() << endl; 00185 m_uiserver->deleting( job->progressId(), url ); 00186 } 00187 00188 void Observer::slotTransferring( TDEIO::Job* job, const KURL& url ) 00189 { 00190 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotTransferring " << job << " " << url.url() << endl; 00191 m_uiserver->transferring( job->progressId(), url ); 00192 } 00193 00194 void Observer::slotCreatingDir( TDEIO::Job* job, const KURL& dir ) 00195 { 00196 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotCreatingDir " << job << " " << dir.url() << endl; 00197 m_uiserver->creatingDir( job->progressId(), dir ); 00198 } 00199 00200 void Observer::slotCanResume( TDEIO::Job* job, TDEIO::filesize_t offset ) 00201 { 00202 //kdDebug(KDEBUG_OBSERVER) << "** Observer::slotCanResume " << job << " " << TDEIO::number(offset) << endl; 00203 m_uiserver->canResume64( job->progressId(), offset ); 00204 } 00205 00206 void Observer::stating( TDEIO::Job* job, const KURL& url ) 00207 { 00208 m_uiserver->stating( job->progressId(), url ); 00209 } 00210 00211 void Observer::mounting( TDEIO::Job* job, const TQString & dev, const TQString & point ) 00212 { 00213 m_uiserver->mounting( job->progressId(), dev, point ); 00214 } 00215 00216 void Observer::unmounting( TDEIO::Job* job, const TQString & point ) 00217 { 00218 m_uiserver->unmounting( job->progressId(), point ); 00219 } 00220 00221 bool Observer::openPassDlg( const TQString& prompt, TQString& user, 00222 TQString& pass, bool readOnly ) 00223 { 00224 AuthInfo info; 00225 info.prompt = prompt; 00226 info.username = user; 00227 info.password = pass; 00228 info.readOnly = readOnly; 00229 bool result = openPassDlg ( info ); 00230 if ( result ) 00231 { 00232 user = info.username; 00233 pass = info.password; 00234 } 00235 return result; 00236 } 00237 00238 bool Observer::openPassDlg( TDEIO::AuthInfo& info ) 00239 { 00240 kdDebug(KDEBUG_OBSERVER) << "Observer::openPassDlg: User= " << info.username 00241 << ", Message= " << info.prompt << endl; 00242 int result = TDEIO::PasswordDialog::getNameAndPassword( info.username, info.password, 00243 &info.keepPassword, info.prompt, 00244 info.readOnly, info.caption, 00245 info.comment, info.commentLabel ); 00246 if ( result == TQDialog::Accepted ) 00247 { 00248 info.setModified( true ); 00249 return true; 00250 } 00251 return false; 00252 } 00253 00254 int Observer::messageBox( int progressId, int type, const TQString &text, 00255 const TQString &caption, const TQString &buttonYes, 00256 const TQString &buttonNo ) 00257 { 00258 return messageBox( progressId, type, text, caption, buttonYes, buttonNo, TQString::null ); 00259 } 00260 00261 int Observer::messageBox( int progressId, int type, const TQString &text, 00262 const TQString &caption, const TQString &buttonYes, 00263 const TQString &buttonNo, const TQString &dontAskAgainName ) 00264 { 00265 kdDebug() << "Observer::messageBox " << type << " " << text << " - " << caption << endl; 00266 int result = -1; 00267 TDEConfig *config = new TDEConfig("tdeioslaverc"); 00268 KMessageBox::setDontShowAskAgainConfig(config); 00269 00270 switch (type) { 00271 case TDEIO::SlaveBase::QuestionYesNo: 00272 result = KMessageBox::questionYesNo( 0L, // parent ? 00273 text, caption, buttonYes, buttonNo, dontAskAgainName ); 00274 break; 00275 case TDEIO::SlaveBase::WarningYesNo: 00276 result = KMessageBox::warningYesNo( 0L, // parent ? 00277 text, caption, buttonYes, buttonNo, dontAskAgainName ); 00278 break; 00279 case TDEIO::SlaveBase::WarningContinueCancel: 00280 result = KMessageBox::warningContinueCancel( 0L, // parent ? 00281 text, caption, buttonYes, dontAskAgainName ); 00282 break; 00283 case TDEIO::SlaveBase::WarningYesNoCancel: 00284 result = KMessageBox::warningYesNoCancel( 0L, // parent ? 00285 text, caption, buttonYes, buttonNo, dontAskAgainName ); 00286 break; 00287 case TDEIO::SlaveBase::Information: 00288 KMessageBox::information( 0L, // parent ? 00289 text, caption, dontAskAgainName ); 00290 result = 1; // whatever 00291 break; 00292 case TDEIO::SlaveBase::SSLMessageBox: 00293 { 00294 TQCString observerAppId = caption.utf8(); // hack, see slaveinterface.cpp 00295 // Contact the object "TDEIO::Observer" in the application <appId> 00296 // Yes, this could be the same application we are, but not necessarily. 00297 Observer_stub observer( observerAppId, "TDEIO::Observer" ); 00298 00299 TDEIO::MetaData meta = observer.metadata( progressId ); 00300 KSSLInfoDlg *kid = new KSSLInfoDlg(meta["ssl_in_use"].upper()=="TRUE", 0L /*parent?*/, 0L, true); 00301 KSSLCertificate *x = KSSLCertificate::fromString(meta["ssl_peer_certificate"].local8Bit()); 00302 if (x) { 00303 // Set the chain back onto the certificate 00304 TQStringList cl = 00305 TQStringList::split(TQString("\n"), meta["ssl_peer_chain"]); 00306 TQPtrList<KSSLCertificate> ncl; 00307 00308 ncl.setAutoDelete(true); 00309 for (TQStringList::Iterator it = cl.begin(); it != cl.end(); ++it) { 00310 KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit()); 00311 if (y) ncl.append(y); 00312 } 00313 00314 if (ncl.count() > 0) 00315 x->chain().setChain(ncl); 00316 00317 kid->setup( x, 00318 meta["ssl_peer_ip"], 00319 text, // the URL 00320 meta["ssl_cipher"], 00321 meta["ssl_cipher_desc"], 00322 meta["ssl_cipher_version"], 00323 meta["ssl_cipher_used_bits"].toInt(), 00324 meta["ssl_cipher_bits"].toInt(), 00325 KSSLCertificate::KSSLValidation(meta["ssl_cert_state"].toInt())); 00326 kdDebug(7024) << "Showing SSL Info dialog" << endl; 00327 kid->exec(); 00328 delete x; 00329 kdDebug(7024) << "SSL Info dialog closed" << endl; 00330 } else { 00331 KMessageBox::information( 0L, // parent ? 00332 i18n("The peer SSL certificate appears to be corrupt."), i18n("SSL") ); 00333 } 00334 // This doesn't have to get deleted. It deletes on it's own. 00335 result = 1; // whatever 00336 break; 00337 } 00338 default: 00339 kdWarning() << "Observer::messageBox: unknown type " << type << endl; 00340 result = 0; 00341 break; 00342 } 00343 KMessageBox::setDontShowAskAgainConfig(0); 00344 delete config; 00345 return result; 00346 #if 0 00347 TQByteArray data, replyData; 00348 TQCString replyType; 00349 TQDataStream arg( data, IO_WriteOnly ); 00350 arg << progressId; 00351 arg << type; 00352 arg << text; 00353 arg << caption; 00354 arg << buttonYes; 00355 arg << buttonNo; 00356 if ( kapp->dcopClient()->call( "tdeio_uiserver", "UIServer", "messageBox(int,int,TQString,TQString,TQString,TQString)", data, replyType, replyData, true ) 00357 && replyType == "int" ) 00358 { 00359 int result; 00360 TQDataStream _reply_stream( replyData, IO_ReadOnly ); 00361 _reply_stream >> result; 00362 kdDebug(KDEBUG_OBSERVER) << "Observer::messageBox got result " << result << endl; 00363 return result; 00364 } 00365 kdDebug(KDEBUG_OBSERVER) << "Observer::messageBox call failed" << endl; 00366 return 0; 00367 #endif 00368 } 00369 00370 RenameDlg_Result Observer::open_RenameDlg( TDEIO::Job* job, 00371 const TQString & caption, 00372 const TQString& src, const TQString & dest, 00373 RenameDlg_Mode mode, TQString& newDest, 00374 TDEIO::filesize_t sizeSrc, 00375 TDEIO::filesize_t sizeDest, 00376 time_t ctimeSrc, 00377 time_t ctimeDest, 00378 time_t mtimeSrc, 00379 time_t mtimeDest 00380 ) 00381 { 00382 kdDebug(KDEBUG_OBSERVER) << "Observer::open_RenameDlg job=" << job << endl; 00383 if (job) 00384 kdDebug(KDEBUG_OBSERVER) << " progressId=" << job->progressId() << endl; 00385 // Hide existing dialog box if any 00386 if (job && job->progressId()) 00387 m_uiserver->setJobVisible( job->progressId(), false ); 00388 // We now do it in process => KDE4: move this code out of Observer (back to job.cpp), so that 00389 // opening the rename dialog doesn't start uiserver for nothing if progressId=0 (e.g. F2 in konq) 00390 RenameDlg_Result res = TDEIO::open_RenameDlg( caption, src, dest, mode, 00391 newDest, sizeSrc, sizeDest, 00392 ctimeSrc, ctimeDest, mtimeSrc, 00393 mtimeDest ); 00394 if (job && job->progressId()) 00395 m_uiserver->setJobVisible( job->progressId(), true ); 00396 return res; 00397 } 00398 00399 SkipDlg_Result Observer::open_SkipDlg( TDEIO::Job* job, 00400 bool _multi, 00401 const TQString& _error_text ) 00402 { 00403 kdDebug(KDEBUG_OBSERVER) << "Observer::open_SkipDlg job=" << job << " progressId=" << job->progressId() << endl; 00404 // Hide existing dialog box if any 00405 if (job && job->progressId()) 00406 m_uiserver->setJobVisible( job->progressId(), false ); 00407 // We now do it in process. So this method is a useless wrapper around TDEIO::open_RenameDlg. 00408 SkipDlg_Result res = TDEIO::open_SkipDlg( _multi, _error_text ); 00409 if (job && job->progressId()) 00410 m_uiserver->setJobVisible( job->progressId(), true ); 00411 return res; 00412 } 00413 00414 void Observer::virtual_hook( int id, void* data ) 00415 { DCOPObject::virtual_hook( id, data ); } 00416 00417 #include "observer.moc"