diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp index 4cb0e06eb62ccc482ddcfb65016fff6058123a75..bb01f531cd8d2ccc84bb4580cd102b1055366ed0 100644 --- a/src/core/print_view_manager_qt.cpp +++ b/src/core/print_view_manager_qt.cpp @@ -43,8 +43,8 @@ #include "type_conversion.h" #include "web_engine_context.h" -#include <QtGui/QPageLayout> -#include <QtGui/QPageSize> +#include <QtGui/qpagelayout.h> +#include <QtGui/qpagesize.h> #include "base/values.h" #include "chrome/browser/printing/print_job_manager.h" @@ -101,43 +101,58 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data, metafile.SaveTo(&file); } -static void applyQPageLayoutSettingsToDictionary(const QPageLayout& pageLayout, base::DictionaryValue& print_settings) +static base::DictionaryValue *createPrintSettings() { + base::DictionaryValue *printSettings = new base::DictionaryValue(); // TO DO: Check if we can use the request ID from Qt here somehow. static int internalRequestId = 0; - print_settings.SetBoolean(printing::kIsFirstRequest, internalRequestId++ == 0); - print_settings.SetInteger(printing::kPreviewRequestID, internalRequestId); + printSettings->SetBoolean(printing::kIsFirstRequest, internalRequestId++ == 0); + printSettings->SetInteger(printing::kPreviewRequestID, internalRequestId); + + // The following are standard settings that Chromium expects to be set. + printSettings->SetBoolean(printing::kSettingPrintToPDF, true); + printSettings->SetBoolean(printing::kSettingCloudPrintDialog, false); + printSettings->SetBoolean(printing::kSettingPrintWithPrivet, false); + printSettings->SetBoolean(printing::kSettingPrintWithExtension, false); + + printSettings->SetBoolean(printing::kSettingGenerateDraftData, false); + printSettings->SetBoolean(printing::kSettingPreviewModifiable, false); + printSettings->SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX); + printSettings->SetInteger(printing::kSettingCopies, 1); + printSettings->SetBoolean(printing::kSettingCollate, false); + printSettings->SetBoolean(printing::kSettingGenerateDraftData, false); + printSettings->SetBoolean(printing::kSettingPreviewModifiable, false); + + printSettings->SetBoolean(printing::kSettingShouldPrintSelectionOnly, false); + printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds, false); + printSettings->SetBoolean(printing::kSettingHeaderFooterEnabled, false); + printSettings->SetString(printing::kSettingDeviceName, ""); + printSettings->SetInteger(printing::kPreviewUIID, 12345678); + + return printSettings; +} + +static void applyQPageLayoutSettingsToDictionary(const QPageLayout &pageLayout, base::DictionaryValue &printSettings) +{ //Set page size attributes, chromium expects these in micrometers QSizeF pageSizeInMilimeter = pageLayout.pageSize().size(QPageSize::Millimeter); scoped_ptr<base::DictionaryValue> sizeDict(new base::DictionaryValue); sizeDict->SetInteger(printing::kSettingMediaSizeWidthMicrons, pageSizeInMilimeter.width() * kMicronsToMillimeter); sizeDict->SetInteger(printing::kSettingMediaSizeHeightMicrons, pageSizeInMilimeter.height() * kMicronsToMillimeter); - print_settings.Set(printing::kSettingMediaSize, std::move(sizeDict)); - - print_settings.SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape); - - // The following are standard settings that Chromium expects to be set. - print_settings.SetBoolean(printing::kSettingPrintToPDF, true); - print_settings.SetBoolean(printing::kSettingCloudPrintDialog, false); - print_settings.SetBoolean(printing::kSettingPrintWithPrivet, false); - print_settings.SetBoolean(printing::kSettingPrintWithExtension, false); - - print_settings.SetBoolean(printing::kSettingGenerateDraftData, false); - print_settings.SetBoolean(printing::kSettingPreviewModifiable, false); - print_settings.SetInteger(printing::kSettingColor, printing::COLOR); - print_settings.SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX); - print_settings.SetInteger(printing::kSettingDuplexMode, printing::UNKNOWN_DUPLEX_MODE); - print_settings.SetInteger(printing::kSettingCopies, 1); - print_settings.SetBoolean(printing::kSettingCollate, false); - print_settings.SetBoolean(printing::kSettingGenerateDraftData, false); - print_settings.SetBoolean(printing::kSettingPreviewModifiable, false); - - print_settings.SetBoolean(printing::kSettingShouldPrintSelectionOnly, false); - print_settings.SetBoolean(printing::kSettingShouldPrintBackgrounds, false); - print_settings.SetBoolean(printing::kSettingHeaderFooterEnabled, false); - print_settings.SetString(printing::kSettingDeviceName, ""); - print_settings.SetInteger(printing::kPreviewUIID, 12345678); + printSettings.Set(printing::kSettingMediaSize, std::move(sizeDict)); + + // Apply page margins + QMargins pageMarginsInPoints = pageLayout.marginsPoints(); + scoped_ptr<base::DictionaryValue> marginsDict(new base::DictionaryValue); + marginsDict->SetInteger(printing::kSettingMarginTop, pageMarginsInPoints.top()); + marginsDict->SetInteger(printing::kSettingMarginBottom, pageMarginsInPoints.bottom()); + marginsDict->SetInteger(printing::kSettingMarginLeft, pageMarginsInPoints.left()); + marginsDict->SetInteger(printing::kSettingMarginRight, pageMarginsInPoints.right()); + printSettings.Set(printing::kSettingMarginsCustom, std::move(marginsDict)); + printSettings.SetInteger(printing::kSettingMarginsType, printing::CUSTOM_MARGINS); + + printSettings.SetBoolean(printing::kSettingLandscape, pageLayout.orientation() == QPageLayout::Landscape); } } // namespace @@ -149,20 +164,20 @@ PrintViewManagerQt::~PrintViewManagerQt() } #if defined(ENABLE_BASIC_PRINTING) -bool PrintViewManagerQt::PrintToPDF(const QPageLayout &pageLayout, const QString &filePath) +bool PrintViewManagerQt::PrintToPDF(const QPageLayout &pageLayout, bool printInColor, const QString &filePath) { if (m_printSettings || !filePath.length()) return false; m_pdfOutputPath = toFilePath(filePath); - if (!PrintToPDFInternal(pageLayout)) { + if (!PrintToPDFInternal(pageLayout, printInColor)) { resetPdfState(); return false; } return true; } -bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, const PrintToPDFCallback& callback) +bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, bool printInColor, const PrintToPDFCallback& callback) { if (callback.is_null()) return false; @@ -176,7 +191,7 @@ bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, c } m_pdfPrintCallback = callback; - if (!PrintToPDFInternal(pageLayout)) { + if (!PrintToPDFInternal(pageLayout, printInColor)) { content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(callback, std::vector<char>())); @@ -187,11 +202,13 @@ bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, c return true; } -bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout) +bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool printInColor) { if (!pageLayout.isValid()) return false; - m_printSettings.reset(new base::DictionaryValue()); + m_printSettings.reset(createPrintSettings()); + + m_printSettings->SetInteger(printing::kSettingColor, printInColor ? printing::COLOR : printing::GRAYSCALE); applyQPageLayoutSettingsToDictionary(pageLayout, *m_printSettings); return Send(new PrintMsg_InitiatePrintPreview(routing_id(), false)); } diff --git a/src/core/print_view_manager_qt.h b/src/core/print_view_manager_qt.h index 8856a5b2b5c9bd86a4401c52a5ef75e60a018b20..668516096b5d3ab7a2b28c019ccdef783f249028 100644 --- a/src/core/print_view_manager_qt.h +++ b/src/core/print_view_manager_qt.h @@ -83,8 +83,8 @@ public: typedef base::Callback<void(const std::vector<char> &result)> PrintToPDFCallback; #if defined(ENABLE_BASIC_PRINTING) // Method to print a page to a Pdf document with page size \a pageSize in location \a filePath. - bool PrintToPDF(const QPageLayout& pageLayout, const QString& filePath); - bool PrintToPDFWithCallback(const QPageLayout& pageLayout, const PrintToPDFCallback& callback); + bool PrintToPDF(const QPageLayout &pageLayout, bool printInColor, const QString &filePath); + bool PrintToPDFWithCallback(const QPageLayout &pageLayout, bool printInColor, const PrintToPDFCallback &callback); #endif // ENABLE_BASIC_PRINTING // PrintedPagesSource implementation. @@ -109,7 +109,7 @@ protected: void OnMetafileReadyForPrinting(const PrintHostMsg_DidPreviewDocument_Params& params); #if defined(ENABLE_BASIC_PRINTING) - bool PrintToPDFInternal(const QPageLayout &); + bool PrintToPDFInternal(const QPageLayout &, bool printInColor); #endif // base::FilePath m_pdfOutputPath; diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index a7799544b9d50b1f46fbb6651440eefa423426b0..ea11d5e9ce4225f858af78be17c23b0493fcf542 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -50,6 +50,7 @@ #include "browser_context_qt.h" #include "download_manager_delegate_qt.h" #include "media_capture_devices_dispatcher.h" +#include "pdfium_printing_wrapper_qt.h" #include "print_view_manager_qt.h" #include "qwebenginecallback_p.h" #include "render_view_observer_host_qt.h" @@ -91,6 +92,9 @@ #include <QtGui/qaccessible.h> #include <QtGui/qdrag.h> #include <QtGui/qpixmap.h> +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) +#include <QtPrintSupport/qprinter.h> +#endif // QT_NO_PRINTER #include <QtWebChannel/QWebChannel> namespace QtWebEngineCore { @@ -189,6 +193,17 @@ static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient, } } +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) +static void callbackOnPrintingOnPrinterFinished(WebContentsAdapterClient *adapterClient, int requestId, QPrinter *printer, const std::vector<char> &result) +{ + if (requestId) { + PdfiumPrintingWrapperQt printWrapper(result.data(), result.size()); + bool printerResult = printWrapper.printOnPrinter(*printer); + adapterClient->didPrintPageOnPrinter(requestId, printerResult); + } +} +#endif // QT_NO_PRINTER + static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext) { content::WebContents::CreateParams create_params(browserContext, NULL); @@ -948,7 +963,7 @@ void WebContentsAdapter::wasHidden() void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString &filePath) { #if defined(ENABLE_BASIC_PRINTING) - PrintViewManagerQt::FromWebContents(webContents())->PrintToPDF(pageLayout, filePath); + PrintViewManagerQt::FromWebContents(webContents())->PrintToPDF(pageLayout, true, filePath); #endif // if defined(ENABLE_BASIC_PRINTING) } @@ -956,13 +971,33 @@ quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayo { #if defined(ENABLE_BASIC_PRINTING) Q_D(WebContentsAdapter); - PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished, d->adapterClient, d->nextRequestId); - PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, callback); + PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished + , d->adapterClient + , d->nextRequestId); + PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, true + , callback); + return d->nextRequestId++; +#else + return 0; +#endif // if defined(ENABLE_BASIC_PRINTING) +} + +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) +quint64 WebContentsAdapter::printOnPrinterCallbackResult(QPrinter *printer) +{ +#if defined(ENABLE_BASIC_PRINTING) + Q_D(WebContentsAdapter); + PrintViewManagerQt::PrintToPDFCallback callback + = base::Bind(&callbackOnPrintingOnPrinterFinished, d->adapterClient + , d->nextRequestId, printer); + PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback( + printer->pageLayout(), printer->colorMode() == QPrinter::Color, callback); return d->nextRequestId++; #else return 0; #endif // if defined(ENABLE_BASIC_PRINTING) } +#endif // QT_NO_PRINTER QPointF WebContentsAdapter::lastScrollOffset() const { diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 08f68e76baeff439c0c34a2e499ca21a3419b16c..7a109770ed5e5fbfb7bcd21140b791ba9f6117cf 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -58,6 +58,9 @@ class QAccessibleInterface; class QDragEnterEvent; class QDragMoveEvent; class QPageLayout; +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) +class QPrinter; +#endif // QT_NO_PRINTER class QString; class QWebChannel; QT_END_NAMESPACE @@ -174,6 +177,10 @@ public: void printToPDF(const QPageLayout&, const QString&); quint64 printToPDFCallbackResult(const QPageLayout &); +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) + quint64 printOnPrinterCallbackResult(QPrinter *printer); +#endif + // meant to be used within WebEngineCore only content::WebContents *webContents() const; void replaceMisspelling(const QString &word); diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 31786a8f8b2ee9949924342cce1f316713819879..165d84e37cbc31037852c99dcc42b28b5e1ad19b 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -234,6 +234,9 @@ public: virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0; virtual void didFindText(quint64 requestId, int matchCount) = 0; virtual void didPrintPage(quint64 requestId, const QByteArray &result) = 0; +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) + virtual void didPrintPageOnPrinter(quint64 requestId, bool result) = 0; +#endif virtual void passOnFocus(bool reverse) = 0; // returns the last QObject (QWidget/QQuickItem) based object in the accessibility // hierarchy before going into the BrowserAccessibility tree diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 7e5e07b95b543c872c73e2c6ec58b3a08c252a23..60692b8aef88284e45acb83375f7ee4cf8030a66 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -168,6 +168,9 @@ public: virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { } virtual void didFindText(quint64, int) Q_DECL_OVERRIDE; virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE; +#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER) + virtual void didPrintPageOnPrinter(quint64, bool) Q_DECL_OVERRIDE { } +#endif virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE; virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE; diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index c180699f365080f0f7f617a0d30275f3a29f41e2..428cccd9acd7500202dc8ba3fc1dd548a1676e09 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -373,6 +373,13 @@ void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &re m_callbacks.invoke(requestId, result); } +#ifndef QT_NO_PRINTER +void QWebEnginePagePrivate::didPrintPageOnPrinter(quint64 requestId, bool result) +{ + m_callbacks.invoke(requestId, result); +} +#endif + void QWebEnginePagePrivate::passOnFocus(bool reverse) { if (view) @@ -1841,6 +1848,28 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res d->m_callbacks.registerCallback(requestId, resultCallback); } +#ifndef QT_NO_PRINTER +/*! + \fn void QWebEnginePage::print(const QPrinter &printer, FunctorOrLambda resultCallback) + Renders the current content of the page into a temporary PDF document, then prints it using \a printer. + + The settings for creating and printing the PDF document will be retrieved from the \a printer + object. + It is the users responsibility to ensure the \a printer remains valid until \a resultCallback + has been called. + + The \a resultCallback must take a boolean as parameter. If printing was successful, this + boolean will have the value \c true, otherwise, its value will be \c false. + \since 5.8 +*/ +void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback) +{ + Q_D(QWebEnginePage); + quint64 requestId = d->adapter->printOnPrinterCallbackResult(printer); + d->m_callbacks.registerCallback(requestId, resultCallback); +} +#endif // QT_NO_PRINTER + /*! \since 5.7 diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index bb46cd9fb07b5b626f11a58ea5c3d57579b9671b..923c3bb7026300238c3147cc9d17bb9f8b84caf0 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -54,6 +54,9 @@ QT_BEGIN_NAMESPACE class QMenu; +#ifndef QT_NO_PRINTER +class QPrinter; +#endif class QWebChannel; class QWebEngineContextMenuData; class QWebEngineFullScreenRequest; @@ -280,6 +283,14 @@ public: void printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &layout = QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF())); #endif +#ifndef QT_NO_PRINTER +#ifdef Q_QDOC + void print(QPrinter *printer, FunctorOrLambda resultCallback) +#else + void print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback); +#endif // QDOC +#endif // QT_NO_PRINTER + const QWebEngineContextMenuData &contextMenuData() const; void viewSource(); bool canViewSource() const; diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 8d2a86350ee895a4ef67f47fd24b46762b2ef787..93ebdf6e6b4141820ae2d3a665ebbedc774b9a63 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -119,6 +119,9 @@ public: virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE; virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE; virtual void didPrintPage(quint64 requestId, const QByteArray &result) Q_DECL_OVERRIDE; +#ifndef QT_NO_PRINTER + virtual void didPrintPageOnPrinter(quint64 requestId, bool result) Q_DECL_OVERRIDE; +#endif virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE; virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE;