summaryrefslogtreecommitdiffstats
path: root/src/webenginewidgets/api
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@qt.io>2016-12-07 13:55:20 +0100
committerMichael BrĂ¼ning <michael.bruning@qt.io>2016-12-07 13:55:20 +0100
commitc7f8e360da41df8b81004fe45f1582845a951c2b (patch)
tree32cf6ecb336af7d89a0a86153bb07ee49f23baa9 /src/webenginewidgets/api
parent3d000cfc013158f56c0b088c9ee99b03938ef50b (diff)
parent5ec330cec86cd7781ced295790ce93ac8748dcc4 (diff)
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: src/3rdparty Change-Id: Ie7b7c469aa24716816a23b8fe7a8df9f477a9f67
Diffstat (limited to 'src/webenginewidgets/api')
-rw-r--r--src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp22
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp171
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h6
3 files changed, 181 insertions, 18 deletions
diff --git a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp b/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
index e47f135e8..a39c0e483 100644
--- a/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
+++ b/src/webenginewidgets/api/qtwebenginewidgetsglobal.cpp
@@ -48,18 +48,26 @@ namespace QtWebEngineCore
}
QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_OPENGL
+Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
+#endif
+
static void initialize()
{
- //On window/ANGLE, calling QtWebEngine::initialize from DllMain will result in a crash.
- //To ensure it doesn't, we check that when loading the library
- //QCoreApplication is not yet instantiated, ensuring the call will be deferred
-#if defined(Q_OS_WIN)
- if (QCoreApplication::instance()
- && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
+#ifndef QT_NO_OPENGL
+ if (QCoreApplication::instance()) {
+ //On window/ANGLE, calling QtWebEngine::initialize from DllMain will result in a crash.
+ if (!qt_gl_global_share_context()) {
+ qWarning("Qt WebEngine seems to be initialized from a plugin. Please "
+ "set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute "
+ "before constructing QGuiApplication.");
+ }
return;
}
-#endif
+ //QCoreApplication is not yet instantiated, ensuring the call will be deferred
qAddPreRoutine(QtWebEngineCore::initialize);
+#endif // QT_NO_OPENGL
}
Q_CONSTRUCTOR_FUNCTION(initialize)
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index ca160c362..16e9438c9 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -47,6 +47,7 @@
#include "favicon_manager.h"
#include "file_picker_controller.h"
#include "javascript_dialog_controller.h"
+#include "pdfium_document_wrapper_qt.h"
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
@@ -79,6 +80,9 @@
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
+#ifndef QT_NO_PRINTER
+#include <QPrinter>
+#endif
#include <QStandardPaths>
#include <QStyle>
#include <QTimer>
@@ -92,6 +96,87 @@ using namespace QtWebEngineCore;
static const int MaxTooltipLength = 1024;
+#ifndef QT_NO_PRINTER
+#if defined(ENABLE_PDF)
+static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer)
+{
+ QRect printerPageRect = printer.pageRect();
+ PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), printerPageRect.size());
+
+ int toPage = printer.toPage();
+ int fromPage = printer.fromPage();
+ bool ascendingOrder = true;
+
+ if (fromPage == 0 && toPage == 0) {
+ fromPage = 1;
+ toPage = pdfiumWrapper.pageCount();
+ }
+ fromPage = qMax(1, fromPage);
+ toPage = qMin(pdfiumWrapper.pageCount(), toPage);
+
+ if (printer.pageOrder() == QPrinter::LastPageFirst) {
+ qSwap(fromPage, toPage);
+ ascendingOrder = false;
+ }
+
+ int pageCopies = 1;
+ int documentCopies = 1;
+
+ if (!printer.supportsMultipleCopies())
+ documentCopies = printer.copyCount();
+
+ if (printer.collateCopies()) {
+ pageCopies = documentCopies;
+ documentCopies = 1;
+ }
+
+ QPainter painter;
+ if (!painter.begin(&printer)) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Failure to print on printer %ls: Could not open printer for painting.", qUtf16Printable(printer.printerName()));
+#else
+ qWarning("Failure to print on printer %s: Could not open printer for painting.", qPrintable(printer.printerName()));
+#endif
+ return false;
+ }
+
+ for (int printedDocuments = 0; printedDocuments < documentCopies; printedDocuments++) {
+ int currentPageIndex = fromPage;
+ while (true) {
+ for (int printedPages = 0; printedPages < pageCopies; printedPages++) {
+ if (printer.printerState() == QPrinter::Aborted
+ || printer.printerState() == QPrinter::Error)
+ return false;
+
+ QImage currentImage = pdfiumWrapper.pageAsQImage(currentPageIndex - 1);
+ if (currentImage.isNull())
+ return false;
+
+ painter.drawImage(printerPageRect, currentImage, currentImage.rect());
+ if (printedPages < pageCopies - 1)
+ printer.newPage();
+ }
+
+ if (currentPageIndex == toPage)
+ break;
+
+ if (ascendingOrder)
+ currentPageIndex++;
+ else
+ currentPageIndex--;
+
+ printer.newPage();
+ }
+ if (printedDocuments < documentCopies - 1)
+ printer.newPage();
+ }
+ painter.end();
+
+ return true;
+}
+#endif // defined(ENABLE_PDF)
+#endif // QT_NO_PRINTER
+
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
@@ -142,6 +227,9 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
, fullscreenMode(false)
, webChannel(nullptr)
, webChannelWorldId(QWebEngineScript::MainWorld)
+#ifndef QT_NO_PRINTER
+ , currentPrinter(nullptr)
+#endif
{
memset(actions, 0, sizeof(actions));
}
@@ -154,7 +242,16 @@ QWebEnginePagePrivate::~QWebEnginePagePrivate()
RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
- return new RenderWidgetHostViewQtDelegateWidget(client);
+ // Set the QWebEngineView as the parent for a popup delegate, so that the new popup window
+ // responds properly to clicks in case the QWebEngineView is inside a modal QDialog. Setting the
+ // parent essentially notifies the OS that the popup window is part of the modal session, and
+ // should allow interaction.
+ // The new delegate will not be deleted by the parent view though, because we unset the parent
+ // when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is
+ // dismissed.
+ // If the delegate is not for a popup, but for a newly created QWebEngineView, the parent is 0
+ // just like before.
+ return new RenderWidgetHostViewQtDelegateWidget(client, this->view);
}
void QWebEnginePagePrivate::titleChanged(const QString &title)
@@ -380,15 +477,27 @@ void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount)
void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &result)
{
- m_callbacks.invoke(requestId, result);
-}
-
+#if defined(ENABLE_PDF)
#ifndef QT_NO_PRINTER
-void QWebEnginePagePrivate::didPrintPageOnPrinter(quint64 requestId, bool result)
-{
+ // If no currentPrinter is set that means that were printing to PDF only.
+ if (!currentPrinter) {
+ m_callbacks.invoke(requestId, result);
+ return;
+ }
+
+ bool printerResult = printPdfDataOnPrinter(result, *currentPrinter);
+
+ m_callbacks.invoke(requestId, printerResult);
+ currentPrinter = nullptr;
+#else // If print support is disabled, only PDF printing is available.
m_callbacks.invoke(requestId, result);
+#endif // ifndef QT_NO_PRINTER
+#else // defined(ENABLE_PDF)
+ // we should never enter this branch, but just for safe-keeping...
+ Q_UNUSED(result);
+ m_callbacks.invoke(requestId, QByteArray());
+#endif // defined(ENABLE_PDF)
}
-#endif
void QWebEnginePagePrivate::passOnFocus(bool reverse)
{
@@ -1835,8 +1944,23 @@ QSizeF QWebEnginePage::contentsSize() const
*/
void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &pageLayout)
{
+#if defined(ENABLE_PDF)
Q_D(const QWebEnginePage);
+#ifndef QT_NO_PRINTER
+ if (d->currentPrinter) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Cannot print to PDF while at the same time printing on printer %ls", qUtf16Printable(d->currentPrinter->printerName()));
+#else
+ qWarning("Cannot print to PDF while at the same time printing on printer %s", qPrintable(d->currentPrinter->printerName()));
+#endif
+ return;
+ }
+#endif
d->adapter->printToPDF(pageLayout, filePath);
+#else
+ Q_UNUSED(filePath);
+ Q_UNUSED(pageLayout);
+#endif // if defined(ENABLE_PDF)
}
@@ -1854,8 +1978,24 @@ void QWebEnginePage::printToPdf(const QString &filePath, const QPageLayout &page
void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &resultCallback, const QPageLayout &pageLayout)
{
Q_D(QWebEnginePage);
+#if defined(ENABLE_PDF)
+#ifndef QT_NO_PRINTER
+ if (d->currentPrinter) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Cannot print to PDF while at the same time printing on printer %ls", qUtf16Printable(d->currentPrinter->printerName()));
+#else
+ qWarning("Cannot print to PDF while at the same time printing on printer %s", qPrintable(d->currentPrinter->printerName()));
+#endif
+ d->m_callbacks.invokeEmpty(resultCallback);
+ return;
+ }
+#endif // ifndef QT_NO_PRINTER
quint64 requestId = d->adapter->printToPDFCallbackResult(pageLayout);
d->m_callbacks.registerCallback(requestId, resultCallback);
+#else // if defined(ENABLE_PDF)
+ Q_UNUSED(pageLayout);
+ d->m_callbacks.invokeEmpty(resultCallback);
+#endif // if defined(ENABLE_PDF)
}
#ifndef QT_NO_PRINTER
@@ -1875,8 +2015,23 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
void QWebEnginePage::print(QPrinter *printer, const QWebEngineCallback<bool> &resultCallback)
{
Q_D(QWebEnginePage);
- quint64 requestId = d->adapter->printOnPrinterCallbackResult(printer);
+#if defined(ENABLE_PDF)
+ if (d->currentPrinter) {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+ qWarning("Cannot print page on printer %ls: Already printing on %ls.", qUtf16Printable(printer->printerName()), qUtf16Printable(d->currentPrinter->printerName()));
+#else
+ qWarning("Cannot print page on printer %s: Already printing on %s.", qPrintable(printer->printerName()), qPrintable(d->currentPrinter->printerName()));
+#endif
+ d->m_callbacks.invokeDirectly(resultCallback, false);
+ return;
+ }
+ d->currentPrinter = printer;
+ quint64 requestId = d->adapter->printToPDFCallbackResult(printer->pageLayout(), printer->colorMode() == QPrinter::Color);
d->m_callbacks.registerCallback(requestId, resultCallback);
+#else // if defined(ENABLE_PDF)
+ Q_UNUSED(printer);
+ d->m_callbacks.invokeDirectly(resultCallback, false);
+#endif // if defined(ENABLE_PDF)
}
#endif // QT_NO_PRINTER
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 8d78429d8..0ad077a0e 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -119,9 +119,6 @@ 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;
@@ -181,6 +178,9 @@ public:
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
+#ifndef QT_NO_PRINTER
+ QPrinter *currentPrinter;
+#endif // QT_NO_PRINTER
};
QT_END_NAMESPACE