From 3f73e47130f3912f99376314a06a2033225b0dda Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Mon, 13 Jun 2016 13:29:51 +0200 Subject: Add context menu request to qml api Introduce qml APIs to support custom context menus. [ChangeLog][QtWebEngine][QML] Added ability to show custom context menu. Task-number: QTBUG-52554 Change-Id: Ief0cbbbf221f4c6849e16bbba7417dccee59ad61 Reviewed-by: Kai Koehne --- src/core/web_contents_adapter_client.h | 161 ++++++++++-- src/core/web_contents_view_qt.cpp | 26 +- .../api/qquickwebenginecontextmenudata.cpp | 243 ------------------ .../api/qquickwebenginecontextmenudata_p.h | 139 ----------- .../api/qquickwebenginecontextmenurequest.cpp | 274 +++++++++++++++++++++ .../api/qquickwebenginecontextmenurequest_p.h | 115 +++++++++ src/webengine/api/qquickwebengineview.cpp | 144 +++++------ src/webengine/api/qquickwebengineview_p.h | 4 +- src/webengine/api/qquickwebengineview_p_p.h | 8 +- src/webengine/doc/src/webengineview.qdoc | 13 + src/webengine/plugin/experimental/plugin.cpp | 5 - src/webengine/plugin/plugin.cpp | 3 + src/webengine/webengine.pro | 4 +- .../api/qwebenginecontextmenudata.cpp | 18 +- src/webenginewidgets/api/qwebenginepage.cpp | 120 ++++----- tests/auto/quick/publicapi/tst_publicapi.cpp | 2 + 16 files changed, 705 insertions(+), 574 deletions(-) delete mode 100644 src/webengine/api/qquickwebenginecontextmenudata.cpp delete mode 100644 src/webengine/api/qquickwebenginecontextmenudata_p.h create mode 100644 src/webengine/api/qquickwebenginecontextmenurequest.cpp create mode 100644 src/webengine/api/qquickwebenginecontextmenurequest_p.h diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 865fd55d7..85a379409 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -71,23 +71,43 @@ class WebContentsAdapter; class WebContentsDelegateQt; class WebEngineSettings; -// FIXME: make this ref-counted and implicitely shared and expose as public API maybe ? -class WebEngineContextMenuData { + +class WebEngineContextMenuSharedData : public QSharedData { public: - WebEngineContextMenuData() - : mediaType(MediaTypeNone) - , hasImageContent(false) - , mediaFlags(0) + WebEngineContextMenuSharedData() + : hasImageContent(false) , isEditable(false) , isSpellCheckerEnabled(false) + , mediaType(0) + , mediaFlags(0) { } + bool hasImageContent; + bool isEditable; + bool isSpellCheckerEnabled; + uint mediaType; + uint mediaFlags; + QPoint pos; + QUrl linkUrl; + QUrl mediaUrl; + QString linkText; + QString selectedText; + QString suggestedFileName; + QString misspelledWord; + QStringList spellCheckerSuggestions; + // Some likely candidates for future additions as we add support for the related actions: + // bool isImageBlocked; + // mediaType; + // ... +}; +class WebEngineContextMenuData { +public: // Must match blink::WebContextMenuData::MediaType: enum MediaType { // No special node is in context. - MediaTypeNone, + MediaTypeNone = 0x0, // An image node is selected. MediaTypeImage, // A video node is selected. @@ -117,25 +137,118 @@ public: MediaCanRotate = 0x200, }; - QPoint pos; - QUrl linkUrl; - QString linkText; - QString selectedText; - QUrl mediaUrl; - MediaType mediaType; - bool hasImageContent; - uint mediaFlags; - QString suggestedFileName; - bool isEditable; - bool isSpellCheckerEnabled; - QString misspelledWord; - QStringList spellCheckerSuggestions; -// Some likely candidates for future additions as we add support for the related actions: -// bool isImageBlocked; -// mediaType; -// ... + WebEngineContextMenuData():d(new WebEngineContextMenuSharedData) { + } + + void setPosition(const QPoint &pos) { + d->pos = pos; + } + + QPoint position() const { + return d->pos; + } + + void setLinkUrl(const QUrl &url) { + d->linkUrl = url; + } + + QUrl linkUrl() const { + return d->linkUrl; + } + + void setLinkText(const QString &text) { + d->linkText = text; + } + + QString linkText() const { + return d->linkText; + } + + void setSelectedText(const QString &text) { + d->selectedText = text; + } + + QString selectedText() const { + return d->selectedText; + } + + void setMediaUrl(const QUrl &url) { + d->mediaUrl = url; + } + + QUrl mediaUrl() const { + return d->mediaUrl; + } + + void setMediaType(MediaType type) { + d->mediaType = type; + } + + MediaType mediaType() const { + return MediaType(d->mediaType); + } + + void setHasImageContent(bool imageContent) { + d->hasImageContent = imageContent; + } + + bool hasImageContent() const { + return d->hasImageContent; + } + + void setMediaFlags(MediaFlags flags) { + d->mediaFlags = flags; + } + + MediaFlags mediaFlags() const { + return MediaFlags(d->mediaFlags); + } + + void setSuggestedFileName(const QString &filename) { + d->suggestedFileName = filename; + } + + QString suggestedFileName() const { + return d->suggestedFileName; + } + + void setIsEditable(bool editable) { + d->isEditable = editable; + } + + bool isEditable() const { + return d->isEditable; + } + + void setIsSpellCheckerEnabled(bool spellCheckerEnabled) { + d->isSpellCheckerEnabled = spellCheckerEnabled; + } + + bool isSpellCheckerEnabled() const { + return d->isSpellCheckerEnabled; + } + + void setMisspelledWord(const QString &word) { + d->misspelledWord = word; + } + + QString misspelledWord() const { + return d->misspelledWord; + } + + void setSpellCheckerSuggestions(const QStringList &suggestions) { + d->spellCheckerSuggestions = suggestions; + } + + QStringList spellCheckerSuggestions() const { + return d->spellCheckerSuggestions; + } + +private: + QSharedDataPointer d; }; + class QWEBENGINE_EXPORT WebContentsAdapterClient { public: // This must match window_open_disposition_list.h. diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index e487fca46..ed6fdabff 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -155,19 +155,19 @@ ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMe static inline WebEngineContextMenuData fromParams(const content::ContextMenuParams ¶ms) { WebEngineContextMenuData ret; - ret.pos = QPoint(params.x, params.y); - ret.linkUrl = toQt(params.link_url); - ret.linkText = toQt(params.link_text.data()); - ret.selectedText = toQt(params.selection_text.data()); - ret.mediaUrl = toQt(params.src_url); - ret.mediaType = (WebEngineContextMenuData::MediaType)params.media_type; - ret.hasImageContent = params.has_image_contents; - ret.mediaFlags = params.media_flags; - ret.suggestedFileName = toQt(params.suggested_filename.data()); - ret.isEditable = params.is_editable; + ret.setPosition(QPoint(params.x, params.y)); + ret.setLinkUrl(toQt(params.link_url)); + ret.setLinkText(toQt(params.link_text.data())); + ret.setSelectedText(toQt(params.selection_text.data())); + ret.setMediaUrl(toQt(params.src_url)); + ret.setMediaType((WebEngineContextMenuData::MediaType)params.media_type); + ret.setHasImageContent(params.has_image_contents); + ret.setMediaFlags((WebEngineContextMenuData::MediaFlags)params.media_flags); + ret.setSuggestedFileName(toQt(params.suggested_filename.data())); + ret.setIsEditable(params.is_editable); #if defined(ENABLE_SPELLCHECK) - ret.misspelledWord = toQt(params.misspelled_word); - ret.spellCheckerSuggestions = fromVector(params.dictionary_suggestions); + ret.setMisspelledWord(toQt(params.misspelled_word)); + ret.setSpellCheckerSuggestions(fromVector(params.dictionary_suggestions)); #endif return ret; } @@ -183,7 +183,7 @@ void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const conten // must be initialized to true due to the way how the initialization sequence // in SpellCheck works ie. typing the first word triggers the creation // of the SpellcheckService. Use user preference store instead. - contextMenuData.isSpellCheckerEnabled = m_client->browserContextAdapter()->isSpellCheckEnabled(); + contextMenuData.setIsSpellCheckerEnabled(m_client->browserContextAdapter()->isSpellCheckEnabled()); #endif m_client->contextMenuRequested(contextMenuData); } diff --git a/src/webengine/api/qquickwebenginecontextmenudata.cpp b/src/webengine/api/qquickwebenginecontextmenudata.cpp deleted file mode 100644 index 36315aebb..000000000 --- a/src/webengine/api/qquickwebenginecontextmenudata.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -#include "qquickwebenginecontextmenudata_p.h" - -#include "web_contents_adapter_client.h" - -QT_BEGIN_NAMESPACE - -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeNone, QQuickWebEngineContextMenuData::MediaTypeNone) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeImage, QQuickWebEngineContextMenuData::MediaTypeImage) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeAudio, QQuickWebEngineContextMenuData::MediaTypeAudio) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeVideo, QQuickWebEngineContextMenuData::MediaTypeVideo) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeCanvas, QQuickWebEngineContextMenuData::MediaTypeCanvas) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeFile, QQuickWebEngineContextMenuData::MediaTypeFile) -ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypePlugin, QQuickWebEngineContextMenuData::MediaTypePlugin) - -/*! - \qmltype WebEngineContextMenuData - \instantiates QQuickWebEngineContextMenuData - \inqmlmodule QtWebEngine - \since QtWebEngine 1.3 - \brief Provides context data for populating or extending a context menu with actions. - - - WebEngineContextMenuData is returned by WebEngineView::contextMenuData() after a context menu event, - and contains information about where the context menu event took place. This is also in the context - in which any context specific WebEngineView::WebAction will be performed. -*/ - -QQuickWebEngineContextMenuData::QQuickWebEngineContextMenuData() : d(nullptr) -{ -} - -QQuickWebEngineContextMenuData::~QQuickWebEngineContextMenuData() -{ - delete d; -} - -/*! - \qmlproperty bool WebEngineContextMenuData::isValid - - Is \c true if the context data is valid; otherwise \c false. -*/ -bool QQuickWebEngineContextMenuData::isValid() const -{ - return d; -} - -/*! - \qmlproperty QPoint WebEngineContextMenuData::position - - - Returns the position of the context, usually the mouse position where the context menu event was triggered. -*/ -QPoint QQuickWebEngineContextMenuData::position() const -{ - return d ? d->pos : QPoint(); -} - -/*! - \qmlproperty QString WebEngineContextMenuData::linkText - - Returns the text of a link if the context is a link. -*/ -QString QQuickWebEngineContextMenuData::linkText() const -{ - return d ? d->linkText : QString(); -} - -/*! - \qmlproperty QUrl WebEngineContextMenuData::linkUrl - - Returns the URL of a link if the context is a link. -*/ -QUrl QQuickWebEngineContextMenuData::linkUrl() const -{ - return d ? d->linkUrl : QUrl(); -} - -/*! - \qmlproperty QString WebEngineContextMenuData::selectedText - - Returns the selected text of the context. -*/ -QString QQuickWebEngineContextMenuData::selectedText() const -{ - return d ? d->selectedText : QString(); -} - -/*! - \qmlproperty QUrl WebEngineContextMenuData::mediaUrl - - If the context is a media element, returns the URL of that media. -*/ -QUrl QQuickWebEngineContextMenuData::mediaUrl() const -{ - return d ? d->mediaUrl : QUrl(); -} - -/*! - \qmlproperty enumeration WebEngineContextMenuData::mediaType - - Returns the type of the media element or \c MediaTypeNone if the context is not a media element. - - \value WebEngineContextMenuData.MediaTypeNone - The context is not a media element. - \value WebEngineContextMenuData.MediaTypeImage - The context is an image element - \value WebEngineContextMenuData.MediaTypeVideo - The context is a video element - \value WebEngineContextMenuData.MediaTypeAudio - The context is an audio element - \value WebEngineContextMenuData.MediaTypeCanvas - The context is a canvas element - \value WebEngineContextMenuData.MediaTypeFile - The context is a file - \value WebEngineContextMenuData.MediaTypePlugin - The context is a plugin -*/ - -QQuickWebEngineContextMenuData::MediaType QQuickWebEngineContextMenuData::mediaType() const -{ - return d ? static_cast(d->mediaType) : MediaTypeNone; -} - -/*! - \qmlproperty bool WebEngineContextMenuData::isContentEditable - - Returns \c true if the content is editable by the user; otherwise returns \c false. -*/ -bool QQuickWebEngineContextMenuData::isContentEditable() const -{ - return d ? d->isEditable : false; -} - -/*! - \qmlproperty QString WebEngineContextMenuData::misspelledWord - - If the context is a word considered misspelled by the spell-checker, returns the misspelled word. - - \since QtWebEngine 1.4 -*/ -QString QQuickWebEngineContextMenuData::misspelledWord() const -{ - if (d) - return d->misspelledWord; - return QString(); -} - -/*! - \qmlproperty QStringList WebEngineContextMenuData::spellCheckerSuggestions - - If the context is a word considered misspelled by the spell-checker, returns a list of suggested replacements. - - \since QtWebEngine 1.4 -*/ -QStringList QQuickWebEngineContextMenuData::spellCheckerSuggestions() const -{ - if (d) - return d->spellCheckerSuggestions; - return QStringList(); -} - -void QQuickWebEngineContextMenuData::update(const QtWebEngineCore::WebEngineContextMenuData &update) -{ - const QQuickWebEngineContextMenuData old(d); - d = new QtWebEngineCore::WebEngineContextMenuData(update); - - if (isValid() != old.isValid()) - Q_EMIT isValidChanged(); - - if (position() != old.position()) - Q_EMIT positionChanged(); - - if (selectedText() != old.selectedText()) - Q_EMIT selectedTextChanged(); - - if (linkText() != old.linkText()) - Q_EMIT linkTextChanged(); - - if (linkUrl() != old.linkUrl()) - Q_EMIT linkUrlChanged(); - - if (mediaUrl() != old.mediaUrl()) - Q_EMIT mediaUrlChanged(); - - if (mediaType() != old.mediaType()) - Q_EMIT mediaTypeChanged(); - - if (isContentEditable() != old.isContentEditable()) - Q_EMIT isContentEditableChanged(); - - if (misspelledWord() != old.misspelledWord()) - Q_EMIT misspelledWordChanged(); - - if (spellCheckerSuggestions() != old.spellCheckerSuggestions()) - Q_EMIT spellCheckerSuggestionsChanged(); -} - -QQuickWebEngineContextMenuData::QQuickWebEngineContextMenuData(const QQuickWebEngineContextMenuDataPrivate *p, QObject *parent) - : QObject(parent) - , d(p) -{ -} - -QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginecontextmenudata_p.h b/src/webengine/api/qquickwebenginecontextmenudata_p.h deleted file mode 100644 index 7175838db..000000000 --- a/src/webengine/api/qquickwebenginecontextmenudata_p.h +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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$ -** -****************************************************************************/ - -#ifndef QQUICKWEBENGINECONTEXTMENUDATA_P_H -#define QQUICKWEBENGINECONTEXTMENUDATA_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include -#include - -namespace QtWebEngineCore { -class WebEngineContextMenuData; -} - -QT_BEGIN_NAMESPACE - -class QQuickWebEngineView; -class QQuickWebEngineViewPrivate; - -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineContextMenuData : public QObject { - Q_OBJECT -public: - QQuickWebEngineContextMenuData(); - ~QQuickWebEngineContextMenuData(); - - enum MediaType { - MediaTypeNone, - MediaTypeImage, - MediaTypeVideo, - MediaTypeAudio, - MediaTypeCanvas, - MediaTypeFile, - MediaTypePlugin - }; - Q_ENUM(MediaType) - - Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged) - Q_PROPERTY(QPoint position READ position NOTIFY positionChanged) - Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectedTextChanged) - Q_PROPERTY(QString linkText READ linkText NOTIFY linkTextChanged) - Q_PROPERTY(QUrl linkUrl READ linkUrl NOTIFY linkUrlChanged) - Q_PROPERTY(QUrl mediaUrl READ mediaUrl NOTIFY mediaUrlChanged) - Q_PROPERTY(MediaType mediaType READ mediaType NOTIFY mediaTypeChanged) - Q_PROPERTY(bool isContentEditable READ isContentEditable NOTIFY isContentEditableChanged) - Q_PROPERTY(QString misspelledWord READ misspelledWord NOTIFY misspelledWordChanged FINAL REVISION 1) - Q_PROPERTY(QStringList spellCheckerSuggestions READ spellCheckerSuggestions NOTIFY spellCheckerSuggestionsChanged FINAL REVISION 1) - - bool isValid() const; - - QPoint position() const; - QString selectedText() const; - QString linkText() const; - QUrl linkUrl() const; - QUrl mediaUrl() const; - MediaType mediaType() const; - bool isContentEditable() const; - - QString misspelledWord() const; - QStringList spellCheckerSuggestions() const; - -Q_SIGNALS: - void isValidChanged(); - void positionChanged(); - void selectedTextChanged(); - void linkTextChanged(); - void linkUrlChanged(); - void mediaUrlChanged(); - void mediaTypeChanged(); - void isContentEditableChanged(); - Q_REVISION(1) void misspelledWordChanged(); - Q_REVISION(1) void spellCheckerSuggestionsChanged(); - -private: - void update(const QtWebEngineCore::WebEngineContextMenuData &update); - - friend class QQuickWebEngineView; - friend class QQuickWebEngineViewPrivate; - Q_DISABLE_COPY(QQuickWebEngineContextMenuData) - typedef QtWebEngineCore::WebEngineContextMenuData QQuickWebEngineContextMenuDataPrivate; - QQuickWebEngineContextMenuData(const QQuickWebEngineContextMenuDataPrivate *priv, QObject *parent = 0); - QQuickWebEngineContextMenuData &operator=(const QQuickWebEngineContextMenuDataPrivate *priv); - const QQuickWebEngineContextMenuDataPrivate *d; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(const QQuickWebEngineContextMenuData); - -#endif // QQUICKWEBENGINECONTEXTMENUDATA_P_H diff --git a/src/webengine/api/qquickwebenginecontextmenurequest.cpp b/src/webengine/api/qquickwebenginecontextmenurequest.cpp new file mode 100644 index 000000000..5ad2b1501 --- /dev/null +++ b/src/webengine/api/qquickwebenginecontextmenurequest.cpp @@ -0,0 +1,274 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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$ +** +****************************************************************************/ + +#include "qquickwebenginecontextmenurequest_p.h" +#include "web_contents_adapter_client.h" + +QT_BEGIN_NAMESPACE + +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeNone, + QQuickWebEngineContextMenuRequest::MediaTypeNone) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeImage, + QQuickWebEngineContextMenuRequest::MediaTypeImage) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeAudio, + QQuickWebEngineContextMenuRequest::MediaTypeAudio) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeVideo, + QQuickWebEngineContextMenuRequest::MediaTypeVideo) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeCanvas, + QQuickWebEngineContextMenuRequest::MediaTypeCanvas) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypeFile, + QQuickWebEngineContextMenuRequest::MediaTypeFile) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebEngineContextMenuData::MediaTypePlugin, + QQuickWebEngineContextMenuRequest::MediaTypePlugin) + +/*! + \qmltype ContextMenuRequest + \instantiates QQuickWebEngineContextMenuRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for showing a context menu. + + A ContextMenuRequest is passed as an argument of the + WebEngineView::contextMenuRequested signal. It provides further + information about the context of the request. The position of the + request origin can be found via the \l x and \l y properties. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default context menu should + be displayed. + + The following code uses a custom menu to handle the request: + + \code + WebEngineView { + id: view + // ... + onContextMenuRequested: { + request.accepted = true; + myMenu.x = request.x; + myMenu.y = request.y; + myMenu.trigger.connect(view.triggerWebAction); + myMenu.popup(); + } + // ... + } + \endcode +*/ + +QQuickWebEngineContextMenuRequest::QQuickWebEngineContextMenuRequest( + const QtWebEngineCore::WebEngineContextMenuData &data, QObject *parent): + QObject(parent) + , m_data(new QtWebEngineCore::WebEngineContextMenuData(data)) + , m_accepted(false) +{ +} + +QQuickWebEngineContextMenuRequest::~QQuickWebEngineContextMenuRequest() +{ +} + +/*! + \qmlproperty int ContextMenuRequest::x + \readonly + + The x coordinate of the user action from where the context + menu request originates. +*/ + +int QQuickWebEngineContextMenuRequest::x() const +{ + return m_data->position().x(); +} + +/*! + \qmlproperty int ContextMenuRequest::y + \readonly + + The y coordinate of the user action from where the context + menu request originates. +*/ + +int QQuickWebEngineContextMenuRequest::y() const +{ + return m_data->position().y(); +} + +/*! + \qmlproperty string ContextMenuRequest::selectedText + \readonly + + The selected text the context menu was created for. +*/ + +QString QQuickWebEngineContextMenuRequest::selectedText() const +{ + return m_data->selectedText(); +} + +/*! + \qmlproperty string ContextMenuRequest::linkText + \readonly + + The text of the link if the context menu was requested for a link. +*/ + +QString QQuickWebEngineContextMenuRequest::linkText() const +{ + return m_data->linkText(); +} + +/*! + \qmlproperty url ContextMenuRequest::linkUrl + \readonly + + The URL of the link if the selected web page content is a link. +*/ + +QUrl QQuickWebEngineContextMenuRequest::linkUrl() const +{ + return m_data->linkUrl(); +} + +/*! + \qmlproperty url ContextMenuRequest::mediaUrl + \readonly + + The URL of media if the selected web content is a media element. +*/ + +QUrl QQuickWebEngineContextMenuRequest::mediaUrl() const +{ + return m_data->mediaUrl(); +} + +/*! + \qmlproperty enumeration ContextMenuRequest::mediaType + \readonly + + The type of the media element or \c MediaTypeNone if + the selected web page content is not a media element. + + \value ContextMenuRequest.MediaTypeNone + Not a media. + \value ContextMenuRequest.MediaTypeImage + An image. + \value ContextMenuRequest.MediaTypeVideo + A video. + \value ContextMenuRequest.MediaTypeAudio + An audio element. + \value ContextMenuRequest.MediaTypeCanvas + A canvas. + \value ContextMenuRequest.MediaTypeFile + A file. + \value ContextMenuRequest.MediaTypePlugin + A plugin. +*/ + +QQuickWebEngineContextMenuRequest::MediaType QQuickWebEngineContextMenuRequest::mediaType() const +{ + return static_cast(m_data->mediaType()); +} + +/*! + \qmlproperty bool ContextMenuRequest::isContentEditable + \readonly + + Indicates whether the selected web content is editable. +*/ + +bool QQuickWebEngineContextMenuRequest::isContentEditable() const +{ + return m_data->isEditable(); +} + +/*! + \qmlproperty string ContextMenuRequest::misspelledWord + \readonly + + If the context is a word considered misspelled by the spell-checker, + returns the misspelled word. +*/ + +QString QQuickWebEngineContextMenuRequest::misspelledWord() const +{ + return m_data->misspelledWord(); +} + +/*! + \qmlproperty stringlist ContextMenuRequest::spellCheckerSuggestions + \readonly + + If the context is a word considered misspelled by the spell-checker, + returns a list of suggested replacements. +*/ + +QStringList QQuickWebEngineContextMenuRequest::spellCheckerSuggestions() const +{ + return m_data->spellCheckerSuggestions(); +} + +/*! + \qmlproperty bool ContextMenuRequest::accepted + + Indicates whether the context menu request has been + handled by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::contextMenuRequested have been executed, + a default context menu will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. + + \note The default content of the context menu depends on the + web element for which the request was actually generated. +*/ + +bool QQuickWebEngineContextMenuRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineContextMenuRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginecontextmenurequest_p.h b/src/webengine/api/qquickwebenginecontextmenurequest_p.h new file mode 100644 index 000000000..3d2de14a2 --- /dev/null +++ b/src/webengine/api/qquickwebenginecontextmenurequest_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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$ +** +****************************************************************************/ + +#ifndef QQUICKWEBENGINECONTEXTMENUREQUEST_H +#define QQUICKWEBENGINECONTEXTMENUREQUEST_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#include +#include +#include +#include + +namespace QtWebEngineCore { + class WebEngineContextMenuData; +} + +QT_BEGIN_NAMESPACE + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineContextMenuRequest: public QObject { + Q_OBJECT +public: + enum MediaType { + MediaTypeNone, + MediaTypeImage, + MediaTypeVideo, + MediaTypeAudio, + MediaTypeCanvas, + MediaTypeFile, + MediaTypePlugin + }; + Q_ENUM(MediaType) + + Q_PROPERTY(int x READ x CONSTANT FINAL) + Q_PROPERTY(int y READ y CONSTANT FINAL) + Q_PROPERTY(QString selectedText READ selectedText CONSTANT FINAL) + Q_PROPERTY(QString linkText READ linkText CONSTANT FINAL) + Q_PROPERTY(QUrl linkUrl READ linkUrl CONSTANT FINAL) + Q_PROPERTY(QUrl mediaUrl READ mediaUrl CONSTANT FINAL) + Q_PROPERTY(MediaType mediaType READ mediaType CONSTANT FINAL) + Q_PROPERTY(bool isContentEditable READ isContentEditable CONSTANT FINAL) + Q_PROPERTY(QString misspelledWord READ misspelledWord CONSTANT FINAL) + Q_PROPERTY(QStringList spellCheckerSuggestions READ spellCheckerSuggestions CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineContextMenuRequest(); + int x() const; + int y() const; + QString selectedText() const; + QString linkText() const; + QUrl linkUrl() const; + QUrl mediaUrl() const; + MediaType mediaType() const; + bool isContentEditable() const; + QString misspelledWord() const; + QStringList spellCheckerSuggestions() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +private: + QQuickWebEngineContextMenuRequest(const QtWebEngineCore::WebEngineContextMenuData &data, QObject *parent = nullptr); + QScopedPointer m_data; + bool m_accepted; + friend class QQuickWebEngineView; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineContextMenuRequest) +}; + +QT_END_NAMESPACE + +#endif // QQUICKWEBENGINECONTEXTMENUREQUEST_H diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 968c9787a..fd1e746a8 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -47,6 +47,8 @@ #include "javascript_dialog_controller.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginecertificateerror_p.h" +#include "qquickwebenginecontextmenurequest_p.h" +#include "qquickwebenginedialogrequests_p.h" #include "qquickwebenginefaviconprovider_p_p.h" #include "qquickwebengineloadrequest_p.h" #include "qquickwebenginenavigationrequest_p.h" @@ -54,7 +56,6 @@ #include "qquickwebengineprofile_p.h" #include "qquickwebenginesettings_p.h" #include "qquickwebenginescript_p_p.h" -#include "qquickwebenginedialogrequests_p.h" #ifdef ENABLE_QML_TESTSUPPORT_API #include "qquickwebenginetestsupport_p.h" @@ -234,34 +235,41 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu { Q_Q(QQuickWebEngineView); + m_contextMenuData = data; + + QQuickWebEngineContextMenuRequest *request = new QQuickWebEngineContextMenuRequest(data); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->contextMenuRequested(request); + + if (request->isAccepted()) + return true; + // Assign the WebEngineView as the parent of the menu, so mouse events are properly propagated // on OSX. - QObject *menu = ui()->addMenu(q, QString(), data.pos); + QObject *menu = ui()->addMenu(q, QString(), data.position()); if (!menu) return false; - contextMenuData.update(data); - Q_EMIT q->experimental()->contextMenuDataChanged(); - // Populate our menu MenuItemHandler *item = 0; - if (contextMenuData.isContentEditable() && !contextMenuData.spellCheckerSuggestions().isEmpty()) { + if (data.isEditable() && !data.spellCheckerSuggestions().isEmpty()) { const QPointer qRef(q); - for (int i=0; i < contextMenuData.spellCheckerSuggestions().count() && i < 4; i++) { + for (int i=0; i < data.spellCheckerSuggestions().count() && i < 4; i++) { item = new MenuItemHandler(menu); - QString replacement = contextMenuData.spellCheckerSuggestions().at(i); + QString replacement = data.spellCheckerSuggestions().at(i); QObject::connect(item, &MenuItemHandler::triggered, [qRef, replacement] { qRef->replaceMisspelledWord(replacement); }); ui()->addMenuItem(item, replacement); } ui()->addMenuSeparator(menu); } - if (!data.linkText.isEmpty() && data.linkUrl.isValid()) { + if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::OpenLinkInThisWindow); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Follow Link")); } - if (data.selectedText.isEmpty()) { + if (data.selectedText().isEmpty()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goBack); ui()->addMenuItem(item, QQuickWebEngineView::tr("Back"), QStringLiteral("go-previous"), q->canGoBack()); @@ -286,7 +294,7 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu ui()->addMenuItem(item, QQuickWebEngineView::tr("Unselect")); } - if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) { + if (!data.linkText().isEmpty() && data.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL")); @@ -294,9 +302,9 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Link")); } - if (contextMenuData.mediaUrl().isValid()) { - switch (contextMenuData.mediaType()) { - case QQuickWebEngineContextMenuData::MediaTypeImage: + if (data.mediaUrl().isValid()) { + switch (data.mediaType()) { + case WebEngineContextMenuData::MediaTypeImage: item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image URL")); @@ -307,11 +315,11 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadImageToDisk); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Image")); break; - case QQuickWebEngineContextMenuData::MediaTypeCanvas: + case WebEngineContextMenuData::MediaTypeCanvas: Q_UNREACHABLE(); // mediaUrl is invalid for canvases break; - case QQuickWebEngineContextMenuData::MediaTypeAudio: - case QQuickWebEngineContextMenuData::MediaTypeVideo: + case WebEngineContextMenuData::MediaTypeAudio: + case WebEngineContextMenuData::MediaTypeVideo: item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyMediaUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Media URL")); @@ -324,12 +332,12 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaLoop); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Looping")); - if (data.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + if (data.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaMute); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Mute")); } - if (data.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { + if (data.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaControls); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Media Controls")); @@ -338,7 +346,7 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu default: break; } - } else if (contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeCanvas) { + } else if (data.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); @@ -1606,118 +1614,118 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) d->adapter->unselect(); break; case OpenLinkInThisWindow: - if (d->contextMenuData.linkUrl().isValid()) - setUrl(d->contextMenuData.linkUrl()); + if (d->m_contextMenuData.linkUrl().isValid()) + setUrl(d->m_contextMenuData.linkUrl()); break; case OpenLinkInNewWindow: - if (d->contextMenuData.linkUrl().isValid()) { + if (d->m_contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; - request.m_requestedUrl = d->contextMenuData.linkUrl(); + request.m_requestedUrl = d->m_contextMenuData.linkUrl(); request.m_isUserInitiated = true; request.m_destination = NewViewInWindow; Q_EMIT newViewRequested(&request); } break; case OpenLinkInNewTab: - if (d->contextMenuData.linkUrl().isValid()) { + if (d->m_contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; - request.m_requestedUrl = d->contextMenuData.linkUrl(); + request.m_requestedUrl = d->m_contextMenuData.linkUrl(); request.m_isUserInitiated = true; request.m_destination = NewViewInBackgroundTab; Q_EMIT newViewRequested(&request); } break; case CopyLinkToClipboard: - if (d->contextMenuData.linkUrl().isValid()) { - QString urlString = d->contextMenuData.linkUrl().toString(QUrl::FullyEncoded); - QString title = d->contextMenuData.linkText().toHtmlEscaped(); + if (d->m_contextMenuData.linkUrl().isValid()) { + QString urlString = d->m_contextMenuData.linkUrl().toString(QUrl::FullyEncoded); + QString title = d->m_contextMenuData.linkText().toHtmlEscaped(); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral("") + title + QStringLiteral(""); data->setHtml(html); - data->setUrls(QList() << d->contextMenuData.linkUrl()); + data->setUrls(QList() << d->m_contextMenuData.linkUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadLinkToDisk: - if (d->contextMenuData.linkUrl().isValid()) - d->adapter->download(d->contextMenuData.linkUrl(), d->contextMenuData.d->suggestedFileName); + if (d->m_contextMenuData.linkUrl().isValid()) + d->adapter->download(d->m_contextMenuData.linkUrl(), d->m_contextMenuData.suggestedFileName()); break; case CopyImageToClipboard: - if (d->contextMenuData.d->hasImageContent && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeImage || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeCanvas)) + if (d->m_contextMenuData.hasImageContent() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeImage || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas)) { - d->adapter->copyImageAt(d->contextMenuData.position()); + d->adapter->copyImageAt(d->m_contextMenuData.position()); } break; case CopyImageUrlToClipboard: - if (d->contextMenuData.mediaUrl().isValid() && d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeImage) { - QString urlString = d->contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); - QString title = d->contextMenuData.linkText(); + if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeImage) { + QString urlString = d->m_contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); + QString title = d->m_contextMenuData.linkText(); if (!title.isEmpty()) title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral(""); data->setHtml(html); - data->setUrls(QList() << d->contextMenuData.mediaUrl()); + data->setUrls(QList() << d->m_contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadImageToDisk: case DownloadMediaToDisk: - if (d->contextMenuData.mediaUrl().isValid()) - d->adapter->download(d->contextMenuData.mediaUrl(), d->contextMenuData.d->suggestedFileName); + if (d->m_contextMenuData.mediaUrl().isValid()) + d->adapter->download(d->m_contextMenuData.mediaUrl(), d->m_contextMenuData.suggestedFileName()); break; case CopyMediaUrlToClipboard: - if (d->contextMenuData.mediaUrl().isValid() && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) + if (d->m_contextMenuData.mediaUrl().isValid() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - QString urlString = d->contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); + QString urlString = d->m_contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); QMimeData *data = new QMimeData(); data->setText(urlString); - if (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio) + if (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio) data->setHtml(QStringLiteral("")); else data->setHtml(QStringLiteral("")); - data->setUrls(QList() << d->contextMenuData.mediaUrl()); + data->setUrls(QList() << d->m_contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case ToggleMediaControls: - if (d->contextMenuData.mediaUrl().isValid() && d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { - bool enable = !(d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaControls); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerControls, enable); + if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { + bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaControls); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerControls, enable); } break; case ToggleMediaLoop: - if (d->contextMenuData.mediaUrl().isValid() && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) + if (d->m_contextMenuData.mediaUrl().isValid() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = !(d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaLoop); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); + bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaLoop); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); } break; case ToggleMediaPlayPause: - if (d->contextMenuData.mediaUrl().isValid() && - (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) + if (d->m_contextMenuData.mediaUrl().isValid() && + (d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + d->m_contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = (d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaPaused); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); + bool enable = (d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaPaused); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); } break; case ToggleMediaMute: - if (d->contextMenuData.mediaUrl().isValid() && d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaHasAudio) { - bool enable = !(d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaMuted); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerMute, enable); + if (d->m_contextMenuData.mediaUrl().isValid() && d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { + bool enable = !(d->m_contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaMuted); + d->adapter->executeMediaPlayerActionAt(d->m_contextMenuData.position(), WebContentsAdapter::MediaPlayerMute, enable); } break; case InspectElement: - d->adapter->inspectElementAt(d->contextMenuData.position()); + d->adapter->inspectElementAt(d->m_contextMenuData.position()); break; case ExitFullScreen: d->adapter->exitFullScreen(); @@ -1733,12 +1741,6 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) } } -const QQuickWebEngineContextMenuData *QQuickWebEngineViewExperimental::contextMenuData() const -{ - Q_D(const QQuickWebEngineView); - return &d->contextMenuData; -} - QSizeF QQuickWebEngineView::contentsSize() const { Q_D(const QQuickWebEngineView); diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 99d0848ce..1d44a48dd 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -62,7 +62,7 @@ class QQmlWebChannel; class QQuickWebEngineAuthenticationDialogRequest; class QQuickWebEngineCertificateError; class QQuickWebEngineColorDialogRequest; -class QQuickWebEngineContextMenuData; +class QQuickWebEngineContextMenuRequest; class QQuickWebEngineFaviconProvider; class QQuickWebEngineFileDialogRequest; class QQuickWebEngineHistory; @@ -511,7 +511,7 @@ Q_SIGNALS: Q_REVISION(3) void audioMutedChanged(bool muted); Q_REVISION(3) void recentlyAudibleChanged(bool recentlyAudible); Q_REVISION(3) void webChannelWorldChanged(uint); - + Q_REVISION(4) void contextMenuRequested(QQuickWebEngineContextMenuRequest *request); Q_REVISION(4) void authenticationDialogRequested(QQuickWebEngineAuthenticationDialogRequest *request); Q_REVISION(4) void javaScriptDialogRequested(QQuickWebEngineJavaScriptDialogRequest *request); Q_REVISION(4) void colorDialogRequested(QQuickWebEngineColorDialogRequest *request); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 3ba1f8ae1..c6ff18373 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -52,7 +52,6 @@ // #include "qquickwebengineview_p.h" -#include "qquickwebenginecontextmenudata_p.h" #include "web_contents_adapter_client.h" #include @@ -70,6 +69,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineView; class QQmlComponent; class QQmlContext; +class QQuickWebEngineContextMenuRequest; class QQuickWebEngineSettings; class QQuickWebEngineFaviconProvider; @@ -101,17 +101,13 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineViewExperimental : public QObjec Q_OBJECT Q_PROPERTY(QQuickWebEngineViewport *viewport READ viewport) Q_PROPERTY(QQmlComponent *extraContextMenuEntriesComponent READ extraContextMenuEntriesComponent WRITE setExtraContextMenuEntriesComponent NOTIFY extraContextMenuEntriesComponentChanged) - Q_PROPERTY(const QQuickWebEngineContextMenuData *contextMenuData READ contextMenuData NOTIFY contextMenuDataChanged) QQuickWebEngineViewport *viewport() const; void setExtraContextMenuEntriesComponent(QQmlComponent *); QQmlComponent *extraContextMenuEntriesComponent() const; - const QQuickWebEngineContextMenuData *contextMenuData() const; - Q_SIGNALS: void extraContextMenuEntriesComponentChanged(); - void contextMenuDataChanged(); private: QQuickWebEngineViewExperimental(QQuickWebEngineViewPrivate* viewPrivate); @@ -221,7 +217,7 @@ public: QQuickWebEngineTestSupport *m_testSupport; #endif QQmlComponent *contextMenuExtraItems; - QQuickWebEngineContextMenuData contextMenuData; + QtWebEngineCore::WebEngineContextMenuData m_contextMenuData; QUrl explicitUrl; QUrl iconUrl; QQuickWebEngineFaviconProvider *faviconProvider; diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index eaf7936d2..4acf3eb55 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -1231,3 +1231,16 @@ \note Signal handlers need to call \c{request.accepted = true} to prevent a default dialog from showing up. */ + +/*! + \qmlsignal WebEngineView::contextMenuRequested(ContextMenuRequest request) + \since QtWebEngine 1.4 + + This signal is emitted when a context menu is requested. + + The request can be handled by using the properties of the ContextMenuRequest + type. + + \note Signal handlers need to call \c{request.accepted = true} to prevent a + default context menu from showing up. +*/ diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp index d4f68d142..23a81d79d 100644 --- a/src/webengine/plugin/experimental/plugin.cpp +++ b/src/webengine/plugin/experimental/plugin.cpp @@ -41,7 +41,6 @@ #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" -#include "qquickwebenginecontextmenudata_p.h" QT_BEGIN_NAMESPACE @@ -70,10 +69,6 @@ public: tr("Cannot create a separate instance of WebEngineViewExperimental")); qmlRegisterUncreatableType(uri, 1, 0, "WebEngineViewport", tr("Cannot create a separate instance of WebEngineViewport")); - qmlRegisterUncreatableType(uri, 1, 0, "WebEngineContextMenuData", - tr("Cannot create a separate instance of WebEngineContextMenuData")); - qmlRegisterUncreatableType(uri, 1, 1, "WebEngineContextMenuData", - tr("Cannot create a separate instance of WebEngineContextMenuData")); // Use the latest revision of QQuickWebEngineView when importing QtWebEngine.experimental 1.0 qmlRegisterRevision(uri, 1, 1); } diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index 0bf2e3d8e..d3f3712b4 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -41,6 +41,7 @@ #include #include "qquickwebenginecertificateerror_p.h" +#include "qquickwebenginecontextmenurequest_p.h" #include "qquickwebenginedialogrequests_p.h" #include "qquickwebenginedownloaditem_p.h" #include "qquickwebenginehistory_p.h" @@ -110,6 +111,8 @@ public: qmlRegisterUncreatableType(uri, 1, 1, "FullScreenRequest", tr("Cannot create a separate instance of FullScreenRequest")); + qmlRegisterUncreatableType(uri, 1, 4, "ContextMenuRequest", + tr("Cannot create separate instance of ContextMenuRequest")); qmlRegisterUncreatableType(uri, 1, 4, "AuthenticationDialogRequest", tr("Cannot create separate instance of AuthenticationDialogRequest")); qmlRegisterUncreatableType(uri, 1, 4, "JavaScriptDialogRequest", diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 1b361d6ae..e84188682 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -12,7 +12,7 @@ INCLUDEPATH += $$PWD api ../core ../core/api SOURCES = \ api/qquickwebenginecertificateerror.cpp \ - api/qquickwebenginecontextmenudata.cpp \ + api/qquickwebenginecontextmenurequest.cpp \ api/qquickwebenginedialogrequests.cpp \ api/qquickwebenginedownloaditem.cpp \ api/qquickwebenginehistory.cpp \ @@ -34,7 +34,7 @@ HEADERS = \ api/qtwebengineglobal.h \ api/qtwebengineglobal_p.h \ api/qquickwebenginecertificateerror_p.h \ - api/qquickwebenginecontextmenudata_p.h \ + api/qquickwebenginecontextmenurequest_p.h \ api/qquickwebenginedialogrequests_p.h \ api/qquickwebenginedownloaditem_p.h \ api/qquickwebenginedownloaditem_p_p.h \ diff --git a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp index 808c6f8b0..23be32bf6 100644 --- a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp +++ b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp @@ -135,7 +135,7 @@ void QWebEngineContextMenuData::reset() */ QPoint QWebEngineContextMenuData::position() const { - return d ? d->pos : QPoint(); + return d ? d->position() : QPoint(); } /*! @@ -143,7 +143,7 @@ QPoint QWebEngineContextMenuData::position() const */ QString QWebEngineContextMenuData::linkText() const { - return d ? d->linkText : QString(); + return d ? d->linkText() : QString(); } /*! @@ -151,7 +151,7 @@ QString QWebEngineContextMenuData::linkText() const */ QUrl QWebEngineContextMenuData::linkUrl() const { - return d ? d->linkUrl : QUrl(); + return d ? d->linkUrl() : QUrl(); } /*! @@ -159,7 +159,7 @@ QUrl QWebEngineContextMenuData::linkUrl() const */ QString QWebEngineContextMenuData::selectedText() const { - return d ? d->selectedText : QString(); + return d ? d->selectedText() : QString(); } /*! @@ -167,7 +167,7 @@ QString QWebEngineContextMenuData::selectedText() const */ QUrl QWebEngineContextMenuData::mediaUrl() const { - return d ? d->mediaUrl : QUrl(); + return d ? d->mediaUrl() : QUrl(); } /*! @@ -175,7 +175,7 @@ QUrl QWebEngineContextMenuData::mediaUrl() const */ QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() const { - return d ? static_cast(d->mediaType) : MediaTypeNone; + return d ? static_cast(d->mediaType()) : MediaTypeNone; } /*! @@ -183,7 +183,7 @@ QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() cons */ bool QWebEngineContextMenuData::isContentEditable() const { - return d ? d->isEditable : false; + return d ? d->isEditable() : false; } /*! @@ -194,7 +194,7 @@ bool QWebEngineContextMenuData::isContentEditable() const QString QWebEngineContextMenuData::misspelledWord() const { if (d) - return d->misspelledWord; + return d->misspelledWord(); return QString(); } @@ -206,7 +206,7 @@ QString QWebEngineContextMenuData::misspelledWord() const QStringList QWebEngineContextMenuData::spellCheckerSuggestions() const { if (d) - return d->spellCheckerSuggestions; + return d->spellCheckerSuggestions(); return QStringList(); } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index ae933f01b..37c156e17 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -1056,122 +1056,122 @@ void QWebEnginePage::triggerAction(WebAction action, bool) d->adapter->unselect(); break; case OpenLinkInThisWindow: - if (menuData.linkUrl.isValid()) - setUrl(menuData.linkUrl); + if (menuData.linkUrl().isValid()) + setUrl(menuData.linkUrl()); break; case OpenLinkInNewWindow: - if (menuData.linkUrl.isValid()) { + if (menuData.linkUrl().isValid()) { QWebEnginePage *newPage = createWindow(WebBrowserWindow); if (newPage) - newPage->setUrl(menuData.linkUrl); + newPage->setUrl(menuData.linkUrl()); } break; case OpenLinkInNewTab: - if (menuData.linkUrl.isValid()) { + if (menuData.linkUrl().isValid()) { QWebEnginePage *newPage = createWindow(WebBrowserTab); if (newPage) - newPage->setUrl(menuData.linkUrl); + newPage->setUrl(menuData.linkUrl()); } break; case OpenLinkInNewBackgroundTab: - if (menuData.linkUrl.isValid()) { + if (menuData.linkUrl().isValid()) { QWebEnginePage *newPage = createWindow(WebBrowserBackgroundTab); if (newPage) - newPage->setUrl(menuData.linkUrl); + newPage->setUrl(menuData.linkUrl()); } break; case CopyLinkToClipboard: - if (menuData.linkUrl.isValid()) { - QString urlString = menuData.linkUrl.toString(QUrl::FullyEncoded); - QString title = menuData.linkText.toHtmlEscaped(); + if (menuData.linkUrl().isValid()) { + QString urlString = menuData.linkUrl().toString(QUrl::FullyEncoded); + QString title = menuData.linkText().toHtmlEscaped(); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral("") + title + QStringLiteral(""); data->setHtml(html); - data->setUrls(QList() << menuData.linkUrl); + data->setUrls(QList() << menuData.linkUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadLinkToDisk: - if (menuData.linkUrl.isValid()) - d->adapter->download(menuData.linkUrl, menuData.suggestedFileName); + if (menuData.linkUrl().isValid()) + d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName()); break; case CopyImageToClipboard: - if (menuData.hasImageContent && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeImage || - menuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas)) + if (menuData.hasImageContent() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas)) { - d->adapter->copyImageAt(menuData.pos); + d->adapter->copyImageAt(menuData.position()); } break; case CopyImageUrlToClipboard: - if (menuData.mediaUrl.isValid() && menuData.mediaType == WebEngineContextMenuData::MediaTypeImage) { - QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded); - QString title = menuData.linkText; + if (menuData.mediaUrl().isValid() && menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage) { + QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded); + QString title = menuData.linkText(); if (!title.isEmpty()) title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral(""); data->setHtml(html); - data->setUrls(QList() << menuData.mediaUrl); + data->setUrls(QList() << menuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadImageToDisk: case DownloadMediaToDisk: - if (menuData.mediaUrl.isValid()) - d->adapter->download(menuData.mediaUrl, menuData.suggestedFileName); + if (menuData.mediaUrl().isValid()) + d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName()); break; case CopyMediaUrlToClipboard: - if (menuData.mediaUrl.isValid() && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (menuData.mediaUrl().isValid() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded); + QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded); QMimeData *data = new QMimeData(); data->setText(urlString); - if (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio) + if (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio) data->setHtml(QStringLiteral("")); else data->setHtml(QStringLiteral("")); - data->setUrls(QList() << menuData.mediaUrl); + data->setUrls(QList() << menuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case ToggleMediaControls: - if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { - bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaControls); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerControls, enable); + if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { + bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaControls); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerControls, enable); } break; case ToggleMediaLoop: - if (menuData.mediaUrl.isValid() && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (menuData.mediaUrl().isValid() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaLoop); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerLoop, enable); + bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaLoop); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); } break; case ToggleMediaPlayPause: - if (menuData.mediaUrl.isValid() && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (menuData.mediaUrl().isValid() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = (menuData.mediaFlags & WebEngineContextMenuData::MediaPaused); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerPlay, enable); + bool enable = (menuData.mediaFlags() & WebEngineContextMenuData::MediaPaused); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); } break; case ToggleMediaMute: - if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { // Make sure to negate the value, so that toggling actually works. - bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaMuted); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerMute, enable); + bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaMuted); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerMute, enable); } break; case InspectElement: - d->adapter->inspectElementAt(menuData.pos); + d->adapter->inspectElementAt(menuData.position()); break; case ExitFullScreen: d->adapter->exitFullScreen(); @@ -1253,7 +1253,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData return false; contextData.reset(); - QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos)); + QContextMenuEvent event(QContextMenuEvent::Mouse, data.position(), view->mapToGlobal(data.position())); switch (view->contextMenuPolicy()) { case Qt::PreventContextMenu: return false; @@ -1263,7 +1263,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData break; case Qt::CustomContextMenu: contextData = data; - Q_EMIT view->customContextMenuRequested(data.pos); + Q_EMIT view->customContextMenuRequested(data.position()); break; case Qt::ActionsContextMenu: if (view->actions().count()) { @@ -1418,11 +1418,11 @@ QMenu *QWebEnginePage::createStandardContextMenu() QAction *action = 0; const WebEngineContextMenuData &contextMenuData = *d->contextData.d; - if (contextMenuData.isEditable && !contextMenuData.spellCheckerSuggestions.isEmpty()) { + if (contextMenuData.isEditable() && !contextMenuData.spellCheckerSuggestions().isEmpty()) { QPointer thisRef(this); - for (int i=0; i < contextMenuData.spellCheckerSuggestions.count() && i < 4; i++) { + for (int i=0; i < contextMenuData.spellCheckerSuggestions().count() && i < 4; i++) { QAction *action = new QAction(menu); - QString replacement = contextMenuData.spellCheckerSuggestions.at(i); + QString replacement = contextMenuData.spellCheckerSuggestions().at(i); QObject::connect(action, &QAction::triggered, [thisRef, replacement] { if (thisRef) thisRef->replaceMisspelledWord(replacement); }); action->setText(replacement); menu->addAction(action); @@ -1430,13 +1430,13 @@ QMenu *QWebEnginePage::createStandardContextMenu() menu->addSeparator(); } - if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) { + if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) { action = QWebEnginePage::action(OpenLinkInThisWindow); action->setText(tr("Follow Link")); menu->addAction(action); menu->addAction(QWebEnginePage::action(DownloadLinkToDisk)); } - if (contextMenuData.selectedText.isEmpty()) { + if (contextMenuData.selectedText().isEmpty()) { action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu); connect(action, &QAction::triggered, d->view, &QWebEngineView::back); action->setEnabled(d->adapter->canGoBack()); @@ -1457,11 +1457,11 @@ QMenu *QWebEnginePage::createStandardContextMenu() menu->addAction(QWebEnginePage::action(Unselect)); } - if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) { + if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) { menu->addAction(QWebEnginePage::action(CopyLinkToClipboard)); } - if (contextMenuData.mediaUrl.isValid()) { - switch (contextMenuData.mediaType) { + if (contextMenuData.mediaUrl().isValid()) { + switch (contextMenuData.mediaType()) { case WebEngineContextMenuData::MediaTypeImage: menu->addAction(QWebEnginePage::action(DownloadImageToDisk)); menu->addAction(QWebEnginePage::action(CopyImageUrlToClipboard)); @@ -1476,15 +1476,15 @@ QMenu *QWebEnginePage::createStandardContextMenu() menu->addAction(QWebEnginePage::action(CopyMediaUrlToClipboard)); menu->addAction(QWebEnginePage::action(ToggleMediaPlayPause)); menu->addAction(QWebEnginePage::action(ToggleMediaLoop)); - if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) + if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) menu->addAction(QWebEnginePage::action(ToggleMediaMute)); - if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) + if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) menu->addAction(QWebEnginePage::action(ToggleMediaControls)); break; default: break; } - } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) { + } else if (contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) { menu->addAction(QWebEnginePage::action(CopyImageToClipboard)); } diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index 92a96273c..f9fd854cc 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -45,6 +45,7 @@ #include #include #include +#include class tst_publicapi : public QObject { Q_OBJECT @@ -71,6 +72,7 @@ static QList typesToCheck = QList() << &QQuickWebEngineColorDialogRequest::staticMetaObject << &QQuickWebEngineFileDialogRequest::staticMetaObject << &QQuickWebEngineFormValidationMessageRequest::staticMetaObject + << &QQuickWebEngineContextMenuRequest::staticMetaObject ; static QList knownEnumNames = QList(); -- cgit v1.2.3