1 | /* This file is part of the KDE project |
2 | * |
3 | * Copyright (C) 2002 David Faure <faure@kde.org> |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Library General Public |
6 | * License version 2, as published by the Free Software Foundation. |
7 | * |
8 | * This library is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | * Library General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU Library General Public License |
14 | * along with this library; see the file COPYING.LIB. If not, write to |
15 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
16 | * Boston, MA 02110-1301, USA. |
17 | */ |
18 | |
19 | #include "browserrun.h" |
20 | #include "browserrun_p.h" |
21 | |
22 | #include <kmessagebox.h> |
23 | #include <kfiledialog.h> |
24 | #include <kio/job.h> |
25 | #include <kio/jobuidelegate.h> |
26 | #include <kio/scheduler.h> |
27 | #include <kio/copyjob.h> |
28 | #include <klocale.h> |
29 | #include <kshell.h> |
30 | #include <kstringhandler.h> |
31 | #include <kmimetypetrader.h> |
32 | #include <ktemporaryfile.h> |
33 | #include <kdebug.h> |
34 | #include <kde_file.h> |
35 | #include <kstandarddirs.h> |
36 | #include <kdatetime.h> |
37 | #include "browseropenorsavequestion.h" |
38 | #include <kprotocolmanager.h> |
39 | |
40 | using namespace KParts; |
41 | |
42 | class BrowserRun::BrowserRunPrivate |
43 | { |
44 | public: |
45 | bool m_bHideErrorDialog; |
46 | bool m_bRemoveReferrer; |
47 | bool m_bTrustedSource; |
48 | KParts::OpenUrlArguments m_args; |
49 | KParts::BrowserArguments m_browserArgs; |
50 | |
51 | KParts::ReadOnlyPart *m_part; // QGuardedPtr? |
52 | QPointer<QWidget> m_window; |
53 | QString m_mimeType; |
54 | QString m_contentDisposition; |
55 | }; |
56 | |
57 | BrowserRun::BrowserRun( const KUrl& url, const KParts::OpenUrlArguments& args, |
58 | const KParts::BrowserArguments& browserArgs, |
59 | KParts::ReadOnlyPart *part, QWidget* window, |
60 | bool removeReferrer, bool trustedSource, bool hideErrorDialog ) |
61 | : KRun( url, window, 0 /*mode*/, false /*is_local_file known*/, false /* no GUI */ ), |
62 | d(new BrowserRunPrivate) |
63 | { |
64 | d->m_bHideErrorDialog = hideErrorDialog; |
65 | d->m_bRemoveReferrer = removeReferrer; |
66 | d->m_bTrustedSource = trustedSource; |
67 | d->m_args = args; |
68 | d->m_browserArgs = browserArgs; |
69 | d->m_part = part; |
70 | d->m_window = window; |
71 | } |
72 | |
73 | BrowserRun::~BrowserRun() |
74 | { |
75 | delete d; |
76 | } |
77 | |
78 | KParts::ReadOnlyPart* BrowserRun::part() const |
79 | { |
80 | return d->m_part; |
81 | } |
82 | |
83 | KUrl BrowserRun::url() const |
84 | { |
85 | return KRun::url(); |
86 | } |
87 | |
88 | void BrowserRun::init() |
89 | { |
90 | if ( d->m_bHideErrorDialog ) |
91 | { |
92 | // ### KRun doesn't call a virtual method when it finds out that the URL |
93 | // is either malformed, or points to a non-existing local file... |
94 | // So we need to reimplement some of the checks, to handle d->m_bHideErrorDialog |
95 | if ( !KRun::url().isValid() ) { |
96 | redirectToError( KIO::ERR_MALFORMED_URL, KRun::url().url() ); |
97 | return; |
98 | } |
99 | if ( !isLocalFile() && !hasError() && KRun::url().isLocalFile() ) |
100 | setIsLocalFile( true ); |
101 | |
102 | if ( isLocalFile() ) { |
103 | KDE_struct_stat buff; |
104 | if ( KDE::stat( KRun::url().toLocalFile(), &buff ) == -1 ) |
105 | { |
106 | kDebug(1000) << KRun::url().toLocalFile() << "doesn't exist." ; |
107 | redirectToError( KIO::ERR_DOES_NOT_EXIST, KRun::url().toLocalFile() ); |
108 | return; |
109 | } |
110 | setMode( buff.st_mode ); // while we're at it, save it for KRun::init() to use it |
111 | } |
112 | } |
113 | KRun::init(); |
114 | } |
115 | |
116 | void BrowserRun::scanFile() |
117 | { |
118 | kDebug(1000) << KRun::url(); |
119 | |
120 | // Let's check for well-known extensions |
121 | // Not when there is a query in the URL, in any case. |
122 | // Optimization for http/https, findByURL doesn't trust extensions over http. |
123 | QString protocol = KRun::url().protocol(); |
124 | |
125 | if (!KProtocolInfo::proxiedBy(protocol).isEmpty()) { |
126 | QString dummy; |
127 | protocol = KProtocolManager::slaveProtocol(KRun::url(), dummy); |
128 | } |
129 | |
130 | if ( KRun::url().query().isEmpty() && !protocol.startsWith(QLatin1String("http" ))) |
131 | { |
132 | KMimeType::Ptr mime = KMimeType::findByUrl( KRun::url() ); |
133 | Q_ASSERT( mime ); |
134 | if ( !mime->isDefault() || isLocalFile() ) |
135 | { |
136 | kDebug(1000) << "MIME TYPE is" << mime->name(); |
137 | mimeTypeDetermined( mime->name() ); |
138 | return; |
139 | } |
140 | } |
141 | |
142 | QMap<QString, QString>& metaData = d->m_args.metaData(); |
143 | if ( d->m_part ) { |
144 | const QString proto = d->m_part->url().protocol(); |
145 | |
146 | if (proto == "https" || proto == "webdavs" ) { |
147 | metaData.insert("main_frame_request" , "TRUE" ); |
148 | metaData.insert("ssl_was_in_use" , "TRUE" ); |
149 | // metaData.insert("ssl_activate_warnings", "TRUE" ); |
150 | } else if (proto == "http" || proto == "webdav" ) { |
151 | // metaData.insert("ssl_activate_warnings", "TRUE" ); |
152 | metaData.insert("ssl_was_in_use" , "FALSE" ); |
153 | } |
154 | |
155 | // Set the PropagateHttpHeader meta-data if it has not already been set... |
156 | if (!metaData.contains("PropagateHttpHeader" )) |
157 | metaData.insert("PropagateHttpHeader" , "TRUE" ); |
158 | } |
159 | |
160 | KIO::TransferJob *job; |
161 | if ( d->m_browserArgs.doPost() && KRun::url().protocol().startsWith(QLatin1String("http" ))) { |
162 | job = KIO::http_post( KRun::url(), d->m_browserArgs.postData, KIO::HideProgressInfo ); |
163 | job->addMetaData( "content-type" , d->m_browserArgs.contentType() ); |
164 | } else { |
165 | job = KIO::get(KRun::url(), |
166 | d->m_args.reload() ? KIO::Reload : KIO::NoReload, |
167 | KIO::HideProgressInfo); |
168 | } |
169 | |
170 | if ( d->m_bRemoveReferrer ) |
171 | metaData.remove("referrer" ); |
172 | |
173 | job->addMetaData( metaData ); |
174 | job->ui()->setWindow( d->m_window ); |
175 | connect( job, SIGNAL(result(KJob*)), |
176 | this, SLOT(slotBrowserScanFinished(KJob*))); |
177 | connect( job, SIGNAL(mimetype(KIO::Job*,QString)), |
178 | this, SLOT(slotBrowserMimetype(KIO::Job*,QString))); |
179 | setJob( job ); |
180 | } |
181 | |
182 | void BrowserRun::slotBrowserScanFinished(KJob *job) |
183 | { |
184 | kDebug(1000) << job->error(); |
185 | if ( job->error() == KIO::ERR_IS_DIRECTORY ) |
186 | { |
187 | // It is in fact a directory. This happens when HTTP redirects to FTP. |
188 | // Due to the "protocol doesn't support listing" code in BrowserRun, we |
189 | // assumed it was a file. |
190 | kDebug(1000) << "It is in fact a directory!" ; |
191 | // Update our URL in case of a redirection |
192 | KRun::setUrl( static_cast<KIO::TransferJob *>(job)->url() ); |
193 | setJob( 0 ); |
194 | mimeTypeDetermined( "inode/directory" ); |
195 | } |
196 | else |
197 | { |
198 | if ( job->error() ) |
199 | handleError( job ); |
200 | else |
201 | KRun::slotScanFinished(job); |
202 | } |
203 | } |
204 | |
205 | static KMimeType::Ptr fixupMimeType (const QString& mimeType, const QString& fileName) |
206 | { |
207 | KMimeType::Ptr mime = KMimeType::mimeType(mimeType); |
208 | if ((!mime || mime->isDefault()) && !fileName.isEmpty()) { |
209 | mime = KMimeType::findByUrl(fileName, 0, false, true); |
210 | } |
211 | return mime; |
212 | } |
213 | |
214 | void BrowserRun::slotBrowserMimetype( KIO::Job *_job, const QString &type ) |
215 | { |
216 | Q_ASSERT( _job == KRun::job() ); Q_UNUSED(_job) |
217 | KIO::TransferJob *job = static_cast<KIO::TransferJob *>(KRun::job()); |
218 | // Update our URL in case of a redirection |
219 | //kDebug(1000) << "old URL=" << KRun::url(); |
220 | //kDebug(1000) << "new URL=" << job->url(); |
221 | setUrl( job->url() ); |
222 | |
223 | if (job->isErrorPage()) { |
224 | d->m_mimeType = type; |
225 | handleError(job); |
226 | setJob( 0 ); |
227 | } else { |
228 | kDebug(1000) << "found" << type << "for" << KRun::url(); |
229 | |
230 | // Suggested filename given by the server (e.g. HTTP content-disposition) |
231 | // When set, we should really be saving instead of embedding |
232 | const QString suggestedFileName = job->queryMetaData("content-disposition-filename" ); |
233 | setSuggestedFileName(suggestedFileName); // store it (in KRun) |
234 | //kDebug(1000) << "suggestedFileName=" << suggestedFileName; |
235 | d->m_contentDisposition = job->queryMetaData("content-disposition-type" ); |
236 | |
237 | const QString modificationTime = job->queryMetaData("content-disposition-modification-date" ); |
238 | if (!modificationTime.isEmpty()) { |
239 | d->m_args.metaData().insert(QLatin1String("content-disposition-modification-date" ), modificationTime); |
240 | } |
241 | |
242 | QMapIterator<QString,QString> it (job->metaData()); |
243 | while (it.hasNext()) { |
244 | it.next(); |
245 | if (it.key().startsWith(QLatin1String("ssl_" ), Qt::CaseInsensitive)) |
246 | d->m_args.metaData().insert(it.key(), it.value()); |
247 | } |
248 | |
249 | // Make a copy to avoid a dead reference |
250 | QString _type = type; |
251 | job->putOnHold(); |
252 | setJob( 0 ); |
253 | |
254 | // If the current mime-type is the default mime-type, then attempt to |
255 | // determine the "real" mimetype from the file name. |
256 | KMimeType::Ptr mimePtr = fixupMimeType(_type, suggestedFileName.isEmpty() ? url().fileName() : suggestedFileName); |
257 | if (mimePtr && mimePtr->name() != _type) { |
258 | _type = mimePtr->name(); |
259 | } |
260 | |
261 | mimeTypeDetermined( _type ); |
262 | } |
263 | } |
264 | |
265 | BrowserRun::NonEmbeddableResult BrowserRun::handleNonEmbeddable(const QString& mimeType) |
266 | { |
267 | return handleNonEmbeddable(mimeType, NULL); |
268 | } |
269 | |
270 | BrowserRun::NonEmbeddableResult BrowserRun::handleNonEmbeddable(const QString& _mimeType, KService::Ptr* selectedService) |
271 | { |
272 | QString mimeType( _mimeType ); |
273 | Q_ASSERT( !hasFinished() ); // only come here if the mimetype couldn't be embedded |
274 | // Support for saving remote files. |
275 | if ( mimeType != "inode/directory" && // dirs can't be saved |
276 | !KRun::url().isLocalFile() ) |
277 | { |
278 | if ( isTextExecutable(mimeType) ) |
279 | mimeType = QLatin1String("text/plain" ); // view, don't execute |
280 | // ... -> ask whether to save |
281 | BrowserOpenOrSaveQuestion question(d->m_window, KRun::url(), mimeType); |
282 | question.setSuggestedFileName(suggestedFileName()); |
283 | if (selectedService) |
284 | question.setFeatures(BrowserOpenOrSaveQuestion::ServiceSelection); |
285 | BrowserOpenOrSaveQuestion::Result res = question.askOpenOrSave(); |
286 | if (res == BrowserOpenOrSaveQuestion::Save) { |
287 | save( KRun::url(), suggestedFileName() ); |
288 | kDebug(1000) << "Save: returning Handled" ; |
289 | setFinished( true ); |
290 | return Handled; |
291 | } |
292 | else if (res == BrowserOpenOrSaveQuestion::Cancel) { |
293 | // saving done or canceled |
294 | kDebug(1000) << "Cancel: returning Handled" ; |
295 | setFinished( true ); |
296 | return Handled; |
297 | } |
298 | else // "Open" chosen (done by KRun::foundMimeType, called when returning NotHandled) |
299 | { |
300 | // If we were in a POST, we can't just pass a URL to an external application. |
301 | // We must save the data to a tempfile first. |
302 | if ( d->m_browserArgs.doPost() ) |
303 | { |
304 | kDebug(1000) << "request comes from a POST, can't pass a URL to another app, need to save" ; |
305 | d->m_mimeType = mimeType; |
306 | QString extension; |
307 | QString fileName = suggestedFileName().isEmpty() ? KRun::url().fileName() : suggestedFileName(); |
308 | int extensionPos = fileName.lastIndexOf( '.' ); |
309 | if ( extensionPos != -1 ) |
310 | extension = fileName.mid( extensionPos ); // keep the '.' |
311 | KTemporaryFile tempFile; |
312 | tempFile.setSuffix(extension); |
313 | tempFile.setAutoRemove(false); |
314 | tempFile.open(); |
315 | KUrl destURL; |
316 | destURL.setPath( tempFile.fileName() ); |
317 | KIO::Job *job = KIO::file_copy( KRun::url(), destURL, 0600, KIO::Overwrite ); |
318 | job->ui()->setWindow(d->m_window); |
319 | connect( job, SIGNAL(result(KJob*)), |
320 | this, SLOT(slotCopyToTempFileResult(KJob*)) ); |
321 | return Delayed; // We'll continue after the job has finished |
322 | } |
323 | if (selectedService && question.selectedService()) { |
324 | *selectedService = question.selectedService(); |
325 | // KRun will use this when starting an app |
326 | KRun::setPreferredService(question.selectedService()->desktopEntryName()); |
327 | } |
328 | } |
329 | } |
330 | |
331 | // Check if running is allowed |
332 | if ( !d->m_bTrustedSource && // ... and untrusted source... |
333 | !allowExecution( mimeType, KRun::url() ) ) // ...and the user said no (for executables etc.) |
334 | { |
335 | setFinished( true ); |
336 | return Handled; |
337 | } |
338 | |
339 | KIO::Scheduler::publishSlaveOnHold(); // publish any slave on hold so it can be reused. |
340 | return NotHandled; |
341 | } |
342 | |
343 | //static |
344 | bool BrowserRun::allowExecution( const QString &mimeType, const KUrl &url ) |
345 | { |
346 | if ( !KRun::isExecutable( mimeType ) ) |
347 | return true; |
348 | |
349 | if ( !url.isLocalFile() ) // Don't permit to execute remote files |
350 | return false; |
351 | |
352 | return ( KMessageBox::warningContinueCancel( 0, |
353 | i18n( "Do you really want to execute '%1'?" , url.prettyUrl() ), |
354 | i18n("Execute File?" ), KGuiItem(i18n("Execute" )) ) == KMessageBox::Continue ); |
355 | } |
356 | |
357 | //static, deprecated |
358 | #ifndef KDE_NO_DEPRECATED |
359 | BrowserRun::AskSaveResult BrowserRun::askSave( const KUrl & url, KService::Ptr offer, const QString& mimeType, const QString & suggestedFileName ) |
360 | { |
361 | Q_UNUSED(offer); |
362 | BrowserOpenOrSaveQuestion question(0, url, mimeType); |
363 | question.setSuggestedFileName(suggestedFileName); |
364 | const BrowserOpenOrSaveQuestion::Result result = question.askOpenOrSave(); |
365 | return result == BrowserOpenOrSaveQuestion::Save ? Save |
366 | : BrowserOpenOrSaveQuestion::Open ? Open |
367 | : Cancel; |
368 | } |
369 | #endif |
370 | |
371 | //static, deprecated |
372 | #ifndef KDE_NO_DEPRECATED |
373 | BrowserRun::AskSaveResult BrowserRun::askEmbedOrSave( const KUrl & url, const QString& mimeType, const QString & suggestedFileName, int flags ) |
374 | { |
375 | BrowserOpenOrSaveQuestion question(0, url, mimeType); |
376 | question.setSuggestedFileName(suggestedFileName); |
377 | const BrowserOpenOrSaveQuestion::Result result = question.askEmbedOrSave(flags); |
378 | return result == BrowserOpenOrSaveQuestion::Save ? Save |
379 | : BrowserOpenOrSaveQuestion::Embed ? Open |
380 | : Cancel; |
381 | } |
382 | #endif |
383 | |
384 | // Default implementation, overridden in KHTMLRun |
385 | void BrowserRun::save( const KUrl & url, const QString & suggestedFileName ) |
386 | { |
387 | saveUrl(url, suggestedFileName, d->m_window, d->m_args); |
388 | } |
389 | |
390 | // static |
391 | void BrowserRun::simpleSave( const KUrl & url, const QString & suggestedFileName, |
392 | QWidget* window ) |
393 | { |
394 | saveUrl(url, suggestedFileName, window, KParts::OpenUrlArguments()); |
395 | } |
396 | |
397 | void KParts::BrowserRun::saveUrl(const KUrl & url, const QString & suggestedFileName, |
398 | QWidget* window, const KParts::OpenUrlArguments& args) |
399 | { |
400 | // DownloadManager <-> konqueror integration |
401 | // find if the integration is enabled |
402 | // the empty key means no integration |
403 | // only use the downloadmanager for non-local urls |
404 | if ( !url.isLocalFile() ) |
405 | { |
406 | KConfigGroup cfg = KSharedConfig::openConfig("konquerorrc" , KConfig::NoGlobals)->group("HTML Settings" ); |
407 | QString downloadManger = cfg.readPathEntry("DownloadManager" , QString()); |
408 | if (!downloadManger.isEmpty()) |
409 | { |
410 | // then find the download manager location |
411 | kDebug(1000) << "Using: " <<downloadManger <<" as Download Manager" ; |
412 | QString cmd=KStandardDirs::findExe(downloadManger); |
413 | if (cmd.isEmpty()) |
414 | { |
415 | QString errMsg=i18n("The Download Manager (%1) could not be found in your $PATH " , downloadManger); |
416 | QString errMsgEx= i18n("Try to reinstall it \n\nThe integration with Konqueror will be disabled." ); |
417 | KMessageBox::detailedSorry(0,errMsg,errMsgEx); |
418 | cfg.writePathEntry("DownloadManager" ,QString()); |
419 | cfg.sync (); |
420 | } |
421 | else |
422 | { |
423 | // ### suggestedFileName not taken into account. Fix this (and |
424 | // the duplicated code) with shiny new KDownload class for 3.2 (pfeiffer) |
425 | // Until the shiny new class comes about, send the suggestedFileName |
426 | // along with the actual URL to download. (DA) |
427 | cmd += ' ' + KShell::quoteArg(url.url()); |
428 | if ( !suggestedFileName.isEmpty() ) |
429 | cmd += ' ' + KShell::quoteArg(suggestedFileName); |
430 | |
431 | kDebug(1000) << "Calling command" << cmd; |
432 | // slave is already on hold (slotBrowserMimetype()) |
433 | KIO::Scheduler::publishSlaveOnHold(); |
434 | KRun::runCommand(cmd, window); |
435 | return; |
436 | } |
437 | } |
438 | } |
439 | |
440 | // no download manager available, let's do it ourself |
441 | KFileDialog *dlg = new KFileDialog( QString(), QString() /*all files*/, |
442 | window); |
443 | dlg->setOperationMode( KFileDialog::Saving ); |
444 | dlg->setCaption(i18n("Save As" )); |
445 | dlg->setConfirmOverwrite(true); |
446 | |
447 | QString name; |
448 | if ( !suggestedFileName.isEmpty() ) |
449 | name = suggestedFileName; |
450 | else |
451 | name = url.fileName(KUrl::ObeyTrailingSlash); // can be empty, e.g. in case http://www.kde.org/ |
452 | |
453 | dlg->setSelection(name); |
454 | if ( dlg->exec() ) |
455 | { |
456 | KUrl destURL( dlg->selectedUrl() ); |
457 | if ( destURL.isValid() ) |
458 | { |
459 | saveUrlUsingKIO(url, destURL, window, args.metaData()); |
460 | } |
461 | } |
462 | delete dlg; |
463 | } |
464 | |
465 | void BrowserRun::saveUrlUsingKIO(const KUrl & srcUrl, const KUrl& destUrl, |
466 | QWidget* window, const QMap<QString, QString> &metaData) |
467 | { |
468 | KIO::FileCopyJob *job = KIO::file_copy(srcUrl, destUrl, -1, KIO::Overwrite); |
469 | |
470 | const QString modificationTime = metaData[QLatin1String("content-disposition-modification-date" )]; |
471 | if (!modificationTime.isEmpty()) { |
472 | job->setModificationTime(KDateTime::fromString(modificationTime, KDateTime::RFCDate).dateTime()); |
473 | } |
474 | job->setMetaData(metaData); |
475 | job->addMetaData("MaxCacheSize" , "0" ); // Don't store in http cache. |
476 | job->addMetaData("cache" , "cache" ); // Use entry from cache if available. |
477 | job->ui()->setWindow(window); |
478 | job->ui()->setAutoErrorHandlingEnabled( true ); |
479 | new DownloadJobWatcher(job, metaData); |
480 | } |
481 | |
482 | void BrowserRun::slotStatResult( KJob *job ) |
483 | { |
484 | if ( job->error() ) { |
485 | kDebug(1000) << job->errorString(); |
486 | handleError( job ); |
487 | } else |
488 | KRun::slotStatResult( job ); |
489 | } |
490 | |
491 | void BrowserRun::handleError( KJob * job ) |
492 | { |
493 | if ( !job ) { // Shouldn't happen, see docu. |
494 | kWarning(1000) << "handleError called with job=0! hideErrorDialog=" << d->m_bHideErrorDialog; |
495 | return; |
496 | } |
497 | |
498 | KIO::TransferJob *tjob = qobject_cast<KIO::TransferJob *>(job); |
499 | if (tjob && tjob->isErrorPage() && !job->error()) { |
500 | // The default handling of error pages is to show them like normal pages |
501 | // But this is done here in handleError so that KHTMLRun can reimplement it |
502 | tjob->putOnHold(); |
503 | setJob(0); |
504 | if (!d->m_mimeType.isEmpty()) |
505 | mimeTypeDetermined(d->m_mimeType); |
506 | return; |
507 | } |
508 | |
509 | if (d->m_bHideErrorDialog && job->error() != KIO::ERR_NO_CONTENT) |
510 | { |
511 | redirectToError( job->error(), job->errorText() ); |
512 | return; |
513 | } |
514 | |
515 | // Reuse code in KRun, to benefit from d->m_showingError etc. |
516 | KRun::slotStatResult( job ); |
517 | } |
518 | |
519 | // static |
520 | KUrl BrowserRun::makeErrorUrl(int error, const QString& errorText, const QString& initialUrl) |
521 | { |
522 | /* |
523 | * The format of the error:/ URL is error:/?query#url, |
524 | * where two variables are passed in the query: |
525 | * error = int kio error code, errText = QString error text from kio |
526 | * The sub-url is the URL that we were trying to open. |
527 | */ |
528 | KUrl newURL(QString("error:/?error=%1&errText=%2" ) |
529 | .arg( error ) |
530 | .arg( QString::fromUtf8( QUrl::toPercentEncoding( errorText ) ) ) ); |
531 | |
532 | QString cleanedOrigUrl = initialUrl; |
533 | KUrl runURL = cleanedOrigUrl; |
534 | if (runURL.isValid()) { |
535 | runURL.setPass( QString() ); // don't put the password in the error URL |
536 | cleanedOrigUrl = runURL.url(); |
537 | } |
538 | |
539 | newURL.setFragment(cleanedOrigUrl); |
540 | return newURL; |
541 | |
542 | // The kde3 approach broke with invalid urls, now that they become empty in qt4. |
543 | //KUrl::List lst; |
544 | //lst << newURL << runURL; |
545 | //return KUrl::join(lst); |
546 | } |
547 | |
548 | void BrowserRun::redirectToError( int error, const QString& errorText ) |
549 | { |
550 | /** |
551 | * To display this error in KHTMLPart instead of inside a dialog box, |
552 | * we tell konq that the mimetype is text/html, and we redirect to |
553 | * an error:/ URL that sends the info to khtml. |
554 | */ |
555 | KRun::setUrl(makeErrorUrl(error, errorText, url().url())); |
556 | setJob( 0 ); |
557 | mimeTypeDetermined( "text/html" ); |
558 | } |
559 | |
560 | void BrowserRun::slotCopyToTempFileResult(KJob *job) |
561 | { |
562 | if ( job->error() ) { |
563 | job->uiDelegate()->showErrorMessage(); |
564 | } else { |
565 | // Same as KRun::foundMimeType but with a different URL |
566 | (void) (KRun::runUrl( static_cast<KIO::FileCopyJob *>(job)->destUrl(), d->m_mimeType, d->m_window )); |
567 | } |
568 | setError( true ); // see above |
569 | setFinished( true ); |
570 | } |
571 | |
572 | bool BrowserRun::isTextExecutable( const QString &mimeType ) |
573 | { |
574 | return ( mimeType == "application/x-desktop" || |
575 | mimeType == "application/x-shellscript" ); |
576 | } |
577 | |
578 | bool BrowserRun::hideErrorDialog() const |
579 | { |
580 | return d->m_bHideErrorDialog; |
581 | } |
582 | |
583 | QString BrowserRun::contentDisposition() const |
584 | { |
585 | return d->m_contentDisposition; |
586 | } |
587 | |
588 | bool BrowserRun::serverSuggestsSave() const |
589 | { |
590 | // RfC 2183, section 2.8: |
591 | // Unrecognized disposition types should be treated as `attachment'. |
592 | return !contentDisposition().isEmpty() && (contentDisposition() != "inline" ); |
593 | } |
594 | |
595 | KParts::OpenUrlArguments& KParts::BrowserRun::arguments() |
596 | { |
597 | return d->m_args; |
598 | } |
599 | |
600 | KParts::BrowserArguments& KParts::BrowserRun::browserArguments() |
601 | { |
602 | return d->m_browserArgs; |
603 | } |
604 | |
605 | #include "browserrun.moc" |
606 | #include "browserrun_p.moc" |
607 | |