diff options
Diffstat (limited to 'src/webengine')
-rw-r--r-- | src/webengine/api/qquickwebenginecontextmenudata.cpp | 243 | ||||
-rw-r--r-- | src/webengine/api/qquickwebenginecontextmenudata_p.h | 145 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 152 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p.h | 13 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p_p.h | 3 | ||||
-rw-r--r-- | src/webengine/doc/src/webengineview.qdoc | 19 | ||||
-rw-r--r-- | src/webengine/plugin/plugin.cpp | 3 | ||||
-rw-r--r-- | src/webengine/webengine.pro | 2 |
8 files changed, 500 insertions, 80 deletions
diff --git a/src/webengine/api/qquickwebenginecontextmenudata.cpp b/src/webengine/api/qquickwebenginecontextmenudata.cpp new file mode 100644 index 000000000..9fec90525 --- /dev/null +++ b/src/webengine/api/qquickwebenginecontextmenudata.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** +** +** 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 WebEngineDownloadItem::isValid + + Is \c true if the context data is valid; otherwise \c false. +*/ +bool QQuickWebEngineContextMenuData::isValid() const +{ + return d; +} + +/*! + \qmlproperty QPoint WebEngineDownloadItem::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 WebEngineDownloadItem::linkText + + Returns the text of a link if the context is a link. +*/ +QString QQuickWebEngineContextMenuData::linkText() const +{ + return d ? d->linkText : QString(); +} + +/*! + \qmlproperty QUrl WebEngineDownloadItem::linkUrl + + Returns the URL of a link if the context is a link. +*/ +QUrl QQuickWebEngineContextMenuData::linkUrl() const +{ + return d ? d->linkUrl : QUrl(); +} + +/*! + \qmlproperty QString WebEngineDownloadItem::selectedText + + Returns the selected text of the context. +*/ +QString QQuickWebEngineContextMenuData::selectedText() const +{ + return d ? d->selectedText : QString(); +} + +/*! + \qmlproperty QUrl WebEngineDownloadItem::mediaUrl + + If the context is a media element, returns the URL of that media. +*/ +QUrl QQuickWebEngineContextMenuData::mediaUrl() const +{ + return d ? d->mediaUrl : QUrl(); +} + +/*! + \qmlproperty MediaType WebEngineDownloadItem::mediaType + + Returns the type of the media element or \c MediaTypeNone if the context is not a media element. + + \value MediaTypeNone + The context is not a media element. + \value MediaTypeImage + The context is an image element + \value MediaTypeVideo + The context is a video element + \value MediaTypeAudio + The context is an audio element + \value MediaTypeCanvas + The context is a canvas element + \value MediaTypeFile + The context is a file + \value MediaTypePlugin + The context is a plugin +*/ + +QQuickWebEngineContextMenuData::MediaType QQuickWebEngineContextMenuData::mediaType() const +{ + return d ? static_cast<QQuickWebEngineContextMenuData::MediaType>(d->mediaType) : MediaTypeNone; +} + +/*! + \qmlproperty bool WebEngineDownloadItem::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; +} + +#if !defined(QT_NO_SPELLCHECK) +/*! + \qmlproperty QString WebEngineDownloadItem::misspelledWord + + If the context is a word considered misspelled by the spell-checker, returns the misspelled word. +*/ +QString QQuickWebEngineContextMenuData::misspelledWord() const +{ + if (d) + return d->misspelledWord; + return QString(); +} + +/*! + \qmlproperty QStringList WebEngineDownloadItem::spellCheckerSuggestions + + If the context is a word considered misspelled by the spell-checker, returns a list of suggested replacements. +*/ +QStringList QQuickWebEngineContextMenuData::spellCheckerSuggestions() const +{ + if (d) + return d->spellCheckerSuggestions; + return QStringList(); +} +#endif + +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 !defined(QT_NO_SPELLCHECK) + if (misspelledWord() != old.misspelledWord()) + Q_EMIT misspelledWordChanged(); + + if (spellCheckerSuggestions() != old.spellCheckerSuggestions()) + Q_EMIT spellCheckerSuggestionsChanged(); +#endif +} + +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 new file mode 100644 index 000000000..162c28662 --- /dev/null +++ b/src/webengine/api/qquickwebenginecontextmenudata_p.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** 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 <private/qtwebengineglobal_p.h> +#include <QtCore/QObject> +#include <QtCore/QPoint> +#include <QtCore/QString> +#include <QtCore/QUrl> +#include <QtQuick/QQuickItem> + +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) +#if !defined(QT_NO_SPELLCHECK) + Q_PROPERTY(QString misspelledWord READ misspelledWord NOTIFY misspelledWordChanged) + Q_PROPERTY(QStringList spellCheckerSuggestions READ spellCheckerSuggestions NOTIFY spellCheckerSuggestionsChanged) +#endif + + bool isValid() const; + + QPoint position() const; + QString selectedText() const; + QString linkText() const; + QUrl linkUrl() const; + QUrl mediaUrl() const; + MediaType mediaType() const; + bool isContentEditable() const; + +#if !defined(QT_NO_SPELLCHECK) + QString misspelledWord() const; + QStringList spellCheckerSuggestions() const; +#endif + +Q_SIGNALS: + void isValidChanged(); + void positionChanged(); + void selectedTextChanged(); + void linkTextChanged(); + void linkUrlChanged(); + void mediaUrlChanged(); + void mediaTypeChanged(); + void isContentEditableChanged(); +#if !defined(QT_NO_SPELLCHECK) + void misspelledWordChanged(); + void spellCheckerSuggestionsChanged(); +#endif + +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/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 23cd25366..e2a5d07c3 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -192,17 +192,19 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu if (!menu) return false; - contextMenuData = data; + contextMenuData.update(data); + Q_EMIT q->contextMenuDataChanged(); // Populate our menu MenuItemHandler *item = 0; #if !defined(QT_NO_SPELLCHECK) - if (contextMenuData.isEditable && !contextMenuData.spellCheckerSuggestions.isEmpty()) { - for (int i=0; i < contextMenuData.spellCheckerSuggestions.count() && i < 4; i++) { + if (contextMenuData.isContentEditable() && !contextMenuData.spellCheckerSuggestions().isEmpty()) { + const QPointer<QQuickWebEngineView> qRef(q); + for (int i=0; i < contextMenuData.spellCheckerSuggestions().count() && i < 4; i++) { item = new MenuItemHandler(menu); - int index = QQuickWebEngineView::ReplaceMisspelledWord_1 + i; - QObject::connect(item, &MenuItemHandler::triggered, [q,index] { q->triggerWebAction(static_cast<QQuickWebEngineView::WebAction>(index)); }); - ui()->addMenuItem(item, contextMenuData.spellCheckerSuggestions.at(i)); + QString replacement = contextMenuData.spellCheckerSuggestions().at(i); + QObject::connect(item, &MenuItemHandler::triggered, [qRef, replacement] { qRef->replaceMisspelledWord(replacement); }); + ui()->addMenuItem(item, replacement); } ui()->addMenuSeparator(menu); } @@ -242,7 +244,7 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu ui()->addMenuItem(item, QQuickWebEngineView::tr("Unselect")); } - if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) { + if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL")); @@ -250,9 +252,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 WebEngineContextMenuData::MediaTypeImage: + if (contextMenuData.mediaUrl().isValid()) { + switch (contextMenuData.mediaType()) { + case QQuickWebEngineContextMenuData::MediaTypeImage: item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image URL")); @@ -263,11 +265,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 WebEngineContextMenuData::MediaTypeCanvas: + case QQuickWebEngineContextMenuData::MediaTypeCanvas: Q_UNREACHABLE(); // mediaUrl is invalid for canvases break; - case WebEngineContextMenuData::MediaTypeAudio: - case WebEngineContextMenuData::MediaTypeVideo: + case QQuickWebEngineContextMenuData::MediaTypeAudio: + case QQuickWebEngineContextMenuData::MediaTypeVideo: item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyMediaUrlToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Media URL")); @@ -280,12 +282,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 (contextMenuData.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 (contextMenuData.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")); @@ -294,7 +296,7 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu default: break; } - } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) { + } else if (contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeCanvas) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); @@ -310,10 +312,10 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu ui()->addMenuItem(item, QQuickWebEngineView::tr("Exit Full Screen Mode")); } #if !defined(QT_NO_SPELLCHECK) - if (contextMenuData.isEditable) { + if (data.isEditable) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleSpellcheck); }); - ui()->addMenuItem(item, QQuickWebEngineView::tr("Check Spelling"), QString(), true, true, contextMenuData.isSpellCheckerEnabled); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Check Spelling"), QString(), true, true, data.isSpellCheckerEnabled); } #endif // FIXME: expose the context menu data as an attached property to make this more useful @@ -1217,6 +1219,12 @@ void QQuickWebEngineView::printToPdf(PrintedPageSizeId pageSizeId, PrintedPageOr d->m_callbacks.insert(requestId, callback); } +void QQuickWebEngineView::replaceMisspelledWord(const QString &replacement) +{ + Q_D(QQuickWebEngineView); + d->adapter->replaceMisspelling(replacement); +} + bool QQuickWebEngineView::isFullScreen() const { Q_D(const QQuickWebEngineView); @@ -1457,118 +1465,118 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) d->adapter->unselect(); break; case OpenLinkInThisWindow: - if (d->contextMenuData.linkUrl.isValid()) - setUrl(d->contextMenuData.linkUrl); + if (d->contextMenuData.linkUrl().isValid()) + setUrl(d->contextMenuData.linkUrl()); break; case OpenLinkInNewWindow: - if (d->contextMenuData.linkUrl.isValid()) { + if (d->contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; - request.m_requestedUrl = d->contextMenuData.linkUrl; + request.m_requestedUrl = d->contextMenuData.linkUrl(); request.m_isUserInitiated = true; request.m_destination = NewViewInWindow; Q_EMIT newViewRequested(&request); } break; case OpenLinkInNewTab: - if (d->contextMenuData.linkUrl.isValid()) { + if (d->contextMenuData.linkUrl().isValid()) { QQuickWebEngineNewViewRequest request; - request.m_requestedUrl = d->contextMenuData.linkUrl; + request.m_requestedUrl = d->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->contextMenuData.linkUrl().isValid()) { + QString urlString = d->contextMenuData.linkUrl().toString(QUrl::FullyEncoded); + QString title = d->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->contextMenuData.linkUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadLinkToDisk: - if (d->contextMenuData.linkUrl.isValid()) - d->adapter->download(d->contextMenuData.linkUrl, d->contextMenuData.suggestedFileName); + if (d->contextMenuData.linkUrl().isValid()) + d->adapter->download(d->contextMenuData.linkUrl(), d->contextMenuData.d->suggestedFileName); break; case CopyImageToClipboard: - if (d->contextMenuData.hasImageContent && - (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage || - d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas)) + if (d->contextMenuData.d->hasImageContent && + (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeImage || + d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeCanvas)) { - d->adapter->copyImageAt(d->contextMenuData.pos); + d->adapter->copyImageAt(d->contextMenuData.position()); } break; case CopyImageUrlToClipboard: - if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage) { - QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded); - QString title = d->contextMenuData.linkText; + if (d->contextMenuData.mediaUrl().isValid() && d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeImage) { + QString urlString = d->contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); + QString title = d->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->contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadImageToDisk: case DownloadMediaToDisk: - if (d->contextMenuData.mediaUrl.isValid()) - d->adapter->download(d->contextMenuData.mediaUrl, d->contextMenuData.suggestedFileName); + if (d->contextMenuData.mediaUrl().isValid()) + d->adapter->download(d->contextMenuData.mediaUrl(), d->contextMenuData.d->suggestedFileName); break; case CopyMediaUrlToClipboard: - if (d->contextMenuData.mediaUrl.isValid() && - (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (d->contextMenuData.mediaUrl().isValid() && + (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) { - QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded); + QString urlString = d->contextMenuData.mediaUrl().toString(QUrl::FullyEncoded); QMimeData *data = new QMimeData(); data->setText(urlString); - if (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio) + if (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::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->contextMenuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case ToggleMediaControls: - if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { - bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaControls); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerControls, enable); + 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); } break; case ToggleMediaLoop: - if (d->contextMenuData.mediaUrl.isValid() && - (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (d->contextMenuData.mediaUrl().isValid() && + (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) { - bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaLoop); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerLoop, enable); + bool enable = !(d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaLoop); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); } break; case ToggleMediaPlayPause: - if (d->contextMenuData.mediaUrl.isValid() && - (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (d->contextMenuData.mediaUrl().isValid() && + (d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType() == QQuickWebEngineContextMenuData::MediaTypeVideo)) { - bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaPaused); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerPlay, enable); + bool enable = (d->contextMenuData.d->mediaFlags & WebEngineContextMenuData::MediaPaused); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); } break; case ToggleMediaMute: - if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { - bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted); - d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerMute, enable); + 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); } break; case InspectElement: - d->adapter->inspectElementAt(d->contextMenuData.pos); + d->adapter->inspectElementAt(d->contextMenuData.position()); break; case ExitFullScreen: d->adapter->exitFullScreen(); @@ -1583,24 +1591,18 @@ void QQuickWebEngineView::triggerWebAction(WebAction action) case ToggleSpellcheck: d->adapter->toogleSpellCheckEnabled(); break; - case ReplaceMisspelledWord_1: - d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(0)); - break; - case ReplaceMisspelledWord_2: - d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(1)); - break; - case ReplaceMisspelledWord_3: - d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(2)); - break; - case ReplaceMisspelledWord_4: - d->adapter->replaceMisspelling(d->contextMenuData.spellCheckerSuggestions.at(3)); - break; #endif default: Q_UNREACHABLE(); } } +const QQuickWebEngineContextMenuData *QQuickWebEngineView::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 595da26cd..7a23e3011 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE class QQmlWebChannel; class QQuickWebEngineCertificateError; +class QQuickWebEngineContextMenuData; class QQuickWebEngineHistory; class QQuickWebEngineLoadRequest; class QQuickWebEngineNavigationRequest; @@ -116,6 +117,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(bool audioMuted READ isAudioMuted WRITE setAudioMuted NOTIFY audioMutedChanged FINAL REVISION 3) Q_PROPERTY(bool recentlyAudible READ recentlyAudible NOTIFY recentlyAudibleChanged FINAL REVISION 3) Q_PROPERTY(uint webChannelWorld READ webChannelWorld WRITE setWebChannelWorld NOTIFY webChannelWorldChanged REVISION 3) + Q_PROPERTY(const QQuickWebEngineContextMenuData *contextMenuData READ contextMenuData NOTIFY contextMenuDataChanged CONSTANT REVISION 3) #ifdef ENABLE_QML_TESTSUPPORT_API Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL) @@ -242,10 +244,6 @@ public: SavePage, #if !defined(QT_NO_SPELLCHECK) ToggleSpellcheck, - ReplaceMisspelledWord_1, - ReplaceMisspelledWord_2, - ReplaceMisspelledWord_3, - ReplaceMisspelledWord_4, #endif WebActionCount }; @@ -452,6 +450,8 @@ public: void setAudioMuted(bool muted); bool recentlyAudible() const; + const QQuickWebEngineContextMenuData *contextMenuData() const; + #ifdef ENABLE_QML_TESTSUPPORT_API QQuickWebEngineTestSupport *testSupport() const; void setTestSupport(QQuickWebEngineTestSupport *testSupport); @@ -477,6 +477,10 @@ public Q_SLOTS: Q_REVISION(3) void printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait); Q_REVISION(3) void printToPdf(PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait, const QJSValue &callback = QJSValue()); +#if !defined(QT_NO_SPELLCHECK) + Q_REVISION(3) void replaceMisspelledWord(const QString &replacement); +#endif + private Q_SLOTS: void lazyInitialize(); @@ -506,6 +510,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(3) void contextMenuDataChanged(); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index d3d6603f5..54de7c1b8 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -52,6 +52,7 @@ // #include "qquickwebengineview_p.h" +#include "qquickwebenginecontextmenudata_p.h" #include "web_contents_adapter_client.h" #include <QScopedPointer> @@ -208,7 +209,7 @@ public: QQuickWebEngineTestSupport *m_testSupport; #endif QQmlComponent *contextMenuExtraItems; - QtWebEngineCore::WebEngineContextMenuData contextMenuData; + QQuickWebEngineContextMenuData contextMenuData; QUrl explicitUrl; QUrl iconUrl; int loadProgress; diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index a52c6c248..5a2623669 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -1086,3 +1086,22 @@ The \a resultCallback must take a string parameter. This string will contain the document's data upon successful printing and an empty string otherwise. */ + +/*! + \qmlmethod void WebEngineView::replaceMisspelledWord(const QString &replacement) + \since QtWebEngine 1.3 + + Replace the current misspelled word with \a replacement. +*/ + +/*! + \qmlsignal void WebEngineView::wasRecentlyAudibleChanged(bool wasRecentlyAudible) + \since QtWebEngine 1.3 + + This signal is emitted when the page's audible state is changed, due to audio + being played or stopped. + + \note The signal is also emitted when calling the setAudioMuted method. + Also if the audio is paused, this signal is emitted with an approximate \b{2 second + delay}, from the moment the audio is paused. +*/ diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index fc8e40bd0..a33b543ac 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -41,6 +41,7 @@ #include <QtWebEngine/QQuickWebEngineProfile> #include "qquickwebenginecertificateerror_p.h" +#include "qquickwebenginecontextmenudata_p.h" #include "qquickwebenginedownloaditem_p.h" #include "qquickwebenginehistory_p.h" #include "qquickwebengineloadrequest_p.h" @@ -79,6 +80,8 @@ public: qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript"); qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", tr("Cannot create separate instance of WebEngineCertificateError")); + qmlRegisterUncreatableType<const QQuickWebEngineContextMenuData>(uri, 1, 3, "WebEngineContextMenuData", + tr("Cannot create a separate instance of WebEngineContextMenuData")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem", tr("Cannot create a separate instance of WebEngineDownloadItem")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 1>(uri, 1, 2, "WebEngineDownloadItem", diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 10353107a..9ec0db5cb 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -12,6 +12,7 @@ INCLUDEPATH += $$PWD api ../core ../core/api SOURCES = \ api/qquickwebenginecertificateerror.cpp \ + api/qquickwebenginecontextmenudata.cpp \ api/qquickwebenginedownloaditem.cpp \ api/qquickwebenginehistory.cpp \ api/qquickwebengineloadrequest.cpp \ @@ -31,6 +32,7 @@ HEADERS = \ api/qtwebengineglobal.h \ api/qtwebengineglobal_p.h \ api/qquickwebenginecertificateerror_p.h \ + api/qquickwebenginecontextmenudata_p.h \ api/qquickwebenginedownloaditem_p.h \ api/qquickwebenginedownloaditem_p_p.h \ api/qquickwebenginehistory_p.h \ |