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, window, 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, window, 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
if ( !m_strURL.isValid() ) {
00077 redirectToError( KIO::ERR_MALFORMED_URL, m_strURL.url() );
00078
return;
00079 }
00080
if ( !m_bIsLocalFile && !m_bFault && m_strURL.isLocalFile() )
00081 m_bIsLocalFile =
true;
00082
00083
if ( m_bIsLocalFile ) {
00084
struct stat buff;
00085
if (
stat( QFile::encodeName(m_strURL.path()), &buff ) == -1 )
00086 {
00087
kdDebug(1000) <<
"BrowserRun::init : " << m_strURL.prettyURL() <<
" doesn't exist." <<
endl;
00088 redirectToError( KIO::ERR_DOES_NOT_EXIST, m_strURL.path() );
00089
return;
00090 }
00091 m_mode = buff.st_mode;
00092 }
00093 }
00094
KRun::init();
00095 }
00096
00097
void BrowserRun::scanFile()
00098 {
00099
kdDebug(1000) <<
"BrowserRun::scanfile " << m_strURL.prettyURL() <<
endl;
00100
00101
00102
00103
00104
if ( m_strURL.query().isEmpty() && !m_strURL.protocol().startsWith(
"http") )
00105 {
00106
KMimeType::Ptr mime =
KMimeType::findByURL( m_strURL );
00107 assert( mime != 0L );
00108
if ( mime->name() !=
"application/octet-stream" || m_bIsLocalFile )
00109 {
00110
kdDebug(1000) <<
"Scanfile: MIME TYPE is " << mime->name() <<
endl;
00111 foundMimeType( mime->name() );
00112
return;
00113 }
00114 }
00115
00116
if ( m_part )
00117 {
00118
QString proto = m_part->url().protocol().lower();
00119
00120
if (proto ==
"https" || proto ==
"webdavs") {
00121 m_args.metaData().insert(
"main_frame_request",
"TRUE" );
00122 m_args.metaData().insert(
"ssl_was_in_use",
"TRUE" );
00123 m_args.metaData().insert(
"ssl_activate_warnings",
"TRUE" );
00124 }
else if (proto ==
"http" || proto ==
"webdav") {
00125 m_args.metaData().insert(
"ssl_activate_warnings",
"TRUE" );
00126 m_args.metaData().insert(
"ssl_was_in_use",
"FALSE" );
00127 }
00128
00129
00130
if (!m_args.metaData().contains(
"PropagateHttpHeader"))
00131 m_args.metaData().insert(
"PropagateHttpHeader",
"TRUE");
00132 }
00133
00134
KIO::TransferJob *job;
00135
if ( m_args.doPost() && m_strURL.protocol().startsWith(
"http"))
00136 {
00137 job =
KIO::http_post( m_strURL, m_args.postData,
false );
00138 job->
addMetaData(
"content-type", m_args.contentType() );
00139 }
00140
else
00141 job =
KIO::get(m_strURL, m_args.reload,
false);
00142
00143
if ( m_bRemoveReferrer )
00144 m_args.metaData().remove(
"referrer");
00145
00146 job->
addMetaData( m_args.metaData() );
00147 job->
setWindow( m_window );
00148 connect( job, SIGNAL( result(
KIO::Job *)),
00149
this, SLOT( slotBrowserScanFinished(
KIO::Job *)));
00150 connect( job, SIGNAL(
mimetype(
KIO::Job *,
const QString &)),
00151
this, SLOT( slotBrowserMimetype(
KIO::Job *,
const QString &)));
00152 m_job = job;
00153 }
00154
00155
void BrowserRun::slotBrowserScanFinished(
KIO::Job *job)
00156 {
00157
kdDebug(1000) <<
"BrowserRun::slotBrowserScanFinished" <<
endl;
00158
if ( job->
error() == KIO::ERR_IS_DIRECTORY )
00159 {
00160
00161
00162
00163
kdDebug(1000) <<
"It is in fact a directory!" <<
endl;
00164
00165 m_strURL = static_cast<KIO::TransferJob *>(job)->url();
00166 m_job = 0;
00167 foundMimeType(
"inode/directory" );
00168 }
00169
else
00170 {
00171
if ( job->
error() )
00172 handleError( job );
00173
else
00174
KRun::slotScanFinished(job);
00175 }
00176 }
00177
00178
void BrowserRun::slotBrowserMimetype(
KIO::Job *_job,
const QString &type )
00179 {
00180 Q_ASSERT( _job == m_job );
00181
KIO::TransferJob *job = static_cast<KIO::TransferJob *>(m_job);
00182
00183
00184
00185 m_strURL = job->
url();
00186
kdDebug(1000) <<
"slotBrowserMimetype: found " << type <<
" for " << m_strURL.prettyURL() <<
endl;
00187
00188 m_suggestedFilename = job->
queryMetaData(
"content-disposition");
00189
00190
00191
00192
QString _type = type;
00193 job->
putOnHold();
00194 m_job = 0;
00195
00196 foundMimeType( _type );
00197 }
00198
00199 BrowserRun::NonEmbeddableResult BrowserRun::handleNonEmbeddable(
const QString& _mimeType )
00200 {
00201
QString mimeType( _mimeType );
00202 Q_ASSERT( !m_bFinished );
00203
00204
if ( mimeType !=
"inode/directory" &&
00205 !m_strURL.isLocalFile() )
00206 {
00207
if ( isTextExecutable(mimeType) )
00208 mimeType = QString::fromLatin1(
"text/plain");
00209
kdDebug(1000) <<
"BrowserRun: ask for saving" <<
endl;
00210
KService::Ptr offer =
KServiceTypeProfile::preferredService(mimeType,
"Application");
00211
00212 KParts::BrowserRun::AskSaveResult res = askSave( m_strURL, offer, mimeType, m_suggestedFilename );
00213
if ( res == KParts::BrowserRun::Save ) {
00214
save( m_strURL, m_suggestedFilename );
00215
kdDebug(1000) <<
"BrowserRun::handleNonEmbeddable: Save: returning Handled" <<
endl;
00216 m_bFinished =
true;
00217
return Handled;
00218 }
00219
else if ( res == KParts::BrowserRun::Cancel ) {
00220
00221
kdDebug(1000) <<
"BrowserRun::handleNonEmbeddable: Cancel: returning Handled" <<
endl;
00222 m_bFinished =
true;
00223
return Handled;
00224 }
00225
else
00226 {
00227
00228
00229
if ( m_args.doPost() )
00230 {
00231
kdDebug(1000) <<
"BrowserRun: request comes from a POST, can't pass a URL to another app, need to save" <<
endl;
00232 m_sMimeType = mimeType;
00233
QString extension;
00234
QString fileName = m_suggestedFilename.isEmpty() ? m_strURL.fileName() : m_suggestedFilename;
00235
int extensionPos = fileName.findRev(
'.' );
00236
if ( extensionPos != -1 )
00237 extension = fileName.mid( extensionPos );
00238
KTempFile tempFile( QString::null, extension );
00239
KURL destURL;
00240 destURL.
setPath( tempFile.name() );
00241
KIO::Job *job =
KIO::file_copy( m_strURL, destURL, 0600,
true ,
false ,
true );
00242 job->
setWindow (m_window);
00243 connect( job, SIGNAL( result(
KIO::Job *)),
00244
this, SLOT( slotCopyToTempFileResult(
KIO::Job *)) );
00245
return Delayed;
00246 }
00247 }
00248 }
00249
00250
00251
if ( !m_bTrustedSource &&
00252 !allowExecution( mimeType, m_strURL ) )
00253 {
00254 m_bFinished =
true;
00255
return Handled;
00256 }
00257
00258
KIO::SimpleJob::removeOnHold();
00259
return NotHandled;
00260 }
00261
00262
00263
bool BrowserRun::allowExecution(
const QString &serviceType,
const KURL &url )
00264 {
00265
if ( !isExecutable( serviceType ) )
00266
return true;
00267
00268
if ( !url.
isLocalFile() )
00269
return false;
00270
00271
return (
KMessageBox::warningContinueCancel( 0, i18n(
"Do you really want to execute '%1'? " ).arg( url.
prettyURL() ),
00272 i18n(
"Execute File?"), i18n(
"Execute") ) == KMessageBox::Continue );
00273 }
00274
00275
static QString makeQuestion(
const KURL& url,
const QString& mimeType,
const QString& suggestedFilename )
00276 {
00277
QString surl =
KStringHandler::csqueeze( url.
prettyURL() );
00278
KMimeType::Ptr mime =
KMimeType::mimeType( mimeType );
00279
QString comment = mimeType;
00280
00281
00282
00283
if (mime->name() !=
KMimeType::defaultMimeType()) {
00284
00285 comment = mime->comment();
00286 }
00287
00288
00289
if ( suggestedFilename.isEmpty() )
00290
return i18n(
"Open '%2'?\nType: %1").arg(comment).arg(surl);
00291
else
00292
return i18n(
"Open '%3'?\nName: %2\nType: %1").arg(comment).arg(suggestedFilename).arg(surl);
00293 }
00294
00295
00296 BrowserRun::AskSaveResult BrowserRun::askSave(
const KURL & url,
KService::Ptr offer,
const QString& mimeType,
const QString & suggestedFilename )
00297 {
00298
00299
00300
00301
00302
QString question = makeQuestion( url, mimeType, suggestedFilename );
00303
00304
00305
QString openText = (offer && !offer->name().isEmpty())
00306 ? i18n(
"&Open with '%1'").arg(offer->name())
00307 : i18n(
"&Open With...");
00308
00309
int choice =
KMessageBox::questionYesNoCancel(
00310 0L, question, QString::null,
00311 KStdGuiItem::saveAs(), openText,
00312 QString::fromLatin1(
"askSave")+ mimeType );
00313
00314
return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00315
00316 }
00317
00318
00319 BrowserRun::AskSaveResult BrowserRun::askEmbedOrSave(
const KURL & url,
const QString& mimeType,
const QString & suggestedFilename,
int )
00320 {
00321
00322
00323
00324
00325
KMimeType::Ptr mime =
KMimeType::mimeType( mimeType );
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
if ( mime->is(
"text/html" ) ||
00336 mime->is(
"text/xml" ) ||
00337 mime->is(
"inode/directory" ) ||
00338 mimeType.startsWith(
"image" ) ||
00339 mime->is(
"multipart/x-mixed-replace" ) ||
00340 mime->is(
"multipart/replace" ) ||
00341 mimeType.startsWith(
"print" ) )
00342
return Open;
00343
00344
QString question = makeQuestion( url, mimeType, suggestedFilename );
00345
00346
int choice =
KMessageBox::questionYesNoCancel(
00347 0L, question, QString::null,
00348 KStdGuiItem::saveAs(),
KGuiItem( i18n(
"&Open" ),
"fileopen"),
00349 QString::fromLatin1(
"askEmbedOrSave")+ mimeType );
00350
return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00351
00352 }
00353
00354
00355
void BrowserRun::save(
const KURL & url,
const QString & suggestedFilename )
00356 {
00357 simpleSave( url, suggestedFilename, m_window );
00358 }
00359
00360
00361
void BrowserRun::simpleSave(
const KURL & url,
const QString & suggestedFilename )
00362 {
00363 simpleSave (url, suggestedFilename, 0);
00364 }
00365
00366
void BrowserRun::simpleSave(
const KURL & url,
const QString & suggestedFilename,
00367
QWidget* window )
00368 {
00369
00370
00371
00372
00373
if ( !url.
isLocalFile() )
00374 {
00375
KConfig cfg(
"konquerorrc",
false,
false);
00376 cfg.setGroup(
"HTML Settings");
00377
QString downloadManger = cfg.readPathEntry(
"DownloadManager");
00378
if (!downloadManger.isEmpty())
00379 {
00380
00381
kdDebug(1000) <<
"Using: "<<downloadManger <<
" as Download Manager" <<
endl;
00382
QString cmd=
KStandardDirs::findExe(downloadManger);
00383
if (cmd.isEmpty())
00384 {
00385
QString errMsg=i18n(
"The Download Manager (%1) could not be found in your $PATH ").arg(downloadManger);
00386
QString errMsgEx= i18n(
"Try to reinstall it \n\nThe integration with Konqueror will be disabled!");
00387
KMessageBox::detailedSorry(0,errMsg,errMsgEx);
00388 cfg.writePathEntry(
"DownloadManager",QString::null);
00389 cfg.sync ();
00390 }
00391
else
00392 {
00393
00394
00395
00396
00397 cmd +=
" " +
KProcess::quote(url.
url()) +
" " +
KProcess::quote(suggestedFilename);
00398
kdDebug(1000) <<
"Calling command " << cmd <<
endl;
00399
00400
KIO::Scheduler::publishSlaveOnHold();
00401
KRun::runCommand(cmd);
00402
return;
00403 }
00404 }
00405 }
00406
00407
00408
KFileDialog *dlg =
new KFileDialog( QString::null, QString::null ,
00409 window ,
"filedialog",
true );
00410 dlg->
setOperationMode( KFileDialog::Saving );
00411 dlg->
setCaption(i18n(
"Save As"));
00412
00413 dlg->
setSelection( suggestedFilename.isEmpty() ? url.
fileName() : suggestedFilename );
00414
if ( dlg->exec() )
00415 {
00416
KURL destURL( dlg->
selectedURL() );
00417
if ( destURL.
isValid() )
00418 {
00419
KIO::Job *job =
KIO::copy( url, destURL );
00420 job->
setWindow (window);
00421 job->
setAutoErrorHandlingEnabled(
true );
00422 }
00423 }
00424
delete dlg;
00425 }
00426
00427
void BrowserRun::slotStatResult(
KIO::Job *job )
00428 {
00429
if ( job->
error() ) {
00430
kdDebug(1000) <<
"BrowserRun::slotStatResult : " << job->
errorString() <<
endl;
00431 handleError( job );
00432 }
else
00433
KRun::slotStatResult( job );
00434 }
00435
00436
void BrowserRun::handleError(
KIO::Job * job )
00437 {
00438
if ( !job ) {
00439
kdWarning(1000) <<
"BrowserRun::handleError called with job=0! hideErrorDialog=" << d->m_bHideErrorDialog <<
endl;
00440
return;
00441 }
00442
00443
if (d->m_bHideErrorDialog && job->
error() != KIO::ERR_NO_CONTENT)
00444 {
00445 redirectToError( job->
error(), job->
errorText() );
00446
return;
00447 }
00448
00449
00450
KRun::slotStatResult( job );
00451 }
00452
00453
void BrowserRun::redirectToError(
int error,
const QString& errorText )
00454 {
00465
QString errText( errorText );
00466 errText.replace(
'#',
"%23" );
00467
KURL newURL(
QString(
"error:/?error=%1&errText=%2")
00468 .arg( error ).arg( errText ), 106 );
00469 m_strURL.setPass( QString::null );
00470
00471
KURL::List lst;
00472 lst << newURL << m_strURL;
00473 m_strURL =
KURL::join( lst );
00474
00475
00476 m_job = 0;
00477 foundMimeType(
"text/html" );
00478 }
00479
00480
void BrowserRun::slotCopyToTempFileResult(
KIO::Job *job)
00481 {
00482
if ( job->
error() ) {
00483 job->
showErrorDialog( m_window );
00484 }
else {
00485
00486 (
void) (
KRun::runURL( static_cast<KIO::FileCopyJob *>(job)->destURL(), m_sMimeType ));
00487 }
00488 m_bFault =
true;
00489 m_bFinished =
true;
00490 m_timer.start( 0,
true );
00491 }
00492
00493
bool BrowserRun::isTextExecutable(
const QString &serviceType )
00494 {
00495
return ( serviceType ==
"application/x-desktop" ||
00496 serviceType ==
"application/x-shellscript" );
00497 }
00498
00499
bool BrowserRun::isExecutable(
const QString &serviceType )
00500 {
00501
return KRun::isExecutable( serviceType );
00502 }
00503
00504
bool BrowserRun::hideErrorDialog()
const
00505
{
00506
return d->m_bHideErrorDialog;
00507 }
00508
00509
#include "browserrun.moc"