diff options
Diffstat (limited to 'src/webenginewidgets/api/qwebenginepage.cpp')
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.cpp | 171 |
1 files changed, 72 insertions, 99 deletions
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index fae34ae8d..696b6723f 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -48,12 +48,13 @@ #include "file_picker_controller.h" #include "javascript_dialog_controller.h" #if QT_CONFIG(webengine_printing_and_pdf) -#include "printing/pdfium_document_wrapper_qt.h" +#include "printer_worker.h" #endif #include "qwebenginecertificateerror.h" #include "qwebenginefullscreenrequest.h" #include "qwebenginehistory.h" #include "qwebenginehistory_p.h" +#include "qwebenginenotification.h" #include "qwebengineprofile.h" #include "qwebengineprofile_p.h" #include "qwebenginequotarequest.h" @@ -62,6 +63,7 @@ #include "qwebenginesettings.h" #include "qwebengineview.h" #include "qwebengineview_p.h" +#include "user_notification_controller.h" #include "render_widget_host_view_qt_delegate_widget.h" #include "web_contents_adapter.h" #include "web_engine_settings.h" @@ -94,6 +96,7 @@ #include <QMimeData> #if QT_CONFIG(webengine_printing_and_pdf) #include <QPrinter> +#include <QThread> #endif #include <QStandardPaths> #include <QStyle> @@ -106,89 +109,6 @@ using namespace QtWebEngineCore; static const int MaxTooltipLength = 1024; -#if QT_CONFIG(webengine_printing_and_pdf) -static bool printPdfDataOnPrinter(const QByteArray& data, QPrinter& printer) -{ - if (!data.size()) { - qWarning("Failure to print on printer %ls: Print result data is empty.", - qUtf16Printable(printer.printerName())); - return false; - } - - QSize pageSize = printer.pageRect().size(); - PdfiumDocumentWrapperQt pdfiumWrapper(data.constData(), data.size(), pageSize); - - 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)) { - qWarning("Failure to print on printer %ls: Could not open printer for painting.", - qUtf16Printable(printer.printerName())); - 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; - - // Painting operations are automatically clipped to the bounds of the drawable part of the page. - painter.drawImage(QRect(0, 0, pageSize.width(), pageSize.height()), 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 // QT_CONFIG(webengine_printing_and_pdf) - static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition) { switch (disposition) { @@ -241,6 +161,7 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) , webChannelWorldId(QWebEngineScript::MainWorld) , defaultAudioMuted(false) , defaultZoomFactor(1.0) + , requestInterceptor(nullptr) #if QT_CONFIG(webengine_printing_and_pdf) , currentPrinter(nullptr) #endif @@ -262,6 +183,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) QWebEnginePagePrivate::~QWebEnginePagePrivate() { + if (requestInterceptor) + profile->d_ptr->profileAdapter()->removePageRequestInterceptor(); delete history; delete settings; profile->d_ptr->removeWebContentsAdapterClient(this); @@ -335,7 +258,7 @@ void QWebEnginePagePrivate::didUpdateTargetURL(const QUrl &hoveredUrl) void QWebEnginePagePrivate::selectionChanged() { Q_Q(QWebEnginePage); - Q_EMIT q->selectionChanged(); + QTimer::singleShot(0, q, &QWebEnginePage::selectionChanged); } void QWebEnginePagePrivate::recentlyAudibleChanged(bool recentlyAudible) @@ -349,11 +272,6 @@ QRectF QWebEnginePagePrivate::viewportRect() const return view ? view->rect() : QRectF(); } -qreal QWebEnginePagePrivate::dpiScale() const -{ - return 1.0; -} - QColor QWebEnginePagePrivate::backgroundColor() const { return m_backgroundColor; @@ -502,19 +420,35 @@ void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount) m_callbacks.invoke(requestId, matchCount > 0); } -void QWebEnginePagePrivate::didPrintPage(quint64 requestId, const QByteArray &result) +void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer<QByteArray> result) { #if QT_CONFIG(webengine_printing_and_pdf) + Q_Q(QWebEnginePage); + // If no currentPrinter is set that means that were printing to PDF only. if (!currentPrinter) { - m_callbacks.invoke(requestId, result); + if (!result.data()) + return; + m_callbacks.invoke(requestId, *(result.data())); return; } - bool printerResult = printPdfDataOnPrinter(result, *currentPrinter); + QThread *printerThread = new QThread; + QObject::connect(printerThread, &QThread::finished, printerThread, &QThread::deleteLater); + printerThread->start(); + + PrinterWorker *printerWorker = new PrinterWorker(result, currentPrinter); + QObject::connect(printerWorker, &PrinterWorker::resultReady, q, [=](bool success) { + currentPrinter = nullptr; + m_callbacks.invoke(requestId, success); + }); + + QObject::connect(printerWorker, &PrinterWorker::resultReady, printerThread, &QThread::quit); + QObject::connect(printerThread, &QThread::finished, printerWorker, &PrinterWorker::deleteLater); + + printerWorker->moveToThread(printerThread); + QMetaObject::invokeMethod(printerWorker, "print"); - currentPrinter = nullptr; - m_callbacks.invoke(requestId, printerResult); #else // we should never enter this branch, but just for safe-keeping... Q_UNUSED(result); @@ -616,6 +550,12 @@ void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegister Q_EMIT q->registerProtocolHandlerRequested(request); } +void QWebEnginePagePrivate::runUserNotificationPermissionRequest(const QUrl &securityOrigin) +{ + Q_Q(QWebEnginePage); + Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::Notifications); +} + QObject *QWebEnginePagePrivate::accessibilityParentObject() { return view; @@ -1862,6 +1802,40 @@ void QWebEnginePagePrivate::printRequested() }); } +/*! + \since 5.13 + + Registers the request interceptor \a interceptor to intercept URL requests. + + The page does not take ownership of the pointer. This interceptor is called + after any interceptors on the profile, and unlike profile interceptors, is run + on the UI thread, making it thread-safer. Only URL requests from this page are + intercepted. + + To unset the request interceptor, set a \c nullptr. + + \sa QWebEngineUrlRequestInfo, QWebEngineProfile::setRequestInterceptor() +*/ + +void QWebEnginePage::setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor) +{ + Q_D(QWebEnginePage); + bool hadInterceptorChanged = bool(d->requestInterceptor) != bool(interceptor); + d->requestInterceptor = interceptor; + if (hadInterceptorChanged) { + if (interceptor) + d->profile->d_ptr->profileAdapter()->addPageRequestInterceptor(); + else + d->profile->d_ptr->profileAdapter()->removePageRequestInterceptor(); + } +} + +void QWebEnginePagePrivate::interceptRequest(QWebEngineUrlRequestInfo &info) +{ + if (requestInterceptor) + requestInterceptor->interceptRequest(info); +} + #if QT_CONFIG(menu) QMenu *QWebEnginePage::createStandardContextMenu() { @@ -1920,6 +1894,7 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine d->adapter->grantMouseLockPermission(true); break; case Notifications: + d->adapter->runUserNotificationRequestCallback(securityOrigin, true); break; } } else { // if (policy == PermissionDeniedByUser) @@ -1938,6 +1913,7 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine d->adapter->grantMouseLockPermission(false); break; case Notifications: + d->adapter->runUserNotificationRequestCallback(securityOrigin, false); break; } } @@ -2450,10 +2426,7 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res It is the users responsibility to ensure the \a printer remains valid until \a resultCallback has been called. - \note The rendering of the current content into a temporary PDF document is asynchronous and does - not block the main thread. However, the subsequent rendering of PDF into \a printer runs on the - main thread and will therefore block the event loop. Moreover, printing runs on the browser - process, which is by default not sandboxed. + \note Printing runs on the browser process, which is by default not sandboxed. 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. |