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::warningYesNo( 0, i18n(
"Do you really want to execute '%1'? " ).arg( url.
prettyURL() ) ) == KMessageBox::Yes );
00272 }
00273
00274
static QString makeQuestion(
const KURL& url,
const QString& mimeType,
const QString& suggestedFilename )
00275 {
00276
QString surl =
KStringHandler::csqueeze( url.
prettyURL() );
00277
KMimeType::Ptr mime =
KMimeType::mimeType( mimeType );
00278
QString comment = mimeType;
00279
00280
00281
00282
if (mime->name() !=
KMimeType::defaultMimeType()) {
00283
00284 comment = mime->comment();
00285 }
00286
00287
00288
if ( suggestedFilename.
isEmpty() )
00289
return i18n(
"Open '%2'?\nType: %1").arg(comment).arg(surl);
00290
else
00291
return i18n(
"Open '%3'?\nName: %2\nType: %1").arg(comment).arg(suggestedFilename).arg(surl);
00292 }
00293
00294
00295 BrowserRun::AskSaveResult BrowserRun::askSave(
const KURL & url,
KService::Ptr offer,
const QString& mimeType,
const QString & suggestedFilename )
00296 {
00297
QString question = makeQuestion( url, mimeType, suggestedFilename );
00298
00299
00300
QString openText = (offer && !offer->name().isEmpty())
00301 ? i18n(
"&Open with '%1'").arg(offer->name())
00302 : i18n(
"&Open with...");
00303
00304
int choice =
KMessageBox::questionYesNoCancel(
00305 0L, question, QString::null,
00306 KStdGuiItem::saveAs(), openText,
00307 QString::fromLatin1(
"askSave")+ mimeType );
00308
return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00309 }
00310
00311
00312 BrowserRun::AskSaveResult BrowserRun::askEmbedOrSave(
const KURL & url,
const QString& mimeType,
const QString & suggestedFilename,
int )
00313 {
00314
KMimeType::Ptr mime =
KMimeType::mimeType( mimeType );
00315
00316
00317
00318
00319
00320
00321
00322
00323
if ( mime->is(
"text/html" ) ||
00324 mime->is(
"text/xml" ) ||
00325 mime->is(
"inode/directory" ) ||
00326 mimeType.
startsWith(
"image" ) ||
00327 mime->is(
"multipart/x-mixed-replace" ) ||
00328 mime->is(
"multipart/replace" ) ||
00329 mimeType.
startsWith(
"print" ) )
00330
return Open;
00331
00332
QString question = makeQuestion( url, mimeType, suggestedFilename );
00333
00334
int choice =
KMessageBox::questionYesNoCancel(
00335 0L, question, QString::null,
00336 KStdGuiItem::saveAs(), KGuiItem( i18n(
"&Open" ),
"fileopen"),
00337 QString::fromLatin1(
"askEmbedOrSave")+ mimeType );
00338
return choice == KMessageBox::Yes ? Save : ( choice == KMessageBox::No ? Open : Cancel );
00339 }
00340
00341
00342
void BrowserRun::save(
const KURL & url,
const QString & suggestedFilename )
00343 {
00344 simpleSave( url, suggestedFilename, m_window );
00345 }
00346
00347
00348
void BrowserRun::simpleSave(
const KURL & url,
const QString & suggestedFilename )
00349 {
00350 simpleSave (url, suggestedFilename, 0);
00351 }
00352
00353
void BrowserRun::simpleSave(
const KURL & url,
const QString & suggestedFilename,
00354
QWidget* window )
00355 {
00356
00357
00358
00359
KConfig cfg(
"konquerorrc",
false,
false);
00360 cfg.
setGroup(
"HTML Settings");
00361
QString downloadManger = cfg.
readPathEntry(
"DownloadManager");
00362
if (!downloadManger.
isEmpty())
00363 {
00364
00365
kdDebug(1000) <<
"Using: "<<downloadManger <<
" as Download Manager" <<
endl;
00366
QString cmd=
KStandardDirs::findExe(downloadManger);
00367
if (cmd.
isEmpty())
00368 {
00369
QString errMsg=i18n(
"The Download Manager (%1) could not be found in your $PATH ").arg(downloadManger);
00370
QString errMsgEx= i18n(
"Try to reinstall it \n\nThe integration with Konqueror will be disabled!");
00371
KMessageBox::detailedSorry(0,errMsg,errMsgEx);
00372 cfg.
writePathEntry(
"DownloadManager",QString::null);
00373 cfg.
sync ();
00374 }
00375
else
00376 {
00377
00378
00379
00380
00381 cmd +=
" " +
KProcess::quote(url.
url()) +
" " +
KProcess::quote(suggestedFilename);
00382
kdDebug(1000) <<
"Calling command " << cmd <<
endl;
00383
00384
KIO::Scheduler::publishSlaveOnHold();
00385
KRun::runCommand(cmd);
00386
return;
00387 }
00388 }
00389
00390
00391
KFileDialog *dlg =
new KFileDialog( QString::null, QString::null ,
00392 window ,
"filedialog",
true );
00393 dlg->
setOperationMode( KFileDialog::Saving );
00394 dlg->
setCaption(i18n(
"Save As"));
00395
00396 dlg->
setSelection( suggestedFilename.
isEmpty() ? url.
fileName() : suggestedFilename );
00397
if ( dlg->
exec() )
00398 {
00399
KURL destURL( dlg->
selectedURL() );
00400
if ( destURL.
isValid() )
00401 {
00402
KIO::Job *job =
KIO::copy( url, destURL );
00403 job->
setWindow (window);
00404 job->
setAutoErrorHandlingEnabled(
true );
00405 }
00406 }
00407
delete dlg;
00408 }
00409
00410
void BrowserRun::slotStatResult(
KIO::Job *job )
00411 {
00412
if ( job->
error() ) {
00413
kdDebug(1000) <<
"BrowserRun::slotStatResult : " << job->
errorString() <<
endl;
00414 handleError( job );
00415 }
else
00416
KRun::slotStatResult( job );
00417 }
00418
00419
void BrowserRun::handleError(
KIO::Job * job )
00420 {
00421
if ( !job ) {
00422
kdWarning(1000) <<
"BrowserRun::handleError called with job=0! hideErrorDialog=" << d->m_bHideErrorDialog <<
endl;
00423
return;
00424 }
00425
00426
if (d->m_bHideErrorDialog && job->
error() != KIO::ERR_NO_CONTENT)
00427 {
00428 redirectToError( job->
error(), job->
errorText() );
00429
return;
00430 }
00431
00432
00433
KRun::slotStatResult( job );
00434 }
00435
00436
void BrowserRun::redirectToError(
int error,
const QString& errorText )
00437 {
00448
QString errText( errorText );
00449 errText.
replace(
'#',
"%23" );
00450
KURL newURL(
QString(
"error:/?error=%1&errText=%2")
00451 .arg( error ).arg( errText ), 106 );
00452 m_strURL.setPass( QString::null );
00453
00454
KURL::List lst;
00455 lst << newURL << m_strURL;
00456 m_strURL =
KURL::join( lst );
00457
00458
00459 m_job = 0;
00460 foundMimeType(
"text/html" );
00461 }
00462
00463
void BrowserRun::slotCopyToTempFileResult(
KIO::Job *job)
00464 {
00465
if ( job->
error() ) {
00466 job->
showErrorDialog( m_window );
00467 }
else {
00468
00469 (
void) (
KRun::runURL( static_cast<KIO::FileCopyJob *>(job)->destURL(), m_sMimeType ));
00470 }
00471 m_bFault =
true;
00472 m_bFinished =
true;
00473 m_timer.start( 0,
true );
00474 }
00475
00476
bool BrowserRun::isTextExecutable(
const QString &serviceType )
00477 {
00478
return ( serviceType ==
"application/x-desktop" ||
00479 serviceType ==
"application/x-shellscript" );
00480 }
00481
00482
bool BrowserRun::isExecutable(
const QString &serviceType )
00483 {
00484
return KRun::isExecutable( serviceType );
00485 }
00486
00487
bool BrowserRun::hideErrorDialog()
const
00488
{
00489
return d->m_bHideErrorDialog;
00490 }
00491
00492
#include "browserrun.moc"