diff options
Diffstat (limited to 'src/webenginequick')
55 files changed, 1338 insertions, 558 deletions
diff --git a/src/webenginequick/CMakeLists.txt b/src/webenginequick/CMakeLists.txt index ebe1ddf54..b7de1c2af 100644 --- a/src/webenginequick/CMakeLists.txt +++ b/src/webenginequick/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + add_subdirectory(ui) qt_internal_add_qml_module(WebEngineQuick @@ -34,9 +37,8 @@ qt_internal_add_qml_module(WebEngineQuick api/qquickwebengineforeigntypes_p.h api/qtwebenginequickglobal.cpp api/qtwebenginequickglobal.h api/qtwebenginequickglobal_p.h - qquickwebengine_accessible.cpp qquickwebengine_accessible.h - render_widget_host_view_qt_delegate_quickwindow.cpp render_widget_host_view_qt_delegate_quickwindow.h - ui_delegates_manager.cpp ui_delegates_manager.h + render_widget_host_view_qt_delegate_quickwindow.cpp render_widget_host_view_qt_delegate_quickwindow_p.h + ui_delegates_manager.cpp ui_delegates_manager_p.h DEFINES QT_BUILD_WEBENGINE_LIB INCLUDE_DIRECTORIES @@ -53,6 +55,17 @@ qt_internal_add_qml_module(WebEngineQuick Qt::Qml Qt::Quick Qt::WebEngineCore + NO_GENERATE_CPP_EXPORTS +) + +qt_internal_extend_target(WebEngineQuick CONDITION QT_FEATURE_webengine_webchannel + PUBLIC_LIBRARIES + Qt::WebChannelQuick +) + +qt_internal_extend_target(WebEngineQuick CONDITION QT_FEATURE_accessibility + SOURCES + qquickwebengine_accessible.cpp qquickwebengine_accessible_p.h ) qt_internal_extend_target(qtwebenginequickplugin diff --git a/src/webenginequick/api/qquickwebengineaction.cpp b/src/webenginequick/api/qquickwebengineaction.cpp index 70205f883..006715c70 100644 --- a/src/webenginequick/api/qquickwebengineaction.cpp +++ b/src/webenginequick/api/qquickwebengineaction.cpp @@ -20,7 +20,7 @@ QT_BEGIN_NAMESPACE method. It provides information about the action, such as whether it is \l enabled. - The following code uses the \l WebEngineView::action() method to check if the + The following code uses the \l WebEngineView::action() method to check if the copy action is enabled: \code @@ -30,6 +30,14 @@ QT_BEGIN_NAMESPACE else console.log("Copy is disabled."); \endcode + + A \l ToolButton can be connected to a WebEngineAction as follows: + + \snippet qtwebengine_webengineaction.qml 0 + + A context menu could be implemented like this: + + \snippet qtwebengine_webengineaction.qml 1 */ QQuickWebEngineActionPrivate::QQuickWebEngineActionPrivate(const QVariant &data, const QString &text, const QString &iconName, bool enabled) diff --git a/src/webenginequick/api/qquickwebengineaction_p.h b/src/webenginequick/api/qquickwebengineaction_p.h index 51267c166..fcada7773 100644 --- a/src/webenginequick/api/qquickwebengineaction_p.h +++ b/src/webenginequick/api/qquickwebengineaction_p.h @@ -29,7 +29,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineActionPrivate; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineAction : public QObject +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineAction : public QObject { Q_OBJECT Q_PROPERTY(QString text READ text CONSTANT FINAL) diff --git a/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp b/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp index f21750053..46e531716 100644 --- a/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp +++ b/src/webenginequick/api/qquickwebengineclientcertificateselection.cpp @@ -126,7 +126,7 @@ QQmlListProperty<QQuickWebEngineClientCertificateOption> QQuickWebEngineClientCe { if (m_certificates.empty()) { QList<QSslCertificate> certificates = d_ptr->certificates(); - for (int i = 0; i < certificates.count(); ++i) + for (int i = 0; i < certificates.size(); ++i) m_certificates.push_back(new QQuickWebEngineClientCertificateOption(this, i)); } diff --git a/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h b/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h index 1c4c214cf..2e0450f8e 100644 --- a/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h +++ b/src/webenginequick/api/qquickwebengineclientcertificateselection_p.h @@ -33,7 +33,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineClientCertificateSelection; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineClientCertificateOption : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineClientCertificateOption : public QObject { Q_OBJECT Q_PROPERTY(QString issuer READ issuer CONSTANT FINAL) Q_PROPERTY(QString subject READ subject CONSTANT FINAL) @@ -62,7 +62,7 @@ private: int m_index; }; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineClientCertificateSelection : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineClientCertificateSelection : public QObject { Q_OBJECT Q_PROPERTY(QUrl host READ host CONSTANT FINAL) Q_PROPERTY(QQmlListProperty<QQuickWebEngineClientCertificateOption> certificates READ certificates CONSTANT FINAL) diff --git a/src/webenginequick/api/qquickwebenginedialogrequests.cpp b/src/webenginequick/api/qquickwebenginedialogrequests.cpp index 3c9f8a9a7..d49f17397 100644 --- a/src/webenginequick/api/qquickwebenginedialogrequests.cpp +++ b/src/webenginequick/api/qquickwebenginedialogrequests.cpp @@ -685,6 +685,35 @@ void QQuickWebEngineFileDialogRequest::dialogReject() \since QtWebEngine 1.10 \brief A request for showing a tooltip to the user. + + A TooltipRequest is a request object that is passed as a + parameter of the WebEngineView::tooltipRequested signal. Use the + \c onTooltipRequested signal handler to handle requests for + custom tooltip menus at specific positions. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default tooltip should + be displayed. + + The following code uses a custom tooltip to handle the request: + + \code + WebEngineView { + // ... + onTooltipRequested: function(request) { + if (request.type == TooltipRequest.Show) { + tooltip.visible = true; + tooltip.x = request.x; + tooltip.y = request.y; + tooltip.text = request.text; + } else { + tooltip.visible = false; + } + request.accepted = true; + } + // ... + } + \endcode */ QQuickWebEngineTooltipRequest::QQuickWebEngineTooltipRequest( diff --git a/src/webenginequick/api/qquickwebenginedialogrequests_p.h b/src/webenginequick/api/qquickwebenginedialogrequests_p.h index e83481400..d33a14df4 100644 --- a/src/webenginequick/api/qquickwebenginedialogrequests_p.h +++ b/src/webenginequick/api/qquickwebenginedialogrequests_p.h @@ -32,7 +32,7 @@ namespace QtWebEngineCore { QT_BEGIN_NAMESPACE -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineAuthenticationDialogRequest : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineAuthenticationDialogRequest : public QObject { Q_OBJECT public: @@ -79,7 +79,7 @@ private: Q_DISABLE_COPY(QQuickWebEngineAuthenticationDialogRequest) }; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineJavaScriptDialogRequest : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineJavaScriptDialogRequest : public QObject { Q_OBJECT public: @@ -130,7 +130,7 @@ private: Q_DISABLE_COPY(QQuickWebEngineJavaScriptDialogRequest) }; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineColorDialogRequest : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineColorDialogRequest : public QObject { Q_OBJECT public: @@ -161,7 +161,7 @@ private: Q_DISABLE_COPY(QQuickWebEngineColorDialogRequest) }; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineFileDialogRequest : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineFileDialogRequest : public QObject { Q_OBJECT public: @@ -206,7 +206,7 @@ private: Q_DISABLE_COPY(QQuickWebEngineFileDialogRequest) }; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineTooltipRequest : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineTooltipRequest : public QObject { Q_OBJECT public: enum RequestType { diff --git a/src/webenginequick/api/qquickwebenginedownloadrequest_p.h b/src/webenginequick/api/qquickwebenginedownloadrequest_p.h index 2d4ac0773..42a0d88ba 100644 --- a/src/webenginequick/api/qquickwebenginedownloadrequest_p.h +++ b/src/webenginequick/api/qquickwebenginedownloadrequest_p.h @@ -24,7 +24,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineProfilePrivate; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineDownloadRequest : public QWebEngineDownloadRequest +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineDownloadRequest : public QWebEngineDownloadRequest { Q_OBJECT public: diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp index 087ab029b..56bbb97ac 100644 --- a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp +++ b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp @@ -35,9 +35,9 @@ static QSize largestSize(const QList<QSize> &availableSizes) static QSize fitSize(const QList<QSize> &availableSizes, const QSize &requestedSize) { - Q_ASSERT(availableSizes.count()); + Q_ASSERT(availableSizes.size()); QSize result = largestSize(availableSizes); - if (availableSizes.count() == 1 || area(requestedSize) >= area(result)) + if (availableSizes.size() == 1 || area(requestedSize) >= area(result)) return result; for (const QSize &size : availableSizes) { diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h index b83db2cb4..89bfb6e73 100644 --- a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h +++ b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h @@ -67,7 +67,7 @@ private: QImage m_image; }; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineFaviconProvider : public QQuickAsyncImageProvider +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineFaviconProvider : public QQuickAsyncImageProvider { public: static QString identifier(); diff --git a/src/webenginequick/api/qquickwebengineforeigntypes_p.h b/src/webenginequick/api/qquickwebengineforeigntypes_p.h index d8351c855..2d205254e 100644 --- a/src/webenginequick/api/qquickwebengineforeigntypes_p.h +++ b/src/webenginequick/api/qquickwebengineforeigntypes_p.h @@ -30,13 +30,22 @@ #include <QtWebEngineCore/qwebenginefullscreenrequest.h> #include <QtWebEngineCore/qwebenginecontextmenurequest.h> #include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h> +#include <QtWebEngineCore/qwebenginefilesystemaccessrequest.h> +#include <QtWebEngineCore/qwebenginewebauthuxrequest.h> QT_BEGIN_NAMESPACE +// To prevent the same type from being exported twice into qmltypes +// (for value type and for the enums) +struct QWebEngineLoadingInfoDerived : public QWebEngineLoadingInfo +{ + Q_GADGET +}; + namespace ForeignWebEngineLoadingInfoNamespace { Q_NAMESPACE - QML_FOREIGN_NAMESPACE(QWebEngineLoadingInfo) + QML_FOREIGN_NAMESPACE(QWebEngineLoadingInfoDerived) QML_NAMED_ELEMENT(WebEngineLoadingInfo) QML_ADDED_IN_VERSION(1, 1) QML_EXTRA_VERSION(2, 0) @@ -52,10 +61,17 @@ struct ForeignWebEngineLoadingInfo QML_UNCREATABLE("") }; +// To prevent the same type from being exported twice into qmltypes +// (for value type and for the enums) +struct QWebEngineCertificateErrorDerived : public QWebEngineCertificateError +{ + Q_GADGET +}; + namespace ForeignWebEngineCertificateErrorNamespace { Q_NAMESPACE - QML_FOREIGN_NAMESPACE(QWebEngineCertificateError) + QML_FOREIGN_NAMESPACE(QWebEngineCertificateErrorDerived) QML_NAMED_ELEMENT(WebEngineCertificateError) QML_ADDED_IN_VERSION(1, 1) QML_EXTRA_VERSION(2, 0) @@ -140,6 +156,7 @@ struct ForeignWebEngineContextMenuRequest QML_UNCREATABLE("") }; +#if QT_DEPRECATED_SINCE(6, 5) struct ForeignWebEngineQuotaRequest { Q_GADGET @@ -149,6 +166,7 @@ struct ForeignWebEngineQuotaRequest QML_EXTRA_VERSION(2, 0) QML_UNCREATABLE("") }; +#endif struct ForeignWebEngineRegisterProtocolHandlerRequest { @@ -180,6 +198,39 @@ struct ForeignWebEngineFindTextResult QML_UNCREATABLE("") }; +struct ForeginWebEngineFileSystemAccessRequest +{ + Q_GADGET + QML_FOREIGN(QWebEngineFileSystemAccessRequest) + QML_NAMED_ELEMENT(webEngineFileSystemAccessRequest) + QML_ADDED_IN_VERSION(6, 4) + QML_UNCREATABLE("") +}; + +// To prevent the same type from being exported twice into qmltypes +// (for value type and for the enums) +struct QWebEngineFileSystemAccessRequestDerived : public QWebEngineFileSystemAccessRequest +{ + Q_GADGET +}; + +namespace ForeginWebEngineFileSystemAccessRequestNamespace +{ + Q_NAMESPACE + QML_FOREIGN_NAMESPACE(QWebEngineFileSystemAccessRequestDerived) + QML_NAMED_ELEMENT(WebEngineFileSystemAccessRequest) + QML_ADDED_IN_VERSION(6, 4) +}; + +struct ForeignWebEngineWebAuthUxRequest +{ + Q_GADGET + QML_FOREIGN(QWebEngineWebAuthUxRequest) + QML_NAMED_ELEMENT(WebEngineWebAuthUxRequest) + QML_ADDED_IN_VERSION(6, 7) + QML_UNCREATABLE("") +}; + QT_END_NAMESPACE #endif // QQUICKWEBENGINEFOREIGNTYPES_H diff --git a/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h b/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h index 39655696e..f170fa0c6 100644 --- a/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h +++ b/src/webenginequick/api/qquickwebenginenewwindowrequest_p.h @@ -23,7 +23,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineView; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineNewWindowRequest : public QWebEngineNewWindowRequest +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineNewWindowRequest : public QWebEngineNewWindowRequest { Q_OBJECT public: diff --git a/src/webenginequick/api/qquickwebengineprofile.cpp b/src/webenginequick/api/qquickwebengineprofile.cpp index 1cfaab3f5..7c3d11fcf 100644 --- a/src/webenginequick/api/qquickwebengineprofile.cpp +++ b/src/webenginequick/api/qquickwebengineprofile.cpp @@ -14,6 +14,7 @@ #include <QtWebEngineCore/qwebenginescriptcollection.h> #include <QtWebEngineCore/private/qwebenginescriptcollection_p.h> +#include <QtWebEngineCore/qwebengineclienthints.h> #include <QtWebEngineCore/qwebenginecookiestore.h> #include <QtWebEngineCore/qwebenginenotification.h> #include <QtWebEngineCore/private/qwebenginedownloadrequest_p.h> @@ -124,8 +125,18 @@ QT_BEGIN_NAMESPACE \sa WebEngineProfile::presentNotification */ +/*! + \fn QQuickWebEngineProfile::clearHttpCacheCompleted() + \since 6.7 + + This signal is emitted when the clearHttpCache() operation is completed. + + \sa clearHttpCache() +*/ + QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter) : m_settings(new QQuickWebEngineSettings()) + , m_clientHints(new QWebEngineClientHints(profileAdapter)) , m_profileAdapter(profileAdapter) { profileAdapter->addClient(this); @@ -209,10 +220,13 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) Q_Q(QQuickWebEngineProfile); Q_ASSERT(!m_ongoingDownloads.contains(info.id)); - QWebEngineDownloadRequestPrivate *itemPrivate = new QWebEngineDownloadRequestPrivate(m_profileAdapter, info.url); + QWebEngineDownloadRequestPrivate *itemPrivate = + new QWebEngineDownloadRequestPrivate(m_profileAdapter); itemPrivate->downloadId = info.id; - itemPrivate->downloadState = QWebEngineDownloadRequest::DownloadRequested; + itemPrivate->downloadState = info.accepted ? QWebEngineDownloadRequest::DownloadInProgress + : QWebEngineDownloadRequest::DownloadRequested; itemPrivate->startTime = info.startTime; + itemPrivate->downloadUrl = info.url; itemPrivate->totalBytes = info.totalBytes; itemPrivate->mimeType = info.mimeType; itemPrivate->downloadDirectory = QFileInfo(info.path).path(); @@ -276,6 +290,12 @@ void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineC Q_EMIT q->presentNotification(notification); } +void QQuickWebEngineProfilePrivate::clearHttpCacheCompleted() +{ + Q_Q(QQuickWebEngineProfile); + Q_EMIT q->clearHttpCacheCompleted(); +} + QQuickWebEngineScriptCollection *QQuickWebEngineProfilePrivate::getUserScripts() { Q_Q(QQuickWebEngineProfile); @@ -322,16 +342,16 @@ QQuickWebEngineScriptCollection *QQuickWebEngineProfilePrivate::getUserScripts() */ /*! - \qmlsignal WebEngineProfile::downloadRequested(WebEngineDownloadItem download) + \qmlsignal WebEngineProfile::downloadRequested(WebEngineDownloadRequest download) This signal is emitted whenever a download has been triggered. The \a download argument holds the state of the download. - The download has to be explicitly accepted with WebEngineDownloadItem::accept() or the + The download has to be explicitly accepted with WebEngineDownloadRequest::accept() or the download will be cancelled by default. */ /*! - \qmlsignal WebEngineProfile::downloadFinished(WebEngineDownloadItem download) + \qmlsignal WebEngineProfile::downloadFinished(WebEngineDownloadRequest download) This signal is emitted whenever downloading stops, because it finished successfully, was cancelled, or was interrupted (for example, because connectivity was lost). @@ -348,6 +368,15 @@ QQuickWebEngineScriptCollection *QQuickWebEngineProfilePrivate::getUserScripts() */ /*! + \qmlsignal WebEngineProfile::clearHttpCacheCompleted() + \since QtWebEngine 6.7 + + This signal is emitted when the clearHttpCache() operation is completed. + + \sa clearHttpCache() +*/ + +/*! Constructs a new profile with the parent \a parent. */ QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent) @@ -821,6 +850,41 @@ QString QQuickWebEngineProfile::downloadPath() const } /*! + \qmlproperty bool WebEngineProfile::isPushServiceEnabled + \since QtWebEngine 6.5 + + Whether the push messaging service is enabled. + \note By default the push messaging service is disabled. + \note \QWE uses the \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)} as a browser push service. + Therefore, all push messages will go through the Google push service and its respective servers. +*/ + +/*! + \property QQuickWebEngineProfile::isPushServiceEnabled + \since QtWebEngine 6.5 + + Whether the push messaging service is enabled. + \note By default the push messaging service is disabled. + \note \QWE uses the \l {https://firebase.google.com}{Firebase Cloud Messaging (FCM)} as a browser push service. + Therefore, all push messages will go through the Google push service and its respective servers. +*/ + +bool QQuickWebEngineProfile::isPushServiceEnabled() const +{ + const Q_D(QQuickWebEngineProfile); + return d->profileAdapter()->pushServiceEnabled(); +} + +void QQuickWebEngineProfile::setPushServiceEnabled(bool enabled) +{ + Q_D(QQuickWebEngineProfile); + if (isPushServiceEnabled() == enabled) + return; + d->profileAdapter()->setPushServiceEnabled(enabled); + emit pushServiceEnabledChanged(); +} + +/*! Returns the cookie store for this profile. */ @@ -836,7 +900,11 @@ QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const Removes the profile's cache entries. - \sa WebEngineProfile::cachePath + \note Make sure that you do not start new navigation or any operation on the profile while + the clear operation is in progress. The clearHttpCacheCompleted() signal notifies about the + completion. + + \sa WebEngineProfile::cachePath clearHttpCacheCompleted() */ /*! @@ -844,7 +912,11 @@ QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const Removes the profile's cache entries. - \sa WebEngineProfile::clearHttpCache + \note Make sure that you do not start new navigation or any operation on the profile while + the clear operation is in progress. The clearHttpCacheCompleted() signal notifies about the + completion. + + \sa WebEngineProfile::clearHttpCache() clearHttpCacheCompleted() */ void QQuickWebEngineProfile::clearHttpCache() { @@ -952,6 +1024,18 @@ QWebEngineClientCertificateStore *QQuickWebEngineProfile::clientCertificateStore #endif } +/*! + Return the Client Hints settings associated with this browsing context. + + \since 6.8 + \sa QWebEngineClientHints +*/ +QWebEngineClientHints *QQuickWebEngineProfile::clientHints() const +{ + Q_D(const QQuickWebEngineProfile); + return d->m_clientHints.data(); +} + void QQuickWebEngineProfile::ensureQmlContext(const QObject *object) { if (!qmlContext(this)) { diff --git a/src/webenginequick/api/qquickwebengineprofile.h b/src/webenginequick/api/qquickwebengineprofile.h index 77e367d02..088a971e0 100644 --- a/src/webenginequick/api/qquickwebengineprofile.h +++ b/src/webenginequick/api/qquickwebengineprofile.h @@ -15,6 +15,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineDownloadRequest; class QQuickWebEngineSettings; class QWebEngineClientCertificateStore; +class QWebEngineClientHints; class QWebEngineCookieStore; class QWebEngineNotification; class QWebEngineUrlRequestInterceptor; @@ -37,6 +38,7 @@ class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION(1,3)) Q_PROPERTY(QQuickWebEngineScriptCollection *userScripts READ userScripts) Q_PROPERTY(QString downloadPath READ downloadPath WRITE setDownloadPath NOTIFY downloadPathChanged FINAL REVISION(1,5)) + Q_PROPERTY(bool isPushServiceEnabled READ isPushServiceEnabled WRITE setPushServiceEnabled NOTIFY pushServiceEnabledChanged FINAL REVISION(6,5)) QML_NAMED_ELEMENT(WebEngineProfile) QML_ADDED_IN_VERSION(1, 1) QML_EXTRA_VERSION(2, 0) @@ -108,7 +110,11 @@ public: QString downloadPath() const; void setDownloadPath(const QString &path); + bool isPushServiceEnabled() const; + void setPushServiceEnabled(bool enable); + QWebEngineClientCertificateStore *clientCertificateStore(); + QWebEngineClientHints *clientHints() const; static QQuickWebEngineProfile *defaultProfile(); @@ -125,6 +131,8 @@ Q_SIGNALS: Q_REVISION(1,3) void spellCheckLanguagesChanged(); Q_REVISION(1,3) void spellCheckEnabledChanged(); Q_REVISION(1,5) void downloadPathChanged(); + Q_REVISION(6,5) void pushServiceEnabledChanged(); + Q_REVISION(6,7) void clearHttpCacheCompleted(); void downloadRequested(QQuickWebEngineDownloadRequest *download); void downloadFinished(QQuickWebEngineDownloadRequest *download); diff --git a/src/webenginequick/api/qquickwebengineprofile_p.h b/src/webenginequick/api/qquickwebengineprofile_p.h index e7d72af17..477936f98 100644 --- a/src/webenginequick/api/qquickwebengineprofile_p.h +++ b/src/webenginequick/api/qquickwebengineprofile_p.h @@ -28,6 +28,7 @@ class ProfileAdapter; QT_BEGIN_NAMESPACE +class QWebEngineClientHints; class QQuickWebEngineDownloadRequest; class QQuickWebEngineSettings; class QQuickWebEngineScriptCollection; @@ -53,10 +54,12 @@ public: void downloadUpdated(const DownloadItemInfo &info) override; void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) override; + void clearHttpCacheCompleted() override; private: QQuickWebEngineProfile *q_ptr; QScopedPointer<QQuickWebEngineSettings> m_settings; + QScopedPointer<QWebEngineClientHints> m_clientHints; QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter; QMap<quint32, QPointer<QQuickWebEngineDownloadRequest> > m_ongoingDownloads; diff --git a/src/webenginequick/api/qquickwebenginescriptcollection.cpp b/src/webenginequick/api/qquickwebenginescriptcollection.cpp index 17db0d4d0..a58d97832 100644 --- a/src/webenginequick/api/qquickwebenginescriptcollection.cpp +++ b/src/webenginequick/api/qquickwebenginescriptcollection.cpp @@ -199,7 +199,7 @@ QJSValue QQuickWebEngineScriptCollection::collection() const const QList<QWebEngineScript> &list = d->toList(); QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(d->m_qmlEngine); QV4::Scope scope(v4); - QV4::Scoped<QV4::ArrayObject> scriptArray(scope, v4->newArrayObject(list.length())); + QV4::Scoped<QV4::ArrayObject> scriptArray(scope, v4->newArrayObject(list.size())); int i = 0; for (const auto &val : list) { QV4::ScopedValue sv(scope, v4->fromVariant(QVariant::fromValue(val))); diff --git a/src/webenginequick/api/qquickwebenginescriptcollection_p.h b/src/webenginequick/api/qquickwebenginescriptcollection_p.h index 657fd5554..fbcc8dde7 100644 --- a/src/webenginequick/api/qquickwebenginescriptcollection_p.h +++ b/src/webenginequick/api/qquickwebenginescriptcollection_p.h @@ -26,7 +26,7 @@ QT_BEGIN_NAMESPACE class QQmlEngine; class QQuickWebEngineScriptCollectionPrivate; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineScriptCollection : public QObject +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineScriptCollection : public QObject { Q_OBJECT public: diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp index 6d64c1d3b..31ed7a661 100644 --- a/src/webenginequick/api/qquickwebenginesettings.cpp +++ b/src/webenginequick/api/qquickwebenginesettings.cpp @@ -77,6 +77,10 @@ bool QQuickWebEngineSettings::javascriptCanOpenWindows() const To enable also the pasting of clipboard content from JavaScript, use javascriptCanPaste. + Since unrestricted clipboard access is a potential security concern, it is + recommended that applications leave this disabled and instead respond to + \l{WebEngineView::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests. + Disabled by default. */ bool QQuickWebEngineSettings::javascriptCanAccessClipboard() const @@ -383,6 +387,10 @@ bool QQuickWebEngineSettings::webRTCPublicInterfacesOnly() const Enables JavaScript \c{execCommand("paste")}. This also requires enabling javascriptCanAccessClipboard. + Since unrestricted clipboard access is a potential security concern, it is + recommended that applications leave this disabled and instead respond to + \l{WebEngineView::ClipboardReadWrite}{ClipboardReadWrite} feature permission requests. + Disabled by default. */ bool QQuickWebEngineSettings::javascriptCanPaste() const @@ -433,6 +441,48 @@ bool QQuickWebEngineSettings::navigateOnDropEnabled() const } /*! + \qmlproperty bool WebEngineSettings::readingFromCanvasEnabled + \since QtWebEngine 6.6 + + Specifies that reading from all canvas elements is enabled. + + This setting will have impact on all HTML5 canvas elements irrespective of origin, and can be disabled + to prevent canvas fingerprinting. + + Enabled by default. + */ +bool QQuickWebEngineSettings::readingFromCanvasEnabled() const +{ + return d_ptr->testAttribute(QWebEngineSettings::ReadingFromCanvasEnabled); +} + +/*! + \qmlproperty bool WebEngineSettings::forceDarkMode + \since QtWebEngine 6.7 + + Automatically render all web contents using a dark theme. + + Disabled by default. + */ +bool QQuickWebEngineSettings::forceDarkMode() const +{ + return d_ptr->testAttribute(QWebEngineSettings::ForceDarkMode); +} + +/*! + \qmlproperty bool WebEngineSettings::scrollAnimatorEnabled + \since QtWebEngine 6.8 + + Enables animated scrolling. + + Disabled by default. + */ +bool QQuickWebEngineSettings::scrollAnimatorEnabled() const +{ + return d_ptr->testAttribute(QWebEngineSettings::ScrollAnimatorEnabled); +} + +/*! \qmlproperty string WebEngineSettings::defaultTextEncoding \since QtWebEngine 1.2 @@ -446,6 +496,33 @@ QString QQuickWebEngineSettings::defaultTextEncoding() const return d_ptr->defaultTextEncoding(); } +ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AllowImageAnimation, + QWebEngineSettings::AllowImageAnimation) +ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AnimateImageOnce, QWebEngineSettings::AnimateImageOnce) +ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::DisallowImageAnimation, + QWebEngineSettings::DisallowImageAnimation) +/*! + \qmlproperty enumeration WebEngineSettings::imageAnimationPolicy + \since QtWebEngine 6.8 + + Specifies how an image animation should be handled when the image frames + are rendered for animation. + + \value WebEngineSettings.AllowImageAnimation + Allows all image animations when the image frames are rendered. + \value WebEngineSettings.AnimateImageOnce + Animate the image once when the image frames are rendered. + \value WebEngineSettings.DisallowImageAnimation + Disallows all image animations when the image frames are rendered. + + Default value is \c {WebEngineSettings.AllowImageAnimation}. +*/ +QQuickWebEngineSettings::ImageAnimationPolicy QQuickWebEngineSettings::imageAnimationPolicy() const +{ + return static_cast<QQuickWebEngineSettings::ImageAnimationPolicy>( + d_ptr->imageAnimationPolicy()); +} + ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::DisallowUnknownUrlSchemes, QWebEngineSettings::DisallowUnknownUrlSchemes) ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction, QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction) ASSERT_ENUMS_MATCH(QQuickWebEngineSettings::AllowAllUnknownUrlSchemes, QWebEngineSettings::AllowAllUnknownUrlSchemes) @@ -715,6 +792,30 @@ void QQuickWebEngineSettings::setNavigateOnDropEnabled(bool on) Q_EMIT navigateOnDropEnabledChanged(); } +void QQuickWebEngineSettings::setReadingFromCanvasEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(QWebEngineSettings::ReadingFromCanvasEnabled); + d_ptr->setAttribute(QWebEngineSettings::ReadingFromCanvasEnabled, on); + if (wasOn != on) + Q_EMIT readingFromCanvasEnabledChanged(); +} + +void QQuickWebEngineSettings::setForceDarkMode(bool on) +{ + bool wasOn = d_ptr->testAttribute(QWebEngineSettings::ForceDarkMode); + d_ptr->setAttribute(QWebEngineSettings::ForceDarkMode, on); + if (wasOn != on) + Q_EMIT forceDarkModeChanged(); +} + +void QQuickWebEngineSettings::setScrollAnimatorEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(QWebEngineSettings::ScrollAnimatorEnabled); + d_ptr->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, on); + if (wasOn != on) + Q_EMIT scrollAnimatorEnabledChanged(); +} + void QQuickWebEngineSettings::setUnknownUrlSchemePolicy(QQuickWebEngineSettings::UnknownUrlSchemePolicy policy) { QWebEngineSettings::UnknownUrlSchemePolicy oldPolicy = d_ptr->unknownUrlSchemePolicy(); @@ -737,6 +838,17 @@ void QQuickWebEngineSettings::setParentSettings(QQuickWebEngineSettings *parentS d_ptr->setParentSettings(parentSettings->d_ptr.data()); } +void QQuickWebEngineSettings::setImageAnimationPolicy( + QQuickWebEngineSettings::ImageAnimationPolicy policy) +{ + QWebEngineSettings::ImageAnimationPolicy oldPolicy = d_ptr->imageAnimationPolicy(); + QWebEngineSettings::ImageAnimationPolicy newPolicy = + static_cast<QWebEngineSettings::ImageAnimationPolicy>(policy); + d_ptr->setImageAnimationPolicy(newPolicy); + if (oldPolicy != newPolicy) + Q_EMIT imageAnimationPolicyChanged(); +} + QT_END_NAMESPACE #include "moc_qquickwebenginesettings_p.cpp" diff --git a/src/webenginequick/api/qquickwebenginesettings_p.h b/src/webenginequick/api/qquickwebenginesettings_p.h index 71081c232..ed3c77884 100644 --- a/src/webenginequick/api/qquickwebenginesettings_p.h +++ b/src/webenginequick/api/qquickwebenginesettings_p.h @@ -23,7 +23,7 @@ QT_BEGIN_NAMESPACE class QWebEngineSettings; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineSettings : public QObject { Q_OBJECT Q_PROPERTY(bool autoLoadImages READ autoLoadImages WRITE setAutoLoadImages NOTIFY autoLoadImagesChanged FINAL) Q_PROPERTY(bool javascriptEnabled READ javascriptEnabled WRITE setJavascriptEnabled NOTIFY javascriptEnabledChanged FINAL) @@ -57,6 +57,10 @@ class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject { Q_PROPERTY(bool dnsPrefetchEnabled READ dnsPrefetchEnabled WRITE setDnsPrefetchEnabled NOTIFY dnsPrefetchEnabledChanged REVISION(1,7) FINAL) Q_PROPERTY(bool pdfViewerEnabled READ pdfViewerEnabled WRITE setPdfViewerEnabled NOTIFY pdfViewerEnabledChanged REVISION(1,8) FINAL) Q_PROPERTY(bool navigateOnDropEnabled READ navigateOnDropEnabled WRITE setNavigateOnDropEnabled NOTIFY navigateOnDropEnabledChanged REVISION(6,4) FINAL) + Q_PROPERTY(bool readingFromCanvasEnabled READ readingFromCanvasEnabled WRITE setReadingFromCanvasEnabled NOTIFY readingFromCanvasEnabledChanged REVISION(6,6) FINAL) + Q_PROPERTY(bool forceDarkMode READ forceDarkMode WRITE setForceDarkMode NOTIFY forceDarkModeChanged REVISION(6,7) FINAL) + Q_PROPERTY(bool scrollAnimatorEnabled READ scrollAnimatorEnabled WRITE setScrollAnimatorEnabled NOTIFY scrollAnimatorEnabledChanged REVISION(6,8) FINAL) + Q_PROPERTY(ImageAnimationPolicy imageAnimationPolicy READ imageAnimationPolicy WRITE setImageAnimationPolicy NOTIFY imageAnimationPolicyChanged REVISION(6,8) FINAL) QML_NAMED_ELEMENT(WebEngineSettings) QML_ADDED_IN_VERSION(1, 1) QML_EXTRA_VERSION(2, 0) @@ -70,6 +74,14 @@ public: Q_ENUM(UnknownUrlSchemePolicy) + enum ImageAnimationPolicy { + AllowImageAnimation = 1, + AnimateImageOnce, + DisallowImageAnimation + }; + + Q_ENUM(ImageAnimationPolicy) + ~QQuickWebEngineSettings(); bool autoLoadImages() const; @@ -104,6 +116,10 @@ public: bool dnsPrefetchEnabled() const; bool pdfViewerEnabled() const; bool navigateOnDropEnabled() const; + bool readingFromCanvasEnabled() const; + bool forceDarkMode() const; + bool scrollAnimatorEnabled() const; + ImageAnimationPolicy imageAnimationPolicy() const; void setAutoLoadImages(bool on); void setJavascriptEnabled(bool on); @@ -137,6 +153,10 @@ public: void setDnsPrefetchEnabled(bool on); void setPdfViewerEnabled(bool on); void setNavigateOnDropEnabled(bool on); + void setReadingFromCanvasEnabled(bool on); + void setForceDarkMode(bool on); + void setScrollAnimatorEnabled(bool on); + void setImageAnimationPolicy(ImageAnimationPolicy policy); signals: void autoLoadImagesChanged(); @@ -171,6 +191,10 @@ signals: Q_REVISION(1,7) void dnsPrefetchEnabledChanged(); Q_REVISION(1,8) void pdfViewerEnabledChanged(); Q_REVISION(6,4) void navigateOnDropEnabledChanged(); + Q_REVISION(6,6) void readingFromCanvasEnabledChanged(); + Q_REVISION(6,7) void forceDarkModeChanged(); + Q_REVISION(6,8) void scrollAnimatorEnabledChanged(); + Q_REVISION(6,8) void imageAnimationPolicyChanged(); private: explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = nullptr); diff --git a/src/webenginequick/api/qquickwebenginesingleton.cpp b/src/webenginequick/api/qquickwebenginesingleton.cpp index 0344f2fab..a51d2aca4 100644 --- a/src/webenginequick/api/qquickwebenginesingleton.cpp +++ b/src/webenginequick/api/qquickwebenginesingleton.cpp @@ -81,6 +81,7 @@ QWebEngineScript QQuickWebEngineSingleton::script() const return QWebEngineScript(); } +QT_END_NAMESPACE + #include "moc_qquickwebenginesingleton_p.cpp" -QT_END_NAMESPACE diff --git a/src/webenginequick/api/qquickwebenginesingleton_p.h b/src/webenginequick/api/qquickwebenginesingleton_p.h index 6ac8aef8c..b05daecd6 100644 --- a/src/webenginequick/api/qquickwebenginesingleton_p.h +++ b/src/webenginequick/api/qquickwebenginesingleton_p.h @@ -25,7 +25,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineSettings; class QQuickWebEngineProfile; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineSingleton : public QObject { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineSingleton : public QObject { Q_OBJECT Q_PROPERTY(QQuickWebEngineSettings* settings READ settings CONSTANT FINAL) Q_PROPERTY(QQuickWebEngineProfile* defaultProfile READ defaultProfile CONSTANT FINAL REVISION(1,1)) diff --git a/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h b/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h index 762bc6fcf..92a13b08e 100644 --- a/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h +++ b/src/webenginequick/api/qquickwebenginetouchhandleprovider_p_p.h @@ -20,7 +20,7 @@ QT_BEGIN_NAMESPACE -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineTouchHandleProvider : public QQuickImageProvider { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineTouchHandleProvider : public QQuickImageProvider { public: static QString identifier(); static QUrl url(int orientation); diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp index b566b038e..89cdd20ca 100644 --- a/src/webenginequick/api/qquickwebengineview.cpp +++ b/src/webenginequick/api/qquickwebengineview.cpp @@ -24,26 +24,29 @@ #include "file_picker_controller.h" #include "find_text_helper.h" #include "javascript_dialog_controller.h" -#include "qquickwebengine_accessible.h" #include "render_widget_host_view_qt_delegate_item.h" -#include "render_widget_host_view_qt_delegate_quickwindow.h" +#include "render_widget_host_view_qt_delegate_quickwindow_p.h" #include "touch_selection_menu_controller.h" -#include "ui_delegates_manager.h" +#include "ui_delegates_manager_p.h" #include "web_contents_adapter.h" #include <QtWebEngineCore/qwebenginecertificateerror.h> +#include <QtWebEngineCore/qwebenginedesktopmediarequest.h> #include <QtWebEngineCore/qwebenginefilesystemaccessrequest.h> #include <QtWebEngineCore/qwebenginefindtextresult.h> #include <QtWebEngineCore/qwebenginefullscreenrequest.h> #include <QtWebEngineCore/qwebengineloadinginfo.h> #include <QtWebEngineCore/qwebenginenavigationrequest.h> -#include <QtWebEngineCore/qwebenginequotarequest.h> +#include <QtWebEngineCore/qwebenginepage.h> #include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h> #include <QtWebEngineCore/qwebenginescriptcollection.h> +#include <QtWebEngineCore/qwebenginewebauthuxrequest.h> #include <QtWebEngineCore/private/qwebenginecontextmenurequest_p.h> +#include <QtWebEngineCore/private/qwebenginedesktopmediarequest_p.h> #include <QtWebEngineCore/private/qwebenginehistory_p.h> #include <QtWebEngineCore/private/qwebenginenewwindowrequest_p.h> #include <QtWebEngineCore/private/qwebenginescriptcollection_p.h> +#include <QtWebEngineCore/private/qwebenginepage_p.h> #include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h> #include <QtCore/qloggingcategory.h> @@ -59,6 +62,12 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlproperty.h> +#if QT_CONFIG(accessibility) +#include "qquickwebengine_accessible_p.h" + +#include <QtGui/qaccessible.h> +#endif + #if QT_CONFIG(webengine_printing_and_pdf) #include <QtCore/qmargins.h> #include <QtGui/qpagelayout.h> @@ -67,12 +76,15 @@ #endif #if QT_CONFIG(webengine_webchannel) -#include <QtWebChannel/qqmlwebchannel.h> +#include <QtWebChannelQuick/qqmlwebchannel.h> #endif QT_BEGIN_NAMESPACE using namespace QtWebEngineCore; +Q_STATIC_ASSERT(int(QQuickWebEngineView::WebActionCount) == int(QWebEnginePage::WebActionCount)); +using LoadStatus = QWebEngineLoadingInfo::LoadStatus; +using ErrorDomain = QWebEngineLoadingInfo::ErrorDomain; #if QT_DEPRECATED_SINCE(6, 2) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::AcceptRequest) == static_cast<int>(QWebEngineNavigationRequest::AcceptRequest)); @@ -88,9 +100,6 @@ Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInWindow) Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInTab) == static_cast<int>(QWebEngineNewWindowRequest::InNewTab)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInDialog) == static_cast<int>(QWebEngineNewWindowRequest::InNewDialog)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NewViewInBackgroundTab) == static_cast<int>(QWebEngineNewWindowRequest::InNewBackgroundTab)); - -using LoadStatus = QWebEngineLoadingInfo::LoadStatus; -using ErrorDomain = QWebEngineLoadingInfo::ErrorDomain; Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::NoErrorDomain) == static_cast<int>(ErrorDomain::NoErrorDomain)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::InternalErrorDomain) == static_cast<int>(ErrorDomain::InternalErrorDomain)); Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::ConnectionErrorDomain) == static_cast<int>(ErrorDomain::ConnectionErrorDomain)); @@ -105,6 +114,134 @@ Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::LoadSucceededStatus) == st QT_WARNING_POP #endif +#if QT_CONFIG(webengine_printing_and_pdf) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Letter, QQuickWebEngineView::PrintedPageSizeId::Letter) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Legal, QQuickWebEngineView::PrintedPageSizeId::Legal) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Executive, QQuickWebEngineView::PrintedPageSizeId::Executive) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A0, QQuickWebEngineView::PrintedPageSizeId::A0) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A1, QQuickWebEngineView::PrintedPageSizeId::A1) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A2, QQuickWebEngineView::PrintedPageSizeId::A2) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A3, QQuickWebEngineView::PrintedPageSizeId::A3) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4, QQuickWebEngineView::PrintedPageSizeId::A4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A5, QQuickWebEngineView::PrintedPageSizeId::A5) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A6, QQuickWebEngineView::PrintedPageSizeId::A6) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A7, QQuickWebEngineView::PrintedPageSizeId::A7) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A8, QQuickWebEngineView::PrintedPageSizeId::A8) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A9, QQuickWebEngineView::PrintedPageSizeId::A9) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A10, QQuickWebEngineView::PrintedPageSizeId::A10) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B0, QQuickWebEngineView::PrintedPageSizeId::B0) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B1, QQuickWebEngineView::PrintedPageSizeId::B1) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B2, QQuickWebEngineView::PrintedPageSizeId::B2) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B3, QQuickWebEngineView::PrintedPageSizeId::B3) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B4, QQuickWebEngineView::PrintedPageSizeId::B4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B5, QQuickWebEngineView::PrintedPageSizeId::B5) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B6, QQuickWebEngineView::PrintedPageSizeId::B6) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B7, QQuickWebEngineView::PrintedPageSizeId::B7) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B8, QQuickWebEngineView::PrintedPageSizeId::B8) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B9, QQuickWebEngineView::PrintedPageSizeId::B9) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B10, QQuickWebEngineView::PrintedPageSizeId::B10) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::C5E, QQuickWebEngineView::PrintedPageSizeId::C5E) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Comm10E, QQuickWebEngineView::PrintedPageSizeId::Comm10E) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::DLE, QQuickWebEngineView::PrintedPageSizeId::DLE) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Folio, QQuickWebEngineView::PrintedPageSizeId::Folio) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Ledger, QQuickWebEngineView::PrintedPageSizeId::Ledger) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Tabloid, QQuickWebEngineView::PrintedPageSizeId::Tabloid) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Custom, QQuickWebEngineView::PrintedPageSizeId::Custom) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A3Extra, QQuickWebEngineView::PrintedPageSizeId::A3Extra) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Extra, QQuickWebEngineView::PrintedPageSizeId::A4Extra) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Plus, QQuickWebEngineView::PrintedPageSizeId::A4Plus) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A4Small, QQuickWebEngineView::PrintedPageSizeId::A4Small) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::A5Extra, QQuickWebEngineView::PrintedPageSizeId::A5Extra) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::B5Extra, QQuickWebEngineView::PrintedPageSizeId::B5Extra) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB0, QQuickWebEngineView::PrintedPageSizeId::JisB0) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB1, QQuickWebEngineView::PrintedPageSizeId::JisB1) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB2, QQuickWebEngineView::PrintedPageSizeId::JisB2) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB3, QQuickWebEngineView::PrintedPageSizeId::JisB3) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB4, QQuickWebEngineView::PrintedPageSizeId::JisB4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB5, QQuickWebEngineView::PrintedPageSizeId::JisB5) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB6, QQuickWebEngineView::PrintedPageSizeId::JisB6) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB7, QQuickWebEngineView::PrintedPageSizeId::JisB7) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB8, QQuickWebEngineView::PrintedPageSizeId::JisB8) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB9, QQuickWebEngineView::PrintedPageSizeId::JisB9) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::JisB10, QQuickWebEngineView::PrintedPageSizeId::JisB10) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiC, QQuickWebEngineView::PrintedPageSizeId::AnsiC) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiD, QQuickWebEngineView::PrintedPageSizeId::AnsiD) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiE, QQuickWebEngineView::PrintedPageSizeId::AnsiE) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LegalExtra, QQuickWebEngineView::PrintedPageSizeId::LegalExtra) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterExtra, QQuickWebEngineView::PrintedPageSizeId::LetterExtra) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterPlus, QQuickWebEngineView::PrintedPageSizeId::LetterPlus) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LetterSmall, QQuickWebEngineView::PrintedPageSizeId::LetterSmall) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::TabloidExtra, QQuickWebEngineView::PrintedPageSizeId::TabloidExtra) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchA, QQuickWebEngineView::PrintedPageSizeId::ArchA) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchB, QQuickWebEngineView::PrintedPageSizeId::ArchB) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchC, QQuickWebEngineView::PrintedPageSizeId::ArchC) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchD, QQuickWebEngineView::PrintedPageSizeId::ArchD) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ArchE, QQuickWebEngineView::PrintedPageSizeId::ArchE) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial7x9, QQuickWebEngineView::PrintedPageSizeId::Imperial7x9) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial8x10, QQuickWebEngineView::PrintedPageSizeId::Imperial8x10) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial9x11, QQuickWebEngineView::PrintedPageSizeId::Imperial9x11) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial9x12, QQuickWebEngineView::PrintedPageSizeId::Imperial9x12) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x11, QQuickWebEngineView::PrintedPageSizeId::Imperial10x11) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x13, QQuickWebEngineView::PrintedPageSizeId::Imperial10x13) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial10x14, QQuickWebEngineView::PrintedPageSizeId::Imperial10x14) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial12x11, QQuickWebEngineView::PrintedPageSizeId::Imperial12x11) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Imperial15x11, QQuickWebEngineView::PrintedPageSizeId::Imperial15x11) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::ExecutiveStandard, QQuickWebEngineView::PrintedPageSizeId::ExecutiveStandard) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Note, QQuickWebEngineView::PrintedPageSizeId::Note) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Quarto, QQuickWebEngineView::PrintedPageSizeId::Quarto) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Statement, QQuickWebEngineView::PrintedPageSizeId::Statement) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::SuperA, QQuickWebEngineView::PrintedPageSizeId::SuperA) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::SuperB, QQuickWebEngineView::PrintedPageSizeId::SuperB) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Postcard, QQuickWebEngineView::PrintedPageSizeId::Postcard) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::DoublePostcard, QQuickWebEngineView::PrintedPageSizeId::DoublePostcard) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc16K, QQuickWebEngineView::PrintedPageSizeId::Prc16K) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc32K, QQuickWebEngineView::PrintedPageSizeId::Prc32K) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Prc32KBig, QQuickWebEngineView::PrintedPageSizeId::Prc32KBig) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldUS, QQuickWebEngineView::PrintedPageSizeId::FanFoldUS) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldGerman, QQuickWebEngineView::PrintedPageSizeId::FanFoldGerman) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::FanFoldGermanLegal, QQuickWebEngineView::PrintedPageSizeId::FanFoldGermanLegal) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB5, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB5) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeB6, QQuickWebEngineView::PrintedPageSizeId::EnvelopeB6) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC0, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC0) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC1, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC1) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC2, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC2) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC3) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC6, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC6) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC65, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC65) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC7, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC7) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope9, QQuickWebEngineView::PrintedPageSizeId::Envelope9) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope11, QQuickWebEngineView::PrintedPageSizeId::Envelope11) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope12, QQuickWebEngineView::PrintedPageSizeId::Envelope12) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope14, QQuickWebEngineView::PrintedPageSizeId::Envelope14) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeMonarch, QQuickWebEngineView::PrintedPageSizeId::EnvelopeMonarch) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePersonal, QQuickWebEngineView::PrintedPageSizeId::EnvelopePersonal) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeChou3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeChou3) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeChou4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeChou4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeInvite, QQuickWebEngineView::PrintedPageSizeId::EnvelopeInvite) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeItalian, QQuickWebEngineView::PrintedPageSizeId::EnvelopeItalian) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeKaku2, QQuickWebEngineView::PrintedPageSizeId::EnvelopeKaku2) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeKaku3, QQuickWebEngineView::PrintedPageSizeId::EnvelopeKaku3) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc1, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc1) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc2, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc2) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc3, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc3) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc4, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc5, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc5) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc6, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc6) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc7, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc7) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc8, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc8) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc9, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc9) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopePrc10, QQuickWebEngineView::PrintedPageSizeId::EnvelopePrc10) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeYou4, QQuickWebEngineView::PrintedPageSizeId::EnvelopeYou4) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::LastPageSize, QQuickWebEngineView::PrintedPageSizeId::LastPageSize) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiA, QQuickWebEngineView::PrintedPageSizeId::AnsiA) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::AnsiB, QQuickWebEngineView::PrintedPageSizeId::AnsiB) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeC5, QQuickWebEngineView::PrintedPageSizeId::EnvelopeC5) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::EnvelopeDL, QQuickWebEngineView::PrintedPageSizeId::EnvelopeDL) +ASSERT_ENUMS_MATCH(QPageSize::PageSizeId::Envelope10, QQuickWebEngineView::PrintedPageSizeId::Envelope10) +#endif + class WebEngineQuickWidgetDelegate : public QtWebEngineCore::WidgetDelegate { public: @@ -174,7 +311,6 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_fullscreenMode(false) , isLoading(false) , m_activeFocusOnPress(true) - , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio()) , m_webChannel(nullptr) , m_webChannelWorld(0) , m_defaultAudioMuted(false) @@ -310,10 +446,10 @@ void QQuickWebEngineViewPrivate::contextMenuRequested(QWebEngineContextMenuReque ui()->showMenu(menu); } -void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame) +void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame, bool hasFrameData) { Q_Q(QQuickWebEngineView); - auto request = new QWebEngineNavigationRequest(url, static_cast<QWebEngineNavigationRequest::NavigationType>(navigationType), isMainFrame); + auto request = new QWebEngineNavigationRequest(url, static_cast<QWebEngineNavigationRequest::NavigationType>(navigationType), isMainFrame, hasFrameData); qmlEngine(q)->newQObject(request); Q_EMIT q->navigationRequested(request); @@ -356,6 +492,10 @@ static QQuickWebEngineView::Feature toFeature(QtWebEngineCore::ProfileAdapter::P return QQuickWebEngineView::Notifications; case QtWebEngineCore::ProfileAdapter::GeolocationPermission: return QQuickWebEngineView::Geolocation; + case QtWebEngineCore::ProfileAdapter::ClipboardReadWrite: + return QQuickWebEngineView::ClipboardReadWrite; + case QtWebEngineCore::ProfileAdapter::LocalFontsPermission: + return QQuickWebEngineView::LocalFontsAccess; default: break; } @@ -574,6 +714,15 @@ void QQuickWebEngineViewPrivate::windowCloseRejected() QMetaObject::invokeMethod(q, "windowCloseRejected"); } +void QQuickWebEngineViewPrivate::desktopMediaRequested( + QtWebEngineCore::DesktopMediaController *controller) +{ + Q_Q(QQuickWebEngineView); + QTimer::singleShot(0, q, [q, controller]() { + Q_EMIT q->desktopMediaRequested(QWebEngineDesktopMediaRequest(controller)); + }); +} + void QQuickWebEngineViewPrivate::requestFullScreenMode(const QUrl &origin, bool fullscreen) { Q_Q(QQuickWebEngineView); @@ -589,7 +738,7 @@ bool QQuickWebEngineViewPrivate::isFullScreenMode() const void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) { Q_Q(QQuickWebEngineView); - if (q->receivers(SIGNAL(javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) { + if (q->receivers(SIGNAL(javaScriptConsoleMessage(QQuickWebEngineView::JavaScriptConsoleMessageLevel,QString,int,QString))) > 0) { Q_EMIT q->javaScriptConsoleMessage(static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID); return; } @@ -651,12 +800,6 @@ void QQuickWebEngineViewPrivate::runMouseLockPermissionRequest(const QUrl &secur adapter->grantMouseLockPermission(securityOrigin, false); } -void QQuickWebEngineViewPrivate::runQuotaRequest(QWebEngineQuotaRequest request) -{ - Q_Q(QQuickWebEngineView); - Q_EMIT q->quotaRequested(request); -} - void QQuickWebEngineViewPrivate::runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest request) { Q_Q(QQuickWebEngineView); @@ -792,6 +935,8 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent) QQuickWebEngineView::~QQuickWebEngineView() { + if (hasFocus()) + setFocus(false); } void QQuickWebEngineViewPrivate::ensureContentsAdapter() @@ -882,11 +1027,17 @@ void QQuickWebEngineViewPrivate::bindViewAndDelegateItem(QQuickWebEngineViewPriv // Change pointers first. - if (oldViewPrivate && oldViewPrivate != viewPrivate) - oldViewPrivate->delegateItem = nullptr; + if (delegateItem && oldViewPrivate != viewPrivate) { + if (oldViewPrivate) + oldViewPrivate->delegateItem = nullptr; + delegateItem->m_adapterClient = viewPrivate; + } - if (viewPrivate && oldDelegateItem != delegateItem) + if (viewPrivate && oldDelegateItem != delegateItem) { + if (oldDelegateItem) + oldDelegateItem->m_adapterClient = nullptr; viewPrivate->delegateItem = delegateItem; + } // Then notify. @@ -1302,6 +1453,12 @@ void QQuickWebEngineViewPrivate::hideTouchSelectionMenu() ui()->hideTouchSelectionMenu(); } +void QQuickWebEngineViewPrivate::showWebAuthDialog(QWebEngineWebAuthUxRequest *request) +{ + Q_Q(QQuickWebEngineView); + Q_EMIT q->webAuthUxRequested(request); +} + bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); @@ -1343,7 +1500,11 @@ void QQuickWebEngineView::runJavaScript(const QString &script, quint32 worldId, d->ensureContentsAdapter(); if (!callback.isUndefined()) { quint64 requestId = d_ptr->adapter->runJavaScriptCallbackResult(script, worldId); - d->m_callbacks.insert(requestId, callback); + if (requestId) { + d->m_callbacks.insert(requestId, callback); + } else { + callback.call(); + } } else d->adapter->runJavaScript(script, worldId); } @@ -1560,6 +1721,12 @@ QQuickWebEngineView *QQuickWebEngineView::devToolsView() const return d->devToolsView; } +QString QQuickWebEngineView::devToolsId() +{ + Q_D(QQuickWebEngineView); + d->ensureContentsAdapter(); + return d->adapter->devToolsId(); +} void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView) { @@ -1618,6 +1785,15 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::NotificationPermission, granted ? ProfileAdapter::AllowedPermission : ProfileAdapter::DeniedPermission); break; + case ClipboardReadWrite: + d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::ClipboardReadWrite, + granted ? ProfileAdapter::AllowedPermission + : ProfileAdapter::DeniedPermission); + break; + case LocalFontsAccess: + d_ptr->adapter->grantFeaturePermission(securityOrigin, ProfileAdapter::LocalFontsPermission, + granted ? ProfileAdapter::AllowedPermission : ProfileAdapter::DeniedPermission); + break; default: Q_UNREACHABLE(); } @@ -1966,8 +2142,15 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) case InsertUnorderedList: runJavaScript(QStringLiteral("document.execCommand('insertUnorderedList');"), QWebEngineScript::ApplicationWorld); break; + case ChangeTextDirectionLTR: + d->adapter->changeTextDirection(true /*left to right*/); + break; + case ChangeTextDirectionRTL: + d->adapter->changeTextDirection(false /*left to right*/); + break; default: - Q_UNREACHABLE(); + // Reachable when a spell checker replacement word has been selected + break; } } @@ -1981,165 +2164,113 @@ QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) return d->actions[action]; } - QString text; + const QString text = QWebEnginePagePrivate::actionText(action); QString iconName; switch (action) { case Back: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back); iconName = QStringLiteral("go-previous"); break; case Forward: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward); iconName = QStringLiteral("go-next"); break; case Stop: - text = tr("Stop"); iconName = QStringLiteral("process-stop"); break; case Reload: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload); iconName = QStringLiteral("view-refresh"); break; case ReloadAndBypassCache: - text = tr("Reload and Bypass Cache"); iconName = QStringLiteral("view-refresh"); break; case Cut: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut); iconName = QStringLiteral("edit-cut"); break; case Copy: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy); iconName = QStringLiteral("edit-copy"); break; case Paste: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste); iconName = QStringLiteral("edit-paste"); break; case Undo: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo); iconName = QStringLiteral("edit-undo"); break; case Redo: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo); iconName = QStringLiteral("edit-redo"); break; case SelectAll: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll); iconName = QStringLiteral("edit-select-all"); break; case PasteAndMatchStyle: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle); iconName = QStringLiteral("edit-paste"); break; case OpenLinkInThisWindow: - text = tr("Open link in this window"); - break; case OpenLinkInNewWindow: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewWindow); - break; case OpenLinkInNewTab: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewTab); - break; case CopyLinkToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyLinkToClipboard); - break; case DownloadLinkToDisk: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadLinkToDisk); - break; case CopyImageToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageToClipboard); - break; case CopyImageUrlToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageUrlToClipboard); - break; case DownloadImageToDisk: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadImageToDisk); - break; case CopyMediaUrlToClipboard: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyMediaUrlToClipboard); - break; case ToggleMediaControls: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaControls); - break; case ToggleMediaLoop: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaLoop); break; case ToggleMediaPlayPause: - text = tr("Toggle Play/Pause"); iconName = QStringLiteral("media-playback-start"); break; case ToggleMediaMute: - text = tr("Toggle Mute"); iconName = QStringLiteral("audio-volume-muted"); break; case DownloadMediaToDisk: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk); - break; case InspectElement: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::InspectElement); break; case ExitFullScreen: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen); iconName = QStringLiteral("view-fullscreen"); break; case RequestClose: - text = tr("Close Page"); iconName = QStringLiteral("window-close"); break; case Unselect: - text = tr("Unselect"); iconName = QStringLiteral("edit-select-none"); break; case SavePage: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage); iconName = QStringLiteral("document-save"); break; + case OpenLinkInNewBackgroundTab: + break; case ViewSource: - text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource); break; case ToggleBold: - text = tr("&Bold"); iconName = QStringLiteral("format-text-bold"); break; case ToggleItalic: - text = tr("&Italic"); iconName = QStringLiteral("format-text-italic"); break; case ToggleUnderline: - text = tr("&Underline"); iconName = QStringLiteral("format-text-underline"); break; case ToggleStrikethrough: - text = tr("&Strikethrough"); iconName = QStringLiteral("format-text-strikethrough"); break; case AlignLeft: - text = tr("Align &Left"); break; case AlignCenter: - text = tr("Align &Center"); break; case AlignRight: - text = tr("Align &Right"); break; case AlignJustified: - text = tr("Align &Justified"); break; case Indent: - text = tr("&Indent"); iconName = QStringLiteral("format-indent-more"); break; case Outdent: - text = tr("&Outdent"); iconName = QStringLiteral("format-indent-less"); break; case InsertOrderedList: - text = tr("Insert &Ordered List"); - break; case InsertUnorderedList: - text = tr("Insert &Unordered List"); + case ChangeTextDirectionLTR: + case ChangeTextDirectionRTL: break; case NoWebAction: case WebActionCount: @@ -2318,10 +2449,12 @@ void QQuickContextMenuBuilder::addMenuItem(ContextMenuItem menuItem) case ContextMenuItem::SpellingSuggestions: { QPointer<QQuickWebEngineView> thisRef(m_view); - for (int i = 0; i < m_contextData->spellCheckerSuggestions().count() && i < 4; i++) { + for (int i = 0; i < m_contextData->spellCheckerSuggestions().size() && i < 4; i++) { action = new QQuickWebEngineAction(m_menu); QString replacement = m_contextData->spellCheckerSuggestions().at(i); QObject::connect(action, &QQuickWebEngineAction::triggered, [thisRef, replacement] { thisRef->replaceMisspelledWord(replacement); }); + action->d_ptr->m_text = replacement; + action->d_ptr->m_enabled = true; m_view->d_ptr->ui()->addMenuItem(action, m_menu); } return; @@ -2396,6 +2529,13 @@ QQmlComponent *QQuickWebEngineView::touchHandleDelegate() const return d_ptr->m_touchHandleDelegate; } +void QQuickWebEngineView::save(const QString &filePath, + QWebEngineDownloadRequest::SavePageFormat format) const +{ + Q_D(const QQuickWebEngineView); + d->adapter->save(filePath, format); +} + QT_END_NAMESPACE #include "moc_qquickwebengineview_p.cpp" diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h index 00c6f3018..0fdd9f787 100644 --- a/src/webenginequick/api/qquickwebengineview_p.h +++ b/src/webenginequick/api/qquickwebengineview_p.h @@ -16,6 +16,9 @@ // #include <QtWebEngineCore/qtwebenginecoreglobal.h> +#include <QtWebEngineCore/qwebenginequotarequest.h> +#include <QtWebEngineCore/qwebenginedesktopmediarequest.h> +#include <QtWebEngineCore/qwebenginedownloadrequest.h> #include <QtWebEngineQuick/private/qtwebenginequickglobal_p.h> #include <QtGui/qcolor.h> #include <QtQml/qqmlregistration.h> @@ -46,12 +49,12 @@ class QWebEngineHistory; class QWebEngineLoadingInfo; class QWebEngineNavigationRequest; class QWebEngineNewWindowRequest; -class QWebEngineQuotaRequest; class QWebEngineRegisterProtocolHandlerRequest; class QQuickWebEngineScriptCollection; class QQuickWebEngineTouchSelectionMenuRequest; +class QWebEngineWebAuthUxRequest; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineView : public QQuickItem { Q_OBJECT Q_CLASSINFO("RegisterEnumClassesUnscoped", "false") Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged FINAL) @@ -80,6 +83,7 @@ class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(QQuickWebEngineView *inspectedView READ inspectedView WRITE setInspectedView NOTIFY inspectedViewChanged REVISION(1,7) FINAL) Q_PROPERTY(QQuickWebEngineView *devToolsView READ devToolsView WRITE setDevToolsView NOTIFY devToolsViewChanged REVISION(1,7) FINAL) + Q_PROPERTY(QString devToolsId READ devToolsId CONSTANT REVISION(6,6) FINAL) Q_PROPERTY(LifecycleState lifecycleState READ lifecycleState WRITE setLifecycleState NOTIFY lifecycleStateChanged REVISION(1,10) FINAL) Q_PROPERTY(LifecycleState recommendedState READ recommendedState NOTIFY recommendedStateChanged REVISION(1,10) FINAL) @@ -169,6 +173,8 @@ QT_WARNING_POP DesktopVideoCapture, DesktopAudioVideoCapture, Notifications, + ClipboardReadWrite, + LocalFontsAccess, }; Q_ENUM(Feature) @@ -212,6 +218,7 @@ QT_WARNING_POP RequestClose, Unselect, SavePage, + OpenLinkInNewBackgroundTab, // Not supported in QML ViewSource, ToggleBold, @@ -229,6 +236,9 @@ QT_WARNING_POP InsertOrderedList, InsertUnorderedList, + ChangeTextDirectionLTR, + ChangeTextDirectionRTL, + WebActionCount }; Q_ENUM(WebAction) @@ -260,8 +270,6 @@ QT_WARNING_POP // must match QPageSize::PageSizeId enum PrintedPageSizeId { // Existing Qt sizes - A4, - B5, Letter, Legal, Executive, @@ -269,21 +277,24 @@ QT_WARNING_POP A1, A2, A3, + A4, A5, A6, A7, A8, A9, + A10, B0, B1, - B10, B2, B3, B4, + B5, B6, B7, B8, B9, + B10, C5E, Comm10E, DLE, @@ -293,7 +304,6 @@ QT_WARNING_POP Custom, // New values derived from PPD standard - A10, A3Extra, A4Extra, A4Plus, @@ -396,10 +406,8 @@ QT_WARNING_POP EnvelopePrc10, EnvelopeYou4, - // Last item, with commonly used synynoms from QPagedPrintEngine / QPrinter + // Last item LastPageSize = EnvelopeYou4, - NPageSize = LastPageSize, - NPaperSize = LastPageSize, // Convenience overloads for naming consistency AnsiA = Letter, @@ -454,6 +462,7 @@ QT_WARNING_POP QQuickWebEngineView *inspectedView() const; void setDevToolsView(QQuickWebEngineView *); QQuickWebEngineView *devToolsView() const; + QString devToolsId(); LifecycleState lifecycleState() const; void setLifecycleState(LifecycleState state); @@ -475,12 +484,15 @@ public Q_SLOTS: void stop(); Q_REVISION(1,1) void findText(const QString &subString, FindFlags options = { }, const QJSValue &callback = QJSValue()); Q_REVISION(1,1) void fullScreenCancelled(); - Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, Feature, bool granted); + Q_REVISION(1,1) void grantFeaturePermission(const QUrl &securityOrigin, QQuickWebEngineView::Feature, bool granted); Q_REVISION(1,2) void setActiveFocusOnPress(bool arg); Q_REVISION(1,2) void triggerWebAction(WebAction action); Q_REVISION(1,3) void printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait); Q_REVISION(1,3) void printToPdf(const QJSValue &callback, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait); Q_REVISION(1,4) void replaceMisspelledWord(const QString &replacement); + Q_REVISION(6, 6) void save(const QString &filePath, + QWebEngineDownloadRequest::SavePageFormat format = + QWebEngineDownloadRequest::MimeHtmlSaveFormat) const; private Q_SLOTS: void lazyInitialize(); @@ -493,17 +505,22 @@ Q_SIGNALS: void loadProgressChanged(); void linkHovered(const QUrl &hoveredUrl); void navigationRequested(QWebEngineNavigationRequest *request); - void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID); + void javaScriptConsoleMessage(QQuickWebEngineView::JavaScriptConsoleMessageLevel level, + const QString &message, int lineNumber, const QString &sourceID); Q_REVISION(1,1) void certificateError(const QWebEngineCertificateError &error); Q_REVISION(1,1) void fullScreenRequested(const QWebEngineFullScreenRequest &request); Q_REVISION(1,1) void isFullScreenChanged(); - Q_REVISION(1,1) void featurePermissionRequested(const QUrl &securityOrigin, Feature feature); + Q_REVISION(1, 1) + void featurePermissionRequested(const QUrl &securityOrigin, + QQuickWebEngineView::Feature feature); Q_REVISION(1,1) void zoomFactorChanged(qreal arg); Q_REVISION(1,1) void profileChanged(); Q_REVISION(1,1) void webChannelChanged(); Q_REVISION(1,2) void activeFocusOnPressChanged(bool); Q_REVISION(1,2) void backgroundColorChanged(); - Q_REVISION(1,2) void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode); + Q_REVISION(1, 2) + void renderProcessTerminated(QQuickWebEngineView::RenderProcessTerminationStatus terminationStatus, + int exitCode); Q_REVISION(1,2) void windowCloseRequested(); Q_REVISION(1,3) void contentsSizeChanged(const QSizeF& size); Q_REVISION(1,3) void scrollPositionChanged(const QPointF& position); @@ -516,7 +533,10 @@ Q_SIGNALS: Q_REVISION(1,4) void colorDialogRequested(QQuickWebEngineColorDialogRequest *request); Q_REVISION(1,4) void fileDialogRequested(QQuickWebEngineFileDialogRequest *request); Q_REVISION(1,5) void pdfPrintingFinished(const QString &filePath, bool success); - Q_REVISION(1,7) void quotaRequested(const QWebEngineQuotaRequest &request); +#if QT_DEPRECATED_SINCE(6, 5) + QT_DEPRECATED_VERSION_X_6_5("Requesting host quota is no longer supported.") + Q_REVISION(1, 7) void quotaRequested(const QWebEngineQuotaRequest &request); +#endif Q_REVISION(1,7) void geometryChangeRequested(const QRect &geometry, const QRect &frameGeometry); Q_REVISION(1,7) void inspectedViewChanged(); Q_REVISION(1,7) void devToolsViewChanged(); @@ -524,8 +544,8 @@ Q_SIGNALS: Q_REVISION(1,8) void printRequested(); Q_REVISION(1,9) void selectClientCertificate(QQuickWebEngineClientCertificateSelection *clientCertSelection); Q_REVISION(1,10) void tooltipRequested(QQuickWebEngineTooltipRequest *request); - Q_REVISION(1,10) void lifecycleStateChanged(LifecycleState state); - Q_REVISION(1,10) void recommendedStateChanged(LifecycleState state); + Q_REVISION(1, 10) void lifecycleStateChanged(QQuickWebEngineView::LifecycleState state); + Q_REVISION(1, 10) void recommendedStateChanged(QQuickWebEngineView::LifecycleState state); Q_REVISION(1,10) void findTextFinished(const QWebEngineFindTextResult &result); Q_REVISION(1,11) void renderProcessPidChanged(qint64 pid); Q_REVISION(1,11) void canGoBackChanged(); @@ -534,6 +554,8 @@ Q_SIGNALS: Q_REVISION(6,3) void touchSelectionMenuRequested(QQuickWebEngineTouchSelectionMenuRequest *request); Q_REVISION(6,4) void touchHandleDelegateChanged(); Q_REVISION(6,4) void fileSystemAccessRequested(const QWebEngineFileSystemAccessRequest &request); + Q_REVISION(6, 7) void webAuthUxRequested(QWebEngineWebAuthUxRequest *request); + Q_REVISION(6,7) void desktopMediaRequested(const QWebEngineDesktopMediaRequest &request); protected: void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h index 2d28a89af..58236bc58 100644 --- a/src/webenginequick/api/qquickwebengineview_p_p.h +++ b/src/webenginequick/api/qquickwebengineview_p_p.h @@ -19,7 +19,7 @@ #include "qquickwebengineview_p.h" #include "render_view_context_menu_qt.h" #include "touch_handle_drawable_client.h" -#include "ui_delegates_manager.h" +#include "ui_delegates_manager_p.h" #include "web_contents_adapter_client.h" #include <QtCore/qcompilerdetection.h> @@ -27,7 +27,6 @@ #include <QtCore/qscopedpointer.h> #include <QtCore/qsharedpointer.h> #include <QtCore/qstring.h> -#include <QtGui/qaccessibleobject.h> namespace QtWebEngineCore { class RenderWidgetHostViewQtDelegateItem; @@ -46,7 +45,7 @@ class QWebEngineContextMenuRequest; class QWebEngineFindTextResult; class QWebEngineHistory; -class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCore::WebContentsAdapterClient +class Q_WEBENGINEQUICK_EXPORT QQuickWebEngineViewPrivate : public QtWebEngineCore::WebContentsAdapterClient { public: Q_DECLARE_PUBLIC(QQuickWebEngineView) @@ -89,9 +88,10 @@ public: void requestFullScreenMode(const QUrl &origin, bool fullscreen) override; bool isFullScreenMode() const override; void contextMenuRequested(QWebEngineContextMenuRequest *request) override; - void navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame) override; + void navigationRequested(int navigationType, const QUrl &url, bool &accepted, bool isMainFrame, bool hasFrameData) override; void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) override; void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) override; + void desktopMediaRequested(QtWebEngineCore::DesktopMediaController *) override; void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) override; void didRunJavaScript(quint64, const QVariant&) override; void didFetchDocumentMarkup(quint64, const QString&) override { } @@ -103,7 +103,6 @@ public: void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override; void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override; void runMouseLockPermissionRequest(const QUrl &securityOrigin) override; - void runQuotaRequest(QWebEngineQuotaRequest) override; void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override; void runFileSystemAccessRequest(QWebEngineFileSystemAccessRequest) override; QObject *accessibilityParentObject() override; @@ -134,6 +133,7 @@ public: void showAutofillPopup(QtWebEngineCore::AutofillPopupController *controller, const QRect &bounds, bool autoselectFirstSuggestion) override; void hideAutofillPopup() override; + void showWebAuthDialog(QWebEngineWebAuthUxRequest *request) override; void updateAction(QQuickWebEngineView::WebAction) const; bool adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents); @@ -158,8 +158,6 @@ public: bool m_fullscreenMode; bool isLoading; bool m_activeFocusOnPress; - bool m_navigationActionTriggered; - qreal devicePixelRatio; QMap<quint64, QJSValue> m_callbacks; QQmlWebChannel *m_webChannel; QPointer<QQuickWebEngineView> inspectedView; diff --git a/src/webenginequick/api/qtwebenginequickglobal.cpp b/src/webenginequick/api/qtwebenginequickglobal.cpp index 607777e55..e24ef643b 100644 --- a/src/webenginequick/api/qtwebenginequickglobal.cpp +++ b/src/webenginequick/api/qtwebenginequickglobal.cpp @@ -37,15 +37,22 @@ namespace QtWebEngineQuick { */ void initialize() { + auto api = QQuickWindow::graphicsApi(); if (!QCoreApplication::startingUp()) { - qWarning("QtWebEngineQuick::initialize() called with QCoreApplication object already created and should be call before. "\ - "This is depreciated and may fail in the future."); + if (api == QSGRendererInterface::OpenGL || (api != QSGRendererInterface::Vulkan + && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11)) { + qWarning("QtWebEngineQuick::initialize() called with QCoreApplication object already created and should be call before. "\ + "This is depreciated and may fail in the future."); + } QtWebEngineCore::initialize(); return; } + // call initialize the same way as widgets do qAddPreRoutine(QtWebEngineCore::initialize); - QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi); + if (api != QSGRendererInterface::OpenGL && api != QSGRendererInterface::Vulkan + && api != QSGRendererInterface::Metal && api != QSGRendererInterface::Direct3D11) + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); } } // namespace QtWebEngineQuick diff --git a/src/webenginequick/api/qtwebenginequickglobal_p.h b/src/webenginequick/api/qtwebenginequickglobal_p.h index 395533604..256bcd590 100644 --- a/src/webenginequick/api/qtwebenginequickglobal_p.h +++ b/src/webenginequick/api/qtwebenginequickglobal_p.h @@ -19,10 +19,4 @@ #include <QtCore/private/qglobal_p.h> #include <QtWebEngineQuick/private/qtwebenginequick-config_p.h> -QT_BEGIN_NAMESPACE - -#define Q_WEBENGINEQUICK_PRIVATE_EXPORT Q_WEBENGINEQUICK_EXPORT - -QT_END_NAMESPACE - #endif // QTWEBENGINEQUICKGLOBAL_P_H diff --git a/src/webenginequick/configure.cmake b/src/webenginequick/configure.cmake index 649154301..b256e5a1d 100644 --- a/src/webenginequick/configure.cmake +++ b/src/webenginequick/configure.cmake @@ -1,3 +1,6 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + qt_feature("webenginequick-ui-delegates" PRIVATE SECTION "WebEngine" LABEL "UI Delegates" diff --git a/src/webenginequick/doc/snippets/minimal/main.cpp b/src/webenginequick/doc/snippets/minimal/main.cpp new file mode 100644 index 000000000..e17493a36 --- /dev/null +++ b/src/webenginequick/doc/snippets/minimal/main.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +//! [Minimal Example] +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <QtWebEngineQuick/qtwebenginequickglobal.h> + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + QtWebEngineQuick::initialize(); + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + return app.exec(); +} +//! [Minimal Example] diff --git a/src/webenginequick/doc/snippets/minimal/main.qml b/src/webenginequick/doc/snippets/minimal/main.qml new file mode 100644 index 000000000..87a8757df --- /dev/null +++ b/src/webenginequick/doc/snippets/minimal/main.qml @@ -0,0 +1,18 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +//! [Minimal Example] +import QtQuick +import QtQuick.Window +import QtWebEngine + +Window { + width: 1024 + height: 750 + visible: true + WebEngineView { + anchors.fill: parent + url: "https://www.qt.io" + } +} +//! [Minimal Example] diff --git a/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc b/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc index d1e230db1..f8fbbd669 100644 --- a/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc +++ b/src/webenginequick/doc/snippets/qtwebengine_build_snippet.qdoc @@ -5,12 +5,7 @@ QT += webenginequick //! [0] - -//! [1] -#include <QtWebEngineQuick> -//! [1] - //! [2] find_package(Qt6 REQUIRED COMPONENTS WebEngineQuick) -target_link_libraries(target PRIVATE Qt::WebEngineQuick) +target_link_libraries(target PRIVATE Qt6::WebEngineQuick) //! [2] diff --git a/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml b/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml new file mode 100644 index 000000000..2fd5f490b --- /dev/null +++ b/src/webenginequick/doc/snippets/qtwebengine_webengineaction.qml @@ -0,0 +1,123 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Window +import QtWebEngine +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: window + visible: true + width: 800 + height: 600 + title: qsTr("WebEngineAction Example") + + header: ToolBar { + RowLayout { + anchors.fill: parent +//! [0] + ToolButton { + property int itemAction: WebEngineView.Back + text: webEngineView.action(itemAction).text + enabled: webEngineView.action(itemAction).enabled + onClicked: webEngineView.action(itemAction).trigger() + icon.name: webEngineView.action(itemAction).iconName + display: AbstractButton.TextUnderIcon + } +//! [0] + ToolButton { + property int itemAction: WebEngineView.Forward + text: webEngineView.action(itemAction).text + enabled: webEngineView.action(itemAction).enabled + onClicked: webEngineView.action(itemAction).trigger() + icon.name: webEngineView.action(itemAction).iconName + display: AbstractButton.TextUnderIcon + } + + ToolButton { + property int itemAction: webEngineView.loading ? WebEngineView.Stop : WebEngineView.Reload + text: webEngineView.action(itemAction).text + enabled: webEngineView.action(itemAction).enabled + onClicked: webEngineView.action(itemAction).trigger() + icon.name: webEngineView.action(itemAction).iconName + display: AbstractButton.TextUnderIcon + } + + TextField { + Layout.fillWidth: true + + text: webEngineView.url + selectByMouse: true + onEditingFinished: webEngineView.url = utils.fromUserInput(text) + } + + ToolButton { + id: settingsButton + text: "Settings" + icon.name: "settings-configure" + display: AbstractButton.TextUnderIcon + onClicked: settingsMenu.open() + checked: settingsMenu.visible + + Menu { + id: settingsMenu + y: settingsButton.height + + MenuItem { + id: customContextMenuOption + checkable: true + checked: true + + text: "Custom context menu" + } + } + } + } + } + + WebEngineView { + id: webEngineView + url: "https://qt.io" + anchors.fill: parent + + Component.onCompleted: { + profile.downloadRequested.connect(function(download){ + download.accept(); + }) + } + +//! [1] + property Menu contextMenu: Menu { + Repeater { + model: [ + WebEngineView.Back, + WebEngineView.Forward, + WebEngineView.Reload, + WebEngineView.SavePage, + WebEngineView.Copy, + WebEngineView.Paste, + WebEngineView.Cut, + WebEngineView.ChangeTextDirectionLTR, + WebEngineView.ChangeTextDirectionRTL, + ] + MenuItem { + text: webEngineView.action(modelData).text + enabled: webEngineView.action(modelData).enabled + onClicked: webEngineView.action(modelData).trigger() + icon.name: webEngineView.action(modelData).iconName + display: MenuItem.TextBesideIcon + } + } + } + + onContextMenuRequested: function(request) { + if (customContextMenuOption.checked) { + request.accepted = true; + contextMenu.popup(); + } + } +//! [1] + } +} diff --git a/src/webenginequick/doc/src/qtwebengine-examples.qdoc b/src/webenginequick/doc/src/qtwebengine-examples.qdoc index b3eb548e5..eebf18ba1 100644 --- a/src/webenginequick/doc/src/qtwebengine-examples.qdoc +++ b/src/webenginequick/doc/src/qtwebengine-examples.qdoc @@ -5,7 +5,6 @@ \group webengine-examples \title Qt WebEngine Quick Examples \brief Examples demonstrating the \QWE usage. - \ingroup all-examples These examples and demonstrations show a range of different uses for \l{Qt WebEngine}, from displaying Web pages within a QML user interface to an implementation of diff --git a/src/webenginequick/doc/src/qtwebengine-module.qdoc b/src/webenginequick/doc/src/qtwebengine-module.qdoc index 21d8b4749..6f50cc2f4 100644 --- a/src/webenginequick/doc/src/qtwebengine-module.qdoc +++ b/src/webenginequick/doc/src/qtwebengine-module.qdoc @@ -12,11 +12,6 @@ The \QWE Quick module exposes C++ functionality to Qt Quick. - To include the definitions of the module's classes, use the - following directive: - - \snippet qtwebengine_build_snippet.qdoc 1 - \if !defined(qtforpython) To link against the module, add the following to your qmake project file: diff --git a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc index 7899fad56..ecf3a4a6e 100644 --- a/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc +++ b/src/webenginequick/doc/src/qtwebengine-qmlmodule.qdoc @@ -8,11 +8,6 @@ \ingroup qtwebengine-modules \ingroup qmlmodules - The QML types can be imported into your application using the following import statements in - your .qml file: - - \snippet qtwebengine_build_snippet.qdoc 1 - To link against the module using build with qmake, add the following QT variable to your qmake .pro file: @@ -22,4 +17,13 @@ in the Qt6 package and \c target_link_libraries() to link against the module: \snippet qtwebengine_build_snippet.qdoc 2 + + The minimal amount of code needed to load and display an HTML page using the QML engine + requires a proper initialization: + + \snippet minimal/main.cpp Minimal Example + + Where the content of main.qml is simply: + + \snippet minimal/main.qml Minimal Example */ diff --git a/src/webenginequick/doc/src/quota_request.qdoc b/src/webenginequick/doc/src/quota_request.qdoc index 579d78008..01f4ec286 100644 --- a/src/webenginequick/doc/src/quota_request.qdoc +++ b/src/webenginequick/doc/src/quota_request.qdoc @@ -6,8 +6,12 @@ \instantiates QWebEngineQuotaRequest \inqmlmodule QtWebEngine \since QtWebEngine 1.7 + \deprecated [6.5] Requesting host quota is no longer supported by Chromium. - \brief A utility type for the WebEngineView::quotaRequested() signal. + The behavior of navigator.webkitPersistentStorage + is identical to navigator.webkitTemporaryStorage. + + For further details, see https://crbug.com/1233525 \sa WebEngineView::quotaRequested() */ @@ -15,36 +19,18 @@ /*! \qmlproperty url QuotaRequest::origin \readonly - - The URL of the web page that issued the quota request. */ /*! \qmlproperty qint64 QuotaRequest::requestedSize \readonly - - Contains the size of the requested disk space in bytes. */ /*! \qmlmethod void QuotaRequest::accept() - - Accepts the quota request. - - \qml - WebEngineView { - onQuotaRequested: function(request) { - if (request.requestedSize <= 5 * 1024 * 1024) - request.accept(); - else - request.reject(); - } - } - \endqml */ /*! \qmlmethod void QuotaRequest::reject() - Rejects the quota request. */ diff --git a/src/webenginequick/doc/src/webengine_certificate_error.qdoc b/src/webenginequick/doc/src/webengine_certificate_error.qdoc index aec8e2d42..93bad9fb1 100644 --- a/src/webenginequick/doc/src/webengine_certificate_error.qdoc +++ b/src/webenginequick/doc/src/webengine_certificate_error.qdoc @@ -9,7 +9,7 @@ \brief A utility type for ignoring certificate errors or rejecting erroneous certificates. - This QML type contains information about a certificate error that occurred. The \l error + This QML type contains information about a certificate error that occurred. The \l type property holds the reason that the error occurred and the \l description property holds a short localized description of the error. The \l url property holds the URL that triggered the error. @@ -49,7 +49,7 @@ The URL that triggered the error. */ /*! - \qmlproperty enumeration WebEngineCertificateError::error + \qmlproperty enumeration WebEngineCertificateError::type \readonly The type of the error. diff --git a/src/webenginequick/doc/src/webenginescript.qdoc b/src/webenginequick/doc/src/webenginescript.qdoc index 5919b29e3..9708ffbf8 100644 --- a/src/webenginequick/doc/src/webenginescript.qdoc +++ b/src/webenginequick/doc/src/webenginescript.qdoc @@ -32,7 +32,7 @@ \l{WebEngineScriptCollection::find}{WebEngineScriptCollection.find} method. */ -*! +/*! \qmlproperty url WebEngineScript::sourceUrl This property holds the remote source location of the user script (if any). diff --git a/src/webenginequick/doc/src/webengineview_lgpl.qdoc b/src/webenginequick/doc/src/webengineview_lgpl.qdoc index 6e3d9ebe3..eeae34dcc 100644 --- a/src/webenginequick/doc/src/webengineview_lgpl.qdoc +++ b/src/webenginequick/doc/src/webengineview_lgpl.qdoc @@ -1,24 +1,7 @@ -/* - * Copyright (C) 2019 The Qt Company Ltd. - * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (c) 2012 Hewlett-Packard Development Company, L.P. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this program; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ +// Copyright (C) 2019 The Qt Company Ltd. +// Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) +// Copyright (c) 2012 Hewlett-Packard Development Company, L.P. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only // The documentation in this file was imported from QtWebKit and is thus constrained // by its LGPL license. @@ -41,7 +24,7 @@ \l QtWebEngineQuick::initialize in the application main source file, as illustrated by the following code snippet: - \quotefromfile webenginequick/minimal/main.cpp + \quotefromfile minimal/main.cpp \skipto main \printuntil } @@ -56,7 +39,7 @@ The following sample QML application loads a web page using the \c url property: - \quotefromfile webenginequick/minimal/main.qml + \quotefromfile minimal/main.qml \skipto import \printuntil /^\}/ @@ -373,9 +356,8 @@ This method offers a lower-level alternative to the \c{url} property, which references HTML pages via URL. - External objects, such as stylesheets or images referenced in the HTML - document, should be located relative to \a baseUrl. For external objects to - be loaded, \c baseUrl cannot be empty. For example, if \a html + \a baseUrl is optional and used to resolve relative URLs in the document, + such as referenced images or stylesheets. For example, if \a html is retrieved from \c http://www.example.com/documents/overview.html, which is the base URL, then an image referenced with the relative URL, \c diagram.png, should be at \c{http://www.example.com/documents/diagram.png}. @@ -804,6 +786,7 @@ Exit the fullscreen mode. (Added in Qt 5.6) \value WebEngineView.SavePage Save the current web page to disk. (Added in Qt 5.7) + \omitvalue WebEngineView.OpenLinkInNewBackgroundTab \value WebEngineView.ViewSource Show the source of the current page in a new tab. Requires a handler for the \l newWindowRequested() signal. (Added in Qt 5.8) @@ -848,6 +831,10 @@ Inserts an unordered list at the current cursor position, deleting the current selection. Requires \c contenteditable="true". (Added in Qt 5.10) + \value WebEngineView.ChangeTextDirectionLTR + Changes text direction to left-to-right in the focused input element. (Added in Qt 6.6) + \value WebEngineView.ChangeTextDirectionRTL + Changes text direction to right-to-left in the focused input element. (Added in Qt 6.6) \omitvalue WebActionCount */ @@ -865,13 +852,22 @@ Video devices, such as cameras. \value WebEngineView.MediaAudioVideoCapture Both audio and video capture devices. - \value DesktopVideoCapture + \value WebEngineView.DesktopVideoCapture Video output capture, that is, the capture of the user's display. (Added in Qt 5.10) - \value DesktopAudioVideoCapture + \value WebEngineView.DesktopAudioVideoCapture Both audio and video output capture. (Added in Qt 5.10) - \value WebEnginView.Notifications + \value WebEngineView.Notifications Web notifications for the end-user. + \value WebEngineView.ClipboardReadWrite + Read and write access for the clipboard. If both \l{WebEngineSettings::JavascriptCanPaste} + {JavascriptCanPaste} and \l{WebEngineSettings::JavascriptCanAccessClipboard} + {JavascriptCanAccessClipboard} settings are enabled, this permission will always be granted + automatically and no feature requests will be made. + (Added in Qt 6.8) + \value WebEngineView.LocalFontsAccess + Access to the fonts installed on the user's machine. Only available on desktop platforms. + (Added in Qt 6.8) \sa featurePermissionRequested(), grantFeaturePermission() */ @@ -1013,8 +1009,6 @@ \value WebEngineView.EnvelopePrc10 \value WebEngineView.EnvelopeYou4 \value WebEngineView.LastPageSize = \c EnvelopeYou4 - \omitvalue NPageSize - \omitvalue NPaperSize \sa WebEngineView::printToPdf() */ @@ -1247,10 +1241,13 @@ /*! \qmlsignal WebEngineView::quotaRequested(QuotaRequest request) \since QtWebEngine 1.7 + \deprecated [6.5] This signal is no longer emitted. - This signal is emitted when the web page issues a \a request for a larger persistent storage - than the application's current allocation in File System API. The default quota - is 0 bytes. + Requesting host quota is no longer supported by Chromium. + The behavior of navigator.webkitPersistentStorage + is identical to navigator.webkitTemporaryStorage. + + For further details, see https://crbug.com/1233525 \sa QuotaRequest */ @@ -1314,6 +1311,20 @@ */ /*! + \qmlproperty WebEngineView WebEngineView::devToolsId + \since QtWebEngine 6.6 + \readonly + + The id of the developer tools host associated with this page. + + If remote debugging is enabled (see \l{Qt WebEngine Developer Tools}), the id can be used to + build the URL to connect to the developer tool websocket: + \c{ws://localhost:<debugggin-port>/devtools/page/<id>)}. The websocket can be used to to interact + with the page using the \l{https://chromedevtools.github.io/devtools-protocol/}{DevTools + Protocol}. +*/ + +/*! \qmlmethod WebEngineAction WebEngineView::action(WebAction action) \since 5.12 @@ -1329,10 +1340,11 @@ */ /*! - \qmlsignal WebEngineView::printRequest + \qmlsignal WebEngineView::printRequested \since QtWebEngine 1.8 - This signal is emitted when the JavaScript \c{window.print()} method is called. + This signal is emitted when the JavaScript \c{window.print()} method is called or the user pressed the print + button of PDF viewer plugin. Typically, the signal handler can simply call printToPdf(). \sa printToPdf @@ -1515,6 +1527,58 @@ // ... } \endcode + + The touch handles can be also switched dynamically: + + \code + Component { + id: circleTouchHandle + Rectangle { + color: "blue" + radius: 50 + } + } + function showDefaultHandle(isDefault) { + if (isDefault) + webEngineView.touchHandleDelegate = circleTouchHandle + else + webEngineView.touchHandleDelegate = null + } + \endcode + + \note If no delegate is provided, Chromium's default touch handles will appear. + +*/ + +/*! + \qmlmethod void WebEngineView::save(const QString &filePath, QWebEngineDownloadRequest::SavePageFormat format) + \since QtWebEngine 6.6 + + Save the current web page to disk. + + The web page is saved to \a filePath in the specified \a{format}. + + This is a shortcut 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 QWebEngineDownloadRequest::SavePageFormat +*/ + +/*! + \qmlsignal WebEngineView::webAuthUxRequested(QWebEngineWebAuthUxRequest *request); + \since QtWebEngine 6.7 + + This signal is emitted when a WebAuth authenticator requires user interaction + during the authentication process. These requests are handled by displaying a dialog to the user. + + The \a request contains the information and API required to complete the WebAuth UX request. + + \sa QWebEngineWebAuthUxRequest */ \sa {WebEngine Qt Quick Custom Touch Handle Example} diff --git a/src/webenginequick/plugin.cpp b/src/webenginequick/plugin.cpp index 1f25f4f98..e06596b44 100644 --- a/src/webenginequick/plugin.cpp +++ b/src/webenginequick/plugin.cpp @@ -7,9 +7,15 @@ #include <QtWebEngineQuick/private/qquickwebenginefaviconprovider_p_p.h> #include <QtWebEngineQuick/private/qquickwebenginetouchhandleprovider_p_p.h> +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) QT_BEGIN_NAMESPACE +void Q_WEBENGINEQUICK_EXPORT qml_register_types_QtWebEngine(); +QT_END_NAMESPACE +#else +void Q_WEBENGINEQUICK_EXPORT qml_register_types_QtWebEngine(); +#endif -void Q_WEBENGINEQUICK_PRIVATE_EXPORT qml_register_types_QtWebEngine(); +QT_BEGIN_NAMESPACE class QtWebEnginePlugin : public QQmlExtensionPlugin { diff --git a/src/webenginequick/qquickwebengine_accessible.cpp b/src/webenginequick/qquickwebengine_accessible.cpp index 80e2adbbd..e156a5e8b 100644 --- a/src/webenginequick/qquickwebengine_accessible.cpp +++ b/src/webenginequick/qquickwebengine_accessible.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#include "qquickwebengine_accessible.h" +#include "qquickwebengine_accessible_p.h" #include <QQuickItem> #include <QQuickWindow> @@ -10,8 +10,6 @@ #include "api/qquickwebengineview_p_p.h" #include "web_contents_adapter.h" - -#if QT_CONFIG(accessibility) QT_BEGIN_NAMESPACE QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o) : QAccessibleObject(o) @@ -147,4 +145,3 @@ QQuickWebEngineViewAccessible *RenderWidgetHostViewQtDelegateQuickAccessible::vi return static_cast<QQuickWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view)); } } // namespace QtWebEngineCore -#endif // QT_CONFIG(accessibility) diff --git a/src/webenginequick/qquickwebengine_accessible.h b/src/webenginequick/qquickwebengine_accessible_p.h index b1a4a34f5..2f774f898 100644 --- a/src/webenginequick/qquickwebengine_accessible.h +++ b/src/webenginequick/qquickwebengine_accessible_p.h @@ -4,11 +4,20 @@ #ifndef QQUICKWEBENGINE_ACCESSIBLE_H #define QQUICKWEBENGINE_ACCESSIBLE_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <QtCore/qpointer.h> #include <QtGui/qaccessibleobject.h> -#if QT_CONFIG(accessibility) - QT_BEGIN_NAMESPACE class QQuickWebEngineView; @@ -55,6 +64,4 @@ private: }; } // namespace QtWebEngineCore -#endif // QT_CONFIG(accessibility) - #endif // QQUICKWEBENGINE_ACCESSIBLE_H diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp index b003dabe4..090b09281 100644 --- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp +++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#include "render_widget_host_view_qt_delegate_quickwindow.h" +#include "render_widget_host_view_qt_delegate_quickwindow_p.h" #include "api/qquickwebengineview_p_p.h" diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h index 0e3b2c003..3559bd2f0 100644 --- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h @@ -4,12 +4,27 @@ #ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICKWINDOW_H #define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICKWINDOW_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "render_widget_host_view_qt_delegate.h" #include "render_widget_host_view_qt_delegate_item.h" #include <QtCore/qpointer.h> #include <QtQuick/qquickwindow.h> +// silence syncqt +QT_BEGIN_NAMESPACE +QT_END_NAMESPACE + namespace QtWebEngineCore { class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public WidgetDelegate { diff --git a/src/webenginequick/ui/AlertDialog.qml b/src/webenginequick/ui/AlertDialog.qml index 53911f0bc..e4c17b056 100644 --- a/src/webenginequick/ui/AlertDialog.qml +++ b/src/webenginequick/ui/AlertDialog.qml @@ -49,6 +49,7 @@ Dialog { id: message Layout.fillWidth: true color: palette.windowText + textFormat: Text.PlainText } } Item { diff --git a/src/webenginequick/ui/AuthenticationDialog.qml b/src/webenginequick/ui/AuthenticationDialog.qml index f9de8d79f..d0611b84f 100644 --- a/src/webenginequick/ui/AuthenticationDialog.qml +++ b/src/webenginequick/ui/AuthenticationDialog.qml @@ -50,6 +50,7 @@ Dialog { Label { id: message color: palette.windowText + textFormat: Text.PlainText } GridLayout { columns: 2 diff --git a/src/webenginequick/ui/AutofillPopup.qml b/src/webenginequick/ui/AutofillPopup.qml index 28b274bb6..0a14b6233 100644 --- a/src/webenginequick/ui/AutofillPopup.qml +++ b/src/webenginequick/ui/AutofillPopup.qml @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2022 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only import QtQuick import QtQuick.Controls diff --git a/src/webenginequick/ui/CMakeLists.txt b/src/webenginequick/ui/CMakeLists.txt index c24d8da8d..ac960535e 100644 --- a/src/webenginequick/ui/CMakeLists.txt +++ b/src/webenginequick/ui/CMakeLists.txt @@ -1,9 +1,18 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if (Qt6Quick_VERSION VERSION_GREATER_EQUAL "6.4.0") +set(colorDialog "ColorDialog.qml") +else() +set(colorDialog "custom/ColorDialog.qml") +endif() + set(qml_files "AlertDialog.qml" "AuthenticationDialog.qml" "AutofillPopup.qml" - "ColorDialog.qml" "ConfirmDialog.qml" + "DirectoryPicker.qml" "FilePicker.qml" "Menu.qml" "MenuItem.qml" @@ -12,6 +21,7 @@ set(qml_files "ToolTip.qml" "TouchHandle.qml" "TouchSelectionMenu.qml" + ${colorDialog} ) set(resource_files @@ -27,6 +37,7 @@ qt_internal_add_qml_module(WebEngineQuickDelegatesQml NO_SYNC_QT PLUGIN_TARGET qtwebenginequickdelegatesplugin DEPENDENCIES QtQuickControls2 + NO_GENERATE_CPP_EXPORTS ) qt_internal_add_resource(qtwebenginequickdelegatesplugin "qtwebenginequickdelegatesplugin" diff --git a/src/webenginequick/ui/ColorDialog.qml b/src/webenginequick/ui/ColorDialog.qml index 895c90198..f4d5b817b 100644 --- a/src/webenginequick/ui/ColorDialog.qml +++ b/src/webenginequick/ui/ColorDialog.qml @@ -1,285 +1,13 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts +import QtQuick.Dialogs -Dialog { +ColorDialog { id: colorDialog - title: qsTr("Color Picker Dialog") - modal: false - anchors.centerIn: parent objectName: "colorDialog" - property bool handled: false - property color color - signal selectedColor(var color) - signal rejected() - - function accept() { - handled = true; - selectedColor(colorDialog.color) - close(); - } - - function reject() { - handled = true; - rejected(); - close(); - } - - // Handle the case where users simply closes or clicks out of the dialog. - onVisibleChanged: { - if (!visible && !handled) { - handled = true; - rejected(); - } else { - handled = false; - } - } - - function selectColorFromPalette(paletteColor) { - colorDialog.color = paletteColor; - } - - function zeroPadding(text, length = 2) { - var textLength = text.length; - - if (textLength >= length) { - return text; - } - - for (var i = 0; i < length - textLength; i++) { - text = "0" + text; - } - - return text; - } - - function calculateRGBA() { - - var rgbArray = [colorDialog.color.r, colorDialog.color.g, colorDialog.color.b] - if (colorDialog.color.a != 1) { - rgbArray.push(colorDialog.color.a); - } - - for (var i = 0; i < rgbArray.length; i++) { - rgbArray[i] = Number(Math.round(rgbArray[i] * 255)).toString(16); - rgbArray[i] = zeroPadding(rgbArray[i]); - } - - return "#" + rgbArray.join(""); - } - - - function isNaNOrUndefined(value) { - return value == null || value == undefined || Number.isNaN(value); - } - - function parseColorText(colorText) { - if (colorText[0] == '#') { - colorText = colorText.substring(1); - } - - if (!(colorText.length == 6 || colorText.length == 8)) { - return undefined; - } - - var rgbaValues = [parseInt("0x" + colorText.substring(0,2)), - parseInt("0x" + colorText.substring(2,4)), - parseInt("0x" + colorText.substring(4,6)), - parseInt("0x" + (colorText.length > 6 ? colorText.substring(6,8) : "FF"))] - - for (var i = 0; i < rgbaValues.length; i++) { - if (isNaNOrUndefined(rgbaValues[i])) { - return undefined; - } - rgbaValues[i] = rgbaValues[i] / 255; - } - - return Qt.rgba(rgbaValues[0], rgbaValues[1], rgbaValues[2], rgbaValues[3]); - } - - ListModel { - id: colorList - ListElement { rectangleColor: "red" } - ListElement { rectangleColor: "orangered" } - ListElement { rectangleColor: "orange" } - ListElement { rectangleColor: "gold" } - ListElement { rectangleColor: "yellow" } - ListElement { rectangleColor: "yellowgreen" } - ListElement { rectangleColor: "green" } - ListElement { rectangleColor: "lightskyblue" } - ListElement { rectangleColor: "blue" } - ListElement { rectangleColor: "blueviolet" } - ListElement { rectangleColor: "violet" } - ListElement { rectangleColor: "mediumvioletred" } - ListElement { rectangleColor: "black" } - ListElement { rectangleColor: "white" } - } - - contentItem: GridLayout { - id: grid - columns: 7 - rows: 5 - - Repeater { - model: colorList - delegate: Rectangle { - width: 50 - height: 50 - color: rectangleColor - border.color: "black" - border.width: 1 - - MouseArea { - anchors.fill: parent - onClicked: selectColorFromPalette(parent.color) - } - } - } - ColumnLayout { - id: colorTools - Layout.columnSpan: 4 - Layout.rowSpan: 2 - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - - Rectangle { - height: 100 - width: 200 - border.color: "black" - border.width: 1 - - Binding on color { - when: colorDialog.color - value: colorDialog.color - } - } - TextField { - id: colorTextField - width: 100 - selectByMouse: true - Layout.alignment: Qt.AlignHCenter - - Binding on text { - when: colorDialog.color - value: calculateRGBA() - delayed: true - } - - onTextEdited: { - var parsedColor = parseColorText(colorTextField.text); - if (parsedColor != undefined) { - colorDialog.color = parsedColor; - } - } - - MouseArea { - id: colorTextFieldMouseArea - anchors.fill: parent - acceptedButtons: Qt.RightButton - onClicked: colorTextFieldContextMenu.open() - } - - Menu { - id: colorTextFieldContextMenu - x: colorTextFieldMouseArea.mouseX - y: colorTextFieldMouseArea.mouseY - MenuItem { - text: qsTr("Copy color") - onTriggered: { - colorTextField.selectAll(); - colorTextField.copy(); - colorTextField.deselect(); - } - } - MenuSeparator {} - MenuItem { - text: qsTr("Paste") - onTriggered: { - colorTextField.selectAll(); - colorTextField.paste(); - } - enabled: colorTextField.canPaste - } - } - } - } - ListModel { - id: sliderBoxElements - ListElement { labelText: "Red value"; colorChannel: 0 } - ListElement { labelText: "Green value"; colorChannel: 1 } - ListElement { labelText: "Blue value"; colorChannel: 2 } - ListElement { labelText: "Alpha value"; colorChannel: 3 } - } - ColumnLayout { - id: sliderBox - Layout.columnSpan: 3 - Layout.rowSpan: 2 - Layout.fillWidth: true - Layout.fillHeight: true - - Repeater { - model: sliderBoxElements - delegate: ColumnLayout { - Label { - text: labelText - } - Slider { - id: colorSlider - property int channel: colorChannel - from: 0 - to: 255 - stepSize: 1 - value: { - if (colorSlider.channel == 0) - return colorDialog.color.r * 255; - else if (colorSlider.channel == 1) - return colorDialog.color.g * 255; - else if (colorSlider.channel == 2) - return colorDialog.color.b * 255; - else if (colorSlider.channel == 3) - return colorDialog.color.a * 255; - } - - Connections { - function onMoved() { - var redChannelValue = colorDialog.color.r; - var greenChannelValue = colorDialog.color.g; - var blueChannelValue = colorDialog.color.b; - var alphaChannelValue = colorDialog.color.a; - - if (colorSlider.channel == 0) - redChannelValue = colorSlider.value / 255; - else if (colorSlider.channel == 1) - greenChannelValue = colorSlider.value / 255; - else if (colorSlider.channel == 2) - blueChannelValue = colorSlider.value / 255; - else if (colorSlider.channel == 3) - alphaChannelValue = colorSlider.value / 255; - - colorDialog.color = Qt.rgba(redChannelValue, greenChannelValue, blueChannelValue, alphaChannelValue); - } - } - } - } - } - } - DialogButtonBox { - id: dialogButtonBox - Layout.columnSpan: 7 - Layout.alignment: Qt.AlignRight - Button { - text: qsTr("Apply") - onClicked: accept() - } - Button { - text: qsTr("Cancel") - onClicked: reject() - } - } - } + onAccepted : selectedColor(selectedColor) } diff --git a/src/webenginequick/ui/ConfirmDialog.qml b/src/webenginequick/ui/ConfirmDialog.qml index 7b5f1f5cf..cfffe7c4d 100644 --- a/src/webenginequick/ui/ConfirmDialog.qml +++ b/src/webenginequick/ui/ConfirmDialog.qml @@ -55,6 +55,7 @@ Dialog { id: message Layout.fillWidth: true color: palette.windowText + textFormat: Text.PlainText } } Item { diff --git a/src/webenginequick/ui/DirectoryPicker.qml b/src/webenginequick/ui/DirectoryPicker.qml new file mode 100644 index 000000000..a8a6d47c9 --- /dev/null +++ b/src/webenginequick/ui/DirectoryPicker.qml @@ -0,0 +1,15 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick.Dialogs + +FolderDialog { + id: folderDialog + objectName: "folderDialog" + + signal folderSelected(var folder) + + onAccepted: { + folderSelected([selectedFolder]) + } +} diff --git a/src/webenginequick/ui/PromptDialog.qml b/src/webenginequick/ui/PromptDialog.qml index f3a15d48d..275deace8 100644 --- a/src/webenginequick/ui/PromptDialog.qml +++ b/src/webenginequick/ui/PromptDialog.qml @@ -52,6 +52,7 @@ Dialog { id: message Layout.fillWidth: true color: palette.windowText + textFormat: Text.PlainText } TextField { id:field diff --git a/src/webenginequick/ui/custom/ColorDialog.qml b/src/webenginequick/ui/custom/ColorDialog.qml new file mode 100644 index 000000000..895c90198 --- /dev/null +++ b/src/webenginequick/ui/custom/ColorDialog.qml @@ -0,0 +1,285 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Dialog { + id: colorDialog + title: qsTr("Color Picker Dialog") + modal: false + anchors.centerIn: parent + objectName: "colorDialog" + + property bool handled: false + property color color + + signal selectedColor(var color) + signal rejected() + + function accept() { + handled = true; + selectedColor(colorDialog.color) + close(); + } + + function reject() { + handled = true; + rejected(); + close(); + } + + // Handle the case where users simply closes or clicks out of the dialog. + onVisibleChanged: { + if (!visible && !handled) { + handled = true; + rejected(); + } else { + handled = false; + } + } + + function selectColorFromPalette(paletteColor) { + colorDialog.color = paletteColor; + } + + function zeroPadding(text, length = 2) { + var textLength = text.length; + + if (textLength >= length) { + return text; + } + + for (var i = 0; i < length - textLength; i++) { + text = "0" + text; + } + + return text; + } + + function calculateRGBA() { + + var rgbArray = [colorDialog.color.r, colorDialog.color.g, colorDialog.color.b] + if (colorDialog.color.a != 1) { + rgbArray.push(colorDialog.color.a); + } + + for (var i = 0; i < rgbArray.length; i++) { + rgbArray[i] = Number(Math.round(rgbArray[i] * 255)).toString(16); + rgbArray[i] = zeroPadding(rgbArray[i]); + } + + return "#" + rgbArray.join(""); + } + + + function isNaNOrUndefined(value) { + return value == null || value == undefined || Number.isNaN(value); + } + + function parseColorText(colorText) { + if (colorText[0] == '#') { + colorText = colorText.substring(1); + } + + if (!(colorText.length == 6 || colorText.length == 8)) { + return undefined; + } + + var rgbaValues = [parseInt("0x" + colorText.substring(0,2)), + parseInt("0x" + colorText.substring(2,4)), + parseInt("0x" + colorText.substring(4,6)), + parseInt("0x" + (colorText.length > 6 ? colorText.substring(6,8) : "FF"))] + + for (var i = 0; i < rgbaValues.length; i++) { + if (isNaNOrUndefined(rgbaValues[i])) { + return undefined; + } + rgbaValues[i] = rgbaValues[i] / 255; + } + + return Qt.rgba(rgbaValues[0], rgbaValues[1], rgbaValues[2], rgbaValues[3]); + } + + ListModel { + id: colorList + ListElement { rectangleColor: "red" } + ListElement { rectangleColor: "orangered" } + ListElement { rectangleColor: "orange" } + ListElement { rectangleColor: "gold" } + ListElement { rectangleColor: "yellow" } + ListElement { rectangleColor: "yellowgreen" } + ListElement { rectangleColor: "green" } + ListElement { rectangleColor: "lightskyblue" } + ListElement { rectangleColor: "blue" } + ListElement { rectangleColor: "blueviolet" } + ListElement { rectangleColor: "violet" } + ListElement { rectangleColor: "mediumvioletred" } + ListElement { rectangleColor: "black" } + ListElement { rectangleColor: "white" } + } + + contentItem: GridLayout { + id: grid + columns: 7 + rows: 5 + + Repeater { + model: colorList + delegate: Rectangle { + width: 50 + height: 50 + color: rectangleColor + border.color: "black" + border.width: 1 + + MouseArea { + anchors.fill: parent + onClicked: selectColorFromPalette(parent.color) + } + } + } + ColumnLayout { + id: colorTools + Layout.columnSpan: 4 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + + Rectangle { + height: 100 + width: 200 + border.color: "black" + border.width: 1 + + Binding on color { + when: colorDialog.color + value: colorDialog.color + } + } + TextField { + id: colorTextField + width: 100 + selectByMouse: true + Layout.alignment: Qt.AlignHCenter + + Binding on text { + when: colorDialog.color + value: calculateRGBA() + delayed: true + } + + onTextEdited: { + var parsedColor = parseColorText(colorTextField.text); + if (parsedColor != undefined) { + colorDialog.color = parsedColor; + } + } + + MouseArea { + id: colorTextFieldMouseArea + anchors.fill: parent + acceptedButtons: Qt.RightButton + onClicked: colorTextFieldContextMenu.open() + } + + Menu { + id: colorTextFieldContextMenu + x: colorTextFieldMouseArea.mouseX + y: colorTextFieldMouseArea.mouseY + MenuItem { + text: qsTr("Copy color") + onTriggered: { + colorTextField.selectAll(); + colorTextField.copy(); + colorTextField.deselect(); + } + } + MenuSeparator {} + MenuItem { + text: qsTr("Paste") + onTriggered: { + colorTextField.selectAll(); + colorTextField.paste(); + } + enabled: colorTextField.canPaste + } + } + } + } + ListModel { + id: sliderBoxElements + ListElement { labelText: "Red value"; colorChannel: 0 } + ListElement { labelText: "Green value"; colorChannel: 1 } + ListElement { labelText: "Blue value"; colorChannel: 2 } + ListElement { labelText: "Alpha value"; colorChannel: 3 } + } + ColumnLayout { + id: sliderBox + Layout.columnSpan: 3 + Layout.rowSpan: 2 + Layout.fillWidth: true + Layout.fillHeight: true + + Repeater { + model: sliderBoxElements + delegate: ColumnLayout { + Label { + text: labelText + } + Slider { + id: colorSlider + property int channel: colorChannel + from: 0 + to: 255 + stepSize: 1 + value: { + if (colorSlider.channel == 0) + return colorDialog.color.r * 255; + else if (colorSlider.channel == 1) + return colorDialog.color.g * 255; + else if (colorSlider.channel == 2) + return colorDialog.color.b * 255; + else if (colorSlider.channel == 3) + return colorDialog.color.a * 255; + } + + Connections { + function onMoved() { + var redChannelValue = colorDialog.color.r; + var greenChannelValue = colorDialog.color.g; + var blueChannelValue = colorDialog.color.b; + var alphaChannelValue = colorDialog.color.a; + + if (colorSlider.channel == 0) + redChannelValue = colorSlider.value / 255; + else if (colorSlider.channel == 1) + greenChannelValue = colorSlider.value / 255; + else if (colorSlider.channel == 2) + blueChannelValue = colorSlider.value / 255; + else if (colorSlider.channel == 3) + alphaChannelValue = colorSlider.value / 255; + + colorDialog.color = Qt.rgba(redChannelValue, greenChannelValue, blueChannelValue, alphaChannelValue); + } + } + } + } + } + } + DialogButtonBox { + id: dialogButtonBox + Layout.columnSpan: 7 + Layout.alignment: Qt.AlignRight + + Button { + text: qsTr("Apply") + onClicked: accept() + } + Button { + text: qsTr("Cancel") + onClicked: reject() + } + } + } +} diff --git a/src/webenginequick/ui_delegates_manager.cpp b/src/webenginequick/ui_delegates_manager.cpp index 19dd04298..a4a22fedd 100644 --- a/src/webenginequick/ui_delegates_manager.cpp +++ b/src/webenginequick/ui_delegates_manager.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -#include "ui_delegates_manager.h" +#include "ui_delegates_manager_p.h" #include "api/qquickwebengineaction_p.h" #include "api/qquickwebengineview_p_p.h" @@ -14,6 +14,7 @@ #include <touch_selection_menu_controller.h> #include <web_contents_adapter_client.h> +#include <QtCore/qdiriterator.h> #include <QtCore/qfileinfo.h> #include <QtCore/qlist.h> #include <QtCore/qtimer.h> @@ -33,15 +34,9 @@ namespace QtWebEngineCore { #define NO_SEPARATOR -#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) -#define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \ - case UIDelegatesManager::TYPE:\ - return QString::fromLatin1(#TYPE ##".qml"); -#else #define FILE_NAME_CASE_STATEMENT(TYPE, COMPONENT) \ case UIDelegatesManager::TYPE:\ return QStringLiteral(#TYPE".qml"); -#endif static QString fileNameForComponent(UIDelegatesManager::ComponentType type) { @@ -136,7 +131,7 @@ bool UIDelegatesManager::ensureComponentLoaded(ComponentType type) if (!engine) return false; - for (const QString &importDir : qAsConst(m_importDirs)) { + for (const QString &importDir : std::as_const(m_importDirs)) { const QString componentFilePath = importDir % QLatin1Char('/') % fileName; if (!QFileInfo(componentFilePath).exists()) @@ -356,6 +351,10 @@ void UIDelegatesManager::showDialog(QSharedPointer<AuthenticationDialogControlle void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> controller) { + if (controller->mode() == FilePickerController::UploadFolder) { + showDirectoryPicker(controller); + return; + } if (!ensureComponentLoaded(FilePicker)) return; @@ -367,19 +366,21 @@ void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> con filePicker->setParent(m_view); filePickerComponent->completeCreate(); + static int fileModeIndex = filePicker->metaObject()->indexOfEnumerator("FileMode"); + QMetaEnum fileModeEnum = filePicker->metaObject()->enumerator(fileModeIndex); + // Fine-tune some properties depending on the mode. switch (controller->mode()) { case FilePickerController::Open: + filePicker->setProperty("fileMode", fileModeEnum.keyToValue("OpenFile")); break; case FilePickerController::Save: - filePicker->setProperty("selectExisting", false); + filePicker->setProperty("fileMode", fileModeEnum.keyToValue("SaveFile")); break; case FilePickerController::OpenMultiple: - filePicker->setProperty("selectMultiple", true); + filePicker->setProperty("fileMode", fileModeEnum.keyToValue("OpenFiles")); break; case FilePickerController::UploadFolder: - filePicker->setProperty("selectFolder", true); - break; default: Q_UNREACHABLE(); } @@ -403,6 +404,35 @@ void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> con QMetaObject::invokeMethod(filePicker, "open"); } +void UIDelegatesManager::showDirectoryPicker(QSharedPointer<FilePickerController> controller) +{ + if (!ensureComponentLoaded(DirectoryPicker)) + return; + + QQmlContext *context = qmlContext(m_view); + QObject *directoryPicker = directoryPickerComponent->beginCreate(context); + if (QQuickItem *item = qobject_cast<QQuickItem*>(directoryPicker)) + item->setParentItem(m_view); + directoryPicker->setParent(m_view); + directoryPickerComponent->completeCreate(); + + QQmlProperty directoryPickedSignal(directoryPicker, QStringLiteral("onFolderSelected")); + CHECK_QML_SIGNAL_PROPERTY(directoryPickedSignal, directoryPickerComponent->url()); + QQmlProperty rejectSignal(directoryPicker, QStringLiteral("onRejected")); + CHECK_QML_SIGNAL_PROPERTY(rejectSignal, directoryPickerComponent->url()); + static int acceptedIndex = controller->metaObject()->indexOfSlot("accepted(QVariant)"); + QObject::connect(directoryPicker, directoryPickedSignal.method(), controller.data(), controller->metaObject()->method(acceptedIndex)); + static int rejectedIndex = controller->metaObject()->indexOfSlot("rejected()"); + QObject::connect(directoryPicker, rejectSignal.method(), controller.data(), controller->metaObject()->method(rejectedIndex)); + + // delete when done. + static int deleteLaterIndex = directoryPicker->metaObject()->indexOfSlot("deleteLater()"); + QObject::connect(directoryPicker, directoryPickedSignal.method(), directoryPicker, directoryPicker->metaObject()->method(deleteLaterIndex)); + QObject::connect(directoryPicker, rejectSignal.method(), directoryPicker, directoryPicker->metaObject()->method(deleteLaterIndex)); + + QMetaObject::invokeMethod(directoryPicker, "open"); +} + class TemporaryCursorMove { public: @@ -702,8 +732,14 @@ bool UIDelegatesManager::initializeImportDirs(QStringList &dirs, QQmlEngine *eng } QFileInfo fi(controlsImportPath); - if (fi.exists()) + if (fi.exists()) { dirs << fi.absolutePath(); + + // add subdirectories + QDirIterator it(controlsImportPath, QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (it.hasNext()) + dirs << QFileInfo(it.next()).absoluteFilePath(); + } } return !dirs.isEmpty(); } diff --git a/src/webenginequick/ui_delegates_manager.h b/src/webenginequick/ui_delegates_manager_p.h index 70e5ba00d..3502757d7 100644 --- a/src/webenginequick/ui_delegates_manager.h +++ b/src/webenginequick/ui_delegates_manager_p.h @@ -4,6 +4,17 @@ #ifndef UI_DELEGATES_MANAGER_H #define UI_DELEGATES_MANAGER_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <QtCore/qcoreapplication.h> // Q_DECLARE_TR_FUNCTIONS #include <QtCore/qobject.h> #include <QtCore/qpoint.h> @@ -22,6 +33,7 @@ F(ConfirmDialog, confirmDialog) SEPARATOR \ F(PromptDialog, promptDialog) SEPARATOR \ F(FilePicker, filePicker) SEPARATOR \ + F(DirectoryPicker, directoryPicker) SEPARATOR \ F(AuthenticationDialog, authenticationDialog) SEPARATOR \ F(ToolTip, toolTip) SEPARATOR \ F(TouchHandle, touchHandle) SEPARATOR \ @@ -80,6 +92,7 @@ public: void showDialog(QSharedPointer<JavaScriptDialogController>); void showDialog(QSharedPointer<AuthenticationDialogController>); void showFilePicker(QSharedPointer<FilePickerController>); + void showDirectoryPicker(QSharedPointer<FilePickerController>); virtual void showMenu(QObject *menu); void showToolTip(const QString &text); QQuickItem *createTouchHandle(); |