diff options
Diffstat (limited to 'src')
26 files changed, 1940 insertions, 509 deletions
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 165d84e37..85a379409 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -71,23 +71,43 @@ class WebContentsAdapter; class WebContentsDelegateQt; class WebEngineSettings; -// FIXME: make this ref-counted and implicitely shared and expose as public API maybe ? -class WebEngineContextMenuData { + +class WebEngineContextMenuSharedData : public QSharedData { public: - WebEngineContextMenuData() - : mediaType(MediaTypeNone) - , hasImageContent(false) - , mediaFlags(0) + WebEngineContextMenuSharedData() + : hasImageContent(false) , isEditable(false) , isSpellCheckerEnabled(false) + , mediaType(0) + , mediaFlags(0) { } + bool hasImageContent; + bool isEditable; + bool isSpellCheckerEnabled; + uint mediaType; + uint mediaFlags; + QPoint pos; + QUrl linkUrl; + QUrl mediaUrl; + QString linkText; + QString selectedText; + QString suggestedFileName; + QString misspelledWord; + QStringList spellCheckerSuggestions; + // Some likely candidates for future additions as we add support for the related actions: + // bool isImageBlocked; + // <enum tbd> mediaType; + // ... +}; +class WebEngineContextMenuData { +public: // Must match blink::WebContextMenuData::MediaType: enum MediaType { // No special node is in context. - MediaTypeNone, + MediaTypeNone = 0x0, // An image node is selected. MediaTypeImage, // A video node is selected. @@ -117,25 +137,118 @@ public: MediaCanRotate = 0x200, }; - QPoint pos; - QUrl linkUrl; - QString linkText; - QString selectedText; - QUrl mediaUrl; - MediaType mediaType; - bool hasImageContent; - uint mediaFlags; - QString suggestedFileName; - bool isEditable; - bool isSpellCheckerEnabled; - QString misspelledWord; - QStringList spellCheckerSuggestions; -// Some likely candidates for future additions as we add support for the related actions: -// bool isImageBlocked; -// <enum tbd> mediaType; -// ... + WebEngineContextMenuData():d(new WebEngineContextMenuSharedData) { + } + + void setPosition(const QPoint &pos) { + d->pos = pos; + } + + QPoint position() const { + return d->pos; + } + + void setLinkUrl(const QUrl &url) { + d->linkUrl = url; + } + + QUrl linkUrl() const { + return d->linkUrl; + } + + void setLinkText(const QString &text) { + d->linkText = text; + } + + QString linkText() const { + return d->linkText; + } + + void setSelectedText(const QString &text) { + d->selectedText = text; + } + + QString selectedText() const { + return d->selectedText; + } + + void setMediaUrl(const QUrl &url) { + d->mediaUrl = url; + } + + QUrl mediaUrl() const { + return d->mediaUrl; + } + + void setMediaType(MediaType type) { + d->mediaType = type; + } + + MediaType mediaType() const { + return MediaType(d->mediaType); + } + + void setHasImageContent(bool imageContent) { + d->hasImageContent = imageContent; + } + + bool hasImageContent() const { + return d->hasImageContent; + } + + void setMediaFlags(MediaFlags flags) { + d->mediaFlags = flags; + } + + MediaFlags mediaFlags() const { + return MediaFlags(d->mediaFlags); + } + + void setSuggestedFileName(const QString &filename) { + d->suggestedFileName = filename; + } + + QString suggestedFileName() const { + return d->suggestedFileName; + } + + void setIsEditable(bool editable) { + d->isEditable = editable; + } + + bool isEditable() const { + return d->isEditable; + } + + void setIsSpellCheckerEnabled(bool spellCheckerEnabled) { + d->isSpellCheckerEnabled = spellCheckerEnabled; + } + + bool isSpellCheckerEnabled() const { + return d->isSpellCheckerEnabled; + } + + void setMisspelledWord(const QString &word) { + d->misspelledWord = word; + } + + QString misspelledWord() const { + return d->misspelledWord; + } + + void setSpellCheckerSuggestions(const QStringList &suggestions) { + d->spellCheckerSuggestions = suggestions; + } + + QStringList spellCheckerSuggestions() const { + return d->spellCheckerSuggestions; + } + +private: + QSharedDataPointer<WebEngineContextMenuSharedData> d; }; + class QWEBENGINE_EXPORT WebContentsAdapterClient { public: // This must match window_open_disposition_list.h. @@ -227,7 +340,7 @@ public: virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) = 0; virtual bool isFullScreenMode() const = 0; virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) = 0; - virtual void runFileChooser(FilePickerController *controller) = 0; + virtual void runFileChooser(QSharedPointer<FilePickerController>) = 0; virtual void showColorDialog(QSharedPointer<ColorChooserController>) = 0; virtual void didRunJavaScript(quint64 requestId, const QVariant& result) = 0; virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index b96452093..6e7d1cddc 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -317,8 +317,9 @@ void WebContentsDelegateQt::RunFileChooser(content::WebContents *web_contents, c for (std::vector<base::string16>::const_iterator it = params.accept_types.begin(); it < params.accept_types.end(); ++it) acceptedMimeTypes.append(toQt(*it)); - FilePickerController *controller = new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode), web_contents, toQt(params.default_file_name.value()), acceptedMimeTypes); - m_viewClient->runFileChooser(controller); + m_filePickerController.reset(new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode), + web_contents, toQt(params.default_file_name.value()), acceptedMimeTypes)); + m_viewClient->runFileChooser(m_filePickerController); } bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, int32_t level, const base::string16 &message, int32_t line_no, const base::string16 &source_id) diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 9aa584369..d2459e79b 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -154,6 +154,7 @@ private: QVector<int64_t> m_loadingErrorFrameList; QScopedPointer<FaviconManager> m_faviconManager; SavePageInfo m_savePageInfo; + QSharedPointer<FilePickerController> m_filePickerController; }; } // namespace QtWebEngineCore diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index e487fca46..ed6fdabff 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -155,19 +155,19 @@ ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMe static inline WebEngineContextMenuData fromParams(const content::ContextMenuParams ¶ms) { WebEngineContextMenuData ret; - ret.pos = QPoint(params.x, params.y); - ret.linkUrl = toQt(params.link_url); - ret.linkText = toQt(params.link_text.data()); - ret.selectedText = toQt(params.selection_text.data()); - ret.mediaUrl = toQt(params.src_url); - ret.mediaType = (WebEngineContextMenuData::MediaType)params.media_type; - ret.hasImageContent = params.has_image_contents; - ret.mediaFlags = params.media_flags; - ret.suggestedFileName = toQt(params.suggested_filename.data()); - ret.isEditable = params.is_editable; + ret.setPosition(QPoint(params.x, params.y)); + ret.setLinkUrl(toQt(params.link_url)); + ret.setLinkText(toQt(params.link_text.data())); + ret.setSelectedText(toQt(params.selection_text.data())); + ret.setMediaUrl(toQt(params.src_url)); + ret.setMediaType((WebEngineContextMenuData::MediaType)params.media_type); + ret.setHasImageContent(params.has_image_contents); + ret.setMediaFlags((WebEngineContextMenuData::MediaFlags)params.media_flags); + ret.setSuggestedFileName(toQt(params.suggested_filename.data())); + ret.setIsEditable(params.is_editable); #if defined(ENABLE_SPELLCHECK) - ret.misspelledWord = toQt(params.misspelled_word); - ret.spellCheckerSuggestions = fromVector(params.dictionary_suggestions); + ret.setMisspelledWord(toQt(params.misspelled_word)); + ret.setSpellCheckerSuggestions(fromVector(params.dictionary_suggestions)); #endif return ret; } @@ -183,7 +183,7 @@ void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const conten // must be initialized to true due to the way how the initialization sequence // in SpellCheck works ie. typing the first word triggers the creation // of the SpellcheckService. Use user preference store instead. - contextMenuData.isSpellCheckerEnabled = m_client->browserContextAdapter()->isSpellCheckEnabled(); + contextMenuData.setIsSpellCheckerEnabled(m_client->browserContextAdapter()->isSpellCheckEnabled()); #endif m_client->contextMenuRequested(contextMenuData); } diff --git a/src/webengine/api/qquickwebenginecertificateerror.cpp b/src/webengine/api/qquickwebenginecertificateerror.cpp index 51a942abe..622fe8614 100644 --- a/src/webengine/api/qquickwebenginecertificateerror.cpp +++ b/src/webengine/api/qquickwebenginecertificateerror.cpp @@ -93,7 +93,9 @@ QQuickWebEngineCertificateError::QQuickWebEngineCertificateError(const QSharedPo QQuickWebEngineCertificateError::~QQuickWebEngineCertificateError() { - rejectCertificate(); + Q_D(QQuickWebEngineCertificateError); + if (!d->answered) + rejectCertificate(); } 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/qquickwebenginedialogrequests.cpp b/src/webengine/api/qquickwebenginedialogrequests.cpp new file mode 100644 index 000000000..d8111e62b --- /dev/null +++ b/src/webengine/api/qquickwebenginedialogrequests.cpp @@ -0,0 +1,856 @@ +/**************************************************************************** +** +** 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 "qquickwebenginedialogrequests_p.h" +#include "authentication_dialog_controller.h" +#include "javascript_dialog_controller.h" +#include "color_chooser_controller.h" +#include "file_picker_controller.h" +#include "web_contents_adapter_client.h" + +QT_BEGIN_NAMESPACE + +using namespace QtWebEngineCore; + +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::AlertDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypeAlert) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::ConfirmDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypeConfirm) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::PromptDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypePrompt) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::UnloadDialog, + QQuickWebEngineJavaScriptDialogRequest::DialogTypeBeforeUnload) + +ASSERT_ENUMS_MATCH(FilePickerController::Open, + QQuickWebEngineFileDialogRequest::FileModeOpen) +ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, + QQuickWebEngineFileDialogRequest::FileModeOpenMultiple) +ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, + QQuickWebEngineFileDialogRequest::FileModeUploadFolder) +ASSERT_ENUMS_MATCH(FilePickerController::Save, + QQuickWebEngineFileDialogRequest::FileModeSave) + +/*! + \qmltype AuthenticationDialogRequest + \instantiates QQuickWebEngineAuthenticationDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for providing authentication credentials required + by proxies or HTTP servers. + + An AuthenticationDialogRequest is passed as an argument of the + WebEngineView::authenticationDialogRequested signal. It is generated + when basic HTTP or proxy authentication is required. The type + of authentication can be checked with the \l type property. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call + either \l dialogAccept() or \l dialogReject() afterwards. + + The following code uses a custom dialog to handle the request: + \code + + WebEngineView { + // ... + onAuthenticationDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + + \endcode +*/ + +QQuickWebEngineAuthenticationDialogRequest::QQuickWebEngineAuthenticationDialogRequest( + QSharedPointer<AuthenticationDialogController> controller, + QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_url(controller->url()) + , m_realm(controller->realm()) + , m_type(controller->isProxy() ? AuthenticationTypeProxy + : AuthenticationTypeHTTP) + , m_host(controller->host()) + , m_accepted(false) +{ + +} + +QQuickWebEngineAuthenticationDialogRequest::~QQuickWebEngineAuthenticationDialogRequest() +{ +} + +/*! + \qmlproperty url AuthenticationDialogRequest::url + \readonly + + The URL of the HTTP request for which authentication was requested. + In case of proxy authentication, this is a request URL which is proxied + via host. + + \sa proxyHost +*/ + +QUrl QQuickWebEngineAuthenticationDialogRequest::url() const +{ + return m_url; +} + +/*! + \qmlproperty string AuthenticationDialogRequest::realm + \readonly + + The HTTP authentication realm attribute value of the \c WWW-Authenticate + header. Empty if \l type is AuthenticationTypeProxy. +*/ + +QString QQuickWebEngineAuthenticationDialogRequest::realm() const +{ + return m_realm; +} + +/*! + \qmlproperty string AuthenticationDialogRequest::proxyHost + \readonly + + The hostname of the authentication proxy. + Empty if \l type is AuthenticationTypeHTTP. +*/ + +QString QQuickWebEngineAuthenticationDialogRequest::proxyHost() const +{ + return m_host; +} + +/*! + \qmlproperty AuthenticationType AuthenticationDialogRequest::type + \readonly + + The type of the authentication request. + + \value AuthenticationTypeHTTP + HTTP authentication. + \value AuthenticationTypeProxy + Proxy authentication. +*/ + +QQuickWebEngineAuthenticationDialogRequest::AuthenticationType +QQuickWebEngineAuthenticationDialogRequest::type() const +{ + return m_type; +} + +/*! + \qmlproperty bool AuthenticationDialogRequest::accepted + + Indicates whether the authentication dialog request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::authenticationDialogRequested have been executed, + a default authentication dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineAuthenticationDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineAuthenticationDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +/*! + \qmlmethod void AuthenticationDialogRequest::dialogAccept(string username, string password) + + This function notifies the engine that the user accepted the dialog, + providing the \a username and the \a password required for authentication. +*/ + +void QQuickWebEngineAuthenticationDialogRequest::dialogAccept(const QString &user, + const QString &password) +{ + m_accepted = true; + QSharedPointer<AuthenticationDialogController> controller + = m_controller.toStrongRef(); + if (controller) + controller->accept(user,password); +} + +/*! + \qmlmethod void AuthenticationDialogRequest::dialogReject() + + This function notifies the engine that the user rejected the dialog and the + authentication shall not proceed. +*/ + +void QQuickWebEngineAuthenticationDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<AuthenticationDialogController> controller + = m_controller.toStrongRef(); + if (controller) + controller->reject(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype JavaScriptDialogRequest + \instantiates QQuickWebEngineJavaScriptDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for showing an alert, a confirmation, or a prompt dialog + from within JavaScript to the user. + + A JavaScriptDialogRequest is passed as an argument of the + WebEngineView::javaScriptDialogRequested signal. The request is emitted + if JavaScript on the page calls HTML5's + \l{https://www.w3.org/TR/html5/webappapis.html#simple-dialogs}{Simple Dialogs} + API, or in response to HTML5's + \l {https://www.w3.org/TR/html5/browsers.html#beforeunloadevent}{BeforeUnloadEvent}. + The type of a particular dialog can be checked with the \l type property. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call either + \l dialogAccept() or \l dialogReject() afterwards. The JavaScript call + causing the request will be blocked until then. + + The following code uses a custom dialog to handle the request: + + \code + WebEngineView { + // ... + onJavaScriptDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + \endcode +*/ + +QQuickWebEngineJavaScriptDialogRequest::QQuickWebEngineJavaScriptDialogRequest( + QSharedPointer<JavaScriptDialogController> controller, QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_message(controller->message()) + , m_defaultPrompt(controller->defaultPrompt()) + , m_title(controller->title()) + , m_type(static_cast<QQuickWebEngineJavaScriptDialogRequest::DialogType>(controller->type())) + , m_securityOrigin(controller->securityOrigin()) + , m_accepted(false) +{ +} + +QQuickWebEngineJavaScriptDialogRequest::~QQuickWebEngineJavaScriptDialogRequest() +{ + +} + +/*! + \qmlproperty string JavaScriptDialogRequest::message + \readonly + + The message to be shown to the user. +*/ + +QString QQuickWebEngineJavaScriptDialogRequest::message() const +{ + return m_message; +} + +/*! + \qmlproperty string JavaScriptDialogRequest::defaultPrompt + \readonly + + The default text if the requested dialog box is of + the \l type PromptDialog. +*/ + + +QString QQuickWebEngineJavaScriptDialogRequest::defaultText() const +{ + return m_defaultPrompt; +} + +/*! + \qmlproperty string JavaScriptDialogRequest::title + \readonly + + A default title for the dialog. +*/ + +QString QQuickWebEngineJavaScriptDialogRequest::title() const +{ + return m_title; +} + +/*! + \qmlproperty enumeration JavaScriptDialogRequest::type + \readonly + + Returns the type of the requested dialog box, see HTML5's + + \l{https://www.w3.org/TR/html5/webappapis.html#simple-dialogs}{Simple Dialogs}. + + \value JavaScriptDialogRequest.DialogTypeAlert + A JavaScript alert dialog. + \value JavaScriptDialogRequest.DialogTypeConfirm + A JavaScript confirmation dialog. + \value JavaScriptDialogRequest.DialogTypePrompt + A JavaScript prompt dialog. + \value JavaScriptDialogRequest.DialogTypeUnload + The users should be asked if they want to leave the page. +*/ + +QQuickWebEngineJavaScriptDialogRequest::DialogType QQuickWebEngineJavaScriptDialogRequest::type() const +{ + return m_type; +} + +/*! + \qmlproperty url JavaScriptDialogRequest::securityOrigin + \readonly + + The URL of the security origin. +*/ + +QUrl QQuickWebEngineJavaScriptDialogRequest::securityOrigin() const +{ + return m_securityOrigin; +} + +/*! + \qmlproperty bool JavaScriptDialogRequest::accepted + + Indicates whether the JavaScript dialog request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::javaScriptDialogRequested have been executed, + a default dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineJavaScriptDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineJavaScriptDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +/*! + \qmlmethod void JavaScriptDialogRequest::dialogAccept() + + This function notifies the engine that the user accepted the dialog. +*/ + +/*! + \qmlmethod void JavaScriptDialogRequest::dialogAccept(string text) + + This function notifies the engine that the user accepted the dialog, + providing the \a text in case of a prompt message box. +*/ + +void QQuickWebEngineJavaScriptDialogRequest::dialogAccept(const QString& text) +{ + m_accepted = true; + QSharedPointer<JavaScriptDialogController> controller + = m_controller.toStrongRef(); + if (controller) { + controller->textProvided(text); + controller->accept(); + } +} + +/*! + \qmlmethod void JavaScriptDialogRequest::dialogReject() + + This function notifies the engine that the user rejected the dialog. +*/ + +void QQuickWebEngineJavaScriptDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<JavaScriptDialogController> controller + = m_controller.toStrongRef(); + if (controller) + controller->reject(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype ColorDialogRequest + \instantiates QQuickWebEngineColorDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for selecting a color by the user. + + A ColorDialogRequest is passed as an argument of the + WebEngineView::colorDialogRequested signal. It is generated when + a color picker dialog is requested. See + \l { https://www.w3.org/TR/html5/forms.html#color-state-(type=color)} + {HTML5 Color State}. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call either + \l dialogAccept() or \l dialogReject() afterwards. + + The following code uses a custom dialog to handle the request: + + \code + WebEngineView { + // ... + onColorDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + \endcode +*/ + +QQuickWebEngineColorDialogRequest::QQuickWebEngineColorDialogRequest( + QSharedPointer<ColorChooserController> controller, QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_color(controller->initialColor()) + , m_accepted(false) +{ + +} + +QQuickWebEngineColorDialogRequest::~QQuickWebEngineColorDialogRequest() +{ + +} + +/*! + \qmlproperty color ColorDialogRequest::color + \readonly + + The default color to be selected in the dialog. +*/ + +QColor QQuickWebEngineColorDialogRequest::color() const +{ + return m_color; +} + +/*! + \qmlproperty bool ColorDialogRequest::accepted + + Indicates whether the color picker dialog request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::colorDialogRequested have been executed, + a default color picker dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineColorDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineColorDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + + +/*! + \qmlmethod void ColorDialogRequest::dialogAccept(color color) + + This function notifies the engine that the user accepted the dialog, + providing the \a color. +*/ + +void QQuickWebEngineColorDialogRequest::dialogAccept(const QColor &color) +{ + m_accepted = true; + QSharedPointer<ColorChooserController> controller = m_controller.toStrongRef(); + if (controller) + controller->accept(color); +} + +/*! + \qmlmethod void ColorDialogRequest::dialogReject() + + This function notifies the engine that the user rejected the dialog. +*/ + +void QQuickWebEngineColorDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<ColorChooserController> controller = m_controller.toStrongRef(); + if (controller) + controller->reject(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype FileDialogRequest + \instantiates QQuickWebEngineFileDialogRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for letting the user choose a (new or existing) file or + directory. + + A FileDialogRequest is passed as an argument of the + WebEngineView::fileDialogRequested signal. It is generated + when the file dialog is requested by the input element. + See \l {https://www.w3.org/TR/html5/forms.html#file-upload-state-(type=file)}{File Upload state}. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default dialog should be displayed. + If you set the \l accepted property to \c true, make sure to call either + \l dialogAccept() or \l dialogReject() afterwards. + + The following code uses a custom dialog to handle the request: + + \code + WebEngineView { + // ... + onFileDialogRequested: function(request) { + request.accepted = true; + myDialog.request = request // keep the reference to the request + myDialog.accept.connect(request.dialogAccept); + myDialog.reject.connect(request.dialogReject); + myDialog.visible = true; + } + // ... + } + \endcode +*/ + +QQuickWebEngineFileDialogRequest::QQuickWebEngineFileDialogRequest( + QSharedPointer<FilePickerController> controller, QObject *parent): + QObject(parent) + , m_controller(controller.toWeakRef()) + , m_filename(controller->defaultFileName()) + , m_acceptedMimeTypes(controller->acceptedMimeTypes()) + , m_mode(static_cast<QQuickWebEngineFileDialogRequest::FileMode>(controller->mode())) + , m_accepted(false) +{ + +} + +QQuickWebEngineFileDialogRequest::~QQuickWebEngineFileDialogRequest() +{ + +} + +/*! + \qmlproperty stringlist FileDialogRequest::acceptedMimeTypes + \readonly + + A list of MIME types specified in the input element. The selection + should be restricted to only these types of files. +*/ + +QStringList QQuickWebEngineFileDialogRequest::acceptedMimeTypes() const +{ + return m_acceptedMimeTypes; +} + +/*! + \qmlproperty string FileDialogRequest::defaultFileName + \readonly + + The default name of the file to be selected in the dialog. +*/ + +QString QQuickWebEngineFileDialogRequest::defaultFileName() const +{ + return m_filename; +} + +/*! + \qmlproperty enumeration FileDialogRequest::mode + \readonly + + The mode of the file dialog. + + \value FileDialogRequest.FileModeOpen + Allows users to specify a single existing file. + \value FileDialogRequest.FileModeOpenMultiple + Allows users to specify multiple existing files. + \value FileDialogRequest.FileModeUploadFolder + Allows users to specify a single existing folder for upload. + \value FileDialogRequest.FileModeSave + Allows users to specify a non-existing file. If an existing file + is selected, the users should be informed that the file is going + to be overwritten. +*/ + +QQuickWebEngineFileDialogRequest::FileMode QQuickWebEngineFileDialogRequest::mode() const +{ + return m_mode; +} + +/*! + \qmlproperty bool FileDialogRequest::accepted + + Indicates whether the file picker dialog request has been + handled by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::fileDialogRequested have been executed, + a default file picker dialog will be shown. + To prevent this, set \c{request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineFileDialogRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineFileDialogRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +/*! + \qmlmethod void FileDialogRequest::dialogAccept(stringlist files) + + This function needs to be called when the user accepted the dialog with + \a files. +*/ + +void QQuickWebEngineFileDialogRequest::dialogAccept(const QStringList &files) +{ + m_accepted = true; + QSharedPointer<FilePickerController> controller = m_controller.toStrongRef(); + if (controller) + controller->accepted(files); +} + +/*! + \qmlmethod void FileDialogRequest::dialogReject() + + This function needs to be called when the user did not accepted the dialog. +*/ + +void QQuickWebEngineFileDialogRequest::dialogReject() +{ + m_accepted = true; + QSharedPointer<FilePickerController> controller = m_controller.toStrongRef(); + if (controller) + controller->rejected(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*! + \qmltype FormValidationMessageRequest + \instantiates QQuickWebEngineFormValidationMessageRequest + \inqmlmodule QtWebEngine + \since QtWebEngine 1.4 + + \brief A request for showing a HTML5 form validation message to the user. + + A FormValidationMessageRequest is passed as an argument of the + WebEngineView::formValidationMessageRequested signal. It is generated when + the handling of the validation message is requested. + + The \l accepted property of the request indicates whether the request + is handled by the user code or the default message should be displayed. + + The following code uses a custom message to handle the request: + + \code + WebEngineView { + // ... + onFormValidationMessageRequested: function(request) { + request.accepted = true; + switch (request.type) { + case FormValidationMessageRequest.RequestTypeShow: + validationMessgae.text = request.text; + validationMessgae.x = request.x; + validationMessage.y = request.y + validationMessgae.visible = true; + break; + case FormValidationMessageRequest.RequestTypeMove: + break; + case FormValidationMessageRequest.RequestTypeHide: + validationMessgae.visible = false; + break; + } + } + // ... + } + \endcode +*/ + +QQuickWebEngineFormValidationMessageRequest::QQuickWebEngineFormValidationMessageRequest( + QQuickWebEngineFormValidationMessageRequest::RequestType type, const QRect& anchor, + const QString &mainText, const QString &subText, QObject *parent): + QObject(parent) + , m_anchor(anchor) + , m_mainText(mainText) + , m_subText(subText) + , m_type(type) + , m_accepted(false) +{ + +} + +QQuickWebEngineFormValidationMessageRequest::~QQuickWebEngineFormValidationMessageRequest() +{ + +} + +/*! + \qmlproperty rectangle FormValidationMessageRequest::anchor + \readonly + + An anchor of an element in the viewport for which the form + validation message should be displayed. +*/ + +QRect QQuickWebEngineFormValidationMessageRequest::anchor() const +{ + return m_anchor; +} + +/*! + \qmlproperty bool FormValidationMessageRequest::text + \readonly + + The text of the form validation message. +*/ + + +QString QQuickWebEngineFormValidationMessageRequest::text() const +{ + return m_mainText; +} + +/*! + \qmlproperty bool FormValidationMessageRequest::subText + \readonly + + The subtext of the form validation message. +*/ + + +QString QQuickWebEngineFormValidationMessageRequest::subText() const +{ + return m_subText; +} + +/*! + \qmlproperty enumeration ValidationMessageRequest::type + \readonly + + The type of the form validation message request. + + \value ValidationMessageRequest.RequestTypeShow + The form validation message should be shown. + \value ValidationMessageRequest.RequestTypeHide + The form validation message should be hidden. + \value ValidationMessageRequest.RequestTypeMove + The form validation message should be moved. +*/ + +QQuickWebEngineFormValidationMessageRequest::RequestType QQuickWebEngineFormValidationMessageRequest::type() const +{ + return m_type; +} + +/*! + \qmlproperty bool FormValidationMessageRequest::accepted + + Indicates whether the form validation request has been + accepted by the signal handler. + + If the property is \c false after any signal handlers + for WebEngineView::validationMessageRequested have been executed, + a default file validation message will be shown. + To prevent this, set \c {request.accepted} to \c true. + + The default is \c false. +*/ + +bool QQuickWebEngineFormValidationMessageRequest::isAccepted() const +{ + return m_accepted; +} + +void QQuickWebEngineFormValidationMessageRequest::setAccepted(bool accepted) +{ + m_accepted = accepted; +} + +QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebenginedialogrequests_p.h b/src/webengine/api/qquickwebenginedialogrequests_p.h new file mode 100644 index 000000000..d1ddc6607 --- /dev/null +++ b/src/webengine/api/qquickwebenginedialogrequests_p.h @@ -0,0 +1,265 @@ +/**************************************************************************** +** +** 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 QQUICKWEBENGINDIALOGREQUESTS_H +#define QQUICKWEBENGINDIALOGREQUESTS_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/QUrl> +#include <QtCore/QWeakPointer> +#include <QtCore/QRect> +#include <QtGui/QColor> + +namespace QtWebEngineCore { + class AuthenticationDialogController; + class ColorChooserController; + class FilePickerController; + class JavaScriptDialogController; +} + +QT_BEGIN_NAMESPACE + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineAuthenticationDialogRequest : public QObject { + Q_OBJECT +public: + + enum AuthenticationType { + AuthenticationTypeHTTP, + AuthenticationTypeProxy + }; + + Q_ENUM(AuthenticationType) + + Q_PROPERTY(QUrl url READ url CONSTANT FINAL) + Q_PROPERTY(QString realm READ realm CONSTANT FINAL) + Q_PROPERTY(QString proxyHost READ proxyHost CONSTANT FINAL) + Q_PROPERTY(AuthenticationType type READ type CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineAuthenticationDialogRequest(); + + QUrl url() const; + QString realm() const; + QString proxyHost() const; + AuthenticationType type() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QString &user, const QString &password); + void dialogReject(); + +private: + QQuickWebEngineAuthenticationDialogRequest(QSharedPointer<QtWebEngineCore::AuthenticationDialogController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::AuthenticationDialogController> m_controller; + QUrl m_url; + QString m_realm; + AuthenticationType m_type; + QString m_host; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineAuthenticationDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineJavaScriptDialogRequest : public QObject { + Q_OBJECT +public: + + enum DialogType { + DialogTypeAlert, + DialogTypeConfirm, + DialogTypePrompt, + DialogTypeBeforeUnload, + }; + Q_ENUM(DialogType) + + Q_PROPERTY(QString message READ message CONSTANT FINAL) + Q_PROPERTY(QString defaultText READ defaultText CONSTANT FINAL) + Q_PROPERTY(QString title READ title CONSTANT FINAL) + Q_PROPERTY(DialogType type READ type CONSTANT FINAL) + Q_PROPERTY(QUrl securityOrigin READ securityOrigin CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineJavaScriptDialogRequest(); + + QString message() const; + QString defaultText() const; + QString title() const; + DialogType type() const; + QUrl securityOrigin() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QString& text = QString()); + void dialogReject(); + +private: + QQuickWebEngineJavaScriptDialogRequest(QSharedPointer<QtWebEngineCore::JavaScriptDialogController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::JavaScriptDialogController> m_controller; + QString m_message; + QString m_defaultPrompt; + QString m_title; + DialogType m_type; + QUrl m_securityOrigin; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineJavaScriptDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineColorDialogRequest : public QObject { + Q_OBJECT +public: + + Q_PROPERTY(QColor color READ color CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineColorDialogRequest(); + + QColor color() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QColor &color); + void dialogReject(); + +private: + QQuickWebEngineColorDialogRequest(QSharedPointer<QtWebEngineCore::ColorChooserController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::ColorChooserController> m_controller; + QColor m_color; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineColorDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFileDialogRequest : public QObject { + Q_OBJECT +public: + + enum FileMode { + FileModeOpen, + FileModeOpenMultiple, + FileModeUploadFolder, + FileModeSave + }; + Q_ENUM(FileMode) + + Q_PROPERTY(QString defaultFileName READ defaultFileName CONSTANT FINAL) + Q_PROPERTY(QStringList acceptedMimeTypes READ acceptedMimeTypes CONSTANT FINAL) + Q_PROPERTY(FileMode mode READ mode CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineFileDialogRequest(); + + QStringList acceptedMimeTypes() const; + QString defaultFileName() const; + FileMode mode() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +public slots: + void dialogAccept(const QStringList &files); + void dialogReject(); + +private: + QQuickWebEngineFileDialogRequest(QSharedPointer<QtWebEngineCore::FilePickerController> controller, + QObject *parent = nullptr); + QWeakPointer<QtWebEngineCore::FilePickerController> m_controller; + QString m_filename; + QStringList m_acceptedMimeTypes; + FileMode m_mode; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; + Q_DISABLE_COPY(QQuickWebEngineFileDialogRequest) +}; + +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFormValidationMessageRequest : public QObject { + Q_OBJECT +public: + enum RequestType { + RequestTypeShow, + RequestTypeHide, + RequestTypeMove, + }; + Q_ENUM(RequestType) + Q_PROPERTY(QRect anchor READ anchor CONSTANT FINAL) + Q_PROPERTY(QString text READ text CONSTANT FINAL) + Q_PROPERTY(QString subText READ subText CONSTANT FINAL) + Q_PROPERTY(RequestType type READ type CONSTANT FINAL) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted FINAL) + + ~QQuickWebEngineFormValidationMessageRequest(); + QRect anchor() const; + QString text() const; + QString subText() const; + RequestType type() const; + bool isAccepted() const; + void setAccepted(bool accepted); + +private: + QQuickWebEngineFormValidationMessageRequest(RequestType type, const QRect &anchor = QRect(), + const QString &mainText = QString(), + const QString &subText = QString(), + QObject *parent = nullptr); + QRect m_anchor; + QString m_mainText; + QString m_subText; + RequestType m_type; + bool m_accepted; + friend class QQuickWebEngineViewPrivate; +}; + +QT_END_NAMESPACE + +#endif // QQUICKWEBENGINDIALOGREQUESTS_H diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index ad4d72d48..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" @@ -233,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()); @@ -285,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")); @@ -293,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")); @@ -306,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")); @@ -323,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")); @@ -337,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")); @@ -380,7 +389,13 @@ void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const Q void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> dialog) { - ui()->showDialog(dialog); + Q_Q(QQuickWebEngineView); + QQuickWebEngineJavaScriptDialogRequest *request = new QQuickWebEngineJavaScriptDialogRequest(dialog); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->javaScriptDialogRequested(request); + if (!request->isAccepted()) + ui()->showDialog(dialog); } void QQuickWebEngineViewPrivate::allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) @@ -405,12 +420,24 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller) { - ui()->showColorDialog(controller); + Q_Q(QQuickWebEngineView); + QQuickWebEngineColorDialogRequest *request = new QQuickWebEngineColorDialogRequest(controller); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->colorDialogRequested(request); + if (!request->isAccepted()) + ui()->showColorDialog(controller); } -void QQuickWebEngineViewPrivate::runFileChooser(FilePickerController* controller) +void QQuickWebEngineViewPrivate::runFileChooser(QSharedPointer<FilePickerController> controller) { - ui()->showFilePicker(controller); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFileDialogRequest *request = new QQuickWebEngineFileDialogRequest(controller); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->fileDialogRequested(request); + if (!request->isAccepted()) + ui()->showFilePicker(controller); } void QQuickWebEngineViewPrivate::passOnFocus(bool reverse) @@ -678,7 +705,13 @@ void QQuickWebEngineViewPrivate::javaScriptConsoleMessage(JavaScriptConsoleMessa void QQuickWebEngineViewPrivate::authenticationRequired(QSharedPointer<AuthenticationDialogController> controller) { - ui()->showDialog(controller); + Q_Q(QQuickWebEngineView); + QQuickWebEngineAuthenticationDialogRequest *request = new QQuickWebEngineAuthenticationDialogRequest(controller); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->authenticationDialogRequested(request); + if (!request->isAccepted()) + ui()->showDialog(controller); } void QQuickWebEngineViewPrivate::runMediaAccessPermissionRequest(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags requestFlags) @@ -1100,18 +1133,40 @@ void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, cons if (m_testSupport) Q_EMIT m_testSupport->validationMessageShown(mainText, subText); #endif - - ui()->showMessageBubble(anchor, mainText, subText); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFormValidationMessageRequest *request; + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeShow, + anchor,mainText,subText); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->formValidationMessageRequested(request); + if (!request->isAccepted()) + ui()->showMessageBubble(anchor, mainText, subText); } void QQuickWebEngineViewPrivate::hideValidationMessage() { - ui()->hideMessageBubble(); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFormValidationMessageRequest *request; + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeHide); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->formValidationMessageRequested(request); + if (!request->isAccepted()) + ui()->hideMessageBubble(); } void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor) { - ui()->moveMessageBubble(anchor); + Q_Q(QQuickWebEngineView); + QQuickWebEngineFormValidationMessageRequest *request; + request = new QQuickWebEngineFormValidationMessageRequest(QQuickWebEngineFormValidationMessageRequest::RequestTypeMove, + anchor); + // mark the object for gc by creating temporary jsvalue + qmlEngine(q)->newQObject(request); + Q_EMIT q->formValidationMessageRequested(request); + if (!request->isAccepted()) + ui()->moveMessageBubble(anchor); } void QQuickWebEngineViewPrivate::updateScrollPosition(const QPointF &position) @@ -1559,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(); @@ -1686,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 dc693a94c..1d44a48dd 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -59,15 +59,20 @@ QT_BEGIN_NAMESPACE class QQmlWebChannel; +class QQuickWebEngineAuthenticationDialogRequest; class QQuickWebEngineCertificateError; -class QQuickWebEngineContextMenuData; +class QQuickWebEngineColorDialogRequest; +class QQuickWebEngineContextMenuRequest; class QQuickWebEngineFaviconProvider; +class QQuickWebEngineFileDialogRequest; class QQuickWebEngineHistory; +class QQuickWebEngineJavaScriptDialogRequest; class QQuickWebEngineLoadRequest; class QQuickWebEngineNavigationRequest; class QQuickWebEngineNewViewRequest; class QQuickWebEngineProfile; class QQuickWebEngineSettings; +class QQuickWebEngineFormValidationMessageRequest; class QQuickWebEngineViewExperimental; class QQuickWebEngineViewPrivate; @@ -506,6 +511,12 @@ 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); + Q_REVISION(4) void fileDialogRequested(QQuickWebEngineFileDialogRequest *request); + Q_REVISION(4) void formValidationMessageRequested(QQuickWebEngineFormValidationMessageRequest *request); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 60692b8ae..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); @@ -161,7 +157,7 @@ public: virtual bool contextMenuRequested(const QtWebEngineCore::WebEngineContextMenuData &) Q_DECL_OVERRIDE; virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE; virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE; - virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE; + virtual void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) Q_DECL_OVERRIDE; virtual void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) Q_DECL_OVERRIDE; virtual void didRunJavaScript(quint64, const QVariant&) Q_DECL_OVERRIDE; virtual void didFetchDocumentMarkup(quint64, const QString&) Q_DECL_OVERRIDE { } @@ -221,7 +217,7 @@ public: QQuickWebEngineTestSupport *m_testSupport; #endif QQmlComponent *contextMenuExtraItems; - QQuickWebEngineContextMenuData contextMenuData; + QtWebEngineCore::WebEngineContextMenuData m_contextMenuData; QUrl explicitUrl; QUrl iconUrl; QQuickWebEngineFaviconProvider *faviconProvider; diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index 5e738f98d..d9b1f1154 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -47,6 +47,7 @@ depends += qtcore \ qtqml \ qtquick \ qtquickcontrols \ + qtquickcontrols2 \ qtdoc \ qtwebchannel \ qtwebview \ diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc index 2ef88e8a4..ced64dff7 100644 --- a/src/webengine/doc/src/external-resources.qdoc +++ b/src/webengine/doc/src/external-resources.qdoc @@ -116,3 +116,8 @@ \externalpage http://www.w3schools.com/tags/att_a_download.asp \title HTML download Attribute */ + +/*! + \externalpage https://www.iana.org/assignments/uri-schemes/prov/view-source + \title view-source URI scheme +*/ diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index 52f7da928..d63e2f4a7 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -42,6 +42,7 @@ \li \l{HTML5 Geolocation} \li \l{Pepper Plugin API} \li \l{Print to PDF} + \li \l{View Source} \li \l{WebRTC} \endlist @@ -222,6 +223,35 @@ Support for this feature was added in Qt 5.7.0. + \section1 View Source + + Qt WebEngine supports viewing the HTML source of a web page. + + This feature can be used from custom menus or assigned to custom events. + For more information, see WebEngineView::viewSource, WebEngineView::canViewSource, + QWebEnginePage::viewSource, and QWebEnginePage::canViewSource. + + This feature can be tested by opening a web page in \l{WebEngine Widgets + Simple Browser Example}{Simple Browser} or \l{WebEngine Quick Nano Browser} + {Nano Browser}, and then selecting \c{Page Source} in the context menu. The + \c{Page Source} context menu entry opens the source view in a new tab. + + For opening the source view in the current tab, URLs with \l{view-source URI scheme} + are also supported. For example, you can type the following URL to the URL bar + to view the HTML source of the qt.io web page: + \code + view-source:https://www.qt.io/ + \endcode + + Auto-completion of incomplete URLs with \l{view-source URI scheme} makes the usage of + this feature more comfortable. For example, the following incomplete URL also loads + the source view of the qt.io web page: + \code + view-source:qt.io + \endcode + + Support for this feature was added in Qt 5.8.0. + \section1 WebRTC WebRTC provides browsers with Real-Time Communications (RTC) capabilities diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index d2c239341..4acf3eb55 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -1160,3 +1160,87 @@ \sa viewSource() */ + +/*! + \qmlsignal WebEngineView::authenticationDialogRequested(AuthenticationDialogRequest request) + \since QtWebEngine 1.4 + + This signal is emitted when an authentication dialog is requested. + + The request can be handled by using the methods of the AuthenticationDialogRequest + type. + + \note Signal handlers need to call \c{request.accepted = true} to prevent a + default dialog from showing up. Make sure to call either + AuthenticationDialogRequest::dialogAccept() or AuthenticationDialogRequest::dialogReject() + afterwards. +*/ + +/*! + \qmlsignal WebEngineView::javaScriptDialogRequested(JavaScriptDialogRequest request) + \since QtWebEngine 1.4 + + This signal is emitted when a JavaScript dialog is requested. + + The request can be handled by using the methods of the JavaScriptDialogRequest + type. + + \note Signal handlers need to call \c{request.accepted = true} to prevent a + default dialog from showing up. Make sure to call either + JavaScriptDialogRequest::dialogAccept() or JavaScriptDialogRequest::dialogReject() + afterwards. +*/ + +/*! + \qmlsignal WebEngineView::colorDialogRequested(ColorDialogRequest request) + \since QtWebEngine 1.4 + + This signal is emitted when a color picker dialog is requested. + + The request can be handled by using the methods of the ColorDialogRequest + type. + + \note Signal handlers need to call \c{request.accepted = true} to prevent a + default dialog from showing up. Make sure to call either + ColorDialogRequest::dialogAccept() or ColorDialogRequest::dialogReject() afterwards. +*/ + +/*! + \qmlsignal WebEngineView::fileDialogRequested(FileDialogRequest request) + \since QtWebEngine 1.4 + + This signal is emitted when a file picker dialog is requested. + + The request error can be handled by using the methods of the FileDialogRequest + type. + + \note Signal handlers need to call \c{request.accepted = true} to prevent a + default dialog from showing up. Make sure to call either FileDialogRequest::dialogAccept() + or FileDialogRequest::dialogReject() afterwards. +*/ + +/*! + \qmlsignal WebEngineView::formValidationMessageRequested(FormValidationMessageRequest request) + \since QtWebEngine 1.4 + + This signal is emitted when a validation message is requested. + + The request can be handled by using the methods of the FormValidationMessageRequest + type. + + \note Signal handlers need to call \c{request.accepted = true} to prevent a + default dialog from showing up. +*/ + +/*! + \qmlsignal WebEngineView::contextMenuRequested(ContextMenuRequest request) + \since QtWebEngine 1.4 + + This signal is emitted when a context menu is requested. + + The request can be handled by using the properties of the ContextMenuRequest + type. + + \note Signal handlers need to call \c{request.accepted = true} to prevent a + default context menu from showing up. +*/ diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp index d4f68d142..d9043f6d3 100644 --- a/src/webengine/plugin/experimental/plugin.cpp +++ b/src/webengine/plugin/experimental/plugin.cpp @@ -41,7 +41,6 @@ #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" -#include "qquickwebenginecontextmenudata_p.h" QT_BEGIN_NAMESPACE @@ -56,7 +55,7 @@ public: class QtWebEngineExperimentalPlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: virtual void registerTypes(const char *uri) { @@ -70,10 +69,6 @@ public: tr("Cannot create a separate instance of WebEngineViewExperimental")); qmlRegisterUncreatableType<QQuickWebEngineViewport>(uri, 1, 0, "WebEngineViewport", tr("Cannot create a separate instance of WebEngineViewport")); - qmlRegisterUncreatableType<const QQuickWebEngineContextMenuData>(uri, 1, 0, "WebEngineContextMenuData", - tr("Cannot create a separate instance of WebEngineContextMenuData")); - qmlRegisterUncreatableType<const QQuickWebEngineContextMenuData, 1>(uri, 1, 1, "WebEngineContextMenuData", - tr("Cannot create a separate instance of WebEngineContextMenuData")); // Use the latest revision of QQuickWebEngineView when importing QtWebEngine.experimental 1.0 qmlRegisterRevision<QQuickWebEngineView, LATEST_WEBENGINEVIEW_REVISION>(uri, 1, 1); } diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index 5c33086c0..e9312a92a 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -41,6 +41,8 @@ #include <QtWebEngine/QQuickWebEngineProfile> #include "qquickwebenginecertificateerror_p.h" +#include "qquickwebenginecontextmenurequest_p.h" +#include "qquickwebenginedialogrequests_p.h" #include "qquickwebenginedownloaditem_p.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginefaviconprovider_p_p.h" @@ -62,7 +64,7 @@ static QObject *webEngineSingletonProvider(QQmlEngine *, QJSEngine *) class QtWebEnginePlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: virtual void initializeEngine(QQmlEngine *engine, const char *uri) { @@ -109,6 +111,19 @@ public: qmlRegisterUncreatableType<QQuickWebEngineFullScreenRequest>(uri, 1, 1, "FullScreenRequest", tr("Cannot create a separate instance of FullScreenRequest")); + qmlRegisterUncreatableType<QQuickWebEngineContextMenuRequest>(uri, 1, 4, "ContextMenuRequest", + tr("Cannot create separate instance of ContextMenuRequest")); + qmlRegisterUncreatableType<QQuickWebEngineAuthenticationDialogRequest>(uri, 1, 4, "AuthenticationDialogRequest", + tr("Cannot create separate instance of AuthenticationDialogRequest")); + qmlRegisterUncreatableType<QQuickWebEngineJavaScriptDialogRequest>(uri, 1, 4, "JavaScriptDialogRequest", + tr("Cannot create separate instance of JavaScriptDialogRequest")); + qmlRegisterUncreatableType<QQuickWebEngineColorDialogRequest>(uri, 1, 4, "ColorDialogRequest", + tr("Cannot create separate instance of ColorDialogRequest")); + qmlRegisterUncreatableType<QQuickWebEngineFileDialogRequest>(uri, 1, 4, "FileDialogRequest", + tr("Cannot create separate instance of FileDialogRequest")); + qmlRegisterUncreatableType<QQuickWebEngineFormValidationMessageRequest>(uri, 1, 4, "FormValidationMessageRequest", + tr("Cannot create separate instance of FormValidationMessageRequest")); + // For now (1.x import), the latest revision matches the minor version of the import. qmlRegisterRevision<QQuickWebEngineView, LATEST_WEBENGINEVIEW_REVISION>(uri, 1, LATEST_WEBENGINEVIEW_REVISION); } diff --git a/src/webengine/plugin/testsupport/plugin.cpp b/src/webengine/plugin/testsupport/plugin.cpp index e1252361e..9352e3666 100644 --- a/src/webengine/plugin/testsupport/plugin.cpp +++ b/src/webengine/plugin/testsupport/plugin.cpp @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE class QtWebEngineTestSupportPlugin : public QQmlExtensionPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: virtual void registerTypes(const char *uri) { diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 608ce2ab3..4ca4ba98c 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -445,7 +445,7 @@ void UIDelegatesManager::showDialog(QSharedPointer<AuthenticationDialogControlle QMetaObject::invokeMethod(authenticationDialog, "open"); } -void UIDelegatesManager::showFilePicker(FilePickerController *controller) +void UIDelegatesManager::showFilePicker(QSharedPointer<FilePickerController> controller) { if (!ensureComponentLoaded(FilePicker)) @@ -475,16 +475,14 @@ void UIDelegatesManager::showFilePicker(FilePickerController *controller) Q_UNREACHABLE(); } - controller->setParent(filePicker); - QQmlProperty filesPickedSignal(filePicker, QStringLiteral("onFilesSelected")); CHECK_QML_SIGNAL_PROPERTY(filesPickedSignal, filePickerComponent->url()); QQmlProperty rejectSignal(filePicker, QStringLiteral("onRejected")); CHECK_QML_SIGNAL_PROPERTY(rejectSignal, filePickerComponent->url()); static int acceptedIndex = controller->metaObject()->indexOfSlot("accepted(QVariant)"); - QObject::connect(filePicker, filesPickedSignal.method(), controller, controller->metaObject()->method(acceptedIndex)); + QObject::connect(filePicker, filesPickedSignal.method(), controller.data(), controller->metaObject()->method(acceptedIndex)); static int rejectedIndex = controller->metaObject()->indexOfSlot("rejected()"); - QObject::connect(filePicker, rejectSignal.method(), controller, controller->metaObject()->method(rejectedIndex)); + QObject::connect(filePicker, rejectSignal.method(), controller.data(), controller->metaObject()->method(rejectedIndex)); // delete when done. static int deleteLaterIndex = filePicker->metaObject()->indexOfSlot("deleteLater()"); diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h index b1eb65513..54ecf0986 100644 --- a/src/webengine/ui_delegates_manager.h +++ b/src/webengine/ui_delegates_manager.h @@ -118,7 +118,7 @@ public: void showColorDialog(QSharedPointer<ColorChooserController>); void showDialog(QSharedPointer<JavaScriptDialogController>); void showDialog(QSharedPointer<AuthenticationDialogController>); - void showFilePicker(FilePickerController *controller); + void showFilePicker(QSharedPointer<FilePickerController>); virtual void showMenu(QObject *menu); void showMessageBubble(const QRect &anchor, const QString &mainText, const QString &subText); diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 236881958..e84188682 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -12,7 +12,8 @@ INCLUDEPATH += $$PWD api ../core ../core/api SOURCES = \ api/qquickwebenginecertificateerror.cpp \ - api/qquickwebenginecontextmenudata.cpp \ + api/qquickwebenginecontextmenurequest.cpp \ + api/qquickwebenginedialogrequests.cpp \ api/qquickwebenginedownloaditem.cpp \ api/qquickwebenginehistory.cpp \ api/qquickwebenginefaviconprovider.cpp \ @@ -33,7 +34,8 @@ HEADERS = \ api/qtwebengineglobal.h \ api/qtwebengineglobal_p.h \ api/qquickwebenginecertificateerror_p.h \ - api/qquickwebenginecontextmenudata_p.h \ + api/qquickwebenginecontextmenurequest_p.h \ + api/qquickwebenginedialogrequests_p.h \ api/qquickwebenginedownloaditem_p.h \ api/qquickwebenginedownloaditem_p_p.h \ api/qquickwebenginehistory_p.h \ diff --git a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp index 808c6f8b0..23be32bf6 100644 --- a/src/webenginewidgets/api/qwebenginecontextmenudata.cpp +++ b/src/webenginewidgets/api/qwebenginecontextmenudata.cpp @@ -135,7 +135,7 @@ void QWebEngineContextMenuData::reset() */ QPoint QWebEngineContextMenuData::position() const { - return d ? d->pos : QPoint(); + return d ? d->position() : QPoint(); } /*! @@ -143,7 +143,7 @@ QPoint QWebEngineContextMenuData::position() const */ QString QWebEngineContextMenuData::linkText() const { - return d ? d->linkText : QString(); + return d ? d->linkText() : QString(); } /*! @@ -151,7 +151,7 @@ QString QWebEngineContextMenuData::linkText() const */ QUrl QWebEngineContextMenuData::linkUrl() const { - return d ? d->linkUrl : QUrl(); + return d ? d->linkUrl() : QUrl(); } /*! @@ -159,7 +159,7 @@ QUrl QWebEngineContextMenuData::linkUrl() const */ QString QWebEngineContextMenuData::selectedText() const { - return d ? d->selectedText : QString(); + return d ? d->selectedText() : QString(); } /*! @@ -167,7 +167,7 @@ QString QWebEngineContextMenuData::selectedText() const */ QUrl QWebEngineContextMenuData::mediaUrl() const { - return d ? d->mediaUrl : QUrl(); + return d ? d->mediaUrl() : QUrl(); } /*! @@ -175,7 +175,7 @@ QUrl QWebEngineContextMenuData::mediaUrl() const */ QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() const { - return d ? static_cast<QWebEngineContextMenuData::MediaType>(d->mediaType) : MediaTypeNone; + return d ? static_cast<QWebEngineContextMenuData::MediaType>(d->mediaType()) : MediaTypeNone; } /*! @@ -183,7 +183,7 @@ QWebEngineContextMenuData::MediaType QWebEngineContextMenuData::mediaType() cons */ bool QWebEngineContextMenuData::isContentEditable() const { - return d ? d->isEditable : false; + return d ? d->isEditable() : false; } /*! @@ -194,7 +194,7 @@ bool QWebEngineContextMenuData::isContentEditable() const QString QWebEngineContextMenuData::misspelledWord() const { if (d) - return d->misspelledWord; + return d->misspelledWord(); return QString(); } @@ -206,7 +206,7 @@ QString QWebEngineContextMenuData::misspelledWord() const QStringList QWebEngineContextMenuData::spellCheckerSuggestions() const { if (d) - return d->spellCheckerSuggestions; + return d->spellCheckerSuggestions(); return QStringList(); } diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 428cccd9a..37c156e17 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -1056,122 +1056,122 @@ void QWebEnginePage::triggerAction(WebAction action, bool) d->adapter->unselect(); break; case OpenLinkInThisWindow: - if (menuData.linkUrl.isValid()) - setUrl(menuData.linkUrl); + if (menuData.linkUrl().isValid()) + setUrl(menuData.linkUrl()); break; case OpenLinkInNewWindow: - if (menuData.linkUrl.isValid()) { + if (menuData.linkUrl().isValid()) { QWebEnginePage *newPage = createWindow(WebBrowserWindow); if (newPage) - newPage->setUrl(menuData.linkUrl); + newPage->setUrl(menuData.linkUrl()); } break; case OpenLinkInNewTab: - if (menuData.linkUrl.isValid()) { + if (menuData.linkUrl().isValid()) { QWebEnginePage *newPage = createWindow(WebBrowserTab); if (newPage) - newPage->setUrl(menuData.linkUrl); + newPage->setUrl(menuData.linkUrl()); } break; case OpenLinkInNewBackgroundTab: - if (menuData.linkUrl.isValid()) { + if (menuData.linkUrl().isValid()) { QWebEnginePage *newPage = createWindow(WebBrowserBackgroundTab); if (newPage) - newPage->setUrl(menuData.linkUrl); + newPage->setUrl(menuData.linkUrl()); } break; case CopyLinkToClipboard: - if (menuData.linkUrl.isValid()) { - QString urlString = menuData.linkUrl.toString(QUrl::FullyEncoded); - QString title = menuData.linkText.toHtmlEscaped(); + if (menuData.linkUrl().isValid()) { + QString urlString = menuData.linkUrl().toString(QUrl::FullyEncoded); + QString title = menuData.linkText().toHtmlEscaped(); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral("<a href=\"") + urlString + QStringLiteral("\">") + title + QStringLiteral("</a>"); data->setHtml(html); - data->setUrls(QList<QUrl>() << menuData.linkUrl); + data->setUrls(QList<QUrl>() << menuData.linkUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadLinkToDisk: - if (menuData.linkUrl.isValid()) - d->adapter->download(menuData.linkUrl, menuData.suggestedFileName); + if (menuData.linkUrl().isValid()) + d->adapter->download(menuData.linkUrl(), menuData.suggestedFileName()); break; case CopyImageToClipboard: - if (menuData.hasImageContent && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeImage || - menuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas)) + if (menuData.hasImageContent() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas)) { - d->adapter->copyImageAt(menuData.pos); + d->adapter->copyImageAt(menuData.position()); } break; case CopyImageUrlToClipboard: - if (menuData.mediaUrl.isValid() && menuData.mediaType == WebEngineContextMenuData::MediaTypeImage) { - QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded); - QString title = menuData.linkText; + if (menuData.mediaUrl().isValid() && menuData.mediaType() == WebEngineContextMenuData::MediaTypeImage) { + QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded); + QString title = menuData.linkText(); if (!title.isEmpty()) title = QStringLiteral(" alt=\"%1\"").arg(title.toHtmlEscaped()); QMimeData *data = new QMimeData(); data->setText(urlString); QString html = QStringLiteral("<img src=\"") + urlString + QStringLiteral("\"") + title + QStringLiteral("></img>"); data->setHtml(html); - data->setUrls(QList<QUrl>() << menuData.mediaUrl); + data->setUrls(QList<QUrl>() << menuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case DownloadImageToDisk: case DownloadMediaToDisk: - if (menuData.mediaUrl.isValid()) - d->adapter->download(menuData.mediaUrl, menuData.suggestedFileName); + if (menuData.mediaUrl().isValid()) + d->adapter->download(menuData.mediaUrl(), menuData.suggestedFileName()); break; case CopyMediaUrlToClipboard: - if (menuData.mediaUrl.isValid() && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (menuData.mediaUrl().isValid() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - QString urlString = menuData.mediaUrl.toString(QUrl::FullyEncoded); + QString urlString = menuData.mediaUrl().toString(QUrl::FullyEncoded); QMimeData *data = new QMimeData(); data->setText(urlString); - if (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio) + if (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio) data->setHtml(QStringLiteral("<audio src=\"") + urlString + QStringLiteral("\"></audio>")); else data->setHtml(QStringLiteral("<video src=\"") + urlString + QStringLiteral("\"></video>")); - data->setUrls(QList<QUrl>() << menuData.mediaUrl); + data->setUrls(QList<QUrl>() << menuData.mediaUrl()); qApp->clipboard()->setMimeData(data); } break; case ToggleMediaControls: - if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { - bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaControls); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerControls, enable); + if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) { + bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaControls); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerControls, enable); } break; case ToggleMediaLoop: - if (menuData.mediaUrl.isValid() && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (menuData.mediaUrl().isValid() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaLoop); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerLoop, enable); + bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaLoop); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerLoop, enable); } break; case ToggleMediaPlayPause: - if (menuData.mediaUrl.isValid() && - (menuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || - menuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + if (menuData.mediaUrl().isValid() && + (menuData.mediaType() == WebEngineContextMenuData::MediaTypeAudio || + menuData.mediaType() == WebEngineContextMenuData::MediaTypeVideo)) { - bool enable = (menuData.mediaFlags & WebEngineContextMenuData::MediaPaused); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerPlay, enable); + bool enable = (menuData.mediaFlags() & WebEngineContextMenuData::MediaPaused); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerPlay, enable); } break; case ToggleMediaMute: - if (menuData.mediaUrl.isValid() && menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + if (menuData.mediaUrl().isValid() && menuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) { // Make sure to negate the value, so that toggling actually works. - bool enable = !(menuData.mediaFlags & WebEngineContextMenuData::MediaMuted); - d->adapter->executeMediaPlayerActionAt(menuData.pos, WebContentsAdapter::MediaPlayerMute, enable); + bool enable = !(menuData.mediaFlags() & WebEngineContextMenuData::MediaMuted); + d->adapter->executeMediaPlayerActionAt(menuData.position(), WebContentsAdapter::MediaPlayerMute, enable); } break; case InspectElement: - d->adapter->inspectElementAt(menuData.pos); + d->adapter->inspectElementAt(menuData.position()); break; case ExitFullScreen: d->adapter->exitFullScreen(); @@ -1253,7 +1253,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData return false; contextData.reset(); - QContextMenuEvent event(QContextMenuEvent::Mouse, data.pos, view->mapToGlobal(data.pos)); + QContextMenuEvent event(QContextMenuEvent::Mouse, data.position(), view->mapToGlobal(data.position())); switch (view->contextMenuPolicy()) { case Qt::PreventContextMenu: return false; @@ -1263,7 +1263,7 @@ bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData break; case Qt::CustomContextMenu: contextData = data; - Q_EMIT view->customContextMenuRequested(data.pos); + Q_EMIT view->customContextMenuRequested(data.position()); break; case Qt::ActionsContextMenu: if (view->actions().count()) { @@ -1418,11 +1418,11 @@ QMenu *QWebEnginePage::createStandardContextMenu() QAction *action = 0; const WebEngineContextMenuData &contextMenuData = *d->contextData.d; - if (contextMenuData.isEditable && !contextMenuData.spellCheckerSuggestions.isEmpty()) { + if (contextMenuData.isEditable() && !contextMenuData.spellCheckerSuggestions().isEmpty()) { QPointer<QWebEnginePage> thisRef(this); - for (int i=0; i < contextMenuData.spellCheckerSuggestions.count() && i < 4; i++) { + for (int i=0; i < contextMenuData.spellCheckerSuggestions().count() && i < 4; i++) { QAction *action = new QAction(menu); - QString replacement = contextMenuData.spellCheckerSuggestions.at(i); + QString replacement = contextMenuData.spellCheckerSuggestions().at(i); QObject::connect(action, &QAction::triggered, [thisRef, replacement] { if (thisRef) thisRef->replaceMisspelledWord(replacement); }); action->setText(replacement); menu->addAction(action); @@ -1430,13 +1430,13 @@ QMenu *QWebEnginePage::createStandardContextMenu() menu->addSeparator(); } - if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) { + if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) { action = QWebEnginePage::action(OpenLinkInThisWindow); action->setText(tr("Follow Link")); menu->addAction(action); menu->addAction(QWebEnginePage::action(DownloadLinkToDisk)); } - if (contextMenuData.selectedText.isEmpty()) { + if (contextMenuData.selectedText().isEmpty()) { action = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), tr("&Back"), menu); connect(action, &QAction::triggered, d->view, &QWebEngineView::back); action->setEnabled(d->adapter->canGoBack()); @@ -1457,11 +1457,11 @@ QMenu *QWebEnginePage::createStandardContextMenu() menu->addAction(QWebEnginePage::action(Unselect)); } - if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) { + if (!contextMenuData.linkText().isEmpty() && contextMenuData.linkUrl().isValid()) { menu->addAction(QWebEnginePage::action(CopyLinkToClipboard)); } - if (contextMenuData.mediaUrl.isValid()) { - switch (contextMenuData.mediaType) { + if (contextMenuData.mediaUrl().isValid()) { + switch (contextMenuData.mediaType()) { case WebEngineContextMenuData::MediaTypeImage: menu->addAction(QWebEnginePage::action(DownloadImageToDisk)); menu->addAction(QWebEnginePage::action(CopyImageUrlToClipboard)); @@ -1476,15 +1476,15 @@ QMenu *QWebEnginePage::createStandardContextMenu() menu->addAction(QWebEnginePage::action(CopyMediaUrlToClipboard)); menu->addAction(QWebEnginePage::action(ToggleMediaPlayPause)); menu->addAction(QWebEnginePage::action(ToggleMediaLoop)); - if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) + if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaHasAudio) menu->addAction(QWebEnginePage::action(ToggleMediaMute)); - if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) + if (contextMenuData.mediaFlags() & WebEngineContextMenuData::MediaCanToggleControls) menu->addAction(QWebEnginePage::action(ToggleMediaControls)); break; default: break; } - } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) { + } else if (contextMenuData.mediaType() == WebEngineContextMenuData::MediaTypeCanvas) { menu->addAction(QWebEnginePage::action(CopyImageToClipboard)); } @@ -1542,7 +1542,7 @@ static inline QWebEnginePage::FileSelectionMode toPublic(FilePickerController::F return static_cast<QWebEnginePage::FileSelectionMode>(mode); } -void QWebEnginePagePrivate::runFileChooser(FilePickerController *controller) +void QWebEnginePagePrivate::runFileChooser(QSharedPointer<FilePickerController> controller) { Q_Q(QWebEnginePage); diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 93ebdf6e6..8d78429d8 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -112,7 +112,7 @@ public: virtual void requestFullScreenMode(const QUrl &origin, bool fullscreen) Q_DECL_OVERRIDE; virtual bool isFullScreenMode() const Q_DECL_OVERRIDE; virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE; - virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE; + virtual void runFileChooser(QSharedPointer<QtWebEngineCore::FilePickerController>) Q_DECL_OVERRIDE; virtual void showColorDialog(QSharedPointer<QtWebEngineCore::ColorChooserController>) Q_DECL_OVERRIDE; virtual void didRunJavaScript(quint64 requestId, const QVariant& result) Q_DECL_OVERRIDE; virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) Q_DECL_OVERRIDE; |