diff --git a/src/kgraphicswebview.h b/src/kgraphicswebview.h index 01439cd..a8a155d 100644 --- a/src/kgraphicswebview.h +++ b/src/kgraphicswebview.h @@ -1,207 +1,207 @@ /* * This file is part of the KDE project. * * Copyright (C) 2007 Trolltech ASA * Copyright (C) 2008 Urs Wolfer * Copyright (C) 2008 Laurent Montel * Copyright (C) 2008 Michael Howell * Copyright (C) 2009 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KGRAPHICSWEBVIEW_H #define KGRAPHICSWEBVIEW_H #include #include class QUrl; template class KWebViewPrivate; /** * @short A re-implementation of QGraphicsWebView that provides KDE Frameworks * integration. * * This is a drop-in replacement for QGraphicsWebView that provides full KDE * frameworks integration through the use of @ref KWebPage. It also provides * signals that capture middle, shift and ctrl mouse clicks on links and URL * pasting from the selection clipboard. * * The specific functionality provided by this class (over and above what * would be acheived by using KWebPage with a QGraphicsWebView) is that * scrolling * with the mouse wheel while holding down CTRL zooms the page (see * QGraphicsWebView::setZoomFactor) and several useful signals are emitted when * the user performs certain actions. * * @author Urs Wolfer * @author Dawit Alemayehu * * @since 4.4 */ class KDEWEBKIT_EXPORT KGraphicsWebView : public QGraphicsWebView { Q_OBJECT public: /** * Constructs a KGraphicsWebView object with parent @p parent. * * Set @p createCustomPage to false to prevent the creation of a * @ref KWebPage object for KDE frameworks integration. Doing so allows you * to avoid unnecessary object creation and deletion if you are going to use * a subclass of KWebPage. * * @param parent the parent object * @param createCustomPage if @c true, the view's page is set to an * instance of KWebPage */ - explicit KGraphicsWebView(QGraphicsItem *parent = 0, bool createCustomPage = true); + explicit KGraphicsWebView(QGraphicsItem *parent = nullptr, bool createCustomPage = true); /** * Destroys the KGraphicsWebView. */ ~KGraphicsWebView(); /** * Returns true if access to remote content is allowed. * * By default access to remote content is allowed. * * @see setAllowExternalContent() * @see KWebPage::isExternalContentAllowed() */ bool isExternalContentAllowed() const; /** * Set @p allow to false if you want to prevent access to remote content. * * If this function is set to false only resources on the local system * can be accessed through this class. By default fetching external content * is allowed. * * @see isExternalContentAllowed() * @see KWebPage::setAllowExternalContent(bool) */ void setAllowExternalContent(bool allow); Q_SIGNALS: /** * Emitted when a URL from the selection clipboard is pasted on this view. * * This is triggered when the user clicks on the page with the middle * mouse button when there is something in the global mouse selection * clipboard. This is typically only possible on X11. * * Uri filters are applied to the selection clipboard to generate @p url. * * If the content in the selection clipboard is not a valid url and a * default search engine is configured, @p url will be set to a query * to the default search engine. * * @param url url generated from the selection clipboard content * * @deprecated use selectionClipboardUrlPasted(QUrl, bool) instead * @see QClipboard */ #ifndef KDEWEBKIT_NO_DEPRECATED KDEWEBKIT_DEPRECATED void selectionClipboardUrlPasted(const QUrl &url); #endif /** * Emitted when a URL from the selection clipboard is pasted on this view. * * This is triggered when the user clicks on the page with the middle * mouse button when there is something in the global mouse selection * clipboard. This is typically only possible on X11. * * Uri filters are applied to the selection clipboard to generate @p url. * * If the content in the selection clipboard is not a valid URL and a * default search engine is configured, @p searchText will be set to the * content of the clipboard (250 characters maximum) and @p url will be * set to a query to the default search engine. * * @param url the URL generated from the selection clipboard content * @param searchText content of the selection clipboard if it is not a * valid URL * * @see KUriFilter * @see QClipboard * @since 4.6 */ void selectionClipboardUrlPasted(const QUrl &url, const QString &searchText); /** * Emitted when a link is clicked with the left mouse button while SHIFT is * held down. * * A user of Plasma Desktop would typically expect this to result in the * triggering of a "save link as" action. * * @param url the URL of the clicked link */ void linkShiftClicked(const QUrl &url); /** * Emitted when a link is clicked with the middle mouse button or clicked * with the left mouse button while CTRL is held down. * * Typically, the user would expect this to result in the URL being opened * in a new tab or window. * * @param url the URL of the clicked link */ void linkMiddleOrCtrlClicked(const QUrl &url); protected: /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWidget::wheelEvent * @internal */ void wheelEvent(QGraphicsSceneWheelEvent *event) Q_DECL_OVERRIDE; /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWidget::mousePressEvent * @internal */ void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWidget::mouseReleaseEvent * @internal */ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; private: friend class KWebViewPrivate; KWebViewPrivate *const d; }; #endif // KWEBVIEW_H diff --git a/src/kwebpage.cpp b/src/kwebpage.cpp index 9580ce9..c07befb 100644 --- a/src/kwebpage.cpp +++ b/src/kwebpage.cpp @@ -1,631 +1,631 @@ /* * This file is part of the KDE project. * * Copyright (C) 2008 Dirk Mueller * Copyright (C) 2008 Urs Wolfer * Copyright (C) 2008 Michael Howell * Copyright (C) 2009,2010 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ // Own #include "kwebpage.h" #include "kwebwallet.h" // Local #include "kwebpluginfactory.h" // KDE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Qt #include #include #include #include #include #include #include #include #define QL1S(x) QLatin1String(x) #define QL1C(x) QLatin1Char(x) static void reloadRequestWithoutDisposition(QNetworkReply *reply) { QNetworkRequest req(reply->request()); req.setRawHeader("x-kdewebkit-ignore-disposition", "true"); QWebFrame *frame = qobject_cast (req.originatingObject()); if (!frame) { return; } frame->load(req); } static bool isMimeTypeAssociatedWithSelf(const KService::Ptr &offer) { if (!offer) { return false; } // qDebug() << offer->desktopEntryName(); const QString &appName = QCoreApplication::applicationName(); if (appName == offer->desktopEntryName() || offer->exec().trimmed().startsWith(appName)) { return true; } // konqueror exception since it uses kfmclient to open html content... if (appName == QL1S("konqueror") && offer->exec().trimmed().startsWith(QL1S("kfmclient"))) { return true; } return false; } static void extractMimeType(const QNetworkReply *reply, QString &mimeType) { mimeType.clear(); const KIO::MetaData &metaData = reply->attribute(static_cast(KIO::AccessManager::MetaData)).toMap(); if (metaData.contains(QL1S("content-type"))) { mimeType = metaData.value(QL1S("content-type")); } if (!mimeType.isEmpty()) { return; } if (!reply->hasRawHeader("Content-Type")) { return; } const QString value(QL1S(reply->rawHeader("Content-Type").simplified().constData())); const int index = value.indexOf(QL1C(';')); mimeType = ((index == -1) ? value : value.left(index)); } static bool downloadResource(const QUrl &srcUrl, const QString &suggestedName = QString(), - QWidget *parent = 0, const KIO::MetaData &metaData = KIO::MetaData()) + QWidget *parent = nullptr, const KIO::MetaData &metaData = KIO::MetaData()) { const QString fileName = suggestedName.isEmpty() ? srcUrl.fileName() : suggestedName; // convert filename to URL using fromPath to avoid trouble with ':' in filenames (#184202) QUrl destUrl = QUrl::fromLocalFile(QFileDialog::getSaveFileName(parent, QString(), fileName)); if (!destUrl.isValid()) { return false; } // Using KIO::copy rather than file_copy, to benefit from "dest already exists" dialogs. KIO::Job *job = KIO::copy(srcUrl, destUrl); if (!metaData.isEmpty()) { job->setMetaData(metaData); } job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache. job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available. - KJobWidgets::setWindow(job, parent ? parent->window() : 0); + KJobWidgets::setWindow(job, parent ? parent->window() : nullptr); job->ui()->setAutoErrorHandlingEnabled(true); return true; } static bool isReplyStatusOk(const QNetworkReply *reply) { if (!reply || reply->error() != QNetworkReply::NoError) { return false; } // Check HTTP status code only for http and webdav protocols... const QString scheme = reply->url().scheme(); if (scheme.startsWith(QLatin1String("http"), Qt::CaseInsensitive) || scheme.startsWith(QLatin1String("webdav"), Qt::CaseInsensitive)) { bool ok = false; const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(&ok); if (!ok || statusCode < 200 || statusCode > 299) { return false; } } return true; } class KWebPage::KWebPagePrivate { public: KWebPagePrivate(KWebPage *page) : q(page) , inPrivateBrowsingMode(false) { } QWidget *windowWidget() { return (window ? window.data() : q->view()); } void _k_copyResultToTempFile(KJob *job) { KIO::FileCopyJob *cJob = qobject_cast(job); if (cJob && !cJob->error()) { // Same as KRun::foundMimeType but with a different URL (void)KRun::runUrl(cJob->destUrl(), mimeType, window); } } void _k_receivedContentType(KIO::Job *job, const QString &mimetype) { KIO::TransferJob *tJob = qobject_cast(job); if (tJob && !tJob->error()) { tJob->putOnHold(); KIO::Scheduler::publishSlaveOnHold(); // Get suggested file name... mimeType = mimetype; const QString suggestedFileName(tJob->queryMetaData(QL1S("content-disposition-filename"))); // qDebug() << "suggested filename:" << suggestedFileName << ", mimetype:" << mimetype; (void) downloadResource(tJob->url(), suggestedFileName, window, tJob->metaData()); } } void _k_contentTypeCheckFailed(KJob *job) { KIO::TransferJob *tJob = qobject_cast(job); // On error simply call downloadResource which will probably fail as well. if (tJob && tJob->error()) { (void)downloadResource(tJob->url(), QString(), window, tJob->metaData()); } } KWebPage *q; QPointer window; QString mimeType; QPointer wallet; bool inPrivateBrowsingMode; }; static void setActionIcon(QAction *action, const QIcon &icon) { if (action) { action->setIcon(icon); } } static void setActionShortcut(QAction *action, const QList &shortcut) { if (action) { action->setShortcuts(shortcut); } } KWebPage::KWebPage(QObject *parent, Integration flags) : QWebPage(parent), d(new KWebPagePrivate(this)) { // KDE KParts integration for tag... if (!flags || (flags & KPartsIntegration)) { setPluginFactory(new KWebPluginFactory(this)); } QWidget *parentWidget = qobject_cast(parent); - d->window = (parentWidget ? parentWidget->window() : 0); + d->window = (parentWidget ? parentWidget->window() : nullptr); // KDE IO (KIO) integration... if (!flags || (flags & KIOIntegration)) { KIO::Integration::AccessManager *manager = new KIO::Integration::AccessManager(this); // Disable QtWebKit's internal cache to avoid duplication with the one in KIO... - manager->setCache(0); + manager->setCache(nullptr); manager->setWindow(d->window); manager->setEmitReadyReadOnMetaDataChange(true); setNetworkAccessManager(manager); } // KWallet integration... if (!flags || (flags & KWalletIntegration)) { - setWallet(new KWebWallet(0, (d->window ? d->window->winId() : 0))); + setWallet(new KWebWallet(nullptr, (d->window ? d->window->winId() : 0))); } setActionIcon(action(Back), QIcon::fromTheme("go-previous")); setActionIcon(action(Forward), QIcon::fromTheme("go-next")); setActionIcon(action(Reload), QIcon::fromTheme("view-refresh")); setActionIcon(action(Stop), QIcon::fromTheme("process-stop")); setActionIcon(action(Cut), QIcon::fromTheme("edit-cut")); setActionIcon(action(Copy), QIcon::fromTheme("edit-copy")); setActionIcon(action(Paste), QIcon::fromTheme("edit-paste")); setActionIcon(action(Undo), QIcon::fromTheme("edit-undo")); setActionIcon(action(Redo), QIcon::fromTheme("edit-redo")); setActionIcon(action(SelectAll), QIcon::fromTheme("edit-select-all")); setActionIcon(action(InspectElement), QIcon::fromTheme("view-process-all")); setActionIcon(action(OpenLinkInNewWindow), QIcon::fromTheme("window-new")); setActionIcon(action(OpenFrameInNewWindow), QIcon::fromTheme("window-new")); setActionIcon(action(OpenImageInNewWindow), QIcon::fromTheme("window-new")); setActionIcon(action(CopyLinkToClipboard), QIcon::fromTheme("edit-copy")); setActionIcon(action(CopyImageToClipboard), QIcon::fromTheme("edit-copy")); setActionIcon(action(ToggleBold), QIcon::fromTheme("format-text-bold")); setActionIcon(action(ToggleItalic), QIcon::fromTheme("format-text-italic")); setActionIcon(action(ToggleUnderline), QIcon::fromTheme("format-text-underline")); setActionIcon(action(DownloadLinkToDisk), QIcon::fromTheme("document-save")); setActionIcon(action(DownloadImageToDisk), QIcon::fromTheme("document-save")); settings()->setWebGraphic(QWebSettings::MissingPluginGraphic, QIcon::fromTheme("preferences-plugin").pixmap(32, 32)); settings()->setWebGraphic(QWebSettings::MissingImageGraphic, QIcon::fromTheme("image-missing").pixmap(32, 32)); settings()->setWebGraphic(QWebSettings::DefaultFrameIconGraphic, QIcon::fromTheme("applications-internet").pixmap(32, 32)); setActionShortcut(action(Back), KStandardShortcut::back()); setActionShortcut(action(Forward), KStandardShortcut::forward()); setActionShortcut(action(Reload), KStandardShortcut::reload()); setActionShortcut(action(Stop), QList() << QKeySequence(Qt::Key_Escape)); setActionShortcut(action(Cut), KStandardShortcut::cut()); setActionShortcut(action(Copy), KStandardShortcut::copy()); setActionShortcut(action(Paste), KStandardShortcut::paste()); setActionShortcut(action(Undo), KStandardShortcut::undo()); setActionShortcut(action(Redo), KStandardShortcut::redo()); setActionShortcut(action(SelectAll), KStandardShortcut::selectAll()); } KWebPage::~KWebPage() { delete d; } bool KWebPage::isExternalContentAllowed() const { KIO::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { return manager->isExternalContentAllowed(); } return true; } KWebWallet *KWebPage::wallet() const { return d->wallet; } void KWebPage::setAllowExternalContent(bool allow) { KIO::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { manager->setExternalContentAllowed(allow); } } void KWebPage::setWallet(KWebWallet *wallet) { // Delete the current wallet if this object is its parent... if (d->wallet && this == d->wallet->parent()) { delete d->wallet; } d->wallet = wallet; if (d->wallet) { d->wallet->setParent(this); } } void KWebPage::downloadRequest(const QNetworkRequest &request) { KIO::TransferJob *job = KIO::get(request.url()); connect(job, SIGNAL(mimetype(KIO::Job*,QString)), this, SLOT(_k_receivedContentType(KIO::Job*,QString))); job->setMetaData(request.attribute(static_cast(KIO::AccessManager::MetaData)).toMap()); job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache. job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available. KJobWidgets::setWindow(job, d->windowWidget()); } void KWebPage::downloadUrl(const QUrl &url) { downloadRequest(QNetworkRequest(url)); } void KWebPage::downloadResponse(QNetworkReply *reply) { Q_ASSERT(reply); if (!reply) { return; } // Put the job on hold only for the protocols we know about (read: http). KIO::Integration::AccessManager::putReplyOnHold(reply); QString mimeType; KIO::MetaData metaData; if (handleReply(reply, &mimeType, &metaData)) { return; } const QUrl replyUrl(reply->url()); // Ask KRun to handle the response when mimetype is unknown if (mimeType.isEmpty()) { (void)new KRun(replyUrl, d->windowWidget()); return; } // Ask KRun::runUrl to handle the response when mimetype is inode/* if (mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive) && KRun::runUrl(replyUrl, mimeType, d->windowWidget(), false, false, metaData.value(QL1S("content-disposition-filename")))) { return; } } QString KWebPage::sessionMetaData(const QString &key) const { QString value; KIO::Integration::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { value = manager->sessionMetaData().value(key); } return value; } QString KWebPage::requestMetaData(const QString &key) const { QString value; KIO::Integration::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { value = manager->requestMetaData().value(key); } return value; } void KWebPage::setSessionMetaData(const QString &key, const QString &value) { KIO::Integration::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { manager->sessionMetaData()[key] = value; } } void KWebPage::setRequestMetaData(const QString &key, const QString &value) { KIO::Integration::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { manager->requestMetaData()[key] = value; } } void KWebPage::removeSessionMetaData(const QString &key) { KIO::Integration::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { manager->sessionMetaData().remove(key); } } void KWebPage::removeRequestMetaData(const QString &key) { KIO::Integration::AccessManager *manager = qobject_cast(networkAccessManager()); if (manager) { manager->requestMetaData().remove(key); } } QString KWebPage::userAgentForUrl(const QUrl &_url) const { const QUrl url(_url); const QString userAgent = KProtocolManager::userAgentForHost((url.isLocalFile() ? QL1S("localhost") : url.host())); if (userAgent == KProtocolManager::defaultUserAgent()) { return QWebPage::userAgentForUrl(_url); } return userAgent; } static void setDisableCookieJarStorage(QNetworkAccessManager *manager, bool status) { if (manager) { - KIO::Integration::CookieJar *cookieJar = manager ? qobject_cast(manager->cookieJar()) : 0; + KIO::Integration::CookieJar *cookieJar = manager ? qobject_cast(manager->cookieJar()) : nullptr; if (cookieJar) { //qDebug() << "Store cookies ?" << !status; cookieJar->setDisableCookieStorage(status); } } } bool KWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type) { // qDebug() << "url:" << request.url() << ", type:" << type << ", frame:" << frame; if (frame && d->wallet && type == QWebPage::NavigationTypeFormSubmitted) { d->wallet->saveFormData(frame); } // Make sure nothing is cached when private browsing mode is enabled... if (settings()->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { if (!d->inPrivateBrowsingMode) { setDisableCookieJarStorage(networkAccessManager(), true); setSessionMetaData(QL1S("no-cache"), QL1S("true")); d->inPrivateBrowsingMode = true; } } else { if (d->inPrivateBrowsingMode) { setDisableCookieJarStorage(networkAccessManager(), false); removeSessionMetaData(QL1S("no-cache")); d->inPrivateBrowsingMode = false; } } /* If the navigation request is from the main frame, set the cross-domain meta-data value to the current url for proper integration with KCookieJar... */ if (frame == mainFrame() && type != QWebPage::NavigationTypeReload) { setSessionMetaData(QL1S("cross-domain"), request.url().toString()); } return QWebPage::acceptNavigationRequest(frame, request, type); } bool KWebPage::handleReply(QNetworkReply *reply, QString *contentType, KIO::MetaData *metaData) { // Reply url... const QUrl replyUrl(reply->url()); // Get suggested file name... const KIO::MetaData &data = reply->attribute(static_cast(KIO::AccessManager::MetaData)).toMap(); const QString suggestedFileName = data.value(QL1S("content-disposition-filename")); if (metaData) { *metaData = data; } // Get the mime-type... QString mimeType; extractMimeType(reply, mimeType); if (contentType) { *contentType = mimeType; } // Let the calling function deal with handling empty or inode/* mimetypes... if (mimeType.isEmpty() || mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive)) { return false; } // Convert executable text files to plain text... if (KParts::BrowserRun::isTextExecutable(mimeType)) { mimeType = QL1S("text/plain"); } //qDebug() << "Content-disposition:" << suggestedFileName; //qDebug() << "Got unsupported content of type:" << mimeType << "URL:" << replyUrl; //qDebug() << "Error code:" << reply->error() << reply->errorString(); if (isReplyStatusOk(reply)) { while (true) { KParts::BrowserOpenOrSaveQuestion::Result result; KParts::BrowserOpenOrSaveQuestion dlg(d->windowWidget(), replyUrl, mimeType); dlg.setSuggestedFileName(suggestedFileName); dlg.setFeatures(KParts::BrowserOpenOrSaveQuestion::ServiceSelection); result = dlg.askOpenOrSave(); switch (result) { case KParts::BrowserOpenOrSaveQuestion::Open: // Handle Post operations that return content... if (reply->operation() == QNetworkAccessManager::PostOperation) { d->mimeType = mimeType; QFileInfo finfo(suggestedFileName.isEmpty() ? replyUrl.fileName() : suggestedFileName); QTemporaryFile tempFile(QDir::tempPath() + QLatin1String("/kwebpage_XXXXXX.") + finfo.suffix()); tempFile.setAutoRemove(false); tempFile.open(); const QUrl destUrl = QUrl::fromLocalFile(tempFile.fileName()); KIO::Job *job = KIO::file_copy(replyUrl, destUrl, 0600, KIO::Overwrite); KJobWidgets::setWindow(job, d->windowWidget()); job->ui()->setAutoErrorHandlingEnabled(true); connect(job, SIGNAL(result(KJob*)), this, SLOT(_k_copyResultToTempFile(KJob*))); return true; } // Ask before running any executables... if (KParts::BrowserRun::allowExecution(mimeType, replyUrl)) { KService::Ptr offer = dlg.selectedService(); // HACK: The check below is necessary to break an infinite // recursion that occurs whenever this function is called as a result // of receiving content that can be rendered by the app using this engine. // For example a text/html header that containing a content-disposition // header is received by the app using this class. if (isMimeTypeAssociatedWithSelf(offer)) { reloadRequestWithoutDisposition(reply); } else { QList list; list.append(replyUrl); bool success = false; // qDebug() << "Suggested file name:" << suggestedFileName; if (offer) { success = KRun::run(*offer, list, d->windowWidget(), false, suggestedFileName); } else { success = KRun::displayOpenWithDialog(list, d->windowWidget(), false, suggestedFileName); if (!success) { break; } } // For non KIO apps and cancelled Open With dialog, remove slave on hold. if (!success || (offer && !offer->categories().contains(QL1S("KDE")))) { KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold... } } return true; } // TODO: Instead of silently failing when allowExecution fails, notify // the user why the requested action cannot be fulfilled... return false; case KParts::BrowserOpenOrSaveQuestion::Save: // Do not download local files... if (!replyUrl.isLocalFile()) { QString downloadCmd(reply->property("DownloadManagerExe").toString()); if (!downloadCmd.isEmpty()) { downloadCmd += QLatin1Char(' '); downloadCmd += KShell::quoteArg(replyUrl.url()); if (!suggestedFileName.isEmpty()) { downloadCmd += QLatin1Char(' '); downloadCmd += KShell::quoteArg(suggestedFileName); } // qDebug() << "download command:" << downloadCmd; if (KRun::runCommand(downloadCmd, view())) { return true; } } if (!downloadResource(replyUrl, suggestedFileName, d->windowWidget())) { return true; // file dialog was cancelled, stop here } } return true; case KParts::BrowserOpenOrSaveQuestion::Cancel: default: KIO::SimpleJob::removeOnHold(); // Remove any slave-on-hold... return true; } } } else { KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimeType); if (isMimeTypeAssociatedWithSelf(offer)) { reloadRequestWithoutDisposition(reply); return true; } } return false; } #include "moc_kwebpage.cpp" diff --git a/src/kwebpage.h b/src/kwebpage.h index f40e64e..deddc10 100644 --- a/src/kwebpage.h +++ b/src/kwebpage.h @@ -1,367 +1,367 @@ /* * This file is part of the KDE project. * * Copyright (C) 2008 Dirk Mueller * Copyright (C) 2008 Urs Wolfer * Copyright (C) 2008 Michael Howell * Copyright (C) 2009,2010 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KWEBPAGE_H #define KWEBPAGE_H #include #include class KWebWallet; class KJob; namespace KIO { class MetaData; class Job; } /** * @short An enhanced QWebPage that provides integration with KDE Frameworks. * * This is a convenience class that provides full integration with KDE * frameworks technologies such as KIO for network request handling, KCookiejar * for cookie handling, KParts for embedding non-html content and KWallet for * storing form data. It also sets standard icons for many of the actions * provided by QWebPage. * * Most of this integration happens behind the scenes. If you want KWallet * integration, however, you will have to provide a mechanism for deciding * whether to allow form data to be stored. To do this, you will need to * connect to the KWebWallet::saveFormDataRequested signal and call either * KWebWallet::acceptSaveFormDataRequest or * KWebWallet::rejectSaveFormDataRequest, typically after asking the user * whether they want to save the form data. If you do not do this, no form * data will be saved. * * KWebPage will also not automatically load form data for you. You should * connect to QWebPage::loadFinished and, if the page was loaded successfully, * call * @code * page->wallet()->fillFormData(page->mainFrame()); * @endcode * * @see KIO::Integration * @see KWebWallet * * @author Urs Wolfer * @author Dawit Alemayehu * * @since 4.4 */ class KDEWEBKIT_EXPORT KWebPage : public QWebPage { Q_OBJECT public: /** * Flags for setting the desired level of integration. */ enum IntegrationFlags { /** * Provide only very basic integration such as using KDE icons for the * actions provided by QWebPage. */ NoIntegration = 0x01, /** * Use KIO to handle network requests. * * @see KIO::Integration::AccessManager */ KIOIntegration = 0x02, /** * Use KPart componenets, if available, to display content in * <embed> and <object> tags. */ KPartsIntegration = 0x04, /** * Use KWallet to store login credentials and other form data from web * sites. * * @see wallet() and setWallet() */ KWalletIntegration = 0x08 }; Q_DECLARE_FLAGS(Integration, IntegrationFlags) Q_FLAG(Integration) /** * Constructs a KWebPage with parent @p parent. * * Note that if no integration flags are set (the default), all integration * options are activated. If you inherit from this class you can use the * flags in @ref IntegrationFlags to control how much integration should * be used. * * @see KIO::Integration::CookieJar * @see KIO::Integration::AccessManager * @see wallet() and setWallet() */ - explicit KWebPage(QObject *parent = 0, Integration flags = Integration()); + explicit KWebPage(QObject *parent = nullptr, Integration flags = Integration()); /** * Destroys the KWebPage. */ ~KWebPage(); /** * Whether access to remote content is permitted. * * If this is @c false, only resources on the local system can be accessed * through this web page. By default access to remote content is allowed. * * If KIO integration is disabled, this will always return @c true. * * @see setAllowExternalContent() * @see KIO::Integration::AccessManager::isExternalContentAllowed() * * @return @c true if access to remote content is permitted, @c false otherwise */ bool isExternalContentAllowed() const; /** * The wallet integration manager. * * If you wish to use KWallet integration, you will have to connect to * signals emitted by this object and react accordingly. See KWebWallet * for more information. * * @return the wallet integration manager, or 0 if KWallet integration * is disabled */ KWebWallet *wallet() const; /** * Set whether to allow remote content. * * If KIO integration is not enabled, this method will have no effect. * * @see isExternalContentAllowed() * @see KIO::Integration::AccessManager::setAllowExternalContent(bool) * * @param allow @c true if access to remote content should be allowed, * @c false if only local content should be accessible */ void setAllowExternalContent(bool allow); /** * Set the @ref KWebWallet that is used to store form data. * * This KWebPage will take ownership of @p wallet, so that the wallet * is deleted when the KWebPage is deleted. If you do not want that * to happen, you should call setParent() on @p wallet after calling * this function. * * @see KWebWallet * * @param wallet the KWebWallet to be used for storing form data, or * 0 to disable KWallet integration */ void setWallet(KWebWallet *wallet); public Q_SLOTS: /** * Download @p request using KIO. * * This slot first prompts the user where to save the requested * resource and then downloads it using KIO. */ virtual void downloadRequest(const QNetworkRequest &request); /** * Download @p url using KIO. * * This slot first prompts the user where to save the requested * resource and then downloads it using KIO. */ virtual void downloadUrl(const QUrl &url); /** * Download the resource specified by @p reply using KIO. * * This slot first prompts the user where to save the requested resource * and then downloads it using KIO. * * If @p reply contains a QObject property called "DownloadManagerExe", then * an attempt will be made to the command specified by that property to * download the specified resource. * * If the "DownloadManagerExe" property is not defined or the command * specified by it could not be successfully executed, then the user will * be prompted for the action to take. * * @since 4.5 * @see handleReply */ void downloadResponse(QNetworkReply *reply); protected: /** * Get an item of session metadata. * * Retrieves the value of the permanent (per-session) metadata for @p key. * * If KIO integration is disabled, this will always return an empty string. * * @see KIO::Integration::AccessManager::sessionMetaData * @see setSessionMetaData * * @param key the key of the metadata to retrieve * @return the value of the metadata associated with @p key, or an * empty string if there is no such metadata */ QString sessionMetaData(const QString &key) const; /** * Get an item of request metadata. * * Retrieves the value of the temporary (per-request) metadata for @p key. * * If KIO integration is disabled, this will always return an empty string. * * @see KIO::Integration::AccessManager::requestMetaData * @see setRequestMetaData * * @param key the key of the metadata to retrieve * @return the value of the metadata associated with @p key, or an * empty string if there is no such metadata */ QString requestMetaData(const QString &key) const; /** * Set an item of metadata to be sent to the KIO slave with every request. * * If KIO integration is disabled, this method will have no effect. * * Metadata set using this method will be sent with every request. * * @see KIO::Integration::AccessManager::sessionMetaData * * @param key the key for the metadata; any existing metadata associated * with this key will be overwritten * @param value the value to associate with @p key */ void setSessionMetaData(const QString &key, const QString &value); /** * Set an item of metadata to be sent to the KIO slave with the next request. * * If KIO integration is disabled, this method will have no effect. * * Metadata set using this method will be deleted after it has been sent * once. * * @see KIO::Integration::AccessManager::requestMetaData * * @param key the key for the metadata; any existing metadata associated * with this key will be overwritten * @param value the value to associate with @p key */ void setRequestMetaData(const QString &key, const QString &value); /** * Remove an item of session metadata. * * Removes the permanent (per-session) metadata associated with @p key. * * @see KIO::Integration::AccessManager::sessionMetaData * @see setSessionMetaData * * @param key the key for the metadata to remove */ void removeSessionMetaData(const QString &key); /** * Remove an item of request metadata. * * Removes the temporary (per-request) metadata associated with @p key. * * @see KIO::Integration::AccessManager::requestMetaData * @see setRequestMetaData * * @param key the key for the metadata to remove */ void removeRequestMetaData(const QString &key); /** * @reimp * * This function is re-implemented to provide KIO user-agent management * integration with KProtocolManager. * * If a special user-agent has been configured for the host indicated by * @p url, that user-agent will be returned. Otherwise, QWebPage's * default user agent is returned. * * @see KProtocolManager::userAgentForHost. * @see QWebPage::userAgentForUrl. */ QString userAgentForUrl(const QUrl &url) const Q_DECL_OVERRIDE; /** * @reimp * * This performs various integration-related actions when navigation is * requested. If you override this method, make sure you call the parent's * implementation unless you want to block the request outright. * * If you do override acceptNavigationRequest and call this method, * however, be aware of the effect of the page's linkDelegationPolicy on * how * QWebPage::acceptNavigationRequest behaves. * * @see QWebPage::acceptNavigationRequest */ bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type) Q_DECL_OVERRIDE; /** * Attempts to handle @p reply and returns true on success, false otherwise. * * If @p reply contains a QObject property called "DownloadManagerExe", then * an attempt will be made to let the command specified by that property to * download the requested resource. * * If the "DownloadManagerExe" property is not defined or the command * specified by it could not be successfully executed, then the user will * be prompted for the action to take. * * @param reply the QNetworkReply object to be handled. * @param contentType if not null, it will be set to the content-type specified in @p reply, if any. * @param metaData if not null, it will be set to the KIO meta-data specified in @p reply, if any. * @since 4.6.3 */ - bool handleReply(QNetworkReply *reply, QString *contentType = 0, KIO::MetaData *metaData = 0); + bool handleReply(QNetworkReply *reply, QString *contentType = nullptr, KIO::MetaData *metaData = nullptr); private: class KWebPagePrivate; KWebPagePrivate *const d; Q_PRIVATE_SLOT(d, void _k_copyResultToTempFile(KJob *)) Q_PRIVATE_SLOT(d, void _k_receivedContentType(KIO::Job *, const QString &)) Q_PRIVATE_SLOT(d, void _k_contentTypeCheckFailed(KJob *)) }; Q_DECLARE_OPERATORS_FOR_FLAGS(KWebPage::Integration) #endif // KWEBPAGE_H diff --git a/src/kwebpluginfactory.cpp b/src/kwebpluginfactory.cpp index 75e38f8..26c85a5 100644 --- a/src/kwebpluginfactory.cpp +++ b/src/kwebpluginfactory.cpp @@ -1,171 +1,171 @@ /* * This file is part of the KDE project. * * Copyright (C) 2008 Michael Howell * Copyright (C) 2008 Urs Wolfer * Copyright (C) 2009 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "kwebpluginfactory.h" #include "kwebpage.h" #include "kwebview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #define QL1S(x) QLatin1String(x) #define QL1C(x) QLatin1Char(x) KWebPluginFactory::KWebPluginFactory(QObject *parent) - : QWebPluginFactory(parent), d(0) + : QWebPluginFactory(parent), d(nullptr) { } KWebPluginFactory::~KWebPluginFactory() { } QObject *KWebPluginFactory::create(const QString &_mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const { QString mimeType(_mimeType.trimmed()); // If no mimetype is provided, we do our best to correctly determine it here... if (mimeType.isEmpty()) { // qDebug() << "Looking up missing mimetype for plugin resource:" << url; extractGuessedMimeType(url, &mimeType); // qDebug() << "Updated mimetype to" << mimeType; } // Defer handling of flash content to QtWebKit's builtin viewer. // If you want to use/test KDE's nspluginviewer, comment out the // if statement below. - KParts::ReadOnlyPart *part = (excludedMimeType(mimeType) ? 0 : createPartInstanceFrom(mimeType, argumentNames, argumentValues, 0, parent())); + KParts::ReadOnlyPart *part = (excludedMimeType(mimeType) ? nullptr : createPartInstanceFrom(mimeType, argumentNames, argumentValues, nullptr, parent())); // qDebug() << "Asked for" << mimeType << "plugin, got" << part; if (part) { QMap metaData = part->arguments().metaData(); QString urlStr = url.toString(QUrl::RemovePath | QUrl::RemoveQuery | QUrl::RemoveFragment); metaData.insert("PropagateHttpHeader", "true"); metaData.insert("referrer", urlStr); metaData.insert("cross-domain", urlStr); metaData.insert("main_frame_request", "TRUE"); metaData.insert("ssl_activate_warnings", "TRUE"); KWebPage *page = qobject_cast(parent()); if (page) { const QString scheme = page->currentFrame()->url().scheme(); if (page && (QString::compare(scheme, QL1S("https"), Qt::CaseInsensitive) == 0 || QString::compare(scheme, QL1S("webdavs"), Qt::CaseInsensitive) == 0)) { metaData.insert("ssl_was_in_use", "TRUE"); } else { metaData.insert("ssl_was_in_use", "FALSE"); } } KParts::OpenUrlArguments openUrlArgs = part->arguments(); openUrlArgs.metaData() = metaData; openUrlArgs.setMimeType(mimeType); part->setArguments(openUrlArgs); part->openUrl(url); return part->widget(); } - return 0; + return nullptr; } QList KWebPluginFactory::plugins() const { QList plugins; return plugins; } static bool isHttpProtocol(const QUrl &url) { const QString scheme(url.scheme()); return (scheme.startsWith(QL1S("http"), Qt::CaseInsensitive) || scheme.startsWith(QL1S("webdav"), Qt::CaseInsensitive)); } void KWebPluginFactory::extractGuessedMimeType(const QUrl &url, QString *mimeType) const { if (mimeType) { const QUrl reqUrl((isHttpProtocol(url) ? QUrl(url.path()) : url)); QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(reqUrl.path(), QMimeDatabase::MatchExtension); if (!mime.isDefault() && !mime.name().startsWith(QL1S("inode/"))) { *mimeType = mime.name(); } } } KParts::ReadOnlyPart *KWebPluginFactory::createPartInstanceFrom(const QString &mimeType, const QStringList &argumentNames, const QStringList &argumentValues, QWidget *parentWidget, QObject *parentObj) const { - KParts::ReadOnlyPart *part = 0; + KParts::ReadOnlyPart *part = nullptr; if (!mimeType.isEmpty()) { // Only attempt to find a KPart for the supported mime types... QVariantList arguments; const int count = argumentNames.count(); for (int i = 0; i < count; ++i) { arguments << QString(argumentNames.at(i) + QL1S("=\"") + argumentValues.at(i) + QL1C('\"')); } part = KMimeTypeTrader::createPartInstanceFromQuery(mimeType, parentWidget, parentObj, QString(), arguments); } return part; } bool KWebPluginFactory::excludedMimeType(const QString &mimeType) const { if (mimeType.startsWith(QL1S("inode/"), Qt::CaseInsensitive)) { return true; } if (mimeType.startsWith(QL1S("application/x-java"), Qt::CaseInsensitive)) { return true; } if (mimeType == QL1S("application/x-shockwave-flash") || mimeType == QL1S("application/futuresplash")) { return true; } return false; } diff --git a/src/kwebpluginfactory.h b/src/kwebpluginfactory.h index 45b444b..d6b5bd9 100644 --- a/src/kwebpluginfactory.h +++ b/src/kwebpluginfactory.h @@ -1,139 +1,139 @@ /* * This file is part of the KDE project. * * Copyright (C) 2008 Michael Howell * Copyright (C) 2009 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KWEBPLUGINFACTORY_H #define KWEBPLUGINFACTORY_H #include #include namespace KParts { class ReadOnlyPart; } /** * @short A QWebPluginFactory that is integrated with KDE frameworks. * * This class will attempt to find a KPart to satisfy a plugin request. * * @author Michael Howell * @author Dawit Alemayehu * * @see QWebPluginFactory * @since 4.4 */ class KDEWEBKIT_EXPORT KWebPluginFactory : public QWebPluginFactory { Q_OBJECT public: /** * Constructs a KWebPluginFactory with parent @p parent. */ KWebPluginFactory(QObject *parent); /** * Destroys the KWebPage. */ ~KWebPluginFactory(); /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWebPluginFactory::create * @internal */ virtual QObject *create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const Q_DECL_OVERRIDE; /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWebPluginFactory::plugins * @internal */ QList plugins() const Q_DECL_OVERRIDE; protected: /** * Sets @p mimeType to the content type guessed from @p url. * * Note that attempting to guess mime-type will not always produce the * correct content-type. This is especially true for the HTTP protocol * since the URL present might be for a cgi script URL instead of a static * URL that directly points to the content. * * If @p mimeType is not NULL, this function will set it to the content * type determined from @p url. * * @since 4.8.3 */ void extractGuessedMimeType(const QUrl &url, QString *mimeType) const; /** * Returns true if the given mime-type is excluded from being used to create * a web plugin using KService's trader. * * Currently this function only returns true for mimetypes 'x-java', * 'x-shockwave-flash', and 'futuresplash' in the 'application' category * and everything under the 'inode' category. * * @since 4.8.3 */ bool excludedMimeType(const QString &mimeType) const; /** * Returns an instance of the service associated with @p mimeType. * * This function uses KService's trader to create an instance of the service * associated with the given parameters. The parameters are the * tags of the HTML object. The name and the value attributes of these * tags are specified by the @p argumentNames and @p argumentValues * respectively. * * The @p parentWidget and @p parent parameters specify the widget to use * as the parent of the newly created part and the parent for the part * itself respectively. * * The parameters for this function mirror that of @ref QWebPluginFactory::create. * * @see QWebPluginFactory::create * @since 4.8.3 */ KParts::ReadOnlyPart *createPartInstanceFrom(const QString &mimeType, const QStringList &argumentNames, const QStringList &argumentValues, - QWidget *parentWidget = 0, - QObject *parent = 0) const; + QWidget *parentWidget = nullptr, + QObject *parent = nullptr) const; private: class KWebPluginFactoryPrivate; KWebPluginFactoryPrivate *const d; }; #endif // KWEBPLUGINFACTORY_H diff --git a/src/kwebview.h b/src/kwebview.h index 8de0acf..3145ae9 100644 --- a/src/kwebview.h +++ b/src/kwebview.h @@ -1,208 +1,208 @@ /* * This file is part of the KDE project. * * Copyright (C) 2007 Trolltech ASA * Copyright (C) 2008 Urs Wolfer * Copyright (C) 2008 Laurent Montel * Copyright (C) 2008 Michael Howell * Copyright (C) 2009 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KWEBVIEW_H #define KWEBVIEW_H #include #include class QUrl; template class KWebViewPrivate; /** * @short A re-implementation of QWebView that provides integration with KDE * frameworks. * * This is a drop-in replacement for QWebView that provides full KDE frameworks * integration through @ref KWebPage as well as additional signals that * capture middle, shift and ctrl mouse clicks on links and URL pasting * from the selection clipboard. * * The specific functionality provided by this class (over and above what * would be acheived by using KWebPage with a QWebView) is that scrolling * with the mouse wheel while holding down CTRL zooms the page (see * QWebView::setZoomFactor) and several useful signals are emitted when * the user performs certain actions. * * See the signal documentation for more details. * * @author Urs Wolfer * @author Dawit Alemayehu * @since 4.4 */ class KDEWEBKIT_EXPORT KWebView : public QWebView { Q_OBJECT Q_PROPERTY(bool externalContentAllowed READ isExternalContentAllowed WRITE setAllowExternalContent) public: /** * Constructs a KWebView object with parent @p parent. * * Set @p createCustomPage to false to prevent the creation of a * @ref KWebPage object for KDE frameworks integration. Doing so allows you * to avoid unnecessary object creation and deletion if you are going to use * a subclass of KWebPage. * * @param parent the parent object * @param createCustomPage if @c true, the view's page is set to an * instance of KWebPage */ - explicit KWebView(QWidget *parent = 0, bool createCustomPage = true); + explicit KWebView(QWidget *parent = nullptr, bool createCustomPage = true); /** * Destroys the KWebView. */ ~KWebView(); /** * Returns true if access to remote content is allowed. * * By default access to remote content is allowed. * * @see setAllowExternalContent() * @see KWebPage::isExternalContentAllowed() */ bool isExternalContentAllowed() const; /** * Set @p allow to false if you want to prevent access to remote content. * * If this function is set to false only resources on the local system * can be accessed through this class. By default fetching external content * is allowed. * * @see isExternalContentAllowed() * @see KWebPage::setAllowExternalContent(bool) */ void setAllowExternalContent(bool allow); Q_SIGNALS: /** * Emitted when a URL from the selection clipboard is pasted on this view. * * This is triggered when the user clicks on the page with the middle * mouse button when there is something in the global mouse selection * clipboard. This is typically only possible on X11. * * Uri filters are applied to the selection clipboard to generate @p url. * * If the content in the selection clipboard is not a valid url and a * default search engine is configured, @p url will be set to a query * to the default search engine. * * @param url url generated from the selection clipboard content * * @deprecated use selectionClipboardUrlPasted(QUrl, bool) instead * @see QClipboard */ #ifndef KDEWEBKIT_NO_DEPRECATED KDEWEBKIT_DEPRECATED void selectionClipboardUrlPasted(const QUrl &url); #endif /** * Emitted when a URL from the selection clipboard is pasted on this view. * * This is triggered when the user clicks on the page with the middle * mouse button when there is something in the global mouse selection * clipboard. This is typically only possible on X11. * * Uri filters are applied to the selection clipboard to generate @p url. * * If the content in the selection clipboard is not a valid URL and a * default search engine is configured, @p searchText will be set to the * content of the clipboard (250 characters maximum) and @p url will be * set to a query to the default search engine. * * @param url the URL generated from the selection clipboard content * @param searchText content of the selection clipboard if it is not a * valid URL * * @see KUriFilter * @see QClipboard * @since 4.6 */ void selectionClipboardUrlPasted(const QUrl &url, const QString &searchText); /** * Emitted when a link is clicked with the left mouse button while SHIFT is * held down. * * A user of Plasma desktop would typically expect this to result in the * triggering of a "save link as" action. * * @param url the URL of the clicked link */ void linkShiftClicked(const QUrl &url); /** * Emitted when a link is clicked with the middle mouse button or clicked * with the left mouse button while CTRL is held down. * * Typically, the user would expect this to result in the URL being opened * in a new tab or window. * * @param url the URL of the clicked link */ void linkMiddleOrCtrlClicked(const QUrl &url); protected: /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWidget::wheelEvent * @internal */ void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWidget::mousePressEvent * @internal */ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; /** * @reimp * * Reimplemented for internal reasons, the API is not affected. * * @see QWidget::mouseReleaseEvent * @internal */ void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; private: friend class KWebViewPrivate; KWebViewPrivate *const d; }; #endif // KWEBVIEW_H diff --git a/src/kwebwallet.cpp b/src/kwebwallet.cpp index 24d23c2..ce0f703 100644 --- a/src/kwebwallet.cpp +++ b/src/kwebwallet.cpp @@ -1,633 +1,633 @@ /* * This file is part of the KDE project. * * Copyright (C) 2009 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "kwebwallet.h" #include #include #include #include #include #include #include #include #include #include #include #include #define QL1S(x) QLatin1String(x) #define QL1C(x) QLatin1Char(x) // Javascript used to extract/set data from
elements. #define FILLABLE_FORM_ELEMENT_EXTRACTOR_JS "(function (){ \ var forms; \ var formList = document.forms; \ if (formList.length > 0) { \ forms = new Array; \ for (var i = 0; i < formList.length; ++i) { \ var inputList = formList[i].elements; \ if (inputList.length < 1) { \ continue; \ } \ var formObject = new Object; \ formObject.name = formList[i].name; \ if (typeof(formObject.name) != 'string') { \ formObject.name = String(formList[i].id); \ } \ formObject.index = i; \ formObject.elements = new Array; \ for (var j = 0; j < inputList.length; ++j) { \ if (inputList[j].type != 'text' && inputList[j].type != 'email' && inputList[j].type != 'password') { \ continue; \ } \ if (inputList[j].disabled || inputList[j].autocomplete == 'off') { \ continue; \ } \ var element = new Object; \ element.name = inputList[j].name; \ if (typeof(element.name) != 'string' ) { \ element.name = String(inputList[j].id); \ } \ element.value = String(inputList[j].value); \ element.type = String(inputList[j].type); \ element.readonly = Boolean(inputList[j].readOnly); \ formObject.elements.push(element); \ } \ if (formObject.elements.length > 0) { \ forms.push(formObject); \ } \ } \ } \ return forms; \ }())" /** * Creates key used to store and retrieve form data. * */ static QString walletKey(KWebWallet::WebForm form) { QString key = form.url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment); key += QL1C('#'); key += form.name; return key; } static void collectAllChildFrames(QWebFrame *frame, QList &list) { list << frame->childFrames(); QListIterator it(frame->childFrames()); while (it.hasNext()) { collectAllChildFrames(it.next(), list); } } static QUrl urlForFrame(QWebFrame *frame) { return (frame->url().isEmpty() ? frame->baseUrl().resolved(frame->url()) : frame->url()); } /* Returns the top most window associated with widget. Unlike QWidget::window(), this function does its best to find and return the main application window associated with a given widget. It will not stop when it encounters a dialog which likely "has (or could have) a window-system frame". */ static QWidget *topLevelWindow(QObject *obj) { QWebPage *page = qobject_cast(obj); QWidget *widget = (page ? page->view() : qobject_cast(page)); while (widget && widget->parentWidget()) { widget = widget->parentWidget(); } - return (widget ? widget->window() : 0); + return (widget ? widget->window() : nullptr); } class KWebWallet::KWebWalletPrivate { public: struct FormsData { QPointer frame; KWebWallet::WebFormList forms; }; KWebWalletPrivate(KWebWallet *parent); KWebWallet::WebFormList parseFormData(QWebFrame *frame, bool fillform = true, bool ignorepasswd = false); void fillDataFromCache(KWebWallet::WebFormList &formList); void saveDataToCache(const QString &key); void removeDataFromCache(const WebFormList &formList); void openWallet(); // Private slots... void _k_openWalletDone(bool); void _k_walletClosed(); WId wid; KWebWallet *q; QScopedPointer wallet; KWebWallet::WebFormList pendingRemoveRequests; QHash pendingFillRequests; QHash pendingSaveRequests; QSet confirmSaveRequestOverwrites; }; KWebWallet::KWebWalletPrivate::KWebWalletPrivate(KWebWallet *parent) : wid(0), q(parent) { } KWebWallet::WebFormList KWebWallet::KWebWalletPrivate::parseFormData(QWebFrame *frame, bool fillform, bool ignorepasswd) { Q_ASSERT(frame); KWebWallet::WebFormList list; const QVariant result(frame->evaluateJavaScript(QL1S(FILLABLE_FORM_ELEMENT_EXTRACTOR_JS))); const QVariantList results(result.toList()); Q_FOREACH (const QVariant &formVariant, results) { QVariantMap map = formVariant.toMap(); KWebWallet::WebForm form; form.url = urlForFrame(frame); form.name = map[QL1S("name")].toString(); form.index = map[QL1S("index")].toString(); bool formHasPasswords = false; const QVariantList elements = map[QL1S("elements")].toList(); QList inputFields; Q_FOREACH (const QVariant &element, elements) { QVariantMap elementMap(element.toMap()); const QString name(elementMap[QL1S("name")].toString()); const QString value(ignorepasswd ? QString() : elementMap[QL1S("value")].toString()); if (name.isEmpty()) { continue; } if (fillform && elementMap[QL1S("readonly")].toBool()) { continue; } if (elementMap[QL1S("type")].toString().compare(QL1S("password"), Qt::CaseInsensitive) == 0) { if (!fillform && value.isEmpty()) { continue; } formHasPasswords = true; } inputFields.append(qMakePair(name, value)); } // Only add the input fields on form save requests... if (formHasPasswords || fillform) { form.fields = inputFields; } // Add the form to the list if we are saving it or it has cached data. if ((fillform && q->hasCachedFormData(form)) || (!fillform && !form.fields.isEmpty())) { list << form; } } return list; } void KWebWallet::KWebWalletPrivate::fillDataFromCache(KWebWallet::WebFormList &formList) { if (!wallet) { qWarning() << "Unable to retrieve form data from wallet"; return; } QString lastKey; QMap cachedValues; QMutableListIterator formIt(formList); while (formIt.hasNext()) { KWebWallet::WebForm &form = formIt.next(); const QString key(walletKey(form)); if (key != lastKey && wallet->readMap(key, cachedValues) != 0) { qWarning() << "Unable to read form data for key:" << key; continue; } for (int i = 0, count = form.fields.count(); i < count; ++i) { form.fields[i].second = cachedValues.value(form.fields[i].first); } lastKey = key; } } void KWebWallet::KWebWalletPrivate::saveDataToCache(const QString &key) { // Make sure the specified keys exists before acting on it. See BR# 270209. if (!pendingSaveRequests.contains(key)) { return; } bool success = false; const QUrl url = pendingSaveRequests.value(key).first().url; if (wallet) { int count = 0; const KWebWallet::WebFormList list = pendingSaveRequests.value(key); QListIterator formIt(list); while (formIt.hasNext()) { QMap values, storedValues; const KWebWallet::WebForm form = formIt.next(); const QString accessKey = walletKey(form); if (confirmSaveRequestOverwrites.contains(url)) { confirmSaveRequestOverwrites.remove(url); const int status = wallet->readMap(accessKey, storedValues); if (status == 0 && storedValues.count()) { QListIterator fieldIt(form.fields); while (fieldIt.hasNext()) { const KWebWallet::WebForm::WebField field = fieldIt.next(); if (storedValues.contains(field.first) && storedValues.value(field.first) != field.second) { emit q->saveFormDataRequested(key, url); return; } } // If we got here it means the new credential is exactly // the same as the one already cached ; so skip the // re-saving part... success = true; continue; } } QListIterator fieldIt(form.fields); while (fieldIt.hasNext()) { const KWebWallet::WebForm::WebField field = fieldIt.next(); values.insert(field.first, field.second); } if (wallet->writeMap(accessKey, values) == 0) { count++; } else { qWarning() << "Unable to write form data to wallet"; } } if (list.isEmpty() || count > 0) { success = true; } pendingSaveRequests.remove(key); } else { qWarning() << "NULL KWallet instance!"; } emit q->saveFormDataCompleted(url, success); } void KWebWallet::KWebWalletPrivate::openWallet() { if (!wallet.isNull()) { return; } wallet.reset(KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), wid, KWallet::Wallet::Asynchronous)); if (wallet.isNull()) { return; } connect(wallet.data(), SIGNAL(walletOpened(bool)), q, SLOT(_k_openWalletDone(bool))); connect(wallet.data(), SIGNAL(walletClosed()), q, SLOT(_k_walletClosed())); } void KWebWallet::KWebWalletPrivate::removeDataFromCache(const WebFormList &formList) { if (!wallet) { qWarning() << "NULL KWallet instance!"; return; } QListIterator formIt(formList); while (formIt.hasNext()) { wallet->removeEntry(walletKey(formIt.next())); } } void KWebWallet::KWebWalletPrivate::_k_openWalletDone(bool ok) { Q_ASSERT(wallet); if (ok && (wallet->hasFolder(KWallet::Wallet::FormDataFolder()) || wallet->createFolder(KWallet::Wallet::FormDataFolder())) && wallet->setFolder(KWallet::Wallet::FormDataFolder())) { // Do pending fill requests... if (!pendingFillRequests.isEmpty()) { QList urlList; QMutableHashIterator requestIt(pendingFillRequests); while (requestIt.hasNext()) { requestIt.next(); KWebWallet::WebFormList list = requestIt.value().forms; fillDataFromCache(list); q->fillWebForm(requestIt.key(), list); } pendingFillRequests.clear(); } // Do pending save requests... if (!pendingSaveRequests.isEmpty()) { QListIterator keysIt(pendingSaveRequests.keys()); while (keysIt.hasNext()) { saveDataToCache(keysIt.next()); } } // Do pending remove requests... if (!pendingRemoveRequests.isEmpty()) { removeDataFromCache(pendingRemoveRequests); pendingRemoveRequests.clear(); } } else { // Delete the wallet if opening the wallet failed or we were unable // to change to the folder we wanted to change to. delete wallet.take(); } } void KWebWallet::KWebWalletPrivate::_k_walletClosed() { if (wallet) { wallet.take()->deleteLater(); } emit q->walletClosed(); } KWebWallet::KWebWallet(QObject *parent, WId wid) : QObject(parent), d(new KWebWalletPrivate(this)) { if (!wid) { // If wid is 0, make a best effort attempt to discern it from our // parent object. QWidget *widget = topLevelWindow(parent); if (widget) { wid = widget->winId(); } } d->wid = wid; } KWebWallet::~KWebWallet() { delete d; } KWebWallet::WebFormList KWebWallet::formsWithCachedData(QWebFrame *frame, bool recursive) const { WebFormList list; if (frame) { list << d->parseFormData(frame); if (recursive) { QList childFrameList; collectAllChildFrames(frame, childFrameList); QListIterator framesIt(childFrameList); while (framesIt.hasNext()) { list << d->parseFormData(framesIt.next()); } } } return list; } void KWebWallet::fillFormData(QWebFrame *frame, bool recursive) { if (!frame) { return; } QList urlList; WebFormList formsList = d->parseFormData(frame); if (!formsList.isEmpty()) { const QUrl url(urlForFrame(frame)); if (d->pendingFillRequests.contains(url)) { qWarning() << "Duplicate request rejected!"; } else { KWebWalletPrivate::FormsData data; data.frame = QPointer(frame); data.forms << formsList; d->pendingFillRequests.insert(url, data); urlList << url; } } if (recursive) { QList childFrameList; collectAllChildFrames(frame, childFrameList); QListIterator frameIt(childFrameList); while (frameIt.hasNext()) { QWebFrame *childFrame = frameIt.next(); formsList = d->parseFormData(childFrame); if (formsList.isEmpty()) { continue; } const QUrl url(childFrame->url()); if (d->pendingFillRequests.contains(url)) { qWarning() << "Duplicate request rejected!!!"; } else { KWebWalletPrivate::FormsData data; data.frame = QPointer(childFrame); data.forms << formsList; d->pendingFillRequests.insert(url, data); urlList << url; } } } if (!urlList.isEmpty()) { fillFormDataFromCache(urlList); } } static void createSaveKeyFor(QWebFrame *frame, QString *key) { QUrl frameUrl(urlForFrame(frame)); frameUrl.setPassword(QString()); frameUrl.setPassword(QString()); QString keyStr = frameUrl.toString(); if (!frame->frameName().isEmpty()) { keyStr += frame->frameName(); } *key = QString::number(qHash(keyStr), 16); } void KWebWallet::saveFormData(QWebFrame *frame, bool recursive, bool ignorePasswordFields) { if (!frame) { return; } QString key; createSaveKeyFor(frame, &key); if (d->pendingSaveRequests.contains(key)) { return; } WebFormList list = d->parseFormData(frame, false, ignorePasswordFields); if (recursive) { QList childFrameList; collectAllChildFrames(frame, childFrameList); QListIterator frameIt(childFrameList); while (frameIt.hasNext()) { list << d->parseFormData(frameIt.next(), false, ignorePasswordFields); } } if (list.isEmpty()) { return; } d->pendingSaveRequests.insert(key, list); QMutableListIterator it(list); while (it.hasNext()) { const WebForm form(it.next()); if (hasCachedFormData(form)) { it.remove(); } } if (list.isEmpty()) { d->confirmSaveRequestOverwrites.insert(urlForFrame(frame)); saveFormDataToCache(key); return; } emit saveFormDataRequested(key, urlForFrame(frame)); } void KWebWallet::removeFormData(QWebFrame *frame, bool recursive) { if (frame) { removeFormDataFromCache(formsWithCachedData(frame, recursive)); } } void KWebWallet::removeFormData(const WebFormList &forms) { d->pendingRemoveRequests << forms; removeFormDataFromCache(forms); } void KWebWallet::acceptSaveFormDataRequest(const QString &key) { saveFormDataToCache(key); } void KWebWallet::rejectSaveFormDataRequest(const QString &key) { d->pendingSaveRequests.remove(key); } void KWebWallet::fillWebForm(const QUrl &url, const KWebWallet::WebFormList &forms) { QPointer frame = d->pendingFillRequests.value(url).frame; if (!frame) { return; } QString script; bool wasFilled = false; Q_FOREACH (const KWebWallet::WebForm &form, forms) { Q_FOREACH (const KWebWallet::WebForm::WebField &field, form.fields) { QString value = field.second; value.replace(QL1C('\\'), QL1S("\\\\")); script += QString::fromLatin1("if (document.forms[\"%1\"].elements[\"%2\"]) document.forms[\"%1\"].elements[\"%2\"].value=\"%3\";\n") .arg((form.name.isEmpty() ? form.index : form.name)) .arg(field.first).arg(value); } } if (!script.isEmpty()) { wasFilled = true; frame.data()->evaluateJavaScript(script); } emit fillFormRequestCompleted(wasFilled); } KWebWallet::WebFormList KWebWallet::formsToFill(const QUrl &url) const { return d->pendingFillRequests.value(url).forms; } KWebWallet::WebFormList KWebWallet::formsToSave(const QString &key) const { return d->pendingSaveRequests.value(key); } bool KWebWallet::hasCachedFormData(const WebForm &form) const { return !KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), KWallet::Wallet::FormDataFolder(), walletKey(form)); } void KWebWallet::fillFormDataFromCache(const QList &urlList) { if (d->wallet) { QListIterator urlIt(urlList); while (urlIt.hasNext()) { const QUrl url = urlIt.next(); WebFormList list = formsToFill(url); d->fillDataFromCache(list); fillWebForm(url, list); } d->pendingFillRequests.clear(); } d->openWallet(); } void KWebWallet::saveFormDataToCache(const QString &key) { if (d->wallet) { d->saveDataToCache(key); return; } d->openWallet(); } void KWebWallet::removeFormDataFromCache(const WebFormList &forms) { if (d->wallet) { d->removeDataFromCache(forms); d->pendingRemoveRequests.clear(); return; } d->openWallet(); } #include "moc_kwebwallet.cpp" diff --git a/src/kwebwallet.h b/src/kwebwallet.h index a0ac70d..5593f3a 100644 --- a/src/kwebwallet.h +++ b/src/kwebwallet.h @@ -1,320 +1,320 @@ /* * This file is part of the KDE project. * * Copyright (C) 2009 Dawit Alemayehu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KWEBWALLET_H #define KWEBWALLET_H #include #include #include #include #include #include #include #include class QWebFrame; class QWebPage; /** * @short A class that provides KWallet integration for QWebFrame. * * Normally, you will use this class via KWebPage. In this case, you need to * connect to the saveFormDataRequested signal and call either * acceptSaveFormDataRequest or rejectSaveFormDataRequest, typically after * asking the user whether they want to save the form data. * * You will also need to call fillFormData when a QWebFrame has finished * loading. To do this, connect to QWebPage::loadFinished and, if the page was * loaded successfully, call * @code * page->wallet()->fillFormData(page->mainFrame()); * @endcode * * If you wish to use this directly with a subclass of QWebPage, you should call * saveFormData from QWebPage::acceptNavigationRequest when a user submits a * form. * * @see KWebPage * * @author Dawit Alemayehu * @since 4.4 */ class KDEWEBKIT_EXPORT KWebWallet : public QObject { Q_OBJECT public: /** * Holds data from a HTML <form> element. */ struct WebForm { /** * A typedef for storing the name and value attributes of HTML <input> * elements. */ typedef QPair WebField; /** The URL the form was found at. */ QUrl url; /** The name attribute of the form. */ QString name; /** The position of the form on the web page, relative to other forms. */ QString index; /** The name and value attributes of each input element in the form. */ QList fields; }; /** * A list of web forms */ typedef QList WebFormList; /** * Constructs a KWebWallet * * @p parent is usually the QWebPage this wallet is being used for. * * The @p wid parameter is used to tell the KWallet manager which window * is requesting access to the wallet. * * @param parent the owner of this wallet * @param wid the window ID of the window the web page will be * embedded in */ - explicit KWebWallet(QObject *parent = 0, WId wid = 0); + explicit KWebWallet(QObject *parent = nullptr, WId wid = 0); /** * Destructor */ virtual ~KWebWallet(); /** * Returns a list of forms in @p frame that have cached data in the * peristent storage. * * If @p recursive is set to true, the default, then this function will * will also return the cached form data for all the children frames of * @p frame. * * If the site currently rendered in @p frame does not contain any forms * or there is no cached data for the forms found in @p frame, then this * function will return an empty list. * * Note that this function will only return the information about the forms * in @p frame and not their cached data, i.e. the fields member variable in * the returned @ref WebForm list will always be empty. */ WebFormList formsWithCachedData(QWebFrame *frame, bool recursive = true) const; /** * Attempts to save the form data from @p frame and its children frames. * * If @p recursive is set to true, the default, then form data from all * the child frames of @p frame will be saved. Set @p ignorePasswordFields * to true if you do not want data from password fields to not be saved. * * You must connect to the @ref saveFormDataRequested signal and call either * @ref rejectSaveFormDataRequest or @ref acceptSaveFormDataRequest signals * in order to complete the save request. Otherwise, you request will simply * be ignored. */ void saveFormData(QWebFrame *frame, bool recursive = true, bool ignorePasswordFields = false); /** * Attempts to fill forms contained in @p frame with cached data. * * If @p recursive is set to true, the default, then this function will * attempt to fill out forms in the specified frame and all its children * frames. */ void fillFormData(QWebFrame *frame, bool recursive = true); /** * Removes the form data specified by @p forms from the persistent storage. * * This function is provided for convenience and simply calls @ref formsWithCachedData * and @ref removeFormData(WebFormList). Note that this function will remove all cached * data for forms found in @p frame. If @p recursive is set to true, then * all cached data for all of the child frames of @p frame will be removed * from the persistent storage as well. * * @see formsWithCachedData * @see removeFormData */ void removeFormData(QWebFrame *frame, bool recursive); /** * Removes the form data specified by @p forms from the persistent storage. * * Call @ref formsWithCachedData to obtain a list of forms with data cached * in persistent storage. * * @see formsWithCachedData */ void removeFormData(const WebFormList &forms); public Q_SLOTS: /** * Accepts the save form data request associated with @p key. * * The @p key parameter is the one sent through the @ref saveFormDataRequested * signal. * * You must always call this function or @ref rejectSaveFormDataRequest in * order to complete the save form data request. Otherwise, the request will * simply be ignored. * * @see saveFormDataRequested. */ void acceptSaveFormDataRequest(const QString &key); /** * Rejects the save form data request associated with @p key. * * The @p key parameter is the one sent through the @ref saveFormDataRequested * signal. * * @see saveFormDataRequested. */ void rejectSaveFormDataRequest(const QString &key); Q_SIGNALS: /** * This signal is emitted whenever a save form data request is received. * * Unless you connect to this signal and and call @ref acceptSaveFormDataRequest * or @ref rejectSaveFormDataRequest slots, the save form data requested through * @ref saveFormData will simply be ignored. * * @p key is a value that uniquely identifies the save request and @p url * is the address for which the form data is being saved. * * @see acceptSaveFormDataRequest * @see rejectSaveFormDataRequest */ void saveFormDataRequested(const QString &key, const QUrl &url); /** * This signal is emitted whenever a save form data request is completed. * * @p ok will be set to true if the save form data request for @p url was * completed successfully. * * @see saveFormDataRequested */ void saveFormDataCompleted(const QUrl &url, bool ok); /** * This signal is emitted whenever a fill form data request is completed. * * @p ok will be set to true if any forms were successfully filled with * cached data from the persistent storage. * * @see fillFormData * @since 4.5 */ void fillFormRequestCompleted(bool ok); /** * This signal is emitted whenever the current wallet is closed. */ void walletClosed(); protected: /** * Returns a list of forms for @p url that are waiting to be filled. * * This function returns an empty list if there is no pending requests * for filling forms associated with @p url. */ WebFormList formsToFill(const QUrl &url) const; /** * Returns a list of for @p key that are waiting to be saved. * * This function returns an empty list if there are no pending requests * for saving forms associated with @p key. */ WebFormList formsToSave(const QString &key) const; /** * Returns forms to be removed from persistent storage. */ WebFormList formsToDelete() const; /** * Returns true when there is data associated with @p form in the * persistent storage. */ virtual bool hasCachedFormData(const WebForm &form) const; /** * Fills the web forms in frame that point to @p url with data from @p forms. * * @see fillFormDataFromCache. */ void fillWebForm(const QUrl &url, const WebFormList &forms); /** * Fills form data from persistent storage. * * If you reimplement this function, call @ref formsToFill to obtain * the list of forms pending to be filled. Once you fill the list with * the cached data from the persistent storage, you must call @p fillWebForm * to fill out the actual web forms. * * @see formsToFill */ virtual void fillFormDataFromCache(const QList &list); /** * Stores form data associated with @p key to a persistent storage. * * If you reimplement this function, call @ref formsToSave to obtain the * list of form data pending to be saved to persistent storage. * *@see formsToSave */ virtual void saveFormDataToCache(const QString &key); /** * Removes all cached form data associated with @p forms from persistent storage. * * If you reimplement this function, call @ref formsToDelete to obtain the * list of form data pending to be removed from persistent storage. * *@see formsToDelete */ virtual void removeFormDataFromCache(const WebFormList &forms); private: class KWebWalletPrivate; friend class KWebWalletPrivate; KWebWalletPrivate *const d; Q_PRIVATE_SLOT(d, void _k_openWalletDone(bool)) Q_PRIVATE_SLOT(d, void _k_walletClosed()) }; #endif // KWEBWALLET_H