154
155
class KWebPage::KWebPagePrivate
157
KWebPagePrivate() : inPrivateBrowsingMode(false) {}
158
void _k_copyResultToTempFile(KJob * job)
160
if ( job->error() ) {
161
job->uiDelegate()->showErrorMessage();
164
// Same as KRun::foundMimeType but with a different URL
165
(void)KRun::runUrl(static_cast<KIO::FileCopyJob *>(job)->destUrl(), mimeType, window);
158
KWebPagePrivate(KWebPage* page)
160
, inPrivateBrowsingMode(false)
164
QWidget* windowWidget()
166
return (window ? window.data() : q->view());
169
void _k_copyResultToTempFile(KJob* job)
171
KIO::FileCopyJob* cJob = qobject_cast<KIO::FileCopyJob *>(job);
172
if (cJob && !cJob->error() ) {
173
// Same as KRun::foundMimeType but with a different URL
174
(void)KRun::runUrl(cJob->destUrl(), mimeType, window);
178
void _k_receivedContentType(KIO::Job* job, const QString& mimetype)
180
KIO::TransferJob* tJob = qobject_cast<KIO::TransferJob*>(job);
181
if (tJob && !tJob->error()) {
183
KIO::Scheduler::publishSlaveOnHold();
184
// Get suggested file name...
186
const QString suggestedFileName (tJob->queryMetaData(QL1S("content-disposition-filename")));
187
// kDebug(800) << "suggested filename:" << suggestedFileName << ", mimetype:" << mimetype;
188
(void) downloadResource(tJob->url(), suggestedFileName, window, tJob->metaData());
192
void _k_contentTypeCheckFailed(KJob* job)
194
KIO::TransferJob* tJob = qobject_cast<KIO::TransferJob*>(job);
195
// On error simply call downloadResource which will probably fail as well.
196
if (tJob && tJob->error()) {
197
(void)downloadResource(tJob->url(), QString(), window, tJob->metaData());
168
202
QPointer<QWidget> window;
169
203
QString mimeType;
170
204
QPointer<KWebWallet> wallet;
188
222
KWebPage::KWebPage(QObject *parent, Integration flags)
189
:QWebPage(parent), d(new KWebPagePrivate)
223
:QWebPage(parent), d(new KWebPagePrivate(this))
191
225
// KDE KParts integration for <embed> tag...
192
226
if (!flags || (flags & KPartsIntegration))
193
227
setPluginFactory(new KWebPluginFactory(this));
195
229
QWidget *parentWidget = qobject_cast<QWidget*>(parent);
196
QWidget *window = parentWidget ? parentWidget->window() : 0;
230
d->window = (parentWidget ? parentWidget->window() : 0);
198
232
// KDE IO (KIO) integration...
199
233
if (!flags || (flags & KIOIntegration)) {
200
234
KIO::Integration::AccessManager *manager = new KIO::Integration::AccessManager(this);
201
235
// Disable QtWebKit's internal cache to avoid duplication with the one in KIO...
202
236
manager->setCache(0);
203
manager->setWindow(window);
237
manager->setWindow(d->window);
204
238
manager->setEmitReadyReadOnMetaDataChange(true);
205
239
setNetworkAccessManager(manager);
208
242
// KWallet integration...
209
243
if (!flags || (flags & KWalletIntegration)) {
210
setWallet(new KWebWallet(0, (window ? window->winId() : 0) ));
244
setWallet(new KWebWallet(0, (d->window ? d->window->winId() : 0) ));
213
247
setActionIcon(action(Back), KIcon("go-previous"));
284
318
d->wallet->setParent(this);
287
void KWebPage::downloadRequest(const QNetworkRequest &request)
322
void KWebPage::downloadRequest(const QNetworkRequest& request)
289
downloadResource(request.url(), QString(), view(),
290
request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap());
324
KIO::TransferJob* job = KIO::get(request.url());
325
connect(job, SIGNAL(mimetype(KIO::Job*,QString)),
326
this, SLOT(_k_receivedContentType(KIO::Job*,QString)));
327
connect(job, SIGNAL(result(KJob*)),
328
this, SLOT(_k_receivedContentTypeResult(KJob*)));
330
job->setMetaData(request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap());
331
job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache.
332
job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available.
333
job->ui()->setWindow(d->windowWidget());
293
336
void KWebPage::downloadUrl(const KUrl &url)
295
downloadResource(url, QString(), view());
338
downloadRequest(QNetworkRequest(url));
298
341
void KWebPage::downloadResponse(QNetworkReply *reply)
469
508
//kDebug(800) << "Error code:" << reply->error() << reply->errorString();
471
510
if (isReplyStatusOk(reply)) {
472
KParts::BrowserOpenOrSaveQuestion::Result result;
473
KParts::BrowserOpenOrSaveQuestion dlg(topLevelWindow, replyUrl, mimeType);
474
dlg.setSuggestedFileName(suggestedFileName);
475
dlg.setFeatures(KParts::BrowserOpenOrSaveQuestion::ServiceSelection);
476
result = dlg.askOpenOrSave();
479
case KParts::BrowserOpenOrSaveQuestion::Open:
480
// Handle Post operations that return content...
481
if (reply->operation() == QNetworkAccessManager::PostOperation) {
482
d->mimeType = mimeType;
483
d->window = topLevelWindow;
484
QFileInfo finfo (suggestedFileName.isEmpty() ? replyUrl.fileName() : suggestedFileName);
485
KTemporaryFile tempFile;
486
tempFile.setSuffix(QL1C('.') + finfo.suffix());
487
tempFile.setAutoRemove(false);
490
destUrl.setPath(tempFile.fileName());
491
KIO::Job *job = KIO::file_copy(replyUrl, destUrl, 0600, KIO::Overwrite);
492
job->ui()->setWindow(topLevelWindow);
493
job->ui()->setAutoErrorHandlingEnabled(true);
494
connect(job, SIGNAL(result(KJob*)),
495
this, SLOT(_k_copyResultToTempFile(KJob*)));
499
// Ask before running any executables...
500
if (KParts::BrowserRun::allowExecution(mimeType, replyUrl)) {
501
KService::Ptr offer = dlg.selectedService();
502
// HACK: The check below is necessary to break an infinite
503
// recursion that occurs whenever this function is called as a result
504
// of receiving content that can be rendered by the app using this engine.
505
// For example a text/html header that containing a content-disposition
506
// header is received by the app using this class.
507
if (isMimeTypeAssociatedWithSelf(offer)) {
508
reloadRequestWithoutDisposition(reply);
511
list.append(replyUrl);
512
bool success = false;
513
// kDebug(800) << "Suggested file name:" << suggestedFileName;
515
success = KRun::run(*offer, list, topLevelWindow , false, suggestedFileName);
512
KParts::BrowserOpenOrSaveQuestion::Result result;
513
KParts::BrowserOpenOrSaveQuestion dlg(d->windowWidget(), replyUrl, mimeType);
514
dlg.setSuggestedFileName(suggestedFileName);
515
dlg.setFeatures(KParts::BrowserOpenOrSaveQuestion::ServiceSelection);
516
result = dlg.askOpenOrSave();
519
case KParts::BrowserOpenOrSaveQuestion::Open:
520
// Handle Post operations that return content...
521
if (reply->operation() == QNetworkAccessManager::PostOperation) {
522
d->mimeType = mimeType;
523
QFileInfo finfo (suggestedFileName.isEmpty() ? replyUrl.fileName() : suggestedFileName);
524
KTemporaryFile tempFile;
525
tempFile.setSuffix(QL1C('.') + finfo.suffix());
526
tempFile.setAutoRemove(false);
529
destUrl.setPath(tempFile.fileName());
530
KIO::Job *job = KIO::file_copy(replyUrl, destUrl, 0600, KIO::Overwrite);
531
job->ui()->setWindow(d->windowWidget());
532
job->ui()->setAutoErrorHandlingEnabled(true);
533
connect(job, SIGNAL(result(KJob*)),
534
this, SLOT(_k_copyResultToTempFile(KJob*)));
538
// Ask before running any executables...
539
if (KParts::BrowserRun::allowExecution(mimeType, replyUrl)) {
540
KService::Ptr offer = dlg.selectedService();
541
// HACK: The check below is necessary to break an infinite
542
// recursion that occurs whenever this function is called as a result
543
// of receiving content that can be rendered by the app using this engine.
544
// For example a text/html header that containing a content-disposition
545
// header is received by the app using this class.
546
if (isMimeTypeAssociatedWithSelf(offer)) {
547
reloadRequestWithoutDisposition(reply);
517
success = KRun::displayOpenWithDialog(list, topLevelWindow, false, suggestedFileName);
519
// For non KIO apps and cancelled Open With dialog, remove slave on hold.
520
if (!success || (offer && !offer->categories().contains(QL1S("KDE")))) {
521
KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
550
list.append(replyUrl);
551
bool success = false;
552
// kDebug(800) << "Suggested file name:" << suggestedFileName;
554
success = KRun::run(*offer, list, d->windowWidget() , false, suggestedFileName);
556
success = KRun::displayOpenWithDialog(list, d->windowWidget(), false, suggestedFileName);
560
// For non KIO apps and cancelled Open With dialog, remove slave on hold.
561
if (!success || (offer && !offer->categories().contains(QL1S("KDE")))) {
562
KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
526
// TODO: Instead of silently failing when allowExecution fails, notify
527
// the user why the requested action cannot be fulfilled...
529
case KParts::BrowserOpenOrSaveQuestion::Save:
530
// Do not download local files...
531
if (!replyUrl.isLocalFile()) {
532
QString downloadCmd (reply->property("DownloadManagerExe").toString());
533
if (!downloadCmd.isEmpty()) {
534
downloadCmd += QLatin1Char(' ');
535
downloadCmd += KShell::quoteArg(replyUrl.url());
536
if (!suggestedFileName.isEmpty()) {
567
// TODO: Instead of silently failing when allowExecution fails, notify
568
// the user why the requested action cannot be fulfilled...
570
case KParts::BrowserOpenOrSaveQuestion::Save:
571
// Do not download local files...
572
if (!replyUrl.isLocalFile()) {
573
QString downloadCmd (reply->property("DownloadManagerExe").toString());
574
if (!downloadCmd.isEmpty()) {
537
575
downloadCmd += QLatin1Char(' ');
538
downloadCmd += KShell::quoteArg(suggestedFileName);
576
downloadCmd += KShell::quoteArg(replyUrl.url());
577
if (!suggestedFileName.isEmpty()) {
578
downloadCmd += QLatin1Char(' ');
579
downloadCmd += KShell::quoteArg(suggestedFileName);
581
// kDebug(800) << "download command:" << downloadCmd;
582
if (KRun::runCommand(downloadCmd, view()))
540
// kDebug(800) << "download command:" << downloadCmd;
541
if (KRun::runCommand(downloadCmd, view()))
585
if (!downloadResource(replyUrl, suggestedFileName, d->windowWidget()))
544
return downloadResource(replyUrl, suggestedFileName, topLevelWindow);
589
case KParts::BrowserOpenOrSaveQuestion::Cancel:
591
KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
547
case KParts::BrowserOpenOrSaveQuestion::Cancel:
552
596
KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimeType);