summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2018-07-05 16:12:23 +0200
committerMichal Klocek <michal.klocek@qt.io>2018-08-09 09:39:27 +0000
commit34a7c2cde9ea3fb2d4c297d60a4e16c9d99cdf9b (patch)
treefed925e2dd9eedc32d4010fa555b3e3194452fdc /src
parentd0f00b47cb91f1f6af920602f8bf8b263a8d7f88 (diff)
Add printRequest()
Adds printRequested() signal for web content. This signal is emitted on javascript window.print(). This change updates also qt printview manager implementation, fixes a corner case and warnings about ipc unconsumed attachments. Task-number: QTBUG-69237 Task-number: QTBUG-53745 Change-Id: I0c47b732e27e929ac6db237fb562b7d5f9b959c2 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/core/printing/print_view_manager_base_qt.cpp113
-rw-r--r--src/core/printing/print_view_manager_base_qt.h29
-rw-r--r--src/core/printing/print_view_manager_qt.cpp132
-rw-r--r--src/core/printing/print_view_manager_qt.h27
-rw-r--r--src/core/renderer/print_web_view_helper_delegate_qt.cpp4
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/webengine/api/qquickwebengineview.cpp8
-rw-r--r--src/webengine/api/qquickwebengineview_p.h1
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h1
-rw-r--r--src/webengine/doc/src/webengineview_lgpl.qdoc10
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp18
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h1
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h1
13 files changed, 244 insertions, 102 deletions
diff --git a/src/core/printing/print_view_manager_base_qt.cpp b/src/core/printing/print_view_manager_base_qt.cpp
index facc4ff84..6c67adbc7 100644
--- a/src/core/printing/print_view_manager_base_qt.cpp
+++ b/src/core/printing/print_view_manager_base_qt.cpp
@@ -72,15 +72,13 @@ namespace QtWebEngineCore {
PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents)
: printing::PrintManager(contents)
- , cookie_(0)
, m_isInsideInnerMessageLoop(false)
-#if !defined(OS_MACOSX)
- , m_isExpectingFirstPage(false)
-#endif
, m_didPrintingSucceed(false)
, m_printerQueriesQueue(WebEngineContext::current()->getPrintJobManager()->queue())
+ , m_printingRFH(nullptr)
{
// FIXME: Check if this needs to be executed async:
+ // TODO: Add isEnabled to profile
PrintViewManagerBaseQt::UpdatePrintingEnabled();
}
@@ -90,8 +88,15 @@ PrintViewManagerBaseQt::~PrintViewManagerBaseQt()
DisconnectFromCurrentPrintJob();
}
+void PrintViewManagerBaseQt::SetPrintingRFH(content::RenderFrameHost *rfh)
+{
+ DCHECK(!m_printingRFH);
+ m_printingRFH = rfh;
+}
+
void PrintViewManagerBaseQt::UpdatePrintingEnabled()
{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
bool enabled = false;
#if QT_CONFIG(webengine_printing_and_pdf)
enabled = true;
@@ -112,24 +117,19 @@ base::string16 PrintViewManagerBaseQt::RenderSourceName()
return toString16(QLatin1String(""));
}
-bool PrintViewManagerBaseQt::PrintDocument(printing::PrintedDocument *document,
- const scoped_refptr<base::RefCountedBytes> &print_data,
+void PrintViewManagerBaseQt::PrintDocument(printing::PrintedDocument *document,
+ const scoped_refptr<base::RefCountedMemory> &print_data,
const gfx::Size &page_size,
const gfx::Rect &content_area,
const gfx::Point &offsets)
{
std::unique_ptr<printing::PdfMetafileSkia> metafile =
std::make_unique<printing::PdfMetafileSkia>();
- if (!metafile->InitFromData(print_data->front(), print_data->size())) {
- NOTREACHED() << "Invalid metafile";
- web_contents()->Stop();
- return false;
- }
+ CHECK(metafile->InitFromData(print_data->front(), print_data->size()));
// Update the rendered document. It will send notifications to the listener.
document->SetDocument(std::move(metafile), page_size, content_area);
ShouldQuitFromInnerMessageLoop();
- return true;
}
printing::PrintedDocument *PrintViewManagerBaseQt::GetDocument(int cookie)
@@ -147,7 +147,8 @@ printing::PrintedDocument *PrintViewManagerBaseQt::GetDocument(int cookie)
}
// IPC handlers
-void PrintViewManagerBaseQt::OnDidPrintDocument(const PrintHostMsg_DidPrintDocument_Params &params)
+void PrintViewManagerBaseQt::OnDidPrintDocument(content::RenderFrameHost* /*render_frame_host*/,
+ const PrintHostMsg_DidPrintDocument_Params &params)
{
printing::PrintedDocument *document = GetDocument(params.document_cookie);
if (!document)
@@ -167,10 +168,10 @@ void PrintViewManagerBaseQt::OnDidPrintDocument(const PrintHostMsg_DidPrintDocum
web_contents()->Stop();
return;
}
- scoped_refptr<base::RefCountedBytes> bytes =
- base::MakeRefCounted<base::RefCountedBytes>(
- reinterpret_cast<const unsigned char*>(shared_buf->memory()), content.data_size);
- PrintDocument(document, bytes, params.page_size, params.content_area, params.physical_offsets);
+ auto data = base::MakeRefCounted<base::RefCountedSharedMemory>(
+ std::move(shared_buf), content.data_size);
+ PrintDocument(document, data, params.page_size, params.content_area,
+ params.physical_offsets);
}
void PrintViewManagerBaseQt::OnShowInvalidPrinterSettingsError()
@@ -182,12 +183,16 @@ void PrintViewManagerBaseQt::DidStartLoading()
UpdatePrintingEnabled();
}
+// Note: In PrintViewManagerQt we always initiate printing with PrintMsg_InitiatePrintPreview
+// so m_printingRFH is never set and used at the moment.
void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render_frame_host)
{
// Terminates or cancels the print job if one was pending.
- if (render_frame_host != web_contents()->GetMainFrame())
+ if (render_frame_host != m_printingRFH)
return;
+ m_printingRFH = nullptr;
+
PrintManager::PrintingRenderFrameDeleted();
ReleasePrinterQuery();
@@ -203,12 +208,20 @@ void PrintViewManagerBaseQt::RenderFrameDeleted(content::RenderFrameHost *render
}
}
-bool PrintViewManagerBaseQt::OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* render_frame_host)
+bool PrintViewManagerBaseQt::OnMessageReceived(const IPC::Message& message,
+ content::RenderFrameHost* render_frame_host)
{
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBaseQt, message)
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintViewManagerBaseQt, message, render_frame_host)
IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintDocument, OnDidPrintDocument)
- IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, OnShowInvalidPrinterSettingsError);
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ if (handled)
+ return true;
+ handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBaseQt, message)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError,
+ OnShowInvalidPrinterSettingsError);
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled || PrintManager::OnMessageReceived(message, render_frame_host);
@@ -225,7 +238,7 @@ void PrintViewManagerBaseQt::Observe(int type,
void PrintViewManagerBaseQt::OnNotifyPrintJobEvent(const printing::JobEventDetails& event_details)
{
switch (event_details.type()) {
- case printing::JobEventDetails::FAILED:
+ case printing::JobEventDetails::FAILED: {
TerminatePrintJob(true);
content::NotificationService::current()->Notify(
@@ -233,21 +246,26 @@ void PrintViewManagerBaseQt::OnNotifyPrintJobEvent(const printing::JobEventDetai
content::Source<content::WebContents>(web_contents()),
content::NotificationService::NoDetails());
break;
+ }
case printing::JobEventDetails::USER_INIT_DONE:
case printing::JobEventDetails::DEFAULT_INIT_DONE:
- case printing::JobEventDetails::USER_INIT_CANCELED:
+ case printing::JobEventDetails::USER_INIT_CANCELED: {
NOTREACHED();
break;
- case printing::JobEventDetails::ALL_PAGES_REQUESTED:
+ }
+ case printing::JobEventDetails::ALL_PAGES_REQUESTED: {
+ ShouldQuitFromInnerMessageLoop();
break;
+ }
case printing::JobEventDetails::NEW_DOC:
#if defined(OS_WIN)
case printing::JobEventDetails::PAGE_DONE:
#endif
- case printing::JobEventDetails::DOC_DONE:
+ case printing::JobEventDetails::DOC_DONE: {
// Don't care about the actual printing process.
break;
- case printing::JobEventDetails::JOB_DONE:
+ }
+ case printing::JobEventDetails::JOB_DONE: {
// Printing is done, we don't need it anymore.
// print_job_->is_job_pending() may still be true, depending on the order
// of object registration.
@@ -259,6 +277,7 @@ void PrintViewManagerBaseQt::OnNotifyPrintJobEvent(const printing::JobEventDetai
content::Source<content::WebContents>(web_contents()),
content::NotificationService::NoDetails());
break;
+ }
default:
NOTREACHED();
break;
@@ -273,6 +292,12 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow()
if (!m_printJob.get() || !m_printJob->is_job_pending())
return false;
+ // Is the document already complete?
+ if (m_printJob->document() && m_printJob->document()->IsComplete()) {
+ m_didPrintingSucceed = true;
+ return true;
+ }
+
// We can't print if there is no renderer.
if (!web_contents() ||
!web_contents()->GetRenderViewHost() ||
@@ -280,12 +305,6 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow()
return false;
}
- // Is the document already complete?
- if (m_printJob->document() && m_printJob->document()->IsComplete()) {
- m_didPrintingSucceed = true;
- return true;
- }
-
// WebContents is either dying or a second consecutive request to print
// happened before the first had time to finish. We need to render all the
// pages in an hurry if a print_job_ is still pending. No need to wait for it
@@ -319,7 +338,7 @@ void PrintViewManagerBaseQt::ShouldQuitFromInnerMessageLoop()
m_isInsideInnerMessageLoop) {
// We are in a message loop created by RenderAllMissingPagesNow. Quit from
// it.
- base::MessageLoop::current()->QuitWhenIdleClosure();
+ base::RunLoop::QuitCurrentWhenIdleDeprecated();
m_isInsideInnerMessageLoop = false;
}
}
@@ -344,7 +363,7 @@ bool PrintViewManagerBaseQt::CreateNewPrintJob(printing::PrintJobWorkerOwner* jo
if (!job)
return false;
- m_printJob = new printing::PrintJob();
+ m_printJob = base::MakeRefCounted<printing::PrintJob>();
m_printJob->Initialize(job, RenderSourceName(), number_pages_);
m_registrar.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
content::Source<printing::PrintJob>(m_printJob.get()));
@@ -369,9 +388,6 @@ void PrintViewManagerBaseQt::DisconnectFromCurrentPrintJob()
// DO NOT wait for the job to finish.
ReleasePrintJob();
}
-#if !defined(OS_MACOSX)
- m_isExpectingFirstPage = true;
-#endif
}
void PrintViewManagerBaseQt::TerminatePrintJob(bool cancel)
@@ -397,13 +413,18 @@ void PrintViewManagerBaseQt::TerminatePrintJob(bool cancel)
void PrintViewManagerBaseQt::ReleasePrintJob()
{
- content::RenderFrameHost *rfh = web_contents() ? web_contents()->GetMainFrame() : nullptr;
+ content::RenderFrameHost* rfh = m_printingRFH;
+ m_printingRFH = nullptr;
if (!m_printJob.get())
return;
- if (rfh)
- rfh->Send(new PrintMsg_PrintingDone(rfh->GetRoutingID(), m_didPrintingSucceed));
+ if (rfh) {
+ auto msg = std::make_unique<PrintMsg_PrintingDone>(rfh->GetRoutingID(),
+ m_didPrintingSucceed);
+ rfh->Send(msg.release());
+ }
+
m_registrar.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
content::Source<printing::PrintJob>(m_printJob.get()));
@@ -411,7 +432,6 @@ void PrintViewManagerBaseQt::ReleasePrintJob()
m_printJob = nullptr;
}
-
bool PrintViewManagerBaseQt::RunInnerMessageLoop() {
// This value may actually be too low:
//
@@ -426,19 +446,18 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() {
// memory-bound.
static const int kPrinterSettingsTimeout = 60000;
base::OneShotTimer quit_timer;
- base::RunLoop runLoop;
+ base::RunLoop run_loop;
quit_timer.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kPrinterSettingsTimeout),
- runLoop.QuitWhenIdleClosure());
+ run_loop.QuitWhenIdleClosure());
m_isInsideInnerMessageLoop = true;
// Need to enable recursive task.
{
- m_quitClosure = runLoop.QuitClosure();
- base::MessageLoop* loop = base::MessageLoop::current();
- base::MessageLoop::ScopedNestableTaskAllower allowNested(loop);
- runLoop.Run();
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
+ run_loop.Run();
}
bool success = true;
diff --git a/src/core/printing/print_view_manager_base_qt.h b/src/core/printing/print_view_manager_base_qt.h
index 0d86fcf90..eb4302fe8 100644
--- a/src/core/printing/print_view_manager_base_qt.h
+++ b/src/core/printing/print_view_manager_base_qt.h
@@ -44,7 +44,7 @@
#ifndef PRINT_VIEW_MANAGER_BASE_QT_H
#define PRINT_VIEW_MANAGER_BASE_QT_H
-#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_memory.h"
#include "base/strings/string16.h"
#include "components/prefs/pref_member.h"
#include "components/printing/browser/print_manager.h"
@@ -87,6 +87,8 @@ public:
protected:
explicit PrintViewManagerBaseQt(content::WebContents*);
+ void SetPrintingRFH(content::RenderFrameHost* rfh);
+
// content::WebContentsObserver implementation.
// Cancels the print job.
void NavigationStopped() override;
@@ -97,16 +99,13 @@ protected:
content::RenderFrameHost* render_frame_host) override;
// IPC Message handlers.
- void OnDidPrintDocument(const PrintHostMsg_DidPrintDocument_Params& params);
+ void OnDidPrintDocument(content::RenderFrameHost* render_frame_host,
+ const PrintHostMsg_DidPrintDocument_Params& params);
void OnShowInvalidPrinterSettingsError();
// Processes a NOTIFY_PRINT_JOB_EVENT notification.
void OnNotifyPrintJobEvent(const printing::JobEventDetails& event_details);
- int number_pages_; // Number of pages to print in the print job.
- int cookie_;
- std::unique_ptr<base::DictionaryValue> m_printSettings;
-
// content::NotificationObserver implementation.
void Observe(int,
const content::NotificationSource&,
@@ -130,8 +129,8 @@ protected:
// Starts printing a document with data given in |print_data|. |print_data|
// must successfully initialize a metafile. |document| is the printed
// document associated with the print job. Returns true if successful.
- bool PrintDocument(printing::PrintedDocument *document,
- const scoped_refptr<base::RefCountedBytes> &print_data,
+ void PrintDocument(printing::PrintedDocument *document,
+ const scoped_refptr<base::RefCountedMemory> &print_data,
const gfx::Size &page_size,
const gfx::Rect &content_area,
const gfx::Point &offsets);
@@ -155,21 +154,17 @@ protected:
private:
// Helper method for UpdatePrintingEnabled().
void SendPrintingEnabled(bool enabled, content::RenderFrameHost* rfh);
+ // content::WebContentsObserver implementation.
+ void DidStartLoading() override;
+private:
content::NotificationRegistrar m_registrar;
scoped_refptr<printing::PrintJob> m_printJob;
- // Closure for quitting nested message loop.
- base::Closure m_quitClosure;
-
bool m_isInsideInnerMessageLoop;
-#if !defined(OS_MACOSX)
- bool m_isExpectingFirstPage;
-#endif
bool m_didPrintingSucceed;
scoped_refptr<printing::PrintQueriesQueue> m_printerQueriesQueue;
- // content::WebContentsObserver implementation.
- void DidStartLoading() override;
-
+ // The current RFH that is printing with a system printing dialog.
+ content::RenderFrameHost* m_printingRFH;
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerBaseQt);
};
diff --git a/src/core/printing/print_view_manager_qt.cpp b/src/core/printing/print_view_manager_qt.cpp
index bb176d687..fffc91631 100644
--- a/src/core/printing/print_view_manager_qt.cpp
+++ b/src/core/printing/print_view_manager_qt.cpp
@@ -45,6 +45,7 @@
#include "type_conversion.h"
#include "web_engine_context.h"
+#include "web_contents_view_qt.h"
#include <QtGui/qpagelayout.h>
#include <QtGui/qpagesize.h>
@@ -66,6 +67,7 @@
DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::PrintViewManagerQt);
namespace {
+
static const qreal kMicronsToMillimeter = 1000.0f;
static std::vector<char>
@@ -85,11 +87,10 @@ GetStdVectorFromHandle(base::SharedMemoryHandle handle, uint32_t data_size)
static scoped_refptr<base::RefCountedBytes>
GetBytesFromHandle(base::SharedMemoryHandle handle, uint32_t data_size)
{
- std::unique_ptr<base::SharedMemory> shared_buf(
- new base::SharedMemory(handle, true));
+ std::unique_ptr<base::SharedMemory> shared_buf(new base::SharedMemory(handle, true));
if (!shared_buf->Map(data_size)) {
- return NULL;
+ return nullptr;
}
unsigned char* data = static_cast<unsigned char*>(shared_buf->memory());
@@ -99,9 +100,8 @@ GetBytesFromHandle(base::SharedMemoryHandle handle, uint32_t data_size)
// Write the PDF file to disk.
static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data,
- const base::FilePath& path,
- const QtWebEngineCore::PrintViewManagerQt::PrintToPDFFileCallback
- &saveCallback)
+ const base::FilePath &path,
+ const QtWebEngineCore::PrintViewManagerQt::PrintToPDFFileCallback &saveCallback)
{
base::AssertBlockingAllowed();
DCHECK_GT(data->size(), 0U);
@@ -197,6 +197,19 @@ static base::DictionaryValue *createPrintSettingsFromQPageLayout(const QPageLayo
namespace QtWebEngineCore {
+struct PrintViewManagerQt::FrameDispatchHelper {
+ PrintViewManagerQt* m_manager;
+ content::RenderFrameHost* m_renderFrameHost;
+
+ bool Send(IPC::Message* msg) {
+ return m_renderFrameHost->Send(msg);
+ }
+
+ void OnSetupScriptedPrintPreview(IPC::Message* reply_msg) {
+ m_manager->OnSetupScriptedPrintPreview(m_renderFrameHost, reply_msg);
+ }
+};
+
PrintViewManagerQt::~PrintViewManagerQt()
{
}
@@ -211,8 +224,7 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
return;
if (m_printSettings || !filePath.length()) {
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(callback, false));
return;
}
@@ -220,8 +232,7 @@ void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayou
m_pdfOutputPath = toFilePath(filePath);
m_pdfSaveCallback = callback;
if (!PrintToPDFInternal(pageLayout, printInColor)) {
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(callback, false));
resetPdfState();
}
@@ -237,9 +248,8 @@ void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout,
// If there already is a pending print in progress, don't try starting another one.
if (m_printSettings) {
- content::BrowserThread::PostTask(content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(callback, std::vector<char>()));
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ base::Bind(callback, std::vector<char>()));
return;
}
@@ -261,12 +271,27 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
return false;
m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout, useCustomMargins));
- m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds
- , web_contents()->GetRenderViewHost()->GetWebkitPreferences().should_print_backgrounds);
+ m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds,
+ web_contents()->GetRenderViewHost()->
+ GetWebkitPreferences().should_print_backgrounds);
m_printSettings->SetInteger(printing::kSettingColor,
printInColor ? printing::COLOR : printing::GRAYSCALE);
- return web_contents()->GetMainFrame()->Send(
- new PrintMsg_InitiatePrintPreview(web_contents()->GetMainFrame()->GetRoutingID(), false));
+
+ if (web_contents()->ShowingInterstitialPage() || web_contents()->IsCrashed())
+ return false;
+
+ content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
+ auto message = std::make_unique<PrintMsg_InitiatePrintPreview>(
+ rfh->GetRoutingID(), false);
+
+ DCHECK(!m_printPreviewRfh);
+
+ if (!rfh->Send(message.release())) {
+ return false;
+ }
+
+ m_printPreviewRfh = rfh;
+ return true;
}
#endif // QT_CONFIG(webengine_printing_and_pdf)
@@ -274,26 +299,42 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout,
// PrintedPagesSource implementation.
base::string16 PrintViewManagerQt::RenderSourceName()
{
- return toString16(QLatin1String(""));
+ return base::string16();
}
PrintViewManagerQt::PrintViewManagerQt(content::WebContents *contents)
: PrintViewManagerBaseQt(contents)
+ , m_printPreviewRfh(nullptr)
{
}
// content::WebContentsObserver implementation.
-bool PrintViewManagerQt::OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* render_frame_host)
+bool PrintViewManagerQt::OnMessageReceived(const IPC::Message& message,
+ content::RenderFrameHost* render_frame_host)
{
+ FrameDispatchHelper helper = {this, render_frame_host};
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(PrintViewManagerQt, message)
- IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
- IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview, OnRequestPrintPreview)
- IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting, OnMetafileReadyForPrinting);
- IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(PrintViewManagerQt, message, render_frame_host);
+ IPC_MESSAGE_HANDLER(PrintHostMsg_DidShowPrintDialog, OnDidShowPrintDialog)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview, OnRequestPrintPreview)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_MetafileReadyForPrinting, OnMetafileReadyForPrinting);
+ IPC_MESSAGE_HANDLER(PrintHostMsg_DidPreviewPage, OnDidPreviewPage)
+ IPC_MESSAGE_FORWARD_DELAY_REPLY(
+ PrintHostMsg_SetupScriptedPrintPreview, &helper,
+ FrameDispatchHelper::OnSetupScriptedPrintPreview)
+ IPC_MESSAGE_HANDLER(PrintHostMsg_ShowScriptedPrintPreview,
+ OnShowScriptedPrintPreview)
+ IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
- return handled || PrintManager::OnMessageReceived(message, render_frame_host);
+ return handled || PrintViewManagerBaseQt::OnMessageReceived(message, render_frame_host);
+}
+
+void PrintViewManagerQt::RenderFrameDeleted(content::RenderFrameHost *render_frame_host)
+{
+ if (render_frame_host == m_printPreviewRfh)
+ PrintPreviewDone();
+ PrintViewManagerBaseQt::RenderFrameDeleted(render_frame_host);
}
void PrintViewManagerQt::resetPdfState()
@@ -309,9 +350,9 @@ void PrintViewManagerQt::resetPdfState()
void PrintViewManagerQt::OnRequestPrintPreview(
const PrintHostMsg_RequestPrintPreview_Params &/*params*/)
{
- auto *rfh = web_contents()->GetMainFrame();
- rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), *m_printSettings));
- rfh->Send(new PrintMsg_ClosePrintPreviewDialog(rfh->GetRoutingID()));
+ m_printPreviewRfh->Send(new PrintMsg_PrintPreview(m_printPreviewRfh->GetRoutingID(),
+ *m_printSettings));
+ PrintPreviewDone();
}
void PrintViewManagerQt::OnMetafileReadyForPrinting(
@@ -359,6 +400,7 @@ void PrintViewManagerQt::NavigationStopped()
base::Bind(m_pdfPrintCallback, std::vector<char>()));
}
resetPdfState();
+ PrintViewManagerBaseQt::NavigationStopped();
}
void PrintViewManagerQt::RenderProcessGone(base::TerminationStatus status)
@@ -372,5 +414,39 @@ void PrintViewManagerQt::RenderProcessGone(base::TerminationStatus status)
resetPdfState();
}
+void PrintViewManagerQt::OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params &params)
+{
+ // just consume the message, this is just for sending 'page-preview-ready' for webui
+}
+
+void PrintViewManagerQt::OnSetupScriptedPrintPreview(content::RenderFrameHost* rfh,
+ IPC::Message* reply_msg)
+{
+ // ignore the scripted print
+ rfh->Send(reply_msg);
+
+ content::WebContentsView *view = static_cast<content::WebContentsImpl*>(web_contents())->GetView();
+ WebContentsAdapterClient *client = WebContentsViewQt::from(view)->client();
+
+ if (!client)
+ return;
+
+ // close preview
+ rfh->Send(new PrintMsg_ClosePrintPreviewDialog(rfh->GetRoutingID()));
+
+ client->printRequested();
+}
+
+void PrintViewManagerQt::OnShowScriptedPrintPreview(content::RenderFrameHost* rfh,
+ bool source_is_modifiable)
+{
+ // ignore for now
+}
+
+void PrintViewManagerQt::PrintPreviewDone() {
+ m_printPreviewRfh->Send(new PrintMsg_ClosePrintPreviewDialog(
+ m_printPreviewRfh->GetRoutingID()));
+ m_printPreviewRfh = nullptr;
+}
} // namespace QtWebEngineCore
diff --git a/src/core/printing/print_view_manager_qt.h b/src/core/printing/print_view_manager_qt.h
index c181d9063..c71ec4a61 100644
--- a/src/core/printing/print_view_manager_qt.h
+++ b/src/core/printing/print_view_manager_qt.h
@@ -51,6 +51,7 @@
#include "base/strings/string16.h"
#include "components/prefs/pref_member.h"
#include "components/printing/browser/print_manager.h"
+#include "components/printing/common/print_messages.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_user_data.h"
@@ -77,7 +78,7 @@ QT_END_NAMESPACE
namespace QtWebEngineCore {
class PrintViewManagerQt
- : PrintViewManagerBaseQt
+ : public PrintViewManagerBaseQt
, public content::WebContentsUserData<PrintViewManagerQt>
{
public:
@@ -111,28 +112,38 @@ protected:
// content::WebContentsObserver implementation.
bool OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* render_frame_host) override;
+ void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
// IPC handlers
void OnDidShowPrintDialog();
void OnRequestPrintPreview(const PrintHostMsg_RequestPrintPreview_Params&);
void OnMetafileReadyForPrinting(const PrintHostMsg_DidPreviewDocument_Params& params);
+ void OnSetupScriptedPrintPreview(content::RenderFrameHost* rfh,
+ IPC::Message* reply_msg);
+ void OnDidPreviewPage(const PrintHostMsg_DidPreviewPage_Params& params);
+ void OnShowScriptedPrintPreview(content::RenderFrameHost* rfh,
+ bool source_is_modifiable);
+
#if QT_CONFIG(webengine_printing_and_pdf)
bool PrintToPDFInternal(const QPageLayout &, bool printInColor, bool useCustomMargins = true);
#endif
- base::FilePath m_pdfOutputPath;
- PrintToPDFCallback m_pdfPrintCallback;
- PrintToPDFFileCallback m_pdfSaveCallback;
-
private:
- friend class content::WebContentsUserData<PrintViewManagerQt>;
-
void resetPdfState();
-
// content::WebContentsObserver implementation.
void DidStartLoading() override;
+ void PrintPreviewDone();
+
+private:
+ content::RenderFrameHost *m_printPreviewRfh;
+ base::FilePath m_pdfOutputPath;
+ PrintToPDFCallback m_pdfPrintCallback;
+ PrintToPDFFileCallback m_pdfSaveCallback;
+ std::unique_ptr<base::DictionaryValue> m_printSettings;
+ friend class content::WebContentsUserData<PrintViewManagerQt>;
DISALLOW_COPY_AND_ASSIGN(PrintViewManagerQt);
+ struct FrameDispatchHelper;
};
} // namespace QtWebEngineCore
diff --git a/src/core/renderer/print_web_view_helper_delegate_qt.cpp b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
index 79d86b00f..e693cf096 100644
--- a/src/core/renderer/print_web_view_helper_delegate_qt.cpp
+++ b/src/core/renderer/print_web_view_helper_delegate_qt.cpp
@@ -53,7 +53,7 @@ PrintWebViewHelperDelegateQt::~PrintWebViewHelperDelegateQt()
bool PrintWebViewHelperDelegateQt::CancelPrerender(content::RenderFrame *)
{
- return true;
+ return false;
}
blink::WebElement PrintWebViewHelperDelegateQt::GetPdfElement(blink::WebLocalFrame* frame)
@@ -63,7 +63,7 @@ blink::WebElement PrintWebViewHelperDelegateQt::GetPdfElement(blink::WebLocalFra
bool PrintWebViewHelperDelegateQt::IsPrintPreviewEnabled()
{
- return false;
+ return true;
}
bool PrintWebViewHelperDelegateQt::OverridePrint(blink::WebLocalFrame* frame)
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 851a6122f..6fd29ec61 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -472,6 +472,7 @@ public:
virtual const QObject *holdingQObject() const = 0;
virtual void setToolTip(const QString& toolTipText) = 0;
virtual ClientType clientType() = 0;
+ virtual void printRequested() = 0;
virtual ProfileAdapter *profileAdapter() = 0;
virtual WebContentsAdapter* webContentsAdapter() = 0;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index aaa8d58c5..f24ba1d7d 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -640,6 +640,14 @@ WebContentsAdapter *QQuickWebEngineViewPrivate::webContentsAdapter()
return adapter.data();
}
+void QQuickWebEngineViewPrivate::printRequested()
+{
+ Q_Q(QQuickWebEngineView);
+ QTimer::singleShot(0, q, [q]() {
+ Q_EMIT q->printRequested();
+ });
+}
+
WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
{
return m_settings->d_ptr.data();
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index d400fc75e..f60fdcddf 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -549,6 +549,7 @@ Q_SIGNALS:
Q_REVISION(7) void inspectedViewChanged();
Q_REVISION(7) void devToolsViewChanged();
Q_REVISION(7) void registerProtocolHandlerRequested(const QWebEngineRegisterProtocolHandlerRequest &request);
+ Q_REVISION(8) void printRequested();
#if QT_CONFIG(webengine_testsupport)
void testSupportChanged();
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 7e5d1e64f..b030b2a29 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -155,6 +155,7 @@ public:
QtWebEngineCore::ProfileAdapter *profileAdapter() override;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
+ void printRequested() override;
void updateAction(QQuickWebEngineView::WebAction) const;
void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc
index 741dee2f7..cc826a0d9 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -1462,3 +1462,13 @@
\sa WebEngineAction
*/
+
+/*!
+ \qmlsignal WebEngineView::printRequest
+ \since QtWebEngine 1.8
+
+ This signal is emitted when the JavaScript \c{window.print()} method is called.
+ Typically, the signal handler can simply call printToPdf().
+
+ \sa printToPdf
+*/
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 16a9c138d..5b42b871a 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -739,6 +739,16 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
}
/*!
+ \fn void QWebEnginePage::printRequested()
+ \since 5.12
+
+ This signal is emitted when the JavaScript \c{window.print()} method is called.
+ Typically, the signal handler can simply call printToPdf().
+
+ \sa printToPdf()
+*/
+
+/*!
\enum QWebEnginePage::RenderProcessTerminationStatus
\since 5.6
@@ -1751,6 +1761,14 @@ void QWebEnginePagePrivate::setToolTip(const QString &toolTipText)
view->setToolTip(wrappedTip);
}
+void QWebEnginePagePrivate::printRequested()
+{
+ Q_Q(QWebEnginePage);
+ QTimer::singleShot(0, q, [q](){
+ Q_EMIT q->printRequested();
+ });
+}
+
#if QT_CONFIG(menu)
QMenu *QWebEnginePage::createStandardContextMenu()
{
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 3e5e083df..b8bf61700 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -343,6 +343,7 @@ Q_SIGNALS:
void recentlyAudibleChanged(bool recentlyAudible);
void pdfPrintingFinished(const QString &filePath, bool success);
+ void printRequested();
protected:
virtual QWebEnginePage *createWindow(WebWindowType type);
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index e2329e8f8..66a92dec9 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -146,6 +146,7 @@ public:
bool supportsDragging() const override;
bool isEnabled() const override;
void setToolTip(const QString &toolTipText) override;
+ void printRequested() override;
const QObject *holdingQObject() const override;
ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; }