diff options
-rw-r--r-- | src/core/download_manager_delegate_qt.cpp | 35 | ||||
-rw-r--r-- | src/core/web_contents_adapter.cpp | 3 | ||||
-rw-r--r-- | src/core/web_contents_adapter.h | 2 | ||||
-rw-r--r-- | src/core/web_contents_delegate_qt.h | 21 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.cpp | 23 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.h | 4 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebengineprofile.cpp | 3 | ||||
-rw-r--r-- | tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp | 37 |
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; |