diff options
Diffstat (limited to 'src/webengine')
-rw-r--r-- | src/webengine/api/qquickwebengineaction.cpp | 172 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineaction_p.h | 108 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineaction_p_p.h | 86 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 282 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p.h | 2 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p_p.h | 2 | ||||
-rw-r--r-- | src/webengine/doc/src/webengineview_lgpl.qdoc | 15 | ||||
-rw-r--r-- | src/webengine/plugin/plugin.cpp | 4 | ||||
-rw-r--r-- | src/webengine/plugin/plugins.qmltypes | 38 | ||||
-rw-r--r-- | src/webengine/ui_delegates_manager.cpp | 35 | ||||
-rw-r--r-- | src/webengine/ui_delegates_manager.h | 18 | ||||
-rw-r--r-- | src/webengine/webengine.pro | 3 |
12 files changed, 678 insertions, 87 deletions
diff --git a/src/webengine/api/qquickwebengineaction.cpp b/src/webengine/api/qquickwebengineaction.cpp new file mode 100644 index 000000000..ce2fe6357 --- /dev/null +++ b/src/webengine/api/qquickwebengineaction.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 "qquickwebengineaction_p.h" +#include "qquickwebengineaction_p_p.h" +#include "qquickwebengineview_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \qmltype WebEngineAction + \instantiates QQuickWebEngineAction + \inqmlmodule QtWebEngine + \since QtWebEngine 1.8 + + \brief An action that represents a \l WebEngineView::WebAction + + A WebEngineAction is returned by the \l WebEngineView::action() + method. It provides information about the action, such as + whether it is \l enabled. + + The following code uses the \l WebEngineView::action() method to check if the + the copy action is enabled: + + \code + var copyAction = webEngineView.action(WebEngineView.Copy); + if (copyAction.enabled) + console.log("Copy is enabled."); + else + console.log("Copy is disabled."); + \endcode +*/ + +QQuickWebEngineActionPrivate::QQuickWebEngineActionPrivate(const QVariant &data, const QString &text, const QString &iconText, bool enabled) + : m_data(data) + , m_text(text) + , m_iconText(iconText) + , m_enabled(enabled) +{ +} + +QQuickWebEngineActionPrivate::~QQuickWebEngineActionPrivate() +{ +} + +void QQuickWebEngineActionPrivate::setEnabled(bool enabled) +{ + Q_Q(QQuickWebEngineAction); + if (m_enabled == enabled) + return; + m_enabled = enabled; + emit q->enabledChanged(enabled); +} + +QVariant QQuickWebEngineActionPrivate::data() const +{ + return m_data; +} + +void QQuickWebEngineActionPrivate::trigger() +{ + Q_Q(QQuickWebEngineAction); + if (QQuickWebEngineView *view = static_cast<QQuickWebEngineView*>(q->parent())) { + view->triggerWebAction(static_cast<QQuickWebEngineView::WebAction>(data().toInt())); + } +} + +QQuickWebEngineAction::QQuickWebEngineAction(const QVariant &data, const QString &text, const QString &iconText, bool enabled, QObject *parent) + : QObject(parent) + , d_ptr(new QQuickWebEngineActionPrivate(data, text, iconText, enabled)) +{ + d_ptr->q_ptr = this; +} + +QQuickWebEngineAction::QQuickWebEngineAction(QObject *parent) + : QObject(parent) + , d_ptr(new QQuickWebEngineActionPrivate(-1, QStringLiteral(""), QStringLiteral(""), false)) +{ + d_ptr->q_ptr = this; +} + +QQuickWebEngineAction::~QQuickWebEngineAction() +{ +} + +/*! + \qmlproperty int WebEngineAction::text + + This property holds a textual description of the action. +*/ +QString QQuickWebEngineAction::text() const +{ + Q_D(const QQuickWebEngineAction); + return d->m_text; +} + +/*! + \qmlproperty string WebEngineAction::iconText + + This property holds the action's descriptive icon text +*/ +QString QQuickWebEngineAction::iconText() const +{ + Q_D(const QQuickWebEngineAction); + return d->m_iconText; +} + +/*! + \qmlproperty bool WebEngineAction::enabled + + This property holds whether the action is enabled. +*/ +bool QQuickWebEngineAction::isEnabled() const +{ + Q_D(const QQuickWebEngineAction); + return d->m_enabled; +} + +/*! + \qmlmethod void WebEngineAction::trigger() + + Triggers the action. +*/ +void QQuickWebEngineAction::trigger() +{ + Q_D(QQuickWebEngineAction); + if (!isEnabled()) + return; + + d->trigger(); + emit triggered(); +} + +QT_END_NAMESPACE + diff --git a/src/webengine/api/qquickwebengineaction_p.h b/src/webengine/api/qquickwebengineaction_p.h new file mode 100644 index 000000000..5296f9dd6 --- /dev/null +++ b/src/webengine/api/qquickwebengineaction_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 QQUICKWEBENGINEACTION_P_H +#define QQUICKWEBENGINEACTION_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 <QObject> +#include <QtQml/qqml.h> +#include "qtwebengineglobal_p.h" +#include <QVariant> + +namespace QtWebEngineCore { + class UIDelegatesManager; + class UI2DelegatesManager; +} + +QT_BEGIN_NAMESPACE + +class QQuickWebEngineActionPrivate; + +class Q_WEBENGINE_EXPORT QQuickWebEngineAction : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString text READ text CONSTANT FINAL) + Q_PROPERTY(QString iconText READ iconText CONSTANT FINAL) + Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged FINAL) + +public: + QQuickWebEngineAction(const QVariant &data, const QString &text, const QString &iconText, bool enabled, QObject *parent); + QQuickWebEngineAction(QObject *parent); + ~QQuickWebEngineAction(); + + QString text() const; + QString iconText() const; + bool isEnabled() const; + +public Q_SLOTS: + Q_INVOKABLE void trigger(); + +Q_SIGNALS: + void toggled(); + void triggered(); + void enabledChanged(const bool enabled); + +private: + Q_DECLARE_PRIVATE(QQuickWebEngineAction) + friend class QQuickWebEngineView; + friend class QQuickWebEngineViewPrivate; + friend class QtWebEngineCore::UIDelegatesManager; + friend class QtWebEngineCore::UI2DelegatesManager; + friend class QQuickContextMenuBuilder; + + QScopedPointer<QQuickWebEngineActionPrivate> d_ptr; +}; + + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickWebEngineAction) + +#endif // QQUICKWEBENGINEACTION_P_H diff --git a/src/webengine/api/qquickwebengineaction_p_p.h b/src/webengine/api/qquickwebengineaction_p_p.h new file mode 100644 index 000000000..cb1817e55 --- /dev/null +++ b/src/webengine/api/qquickwebengineaction_p_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 QQUICKWEBENGINEACTION_P_P_H +#define QQUICKWEBENGINEACTION_P_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 <QObject> +#include "qtwebengineglobal_p.h" +#include <QVariant> + +QT_BEGIN_NAMESPACE + +class QQuickWebEngineAction; + +class QQuickWebEngineActionPrivate +{ +public: + Q_DECLARE_PUBLIC(QQuickWebEngineAction) + QQuickWebEngineActionPrivate(const QVariant &data, const QString &text, const QString &iconText, bool enabled); + ~QQuickWebEngineActionPrivate(); + + void setEnabled(bool enabled); + + QVariant data() const; + + void trigger(); + +private: + QQuickWebEngineAction *q_ptr; + + QVariant m_data; + QString m_text; + QString m_iconText; + bool m_enabled; +}; + +QT_END_NAMESPACE + +#endif // QQUICKWEBENGINEACTION_P_P_H diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 9c999e290..aaa8d58c5 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -45,6 +45,9 @@ #include "certificate_error_controller.h" #include "file_picker_controller.h" #include "javascript_dialog_controller.h" + +#include "qquickwebengineaction_p.h" +#include "qquickwebengineaction_p_p.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginecertificateerror_p.h" #include "qquickwebenginecontextmenurequest_p.h" @@ -126,6 +129,7 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_ui2Enabled(false) { m_profile->d_ptr->addWebContentsAdapterClient(this); + memset(actions, 0, sizeof(actions)); QString platform = qApp->platformName().toLower(); if (platform == QLatin1Literal("eglfs")) m_ui2Enabled = true; @@ -803,6 +807,39 @@ void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen) } } +void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction action) const +{ + QQuickWebEngineAction *a = actions[action]; + if (!a) + return; + + bool enabled = true; + + switch (action) { + case QQuickWebEngineView::Back: + enabled = adapter->canGoBack(); + break; + case QQuickWebEngineView::Forward: + enabled = adapter->canGoForward(); + break; + case QQuickWebEngineView::Stop: + enabled = isLoading; + break; + case QQuickWebEngineView::Reload: + case QQuickWebEngineView::ReloadAndBypassCache: + enabled = !isLoading; + break; + case QQuickWebEngineView::ViewSource: + enabled = adapter->canViewSource(); + break; + default: + break; + } + + a->d_ptr->setEnabled(enabled); +} + + QUrl QQuickWebEngineView::url() const { Q_D(const QQuickWebEngineView); @@ -1650,6 +1687,170 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) } } +QQuickWebEngineAction *QQuickWebEngineView::action(WebAction action) +{ + Q_D(QQuickWebEngineView); + if (action == QQuickWebEngineView::NoWebAction) + return nullptr; + if (d->actions[action]) { + d->updateAction(action); + return d->actions[action]; + } + + QString text; + QString iconText; + + switch (action) { + case Back: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Back); + iconText = QStringLiteral("go-previous"); + break; + case Forward: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Forward); + iconText = QStringLiteral("go-next"); + break; + case Stop: + text = tr("Stop"); + break; + case Reload: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Reload); + iconText = QStringLiteral("view-refresh"); + break; + case ReloadAndBypassCache: + text = tr("Reload and Bypass Cache"); + break; + case Cut: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Cut); + iconText = QStringLiteral("Cut"); + break; + case Copy: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Copy); + break; + case Paste: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Paste); + break; + case Undo: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Undo); + break; + case Redo: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::Redo); + break; + case SelectAll: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SelectAll); + break; + case PasteAndMatchStyle: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::PasteAndMatchStyle); + break; + case OpenLinkInThisWindow: + text = tr("Open link in this window"); + break; + case OpenLinkInNewWindow: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewWindow); + break; + case OpenLinkInNewTab: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::OpenLinkInNewTab); + break; + case CopyLinkToClipboard: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyLinkToClipboard); + break; + case DownloadLinkToDisk: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadLinkToDisk); + break; + case CopyImageToClipboard: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageToClipboard); + break; + case CopyImageUrlToClipboard: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyImageUrlToClipboard); + break; + case DownloadImageToDisk: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadImageToDisk); + break; + case CopyMediaUrlToClipboard: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::CopyMediaUrlToClipboard); + break; + case ToggleMediaControls: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaControls); + break; + case ToggleMediaLoop: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ToggleMediaLoop); + break; + case ToggleMediaPlayPause: + text = tr("Toggle Play/Pause"); + break; + case ToggleMediaMute: + text = tr("Toggle Mute"); + break; + case DownloadMediaToDisk: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::DownloadMediaToDisk); + break; + case InspectElement: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::InspectElement); + break; + case ExitFullScreen: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ExitFullScreen); + break; + case RequestClose: + text = tr("Close Page"); + break; + case Unselect: + text = tr("Unselect"); + break; + case SavePage: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::SavePage); + break; + case ViewSource: + text = RenderViewContextMenuQt::getMenuItemName(RenderViewContextMenuQt::ContextMenuItem::ViewSource); + iconText = QStringLiteral("view-source"); + break; + case ToggleBold: + text = tr("&Bold"); + break; + case ToggleItalic: + text = tr("&Italic"); + break; + case ToggleUnderline: + text = tr("&Underline"); + break; + case ToggleStrikethrough: + text = tr("&Strikethrough"); + break; + case AlignLeft: + text = tr("Align &Left"); + break; + case AlignCenter: + text = tr("Align &Center"); + break; + case AlignRight: + text = tr("Align &Right"); + break; + case AlignJustified: + text = tr("Align &Justified"); + break; + case Indent: + text = tr("&Indent"); + break; + case Outdent: + text = tr("&Outdent"); + break; + case InsertOrderedList: + text = tr("Insert &Ordered List"); + break; + case InsertUnorderedList: + text = tr("Insert &Unordered List"); + break; + case NoWebAction: + case WebActionCount: + Q_UNREACHABLE(); + break; + } + + QQuickWebEngineAction *retVal = new QQuickWebEngineAction(action, text, iconText, false, this); + + d->actions[action] = retVal; + d->updateAction(action); + return retVal; +} + QSizeF QQuickWebEngineView::contentsSize() const { Q_D(const QQuickWebEngineView); @@ -1778,112 +1979,101 @@ bool QQuickContextMenuBuilder::isFullScreenMode() void QQuickContextMenuBuilder::addMenuItem(ContextMenuItem menuItem) { - MenuItemHandler *item = new MenuItemHandler(m_menu); - QString menuItemIcon; - QPointer<QQuickWebEngineView> thisRef(m_view); + QQuickWebEngineAction *action = nullptr; switch (menuItem) { case ContextMenuItem::Back: - QObject::connect(item, &MenuItemHandler::triggered, thisRef, &QQuickWebEngineView::goBack); - menuItemIcon = QStringLiteral("go-previous"); + action = m_view->action(QQuickWebEngineView::Back); break; case ContextMenuItem::Forward: - QObject::connect(item, &MenuItemHandler::triggered, thisRef, &QQuickWebEngineView::goForward); - menuItemIcon = QStringLiteral("go-next"); + action = m_view->action(QQuickWebEngineView::Forward); break; case ContextMenuItem::Reload: - QObject::connect(item, &MenuItemHandler::triggered, thisRef, &QQuickWebEngineView::reload); - menuItemIcon = QStringLiteral("view-refresh"); + action = m_view->action(QQuickWebEngineView::Reload); break; case ContextMenuItem::Cut: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::Cut); }); - menuItemIcon = QStringLiteral("Cut"); + action = m_view->action(QQuickWebEngineView::Cut); break; case ContextMenuItem::Copy: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::Copy); }); - menuItemIcon = QStringLiteral("Copy"); + action = m_view->action(QQuickWebEngineView::Copy); break; - case ContextMenuItem::Paste: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::Paste); }); - menuItemIcon = QStringLiteral("Paste"); + action = m_view->action(QQuickWebEngineView::Paste); break; case ContextMenuItem::Undo: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::Undo); }); - menuItemIcon = QStringLiteral("Undo"); + action = m_view->action(QQuickWebEngineView::Undo); break; case ContextMenuItem::Redo: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::Redo); }); - menuItemIcon = QStringLiteral("Redo"); + action = m_view->action(QQuickWebEngineView::Redo); break; case ContextMenuItem::SelectAll: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::SelectAll); }); - menuItemIcon = QStringLiteral("Select All"); + action = m_view->action(QQuickWebEngineView::SelectAll); break; case ContextMenuItem::PasteAndMatchStyle: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::PasteAndMatchStyle); }); - menuItemIcon = QStringLiteral("Paste And Match Style"); + action = m_view->action(QQuickWebEngineView::PasteAndMatchStyle); break; case ContextMenuItem::OpenLinkInNewWindow: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::OpenLinkInNewWindow); }); + action = m_view->action(QQuickWebEngineView::OpenLinkInNewWindow); break; case ContextMenuItem::OpenLinkInNewTab: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::OpenLinkInNewTab); }); + action = m_view->action(QQuickWebEngineView::OpenLinkInNewTab); break; case ContextMenuItem::CopyLinkToClipboard: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); + action = m_view->action(QQuickWebEngineView::CopyLinkToClipboard); break; case ContextMenuItem::DownloadLinkToDisk: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); }); + action = m_view->action(QQuickWebEngineView::DownloadLinkToDisk); break; case ContextMenuItem::CopyImageToClipboard: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); + action = m_view->action(QQuickWebEngineView::CopyImageToClipboard); break; case ContextMenuItem::CopyImageUrlToClipboard: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); }); + action = m_view->action(QQuickWebEngineView::CopyImageUrlToClipboard); break; case ContextMenuItem::DownloadImageToDisk: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::DownloadImageToDisk); }); + action = m_view->action(QQuickWebEngineView::DownloadImageToDisk); break; case ContextMenuItem::CopyMediaUrlToClipboard: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::CopyMediaUrlToClipboard); }); + action = m_view->action(QQuickWebEngineView::CopyMediaUrlToClipboard); break; case ContextMenuItem::ToggleMediaControls: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::ToggleMediaControls); }); + action = m_view->action(QQuickWebEngineView::ToggleMediaControls); break; case ContextMenuItem::ToggleMediaLoop: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::ToggleMediaLoop); }); + action = m_view->action(QQuickWebEngineView::ToggleMediaLoop); break; case ContextMenuItem::DownloadMediaToDisk: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::DownloadMediaToDisk); }); + action = m_view->action(QQuickWebEngineView::DownloadMediaToDisk); break; case ContextMenuItem::InspectElement: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::InspectElement); }); + action = m_view->action(QQuickWebEngineView::InspectElement); break; case ContextMenuItem::ExitFullScreen: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::ExitFullScreen); }); + action = m_view->action(QQuickWebEngineView::ExitFullScreen); break; case ContextMenuItem::SavePage: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::SavePage); }); + action = m_view->action(QQuickWebEngineView::SavePage); break; case ContextMenuItem::ViewSource: - QObject::connect(item, &MenuItemHandler::triggered, [thisRef] { thisRef->triggerWebAction(QQuickWebEngineView::ViewSource); }); - menuItemIcon = QStringLiteral("view-source"); + action = m_view->action(QQuickWebEngineView::ViewSource); break; case ContextMenuItem::SpellingSuggestions: + { + QPointer<QQuickWebEngineView> thisRef(m_view); for (int i=0; i < m_contextData.spellCheckerSuggestions().count() && i < 4; i++) { - item = new MenuItemHandler(m_menu); + action = new QQuickWebEngineAction(m_menu); QString replacement = m_contextData.spellCheckerSuggestions().at(i); - QObject::connect(item, &MenuItemHandler::triggered, [thisRef, replacement] { thisRef->replaceMisspelledWord(replacement); }); - m_view->d_ptr->ui()->addMenuItem(item, replacement); + QObject::connect(action, &QQuickWebEngineAction::triggered, [thisRef, replacement] { thisRef->replaceMisspelledWord(replacement); }); + m_view->d_ptr->ui()->addMenuItem(action, m_menu); } return; + } case ContextMenuItem::Separator: - thisRef->d_ptr->ui()->addMenuSeparator(m_menu); + m_view->d_ptr->ui()->addMenuSeparator(m_menu); return; } - QString menuItemName = RenderViewContextMenuQt::getMenuItemName(menuItem); - thisRef->d_ptr->ui()->addMenuItem(item, menuItemName, menuItemIcon, isMenuItemEnabled(menuItem)); + action->d_ptr->setEnabled(isMenuItemEnabled(menuItem)); + m_view->d_ptr->ui()->addMenuItem(action, m_menu); } bool QQuickContextMenuBuilder::isMenuItemEnabled(ContextMenuItem menuItem) diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 0ca0c7886..d400fc75e 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -62,6 +62,7 @@ QT_BEGIN_NAMESPACE class QQmlWebChannel; class QQuickContextMenuBuilder; +class QQuickWebEngineAction; class QQuickWebEngineAuthenticationDialogRequest; class QQuickWebEngineCertificateError; class QQuickWebEngineColorDialogRequest; @@ -470,6 +471,7 @@ public: QQuickWebEngineHistory *navigationHistory() const; uint webChannelWorld() const; void setWebChannelWorld(uint); + Q_REVISION(8) Q_INVOKABLE QQuickWebEngineAction *action(WebAction action); bool isAudioMuted() const; void setAudioMuted(bool muted); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 062125e70..7f52c7216 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -155,6 +155,7 @@ public: QtWebEngineCore::ProfileAdapter *profileAdapter() override; QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override; + void updateAction(QQuickWebEngineView::WebAction) const; void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents); void setProfile(QQuickWebEngineProfile *profile); void ensureContentsAdapter(); @@ -191,6 +192,7 @@ public: QPointer<QQuickWebEngineView> devToolsView; uint m_webChannelWorld; bool m_isBeingAdopted; + mutable QQuickWebEngineAction *actions[QQuickWebEngineView::WebActionCount]; private: QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager; diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc index a6a7c088b..741dee2f7 100644 --- a/src/webengine/doc/src/webengineview_lgpl.qdoc +++ b/src/webengine/doc/src/webengineview_lgpl.qdoc @@ -1447,3 +1447,18 @@ \sa inspectedView */ + +/*! + \qmlmethod WebEngineAction WebEngineView::action(WebAction action) + \since 5.12 + + Returns a \l WebEngineAction for the specified \l WebAction action. + WebEngineView also takes care of implementing the action, + so that upon triggering the corresponding action is performed on the view. + + \code + var copyAction = webEngineView.action(WebEngineView.Copy); + \endcode + + \sa WebEngineAction +*/ diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index 545f17f82..76bee50be 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -52,6 +52,7 @@ #include "qquickwebenginesettings_p.h" #include "qquickwebenginesingleton_p.h" #include "qquickwebengineview_p.h" +#include "qquickwebengineaction_p.h" #include "qwebenginequotarequest.h" #include "qwebengineregisterprotocolhandlerrequest.h" #include "qtwebengineversion.h" @@ -89,6 +90,7 @@ public: qmlRegisterType<QQuickWebEngineView, 5>(uri, 1, 5, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 6>(uri, 1, 6, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 7>(uri, 1, 7, "WebEngineView"); + qmlRegisterType<QQuickWebEngineView, 8>(uri, 1, 8, "WebEngineView"); qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile"); @@ -148,7 +150,7 @@ public: qRegisterMetaType<QWebEngineRegisterProtocolHandlerRequest>(); qmlRegisterUncreatableType<QWebEngineRegisterProtocolHandlerRequest>(uri, 1, 7, "RegisterProtocolHandlerRequest", msgUncreatableType("RegisterProtocolHandlerRequest")); - + qmlRegisterUncreatableType<QQuickWebEngineAction>(uri, 1, 8, "WebEngineAction", msgUncreatableType("WebEngineAction")); } private: diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes index 5c61ee8d0..44c85bd8e 100644 --- a/src/webengine/plugin/plugins.qmltypes +++ b/src/webengine/plugin/plugins.qmltypes @@ -4,11 +4,36 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -defaultplatform -dependencies dependencies.json -nonrelocatable QtWebEngine 1.7' +// 'qmlplugindump -defaultplatform -dependencies dependencies.json -nonrelocatable QtWebEngine 1.8' Module { dependencies: ["QtQuick 2.8"] Component { + name: "QQuickWebEngineAction" + prototype: "QObject" + exports: ["QtWebEngine/WebEngineAction 1.8"] + isCreatable: false + exportMetaObjectRevisions: [0] + Property { name: "text"; type: "string"; isReadonly: true } + Property { name: "iconText"; type: "string"; isReadonly: true } + Property { name: "enabled"; type: "bool"; isReadonly: true } + Signal { name: "toggled" } + Signal { name: "triggered" } + Signal { + name: "textChanged" + Parameter { name: "text"; type: "string" } + } + Signal { + name: "iconTextChanged" + Parameter { name: "iconText"; type: "string" } + } + Signal { + name: "enabledChanged" + Parameter { name: "enabled"; type: "bool" } + } + Method { name: "trigger" } + } + Component { name: "QQuickWebEngineAuthenticationDialogRequest" prototype: "QObject" exports: ["QtWebEngine/AuthenticationDialogRequest 1.4"] @@ -640,9 +665,10 @@ Module { "QtWebEngine/WebEngineView 1.4", "QtWebEngine/WebEngineView 1.5", "QtWebEngine/WebEngineView 1.6", - "QtWebEngine/WebEngineView 1.7" + "QtWebEngine/WebEngineView 1.7", + "QtWebEngine/WebEngineView 1.8" ] - exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7] + exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7, 8] Enum { name: "NavigationRequestAction" values: { @@ -1224,6 +1250,12 @@ Module { revision: 4 Parameter { name: "replacement"; type: "string" } } + Method { + name: "action" + revision: 8 + type: "QQuickWebEngineAction*" + Parameter { name: "action"; type: "WebAction" } + } } Component { name: "QWebEngineQuotaRequest" diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 4570172d7..c35d26017 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -119,11 +119,6 @@ const char *defaultPropertyName(QObject *obj) return info.value(); } -MenuItemHandler::MenuItemHandler(QObject *parent) - : QObject(parent) -{ -} - #define COMPONENT_MEMBER_INIT(TYPE, COMPONENT) \ , COMPONENT##Component(0) @@ -212,26 +207,25 @@ bool UIDelegatesManager::ensureComponentLoaded(ComponentType type) if (!prop.isSignalProperty()) \ qWarning("%s is missing %s signal property.\n", qPrintable(location.toString()), qPrintable(prop.name())); -void UIDelegatesManager::addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, const QString &iconName, bool enabled, - bool checkable, bool checked) +void UIDelegatesManager::addMenuItem(QQuickWebEngineAction *action, QObject *menu, bool checkable, bool checked) { - Q_ASSERT(menuItemHandler); + Q_ASSERT(action); if (!ensureComponentLoaded(MenuItem)) return; QObject *it = menuItemComponent->beginCreate(qmlContext(m_view)); - QQmlProperty(it, QStringLiteral("text")).write(text); - QQmlProperty(it, QStringLiteral("iconName")).write(iconName); - QQmlProperty(it, QStringLiteral("enabled")).write(enabled); + QQmlProperty(it, QStringLiteral("text")).write(action->text()); + QQmlProperty(it, QStringLiteral("iconName")).write(action->iconText()); + QQmlProperty(it, QStringLiteral("enabled")).write(action->isEnabled()); QQmlProperty(it, QStringLiteral("checkable")).write(checkable); QQmlProperty(it, QStringLiteral("checked")).write(checked); QQmlProperty signal(it, QStringLiteral("onTriggered")); CHECK_QML_SIGNAL_PROPERTY(signal, menuItemComponent->url()); - QObject::connect(it, signal.method(), menuItemHandler, QMetaMethod::fromSignal(&MenuItemHandler::triggered)); + const QMetaObject *actionMeta = action->metaObject(); + QObject::connect(it, signal.method(), action, actionMeta->method(actionMeta->indexOfSlot("trigger()"))); menuItemComponent->completeCreate(); - QObject *menu = menuItemHandler->parent(); it->setParent(menu); QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(m_view)); @@ -636,28 +630,25 @@ QObject *UI2DelegatesManager::addMenu(QObject *parentMenu, const QString &title, return menu; } -void UI2DelegatesManager::addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, - const QString &/*iconName*/, bool enabled, - bool checkable, bool checked) +void UI2DelegatesManager::addMenuItem(QQuickWebEngineAction *action, QObject *menu, bool checkable, bool checked) { - Q_ASSERT(menuItemHandler); + Q_ASSERT(action); if (!ensureComponentLoaded(MenuItem)) return; QObject *it = menuItemComponent->beginCreate(qmlContext(m_view)); - it->setProperty("text", text); - it->setProperty("enabled", enabled); + it->setProperty("text", action->text()); + it->setProperty("enabled", action->isEnabled()); it->setProperty("checked", checked); it->setProperty("checkable", checkable); QQmlProperty signal(it, QStringLiteral("onTriggered")); CHECK_QML_SIGNAL_PROPERTY(signal, menuItemComponent->url()); - QObject::connect(it, signal.method(), menuItemHandler, - QMetaMethod::fromSignal(&MenuItemHandler::triggered)); + const QMetaObject *actionMeta = action->metaObject(); + QObject::connect(it, signal.method(), action, actionMeta->method(actionMeta->indexOfSlot("trigger()"))); menuItemComponent->completeCreate(); - QObject *menu = menuItemHandler->parent(); it->setParent(menu); QQmlListReference entries(menu, defaultPropertyName(menu), qmlEngine(m_view)); diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h index 1cbf2ad28..18457e4ed 100644 --- a/src/webengine/ui_delegates_manager.h +++ b/src/webengine/ui_delegates_manager.h @@ -40,6 +40,7 @@ #ifndef UI_DELEGATES_MANAGER_H #define UI_DELEGATES_MANAGER_H +#include "api/qquickwebengineaction_p.h" #include "qglobal.h" #include "web_contents_adapter.h" #include "web_contents_adapter_client.h" @@ -83,15 +84,6 @@ class FilePickerController; const char *defaultPropertyName(QObject *obj); -class MenuItemHandler : public QObject { -Q_OBJECT -public: - MenuItemHandler(QObject *parent); - -Q_SIGNALS: - void triggered(); -}; - class UIDelegatesManager { Q_DECLARE_TR_FUNCTIONS(UIDelegatesManager) @@ -106,9 +98,7 @@ public: virtual ~UIDelegatesManager(); virtual bool initializeImportDirs(QStringList &dirs, QQmlEngine *engine); - virtual void addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, - const QString &iconName = QString(), - bool enabled = true, + virtual void addMenuItem(QQuickWebEngineAction *action, QObject *menu, bool checkable = false, bool checked = true); void addMenuSeparator(QObject *menu); virtual QObject *addMenu(QObject *parentMenu, const QString &title, @@ -143,9 +133,7 @@ public: bool initializeImportDirs(QStringList &dirs, QQmlEngine *engine) override; QObject *addMenu(QObject *parentMenu, const QString &title, const QPoint &pos = QPoint()) override; - void addMenuItem(MenuItemHandler *menuItemHandler, const QString &text, - const QString &iconName = QString(), - bool enabled = true, + void addMenuItem(QQuickWebEngineAction *action, QObject *menu, bool checkable = false, bool checked = false) override; void showMenu(QObject *menu) override; Q_DISABLE_COPY(UI2DelegatesManager) diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 7b2818a06..418ade9a8 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -14,6 +14,7 @@ QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf INCLUDEPATH += $$PWD api ../core ../core/api SOURCES = \ + api/qquickwebengineaction.cpp \ api/qquickwebenginecertificateerror.cpp \ api/qquickwebenginecontextmenurequest.cpp \ api/qquickwebenginedialogrequests.cpp \ @@ -36,6 +37,8 @@ SOURCES = \ HEADERS = \ api/qtwebengineglobal.h \ api/qtwebengineglobal_p.h \ + api/qquickwebengineaction_p.h \ + api/qquickwebengineaction_p_p.h \ api/qquickwebenginecertificateerror_p.h \ api/qquickwebenginecontextmenurequest_p.h \ api/qquickwebenginedialogrequests_p.h \ |