• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.9.5 API Reference
  • KDE Home
  • Contact Us
 

KDEWebKit

kwebpage.cpp
Go to the documentation of this file.
00001 /*
00002  * This file is part of the KDE project.
00003  *
00004  * Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
00005  * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
00006  * Copyright (C) 2008 Michael Howell <mhowell123@gmail.com>
00007  * Copyright (C) 2009,2010 Dawit Alemayehu <adawit@kde.org>
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Library General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Library General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public License
00020  * along with this library; see the file COPYING.LIB.  If not, write to
00021  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00022  * Boston, MA 02110-1301, USA.
00023  *
00024  */
00025 
00026 // Own
00027 #include "kwebpage.h"
00028 #include "kwebwallet.h"
00029 
00030 // Local
00031 #include "kwebpluginfactory.h"
00032 
00033 // KDE
00034 #include <kaction.h>
00035 #include <kfiledialog.h>
00036 #include <kprotocolmanager.h>
00037 #include <kjobuidelegate.h>
00038 #include <krun.h>
00039 #include <kstandarddirs.h>
00040 #include <kstandardshortcut.h>
00041 #include <kurl.h>
00042 #include <kdebug.h>
00043 #include <kshell.h>
00044 #include <kmimetypetrader.h>
00045 #include <klocalizedstring.h>
00046 #include <ktemporaryfile.h>
00047 #include <kio/accessmanager.h>
00048 #include <kio/job.h>
00049 #include <kio/copyjob.h>
00050 #include <kio/jobuidelegate.h>
00051 #include <kio/renamedialog.h>
00052 #include <kio/scheduler.h>
00053 #include <kparts/browseropenorsavequestion.h>
00054 
00055 // Qt
00056 #include <QtCore/QPointer>
00057 #include <QtCore/QFileInfo>
00058 #include <QtCore/QCoreApplication>
00059 #include <QtWebKit/QWebFrame>
00060 #include <QtNetwork/QNetworkReply>
00061 
00062 
00063 #define QL1S(x)  QLatin1String(x)
00064 #define QL1C(x)  QLatin1Char(x)
00065 
00066 static void reloadRequestWithoutDisposition (QNetworkReply* reply)
00067 {
00068     QNetworkRequest req (reply->request());
00069     req.setRawHeader("x-kdewebkit-ignore-disposition", "true");
00070 
00071     QWebFrame* frame = qobject_cast<QWebFrame*> (req.originatingObject());
00072     if (!frame)
00073         return;
00074 
00075     frame->load(req);
00076 }
00077 
00078 static bool isMimeTypeAssociatedWithSelf(const KService::Ptr &offer)
00079 {
00080     if (!offer)
00081         return false;
00082 
00083     kDebug(800) << offer->desktopEntryName();
00084 
00085     const QString& appName = QCoreApplication::applicationName();
00086 
00087     if (appName == offer->desktopEntryName() || offer->exec().trimmed().startsWith(appName))
00088         return true;
00089 
00090     // konqueror exception since it uses kfmclient to open html content...
00091     if (appName == QL1S("konqueror") && offer->exec().trimmed().startsWith(QL1S("kfmclient")))
00092         return true;
00093 
00094     return false;
00095 }
00096 
00097 static void extractMimeType(const QNetworkReply* reply, QString& mimeType)
00098 {
00099     mimeType.clear();
00100     const KIO::MetaData& metaData = reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap();
00101     if (metaData.contains(QL1S("content-type")))
00102         mimeType = metaData.value(QL1S("content-type"));
00103 
00104     if (!mimeType.isEmpty())
00105         return;
00106 
00107     if (!reply->hasRawHeader("Content-Type"))
00108         return;
00109 
00110     const QString value (QL1S(reply->rawHeader("Content-Type").simplified().constData()));
00111     const int index = value.indexOf(QL1C(';'));
00112     mimeType = ((index == -1) ? value : value.left(index));
00113 }
00114 
00115 static bool downloadResource (const KUrl& srcUrl, const QString& suggestedName = QString(),
00116                               QWidget* parent = 0, const KIO::MetaData& metaData = KIO::MetaData())
00117 {
00118     const QString fileName = suggestedName.isEmpty() ? srcUrl.fileName() : suggestedName;
00119     // convert filename to URL using fromPath to avoid trouble with ':' in filenames (#184202)
00120     KUrl destUrl = KFileDialog::getSaveFileName(KUrl::fromPath(fileName), QString(), parent);
00121     if (!destUrl.isValid())
00122         return false;
00123 
00124     // Using KIO::copy rather than file_copy, to benefit from "dest already exists" dialogs.
00125     KIO::Job *job = KIO::copy(srcUrl, destUrl);
00126 
00127     if (!metaData.isEmpty())
00128         job->setMetaData(metaData);
00129 
00130     job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache.
00131     job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available.
00132     job->ui()->setWindow((parent ? parent->window() : 0));
00133     job->ui()->setAutoErrorHandlingEnabled(true);
00134     return true;
00135 }
00136 
00137 static bool isReplyStatusOk(const QNetworkReply* reply)
00138 {
00139     if (!reply || reply->error() != QNetworkReply::NoError)
00140         return false;
00141 
00142     // Check HTTP status code only for http and webdav protocols...
00143     const QString scheme = reply->url().scheme();
00144     if (scheme.startsWith(QLatin1String("http"), Qt::CaseInsensitive) ||
00145         scheme.startsWith(QLatin1String("webdav"), Qt::CaseInsensitive)) {
00146         bool ok = false;
00147         const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(&ok);
00148         if (!ok || statusCode < 200 || statusCode > 299)
00149             return false;
00150     }
00151 
00152     return true;
00153 }
00154 
00155 class KWebPage::KWebPagePrivate
00156 {
00157 public:
00158     KWebPagePrivate(KWebPage* page)
00159         : q(page)
00160           , inPrivateBrowsingMode(false)
00161     {
00162     }
00163 
00164     QWidget* windowWidget()
00165     {
00166         return (window ? window.data() : q->view());
00167     }
00168 
00169     void _k_copyResultToTempFile(KJob* job)
00170     {
00171         KIO::FileCopyJob* cJob = qobject_cast<KIO::FileCopyJob *>(job);
00172         if (cJob && !cJob->error() ) {
00173             // Same as KRun::foundMimeType but with a different URL
00174             (void)KRun::runUrl(cJob->destUrl(), mimeType, window);
00175         }
00176     }
00177 
00178     void _k_receivedContentType(KIO::Job* job, const QString& mimetype)
00179     {
00180         KIO::TransferJob* tJob = qobject_cast<KIO::TransferJob*>(job);
00181         if (tJob && !tJob->error()) {
00182             tJob->putOnHold();
00183             KIO::Scheduler::publishSlaveOnHold();
00184             // Get suggested file name...
00185             mimeType = mimetype;
00186             const QString suggestedFileName (tJob->queryMetaData(QL1S("content-disposition-filename")));
00187             // kDebug(800) << "suggested filename:" << suggestedFileName << ", mimetype:" << mimetype;
00188             (void) downloadResource(tJob->url(), suggestedFileName, window, tJob->metaData());
00189         }
00190     }
00191 
00192     void _k_contentTypeCheckFailed(KJob* job)
00193     {
00194         KIO::TransferJob* tJob = qobject_cast<KIO::TransferJob*>(job);
00195         // On error simply call downloadResource which will probably fail as well.
00196         if (tJob && tJob->error()) {
00197             (void)downloadResource(tJob->url(), QString(), window, tJob->metaData());
00198         }
00199     }
00200 
00201     KWebPage* q;
00202     QPointer<QWidget> window;
00203     QString mimeType;
00204     QPointer<KWebWallet> wallet;
00205     bool inPrivateBrowsingMode;
00206 };
00207 
00208 static void setActionIcon(QAction* action, const QIcon& icon)
00209 {
00210     if (action) {
00211         action->setIcon(icon);
00212     }
00213 }
00214 
00215 static void setActionShortcut(QAction* action, const KShortcut& shortcut)
00216 {
00217     if (action) {
00218         action->setShortcuts(shortcut.toList());
00219     }
00220 }
00221 
00222 KWebPage::KWebPage(QObject *parent, Integration flags)
00223          :QWebPage(parent), d(new KWebPagePrivate(this))
00224 { 
00225     // KDE KParts integration for <embed> tag...
00226     if (!flags || (flags & KPartsIntegration))
00227         setPluginFactory(new KWebPluginFactory(this));
00228 
00229     QWidget *parentWidget = qobject_cast<QWidget*>(parent);
00230     d->window = (parentWidget ? parentWidget->window() : 0);
00231 
00232     // KDE IO (KIO) integration...
00233     if (!flags || (flags & KIOIntegration)) {
00234         KIO::Integration::AccessManager *manager = new KIO::Integration::AccessManager(this);
00235         // Disable QtWebKit's internal cache to avoid duplication with the one in KIO...
00236         manager->setCache(0);
00237         manager->setWindow(d->window);
00238         manager->setEmitReadyReadOnMetaDataChange(true);
00239         setNetworkAccessManager(manager);
00240     }
00241 
00242     // KWallet integration...
00243     if (!flags || (flags & KWalletIntegration)) {
00244         setWallet(new KWebWallet(0, (d->window ? d->window->winId() : 0) ));
00245     }
00246 
00247     setActionIcon(action(Back), KIcon("go-previous"));
00248     setActionIcon(action(Forward), KIcon("go-next"));
00249     setActionIcon(action(Reload), KIcon("view-refresh"));
00250     setActionIcon(action(Stop), KIcon("process-stop"));
00251     setActionIcon(action(Cut), KIcon("edit-cut"));
00252     setActionIcon(action(Copy), KIcon("edit-copy"));
00253     setActionIcon(action(Paste), KIcon("edit-paste"));
00254     setActionIcon(action(Undo), KIcon("edit-undo"));
00255     setActionIcon(action(Redo), KIcon("edit-redo"));
00256     setActionIcon(action(InspectElement), KIcon("view-process-all"));
00257     setActionIcon(action(OpenLinkInNewWindow), KIcon("window-new"));
00258     setActionIcon(action(OpenFrameInNewWindow), KIcon("window-new"));
00259     setActionIcon(action(OpenImageInNewWindow), KIcon("window-new"));
00260     setActionIcon(action(CopyLinkToClipboard), KIcon("edit-copy"));
00261     setActionIcon(action(CopyImageToClipboard), KIcon("edit-copy"));
00262     setActionIcon(action(ToggleBold), KIcon("format-text-bold"));
00263     setActionIcon(action(ToggleItalic), KIcon("format-text-italic"));
00264     setActionIcon(action(ToggleUnderline), KIcon("format-text-underline"));
00265     setActionIcon(action(DownloadLinkToDisk), KIcon("document-save"));
00266     setActionIcon(action(DownloadImageToDisk), KIcon("document-save"));
00267 
00268     settings()->setWebGraphic(QWebSettings::MissingPluginGraphic, KIcon("preferences-plugin").pixmap(32, 32));
00269     settings()->setWebGraphic(QWebSettings::MissingImageGraphic, KIcon("image-missing").pixmap(32, 32));
00270     settings()->setWebGraphic(QWebSettings::DefaultFrameIconGraphic, KIcon("applications-internet").pixmap(32, 32));
00271 
00272     setActionShortcut(action(Back), KStandardShortcut::back());
00273     setActionShortcut(action(Forward), KStandardShortcut::forward());
00274     setActionShortcut(action(Reload), KStandardShortcut::reload());
00275     setActionShortcut(action(Stop), KShortcut(QKeySequence(Qt::Key_Escape)));
00276     setActionShortcut(action(Cut), KStandardShortcut::cut());
00277     setActionShortcut(action(Copy), KStandardShortcut::copy());
00278     setActionShortcut(action(Paste), KStandardShortcut::paste());
00279     setActionShortcut(action(Undo), KStandardShortcut::undo());
00280     setActionShortcut(action(Redo), KStandardShortcut::redo());
00281     setActionShortcut(action(SelectAll), KStandardShortcut::selectAll());
00282 }
00283 
00284 KWebPage::~KWebPage()
00285 {
00286     delete d;
00287 }
00288 
00289 bool KWebPage::isExternalContentAllowed() const
00290 {
00291     KIO::AccessManager *manager = qobject_cast<KIO::AccessManager*>(networkAccessManager());
00292     if (manager)
00293         return manager->isExternalContentAllowed();
00294     return true;
00295 }
00296 
00297 KWebWallet *KWebPage::wallet() const
00298 {
00299     return d->wallet;
00300 }
00301 
00302 void KWebPage::setAllowExternalContent(bool allow)
00303 {
00304     KIO::AccessManager *manager = qobject_cast<KIO::AccessManager*>(networkAccessManager());
00305     if (manager)
00306       manager->setExternalContentAllowed(allow);
00307 }
00308 
00309 void KWebPage::setWallet(KWebWallet* wallet)
00310 {
00311     // Delete the current wallet if this object is its parent...
00312     if (d->wallet && this == d->wallet->parent())
00313         delete d->wallet;
00314 
00315     d->wallet = wallet;
00316 
00317     if (d->wallet)
00318         d->wallet->setParent(this);
00319 }
00320 
00321 
00322 void KWebPage::downloadRequest(const QNetworkRequest& request)
00323 {
00324     KIO::TransferJob* job = KIO::get(request.url());
00325     connect(job, SIGNAL(mimetype(KIO::Job*,QString)),
00326             this, SLOT(_k_receivedContentType(KIO::Job*,QString)));
00327     connect(job, SIGNAL(result(KJob*)),
00328             this, SLOT(_k_receivedContentTypeResult(KJob*)));
00329 
00330     job->setMetaData(request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap());
00331     job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache.
00332     job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available.
00333     job->ui()->setWindow(d->windowWidget());
00334 }
00335 
00336 void KWebPage::downloadUrl(const KUrl &url)
00337 {
00338     downloadRequest(QNetworkRequest(url));
00339 }
00340 
00341 void KWebPage::downloadResponse(QNetworkReply *reply)
00342 {
00343     Q_ASSERT(reply);
00344 
00345     if (!reply)
00346         return;
00347 
00348     // Put the job on hold only for the protocols we know about (read: http).
00349     KIO::Integration::AccessManager::putReplyOnHold(reply);
00350 
00351     QString mimeType;
00352     KIO::MetaData metaData;
00353 
00354     if (handleReply(reply, &mimeType, &metaData)) {
00355         return;
00356     }
00357 
00358     const KUrl replyUrl (reply->url());
00359 
00360     // Ask KRun to handle the response when mimetype is unknown
00361     if (mimeType.isEmpty()) {
00362         (void)new KRun(replyUrl, d->windowWidget(), 0 , replyUrl.isLocalFile());
00363         return;
00364     }
00365 
00366     // Ask KRun::runUrl to handle the response when mimetype is inode/*
00367     if (mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive) &&
00368         KRun::runUrl(replyUrl, mimeType, d->windowWidget(), false, false,
00369                      metaData.value(QL1S("content-disposition-filename")))) {
00370         return;
00371     }
00372 }
00373 
00374 QString KWebPage::sessionMetaData(const QString &key) const
00375 {
00376     QString value;
00377 
00378     KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
00379     if (manager)
00380         value = manager->sessionMetaData().value(key);
00381 
00382     return value;
00383 }
00384 
00385 QString KWebPage::requestMetaData(const QString &key) const
00386 {
00387     QString value;
00388 
00389     KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
00390     if (manager)
00391         value = manager->requestMetaData().value(key);
00392 
00393     return value;
00394 }
00395 
00396 void KWebPage::setSessionMetaData(const QString &key, const QString &value)
00397 {
00398     KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
00399     if (manager)
00400         manager->sessionMetaData()[key] = value;
00401 }
00402 
00403 void KWebPage::setRequestMetaData(const QString &key, const QString &value)
00404 {
00405     KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
00406     if (manager)
00407         manager->requestMetaData()[key] = value;
00408 }
00409 
00410 void KWebPage::removeSessionMetaData(const QString &key)
00411 {
00412     KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
00413     if (manager)
00414         manager->sessionMetaData().remove(key);
00415 }
00416 
00417 void KWebPage::removeRequestMetaData(const QString &key)
00418 {
00419     KIO::Integration::AccessManager *manager = qobject_cast<KIO::Integration::AccessManager *>(networkAccessManager());
00420     if (manager)
00421         manager->requestMetaData().remove(key);
00422 }
00423 
00424 QString KWebPage::userAgentForUrl(const QUrl& _url) const
00425 {
00426     const KUrl url(_url);
00427     const QString userAgent = KProtocolManager::userAgentForHost((url.isLocalFile() ? QL1S("localhost") : url.host()));
00428 
00429     if (userAgent == KProtocolManager::defaultUserAgent())
00430         return QWebPage::userAgentForUrl(_url);
00431 
00432     return userAgent;
00433 }
00434 
00435 static void setDisableCookieJarStorage(QNetworkAccessManager* manager, bool status)
00436 {
00437     if (manager) {
00438         KIO::Integration::CookieJar *cookieJar = manager ? qobject_cast<KIO::Integration::CookieJar*>(manager->cookieJar()) : 0;
00439         if (cookieJar) {
00440             //kDebug(800) << "Store cookies ?" << !status;
00441             cookieJar->setDisableCookieStorage(status);
00442         }
00443     }
00444 }
00445 
00446 bool KWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
00447 {
00448     kDebug(800) << "url:" << request.url() << ", type:" << type << ", frame:" << frame;
00449 
00450     if (frame && d->wallet && type == QWebPage::NavigationTypeFormSubmitted)
00451         d->wallet->saveFormData(frame);
00452 
00453     // Make sure nothing is cached when private browsing mode is enabled...
00454     if (settings()->testAttribute(QWebSettings::PrivateBrowsingEnabled)) {
00455         if (!d->inPrivateBrowsingMode) {
00456             setDisableCookieJarStorage(networkAccessManager(), true);
00457             setSessionMetaData(QL1S("no-cache"), QL1S("true"));
00458             d->inPrivateBrowsingMode = true;
00459         }
00460     } else  {
00461         if (d->inPrivateBrowsingMode) {
00462             setDisableCookieJarStorage(networkAccessManager(), false);
00463             removeSessionMetaData(QL1S("no-cache"));
00464             d->inPrivateBrowsingMode = false;
00465         }
00466     }
00467 
00468     /*
00469       If the navigation request is from the main frame, set the cross-domain
00470       meta-data value to the current url for proper integration with KCookieJar...
00471     */
00472     if (frame == mainFrame() && type != QWebPage::NavigationTypeReload)
00473         setSessionMetaData(QL1S("cross-domain"), request.url().toString());
00474 
00475     return QWebPage::acceptNavigationRequest(frame, request, type);
00476 }
00477 
00478 bool KWebPage::handleReply(QNetworkReply* reply, QString* contentType, KIO::MetaData* metaData)
00479 {
00480     // Reply url...
00481     const KUrl replyUrl (reply->url());
00482 
00483     // Get suggested file name...
00484     const KIO::MetaData& data = reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)).toMap();
00485     const QString suggestedFileName = data.value(QL1S("content-disposition-filename"));
00486     if (metaData) {
00487         *metaData = data;
00488     }
00489 
00490     // Get the mime-type...
00491     QString mimeType;
00492     extractMimeType(reply, mimeType);
00493     if (contentType) {
00494         *contentType = mimeType;
00495     }
00496 
00497     // Let the calling function deal with handling empty or inode/* mimetypes...
00498     if (mimeType.isEmpty() || mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive)) {
00499         return false;
00500     }
00501 
00502     // Convert executable text files to plain text...
00503     if (KParts::BrowserRun::isTextExecutable(mimeType))
00504         mimeType = QL1S("text/plain");
00505 
00506     //kDebug(800) << "Content-disposition:" << suggestedFileName;
00507     //kDebug(800) << "Got unsupported content of type:" << mimeType << "URL:" << replyUrl;
00508     //kDebug(800) << "Error code:" << reply->error() << reply->errorString();
00509 
00510     if (isReplyStatusOk(reply)) {
00511         while (true) {
00512             KParts::BrowserOpenOrSaveQuestion::Result result;
00513             KParts::BrowserOpenOrSaveQuestion dlg(d->windowWidget(), replyUrl, mimeType);
00514             dlg.setSuggestedFileName(suggestedFileName);
00515             dlg.setFeatures(KParts::BrowserOpenOrSaveQuestion::ServiceSelection);
00516             result = dlg.askOpenOrSave();
00517 
00518             switch (result) {
00519             case KParts::BrowserOpenOrSaveQuestion::Open:
00520                 // Handle Post operations that return content...
00521                 if (reply->operation() == QNetworkAccessManager::PostOperation) {
00522                     d->mimeType = mimeType;
00523                     QFileInfo finfo (suggestedFileName.isEmpty() ? replyUrl.fileName() : suggestedFileName);
00524                     KTemporaryFile tempFile;
00525                     tempFile.setSuffix(QL1C('.') + finfo.suffix());
00526                     tempFile.setAutoRemove(false);
00527                     tempFile.open();
00528                     KUrl destUrl;
00529                     destUrl.setPath(tempFile.fileName());
00530                     KIO::Job *job = KIO::file_copy(replyUrl, destUrl, 0600, KIO::Overwrite);
00531                     job->ui()->setWindow(d->windowWidget());
00532                     job->ui()->setAutoErrorHandlingEnabled(true);
00533                     connect(job, SIGNAL(result(KJob*)),
00534                             this, SLOT(_k_copyResultToTempFile(KJob*)));
00535                     return true;
00536                 }
00537 
00538                 // Ask before running any executables...
00539                 if (KParts::BrowserRun::allowExecution(mimeType, replyUrl)) {
00540                     KService::Ptr offer = dlg.selectedService();
00541                     // HACK: The check below is necessary to break an infinite
00542                     // recursion that occurs whenever this function is called as a result
00543                     // of receiving content that can be rendered by the app using this engine.
00544                     // For example a text/html header that containing a content-disposition
00545                     // header is received by the app using this class.
00546                     if (isMimeTypeAssociatedWithSelf(offer)) {
00547                         reloadRequestWithoutDisposition(reply);
00548                     } else {
00549                         KUrl::List list;
00550                         list.append(replyUrl);
00551                         bool success = false;
00552                         // kDebug(800) << "Suggested file name:" << suggestedFileName;
00553                         if (offer) {
00554                             success = KRun::run(*offer, list, d->windowWidget() , false, suggestedFileName);
00555                         } else {
00556                             success = KRun::displayOpenWithDialog(list, d->windowWidget(), false, suggestedFileName);
00557                             if (!success)
00558                                 break;
00559                         }
00560                         // For non KIO apps and cancelled Open With dialog, remove slave on hold.
00561                         if (!success || (offer && !offer->categories().contains(QL1S("KDE")))) {
00562                             KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
00563                         }
00564                     }
00565                     return true;
00566                 }
00567                 // TODO: Instead of silently failing when allowExecution fails, notify
00568                 // the user why the requested action cannot be fulfilled...
00569                 return false;
00570             case KParts::BrowserOpenOrSaveQuestion::Save:
00571                 // Do not download local files...
00572                 if (!replyUrl.isLocalFile()) {
00573                     QString downloadCmd (reply->property("DownloadManagerExe").toString());
00574                     if (!downloadCmd.isEmpty()) {
00575                         downloadCmd += QLatin1Char(' ');
00576                         downloadCmd += KShell::quoteArg(replyUrl.url());
00577                         if (!suggestedFileName.isEmpty()) {
00578                             downloadCmd += QLatin1Char(' ');
00579                             downloadCmd += KShell::quoteArg(suggestedFileName);
00580                         }
00581                         // kDebug(800) << "download command:" << downloadCmd;
00582                         if (KRun::runCommand(downloadCmd, view()))
00583                             return true;
00584                     }
00585                     if (!downloadResource(replyUrl, suggestedFileName, d->windowWidget()))
00586                         break;
00587                 }
00588                 return true;
00589             case KParts::BrowserOpenOrSaveQuestion::Cancel:
00590             default:
00591                 KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold...
00592                 return true;
00593             }
00594         }
00595     } else {
00596         KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimeType);
00597         if (isMimeTypeAssociatedWithSelf(offer)) {
00598             reloadRequestWithoutDisposition(reply);
00599             return true;
00600         }
00601     }
00602 
00603     return false;
00604 }
00605 
00606 #include "kwebpage.moc"
00607 
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:37:47 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEWebKit

Skip menu "KDEWebKit"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.9.5 API Reference

Skip menu "kdelibs-4.9.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal