diff options
author | Michal Klocek <michal.klocek@theqtcompany.com> | 2016-06-13 13:29:51 +0200 |
---|---|---|
committer | Kai Koehne <kai.koehne@qt.io> | 2016-08-31 09:11:53 +0000 |
commit | 3f73e47130f3912f99376314a06a2033225b0dda (patch) | |
tree | 29a554b1299a1efe45032729303c047e368476f0 /src/webengine/api | |
parent | 3cbe59e29a2702a2c184be10845b9bdd342c24d0 (diff) |
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 <kai.koehne@qt.io>
Diffstat (limited to 'src/webengine/api')
-rw-r--r-- | src/webengine/api/qquickwebenginecontextmenudata.cpp | 243 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginecontextmenurequest.cpp | 274 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginecontextmenurequest_p.h (renamed from src/webengine/api/qquickwebenginecontextmenudata_p.h) | 78 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 144 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p.h | 4 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p_p.h | 8 |
6 files changed, 378 insertions, 373 deletions
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<QQuickWebEngineContextMenuData::MediaType>(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/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<QQuickWebEngineContextMenuRequest::MediaType>(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/qquickwebenginecontextmenudata_p.h b/src/webengine/api/qquickwebenginecontextmenurequest_p.h index 7175838db..3d2de14a2 100644 --- a/src/webengine/api/qquickwebenginecontextmenudata_p.h +++ b/src/webengine/api/qquickwebenginecontextmenurequest_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QQUICKWEBENGINECONTEXTMENUDATA_P_H -#define QQUICKWEBENGINECONTEXTMENUDATA_P_H +#ifndef QQUICKWEBENGINECONTEXTMENUREQUEST_H +#define QQUICKWEBENGINECONTEXTMENUREQUEST_H // // W A R N I N G @@ -49,30 +49,21 @@ // version without notice, or even be removed. // // We mean it. -// #include <private/qtwebengineglobal_p.h> +#include <QtCore/QScopedPointer> #include <QtCore/QObject> -#include <QtCore/QPoint> -#include <QtCore/QString> #include <QtCore/QUrl> -#include <QtQuick/QQuickItem> namespace QtWebEngineCore { -class WebEngineContextMenuData; + class WebEngineContextMenuData; } QT_BEGIN_NAMESPACE -class QQuickWebEngineView; -class QQuickWebEngineViewPrivate; - -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineContextMenuData : public QObject { +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineContextMenuRequest: public QObject { Q_OBJECT public: - QQuickWebEngineContextMenuData(); - ~QQuickWebEngineContextMenuData(); - enum MediaType { MediaTypeNone, MediaTypeImage, @@ -84,56 +75,41 @@ public: }; 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; + 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; - -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(); + bool isAccepted() const; + void setAccepted(bool accepted); private: - void update(const QtWebEngineCore::WebEngineContextMenuData &update); - + QQuickWebEngineContextMenuRequest(const QtWebEngineCore::WebEngineContextMenuData &data, QObject *parent = nullptr); + QScopedPointer<QtWebEngineCore::WebEngineContextMenuData> m_data; + bool m_accepted; 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; + Q_DISABLE_COPY(QQuickWebEngineContextMenuRequest) }; QT_END_NAMESPACE -QML_DECLARE_TYPE(const QQuickWebEngineContextMenuData); - -#endif // QQUICKWEBENGINECONTEXTMENUDATA_P_H +#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<QQuickWebEngineView> 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("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>"); data->setHtml(html); - data->setUrls(QList<QUrl>() << d->contextMenuData.linkUrl()); + data->setUrls(QList<QUrl>() << 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("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>"); data->setHtml(html); - data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl()); + data->setUrls(QList<QUrl>() << 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("<audio src=\"") + urlString + QStringLiteral("\"></audio>")); else data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>")); - data->setUrls(QList<QUrl>() << d->contextMenuData.mediaUrl()); + data->setUrls(QList<QUrl>() << 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 <QScopedPointer> @@ -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; |