00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "browserrun.h"
00020 #include <kmessagebox.h>
00021 #include <kfiledialog.h>
00022 #include <kio/job.h>
00023 #include <kio/scheduler.h>
00024 #include <klocale.h>
00025 #include <kprocess.h>
00026 #include <kstringhandler.h>
00027 #include <kuserprofile.h>
00028 #include <ktempfile.h>
00029 #include <kdebug.h>
00030 #include <kstandarddirs.h>
00031 #include <assert.h>
00032
00033 using namespace KParts;
00034
00035 class BrowserRun::BrowserRunPrivate
00036 {
00037 public:
00038 bool m_bHideErrorDialog;
00039 };
00040
00041 BrowserRun::BrowserRun( const KURL& url, const KParts::URLArgs& args,
00042 KParts::ReadOnlyPart *part, QWidget* window,
00043 bool removeReferrer, bool trustedSource )
00044 : KRun( url, 0 , false , false ),
00045 m_args( args ), m_part( part ), m_window( window ),
00046 m_bRemoveReferrer( removeReferrer ), m_bTrustedSource( trustedSource )
00047 {
00048 d = new BrowserRunPrivate;
00049 d->m_bHideErrorDialog = false;
00050 }
00051
00052
00053 BrowserRun::BrowserRun( const KURL& url, const KParts::URLArgs& args,
00054 KParts::ReadOnlyPart *part, QWidget* window,
00055 bool removeReferrer, bool trustedSource, bool hideErrorDialog )
00056 : KRun( url, 0 , false , false ),
00057 m_args( args ), m_part( part ), m_window( window ),
00058 m_bRemoveReferrer( removeReferrer ), m_bTrustedSource( trustedSource )
00059 {
00060 d = new BrowserRunPrivate;
00061 d->m_bHideErrorDialog = hideErrorDialog;
00062 }
00063
00064 BrowserRun::~BrowserRun()
00065 {
00066 delete d;
00067 }
00068
00069 void BrowserRun::init()
00070 {
00071 if ( d->m_bHideErrorDialog )
00072 {
00073
00074
00075
00076 m_bFault = !m_strURL.isValid();
00077 if ( !m_bIsLocalFile && !m_bFault && m_strURL.isLocalFile() )
00078 m_bIsLocalFile = true;
00079
00080 if ( m_bIsLocalFile ) {
00081 struct stat buff;
00082 if ( stat( QFile::encodeName(m_strURL.path()), &buff ) == -1 )
00083 {
00084 m_bFault = true;
00085 kdDebug(1000) << "BrowserRun::init : " << m_strURL.prettyURL() << " doesn't exist." << endl;
00086 }
00087 m_mode = buff.st_mode;
00088 }
00089
00090 if ( m_bFault )
00091 {
00092 m_bFinished = true;
00093 m_timer.start( 0, true );
00094 handleError( 0 );
00095 return;
00096 }
00097 }
00098 KRun::init();
00099 }
00100
00101 void BrowserRun::scanFile()
00102 {
00103 kdDebug(1000) << "BrowserRun::scanfile " << m_strURL.prettyURL() << endl;
00104
00105
00106
00107
00108 if ( m_strURL.query().isEmpty() && !m_strURL.protocol().startsWith("http") )
00109 {
00110 KMimeType::Ptr mime = KMimeType::findByURL( m_strURL );
00111 assert( mime != 0L );
00112 if ( mime->name() != "application/octet-stream" || m_bIsLocalFile )
00113 {
00114 kdDebug(1000) << "Scanfile: MIME TYPE is " << mime->name() << endl;
00115 foundMimeType( mime->name() );
00116 return;
00117 }
00118 }
00119
00120 if ( m_part )
00121 {
00122 QString proto = m_part->url().protocol();
00123 if (proto.find("https", 0, false) == 0) {
00124 m_args.metaData().insert("main_frame_request", "TRUE" );
00125 m_args.metaData().insert("ssl_was_in_use", "TRUE" );
00126 m_args.metaData().insert("ssl_activate_warnings", "TRUE" );
00127 } else if (proto.find("http", 0, false) == 0) {
00128 m_args.metaData().insert("ssl_activate_warnings", "TRUE" );
00129 m_args.metaData().insert("ssl_was_in_use", "FALSE" );
00130 }
00131 }
00132
00133 KIO::TransferJob *job;
00134 if ( m_args.doPost() && m_strURL.protocol().startsWith("http"))
00135 {
00136 job = KIO::http_post( m_strURL, m_args.postData, false );
00137 job->addMetaData( "content-type", m_args.contentType() );
00138 }
00139 else
00140 job = KIO::get(m_strURL, m_args.reload, false);
00141
00142 if ( m_bRemoveReferrer )
00143 m_args.metaData().remove("referrer");
00144
00145 job->addMetaData( m_args.metaData() );
00146 job->setWindow( m_window );
00147 connect( job, SIGNAL( result( KIO::Job *)),
00148 this, SLOT( slotBrowserScanFinished(KIO::Job *)));
00149 connect( job, SIGNAL( mimetype( KIO::Job *, const QString &)),
00150 this, SLOT( slotBrowserMimetype(KIO::Job *, const QString &)));
00151 m_job = job;
00152 }
00153
00154 void BrowserRun::slotBrowserScanFinished(KIO::Job *job)
00155 {
00156 kdDebug(1000) << "BrowserRun::slotBrowserScanFinished" << endl;
00157 if ( job->error() == KIO::ERR_IS_DIRECTORY )
00158 {
00159
00160
00161
00162 kdDebug(1000) << "It is in fact a directory!" << endl;
00163
00164 m_strURL = static_cast<KIO::TransferJob *>(job)->url();
00165 m_job = 0;
00166 foundMimeType( "inode/directory" );
00167 }
00168 else
00169 {
00170 if ( job->error() )
00171 handleError( job );
00172 else
00173 KRun::slotScanFinished(job);
00174 }
00175 }
00176
00177 void BrowserRun::slotBrowserMimetype( KIO::Job *_job, const QString &type )
00178 {
00179 Q_ASSERT( _job == m_job );
00180 KIO::TransferJob *job = (KIO::TransferJob *) m_job;
00181
00182
00183
00184 m_strURL = job->url();
00185 kdDebug(1000) << "slotBrowserMimetype: found " << type << " for " << m_strURL.prettyURL() << endl;
00186
00187 m_suggestedFilename = job->queryMetaData("content-disposition");
00188
00189
00190
00191 QString _type = type;
00192 job->putOnHold();
00193 m_job = 0;
00194
00195 foundMimeType( _type );
00196 }
00197
00198 BrowserRun::NonEmbeddableResult BrowserRun::handleNonEmbeddable( const QString& _mimeType )
00199 {
00200 QString mimeType( _mimeType );
00201 Q_ASSERT( !m_bFinished );
00202
00203 if ( mimeType != "inode/directory" &&
00204 !m_strURL.isLocalFile() )
00205 {
00206 if ( isTextExecutable(mimeType) )
00207 mimeType = QString::fromLatin1("text/plain");
00208 kdDebug(1000) << "BrowserRun: ask for saving" << endl;
00209 KService::Ptr offer = KServiceTypeProfile::preferredService(mimeType, "Application");
00210
00211 KParts::BrowserRun::AskSaveResult res = askSave( m_strURL, offer, mimeType, m_suggestedFilename );
00212 if ( res == KParts::BrowserRun::Save ) {
00213 save( m_strURL, m_suggestedFilename );
00214 kdDebug(1000) << "BrowserRun::handleNonEmbeddable: Save: returning Handled" << endl;
00215 m_bFinished = true;
00216 return Handled;
00217 }
00218 else if ( res == KParts::BrowserRun::Cancel ) {
00219
00220 kdDebug(1000) << "BrowserRun::handleNonEmbeddable: Cancel: returning Handled" << endl;
00221 m_bFinished = true;
00222 return Handled;
00223 }
00224 else
00225 {
00226
00227
00228 if ( m_args.doPost() )
00229 {
00230 kdDebug(1000) << "BrowserRun: request comes from a POST, can't pass a URL to another app, need to save" << endl;
00231 m_sMimeType = mimeType;
00232 QString extension;
00233 QString fileName = m_suggestedFilename.isEmpty() ? m_strURL.fileName() : m_suggestedFilename;
00234 int extensionPos = fileName.findRev( '.' );
00235 if ( extensionPos != -1 )
00236 extension = fileName.mid( extensionPos );
00237 KTempFile tempFile( QString::null, extension );
00238 KURL destURL;
00239 destURL.setPath( tempFile.name() );
00240 KIO::Job *job = KIO::file_copy( m_strURL, destURL, 0600, true , false , true );
00241 connect( job, SIGNAL( result( KIO::Job *)),
00242 this, SLOT( slotCopyToTempFileResult(KIO::Job *)) );
00243 return Delayed;
00244 }
00245 }
00246 }
00247
00248
00249 if ( !m_bTrustedSource &&
00250 !allowExecution( mimeType, m_strURL ) )
00251 {
00252 m_bFinished = true;
00253 return Handled;
00254 }
00255
00256 KIO::SimpleJob::removeOnHold();
00257 return NotHandled;
00258 }
00259
00260
00261 bool BrowserRun::allowExecution( const QString &serviceType, const KURL &url )
00262 {
00263 if ( !isExecutable( serviceType ) )
00264 return true;
00265
00266 if ( !url.isLocalFile() )
00267 return false;
00268
00269 return ( KMessageBox::warningYesNo( 0, i18n( "Do you really want to execute '%1'? " ).arg( url.prettyURL() ) ) == KMessageBox::Yes );
00270 }
00271
00272
00273 BrowserRun::AskSaveResult BrowserRun::askSave( const KURL & url, KService::Ptr offer, const QString& mimeType, const QString & suggestedFilename )
00274 {
00275 QString surl = KStringHandler::csqueeze( url.prettyURL() );
00276 QString question;
00277 if ( suggestedFilename.isEmpty() )
00278 {
00279 question = offer ? i18n("Open '%1' using '%2'?").
00280 arg( surl ).arg(offer->name())
00281 : i18n("Open '%1'?").arg( surl );
00282 } else {
00283 question = offer ? i18n("Open '%1' (%2) using '%3'?").
00284 arg( surl ).arg(suggestedFilename).arg(offer->name())
00285 : i18n("Open '%1' (%2)?").arg( surl ).arg(suggestedFilename);
00286 }
00287 int choice = KMessageBox::questionYesNoCancel(
00288 0L, question, QString::null,
00289 KStdGuiItem::saveAs(), i18n("&Open"),
00290 QString::fromLatin1("askSave")+ mimeType );
00291 return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00292 }
00293
00294 void BrowserRun::save( const KURL & url, const QString & suggestedFilename )
00295 {
00296 simpleSave( url, suggestedFilename );
00297 }
00298
00299
00300 void BrowserRun::simpleSave( const KURL & url, const QString & suggestedFilename )
00301 {
00302
00303
00304
00305 KConfig cfg("konquerorrc", false, false);
00306 cfg.setGroup("HTML Settings");
00307 QString downloadManger = cfg.readEntry("DownloadManager");
00308 if (!downloadManger.isEmpty())
00309 {
00310
00311 kdDebug(1000) << "Using: "<<downloadManger <<" as Download Manager" <<endl;
00312 QString cmd=KStandardDirs::findExe(downloadManger);
00313 if (cmd.isEmpty())
00314 {
00315 QString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH ").arg(downloadManger);
00316 QString errMsgEx= i18n("Try to reinstall it \n\nThe integration with Konqueror will be disabled!");
00317 KMessageBox::detailedSorry(0,errMsg,errMsgEx);
00318 cfg.writeEntry("DownloadManager",QString::null);
00319 cfg.sync ();
00320 }
00321 else
00322 {
00323
00324
00325
00326 cmd += " " + KProcess::quote(url.url());
00327 kdDebug(1000) << "Calling command "<<cmd<<endl;
00328
00329 KIO::Scheduler::publishSlaveOnHold();
00330 KRun::runCommand(cmd);
00331 return;
00332 }
00333 }
00334
00335
00336 KFileDialog *dlg = new KFileDialog( QString::null, QString::null ,
00337 0L , "filedialog", true );
00338 dlg->setOperationMode( KFileDialog::Saving );
00339 dlg->setCaption(i18n("Save As"));
00340
00341 dlg->setSelection( suggestedFilename.isEmpty() ? url.fileName() : suggestedFilename );
00342 if ( dlg->exec() )
00343 {
00344 KURL destURL( dlg->selectedURL() );
00345 if ( !destURL.isMalformed() )
00346 {
00347 KIO::Job *job = KIO::copy( url, destURL );
00348 job->setAutoErrorHandlingEnabled( true );
00349 }
00350 }
00351 delete dlg;
00352 }
00353
00354 void BrowserRun::slotStatResult( KIO::Job *job )
00355 {
00356 if ( job->error() ) {
00357 kdDebug(1000) << "BrowserRun::slotStatResult : " << job->errorString() << endl;
00358 handleError( job );
00359 } else
00360 KRun::slotStatResult( job );
00361 }
00362
00363 void BrowserRun::handleError( KIO::Job * job )
00364 {
00365 if ( !job ) {
00366 kdWarning(1000) << "BrowserRun::handleError called with job=0! hideErrorDialog=" << d->m_bHideErrorDialog << endl;
00367 return;
00368 }
00369
00370
00371
00372 KRun::slotStatResult( job );
00373 }
00374
00375 void BrowserRun::slotCopyToTempFileResult(KIO::Job *job)
00376 {
00377 if ( job->error() ) {
00378 job->showErrorDialog( m_window );
00379 } else {
00380
00381 (void) (KRun::runURL( static_cast<KIO::FileCopyJob *>(job)->destURL(), m_sMimeType ));
00382 }
00383 m_bFault = true;
00384 m_bFinished = true;
00385 m_timer.start( 0, true );
00386 }
00387
00388 bool BrowserRun::isTextExecutable( const QString &serviceType )
00389 {
00390 return ( serviceType == "application/x-desktop" ||
00391 serviceType == "application/x-shellscript" );
00392 }
00393
00394 bool BrowserRun::isExecutable( const QString &serviceType )
00395 {
00396 return ( serviceType == "application/x-desktop" ||
00397 serviceType == "application/x-executable" ||
00398 serviceType == "application/x-msdos-program" ||
00399 serviceType == "application/x-shellscript" );
00400 }
00401
00402 bool BrowserRun::hideErrorDialog() const
00403 {
00404 return d->m_bHideErrorDialog;
00405 }
00406
00407 #include "browserrun.moc"