summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/download_manager_delegate_qt.cpp35
-rw-r--r--src/core/web_contents_adapter.cpp3
-rw-r--r--src/core/web_contents_adapter.h2
-rw-r--r--src/core/web_contents_delegate_qt.h21
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp23
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h4
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp3
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp37
8 files changed, 117 insertions, 11 deletions
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 857af2e18..42b26072c 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -56,6 +56,7 @@
#include "browser_context_adapter_client.h"
#include "browser_context_qt.h"
#include "type_conversion.h"
+#include "web_contents_delegate_qt.h"
#include "qtwebenginecoreglobal.h"
namespace QtWebEngineCore {
@@ -211,12 +212,30 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
if (clients.isEmpty())
return;
- const QString suggestedFileName
- = QFileInfo(toQt(suggested_path.AsUTF8Unsafe())).completeBaseName()
- + QStringLiteral(".mhtml");
- const QDir defaultDownloadDirectory
- = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
- const QString suggestedFilePath = defaultDownloadDirectory.absoluteFilePath(suggestedFileName);
+ WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
+ web_contents->GetDelegate());
+ const SavePageInfo &spi = contentsDelegate->savePageInfo();
+
+ bool acceptedByDefault = false;
+ QString suggestedFilePath = spi.requestedFilePath;
+ if (suggestedFilePath.isEmpty()) {
+ suggestedFilePath = QFileInfo(toQt(suggested_path.AsUTF8Unsafe())).completeBaseName()
+ + QStringLiteral(".mhtml");
+ } else {
+ acceptedByDefault = true;
+ }
+ if (QFileInfo(suggestedFilePath).isRelative()) {
+ const QDir downloadDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation));
+ suggestedFilePath = downloadDir.absoluteFilePath(suggestedFilePath);
+ }
+
+ BrowserContextAdapterClient::SavePageFormat suggestedSaveFormat
+ = static_cast<BrowserContextAdapterClient::SavePageFormat>(spi.requestedFormat);
+ if (suggestedSaveFormat == BrowserContextAdapterClient::UnknownSavePageFormat)
+ suggestedSaveFormat = BrowserContextAdapterClient::MimeHtmlSaveFormat;
+
+ // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved.
+ contentsDelegate->setSavePageInfo(SavePageInfo());
BrowserContextAdapterClient::DownloadItemInfo info = {
m_currentId + 1,
@@ -226,8 +245,8 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content
0, /* receivedBytes */
QStringLiteral("application/x-mimearchive"),
suggestedFilePath,
- BrowserContextAdapterClient::MimeHtmlSaveFormat,
- false /* accepted */
+ suggestedSaveFormat,
+ acceptedByDefault
};
Q_FOREACH (BrowserContextAdapterClient *client, clients) {
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 15125b9d8..e37a3ad24 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -535,9 +535,10 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
d->webContents->Unselect();
}
-void WebContentsAdapter::save()
+void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
{
Q_D(WebContentsAdapter);
+ d->webContentsDelegate->setSavePageInfo(SavePageInfo(filePath, savePageFormat));
d->webContents->OnSavePage();
}
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 0de1fb1d5..63b99d013 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -85,7 +85,7 @@ public:
void reloadAndBypassCache();
void load(const QUrl&);
void setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl);
- void save();
+ void save(const QString &filePath = QString(), int savePageFormat = -1);
QUrl activeUrl() const;
QUrl requestedUrl() const;
QString pageTitle() const;
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 73ad5a9ac..b60f31ac3 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -69,6 +69,23 @@ namespace QtWebEngineCore {
class WebContentsAdapterClient;
+class SavePageInfo
+{
+public:
+ SavePageInfo()
+ : requestedFormat(-1)
+ {
+ }
+
+ SavePageInfo(const QString &filePath, int format)
+ : requestedFilePath(filePath), requestedFormat(format)
+ {
+ }
+
+ QString requestedFilePath;
+ int requestedFormat;
+};
+
class WebContentsDelegateQt : public content::WebContentsDelegate
, public content::WebContentsObserver
{
@@ -125,6 +142,9 @@ public:
void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame);
FaviconManager *faviconManager();
+ void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; }
+ const SavePageInfo &savePageInfo() { return m_savePageInfo; }
+
private:
WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture);
@@ -133,6 +153,7 @@ private:
int m_lastReceivedFindReply;
QVector<int64_t> m_loadingErrorFrameList;
QScopedPointer<FaviconManager> m_faviconManager;
+ SavePageInfo m_savePageInfo;
};
} // namespace QtWebEngineCore
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 3f11e5aef..8a9f04860 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -716,6 +716,29 @@ void QWebEnginePage::setBackgroundColor(const QColor &color)
}
/*!
+ * Save the currently loaded web page to disk.
+ *
+ * The web page is saved to \a filePath in the specified \a{format}.
+ *
+ * This is a short cut for the following actions:
+ * \list
+ * \li Trigger the Save web action.
+ * \li Accept the next download item and set the specified file path and save format.
+ * \endlist
+ *
+ * This function issues an asynchronous download request for the web page and returns immediately.
+ *
+ * \sa QWebEngineDownloadItem::SavePageFormat
+ * \since 5.8
+ */
+void QWebEnginePage::save(const QString &filePath,
+ QWebEngineDownloadItem::SavePageFormat format) const
+{
+ Q_D(const QWebEnginePage);
+ d->adapter->save(filePath, format);
+}
+
+/*!
\property QWebEnginePage::audioMuted
\brief whether the current page audio is muted.
\since 5.7
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 2ac8e0f3e..40f5b1a23 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -42,6 +42,7 @@
#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
#include <QtWebEngineWidgets/qwebenginecertificateerror.h>
+#include <QtWebEngineWidgets/qwebenginedownloaditem.h>
#include <QtWebEngineCore/qwebenginecallback.h>
#include <QtCore/qobject.h>
@@ -261,6 +262,9 @@ public:
QColor backgroundColor() const;
void setBackgroundColor(const QColor &color);
+ void save(const QString &filePath, QWebEngineDownloadItem::SavePageFormat format
+ = QWebEngineDownloadItem::MimeHtmlSaveFormat) const;
+
bool isAudioMuted() const;
void setAudioMuted(bool muted);
bool recentlyAudible() const;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index 664323034..7e87aed50 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -180,7 +180,8 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info)
Q_ASSERT(!m_ongoingDownloads.contains(info.id));
QWebEngineDownloadItemPrivate *itemPrivate = new QWebEngineDownloadItemPrivate(this, info.url);
itemPrivate->downloadId = info.id;
- itemPrivate->downloadState = QWebEngineDownloadItem::DownloadRequested;
+ itemPrivate->downloadState = info.accepted ? QWebEngineDownloadItem::DownloadInProgress
+ : QWebEngineDownloadItem::DownloadRequested;
itemPrivate->downloadPath = info.path;
itemPrivate->mimeType = info.mimeType;
itemPrivate->savePageFormat = static_cast<QWebEngineDownloadItem::SavePageFormat>(info.savePageFormat);
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index e50692226..b39c07fc2 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -41,6 +41,7 @@
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
#include <qpa/qplatforminputcontext.h>
+#include <qwebenginedownloaditem.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
#include <qwebenginepage.h>
@@ -159,6 +160,7 @@ private Q_SLOTS:
void undoActionHaveCustomText();
void renderWidgetHostViewNotShowTopLevel();
void getUserMediaRequest();
+ void savePage();
void crashTests_LazyInitializationOfMainFrame();
@@ -3409,6 +3411,41 @@ void tst_QWebEnginePage::getUserMediaRequest()
delete page;
}
+void tst_QWebEnginePage::savePage()
+{
+ QWebEngineView view;
+ QWebEnginePage *page = view.page();
+
+ connect(page->profile(), &QWebEngineProfile::downloadRequested,
+ [] (QWebEngineDownloadItem *item)
+ {
+ connect(item, &QWebEngineDownloadItem::finished,
+ &QTestEventLoop::instance(), &QTestEventLoop::exitLoop, Qt::QueuedConnection);
+ });
+
+ const QString urlPrefix = QStringLiteral("data:text/html,<h1>");
+ const QString text = QStringLiteral("There is Thingumbob shouting!");
+ page->load(QUrl(urlPrefix + text));
+ waitForSignal(page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(toPlainTextSync(page), text);
+
+ // Save the loaded page as HTML.
+ QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX");
+ const QString filePath = tempDir.path() + "/thingumbob.html";
+ page->save(filePath, QWebEngineDownloadItem::CompleteHtmlSaveFormat);
+ QTestEventLoop::instance().enterLoop(10);
+
+ // Load something else.
+ page->load(QUrl(urlPrefix + QLatin1String("It's a Snark!")));
+ waitForSignal(page, SIGNAL(loadFinished(bool)));
+ QVERIFY(toPlainTextSync(page) != text);
+
+ // Load the saved page and compare the contents.
+ page->load(QUrl::fromLocalFile(filePath));
+ waitForSignal(page, SIGNAL(loadFinished(bool)));
+ QCOMPARE(toPlainTextSync(page), text);
+}
+
void tst_QWebEnginePage::openWindowDefaultSize()
{
TestPage page;