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 && !offer->name().isEmpty())
00280 ? i18n("Open '%1' using '%2'?").arg(surl).arg(offer->name())
00281 : i18n("Open '%1'?").arg(surl);
00282 } else {
00283 question = (offer && !offer->name().isEmpty())
00284 ? i18n("Open '%1' (%2) using '%3'?").
00285 arg( surl ).arg(suggestedFilename).arg(offer->name())
00286 : i18n("Open '%1' (%2)?").arg( surl ).arg(suggestedFilename);
00287 }
00288 int choice = KMessageBox::questionYesNoCancel(
00289 0L, question, QString::null,
00290 KStdGuiItem::saveAs(), i18n("&Open"),
00291 QString::fromLatin1("askSave")+ mimeType );
00292 return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00293 }
00294
00295 void BrowserRun::save( const KURL & url, const QString & suggestedFilename )
00296 {
00297 simpleSave( url, suggestedFilename );
00298 }
00299
00300
00301 void BrowserRun::simpleSave( const KURL & url, const QString & suggestedFilename )
00302 {
00303
00304
00305
00306 KConfig cfg("konquerorrc", false, false);
00307 cfg.setGroup("HTML Settings");
00308 QString downloadManger = cfg.readPathEntry("DownloadManager");
00309 if (!downloadManger.isEmpty())
00310 {
00311
00312 kdDebug(1000) << "Using: "<<downloadManger <<" as Download Manager" <<endl;
00313 QString cmd=KStandardDirs::findExe(downloadManger);
00314 if (cmd.isEmpty())
00315 {
00316 QString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH ").arg(downloadManger);
00317 QString errMsgEx= i18n("Try to reinstall it \n\nThe integration with Konqueror will be disabled!");
00318 KMessageBox::detailedSorry(0,errMsg,errMsgEx);
00319 cfg.writeEntry("DownloadManager",QString::null);
00320 cfg.sync ();
00321 }
00322 else
00323 {
00324
00325
00326
00327
00328
00329 cmd += " " + KProcess::quote(url.url()) + " " + KProcess::quote(suggestedFilename);
00330 kdDebug(1000) << "Calling command " << cmd << endl;
00331
00332 KIO::Scheduler::publishSlaveOnHold();
00333 KRun::runCommand(cmd);
00334 return;
00335 }
00336 }
00337
00338
00339 KFileDialog *dlg = new KFileDialog( QString::null, QString::null ,
00340 0L , "filedialog", true );
00341 dlg->setOperationMode( KFileDialog::Saving );
00342 dlg->setCaption(i18n("Save As"));
00343
00344 dlg->setSelection( suggestedFilename.isEmpty() ? url.fileName() : suggestedFilename );
00345 if ( dlg->exec() )
00346 {
00347 KURL destURL( dlg->selectedURL() );
00348 if ( !destURL.isMalformed() )
00349 {
00350 KIO::Job *job = KIO::copy( url, destURL );
00351 job->setAutoErrorHandlingEnabled( true );
00352 }
00353 }
00354 delete dlg;
00355 }
00356
00357 void BrowserRun::slotStatResult( KIO::Job *job )
00358 {
00359 if ( job->error() ) {
00360 kdDebug(1000) << "BrowserRun::slotStatResult : " << job->errorString() << endl;
00361 handleError( job );
00362 } else
00363 KRun::slotStatResult( job );
00364 }
00365
00366 void BrowserRun::handleError( KIO::Job * job )
00367 {
00368 if ( !job ) {
00369 kdWarning(1000) << "BrowserRun::handleError called with job=0! hideErrorDialog=" << d->m_bHideErrorDialog << endl;
00370 return;
00371 }
00372
00373
00374
00375 KRun::slotStatResult( job );
00376 }
00377
00378 void BrowserRun::slotCopyToTempFileResult(KIO::Job *job)
00379 {
00380 if ( job->error() ) {
00381 job->showErrorDialog( m_window );
00382 } else {
00383
00384 (void) (KRun::runURL( static_cast<KIO::FileCopyJob *>(job)->destURL(), m_sMimeType ));
00385 }
00386 m_bFault = true;
00387 m_bFinished = true;
00388 m_timer.start( 0, true );
00389 }
00390
00391 bool BrowserRun::isTextExecutable( const QString &serviceType )
00392 {
00393 return ( serviceType == "application/x-desktop" ||
00394 serviceType == "application/x-shellscript" );
00395 }
00396
00397 bool BrowserRun::isExecutable( const QString &serviceType )
00398 {
00399 return ( serviceType == "application/x-desktop" ||
00400 serviceType == "application/x-executable" ||
00401 serviceType == "application/x-msdos-program" ||
00402 serviceType == "application/x-shellscript" );
00403 }
00404
00405 bool BrowserRun::hideErrorDialog() const
00406 {
00407 return d->m_bHideErrorDialog;
00408 }
00409
00410 #include "browserrun.moc"