diff options
Diffstat (limited to 'src/webengine')
28 files changed, 864 insertions, 222 deletions
diff --git a/src/webengine/api/qquickwebenginenewviewrequest.cpp b/src/webengine/api/qquickwebenginenewviewrequest.cpp index 68ea73208..893df7f46 100644 --- a/src/webengine/api/qquickwebenginenewviewrequest.cpp +++ b/src/webengine/api/qquickwebenginenewviewrequest.cpp @@ -89,7 +89,7 @@ bool QQuickWebEngineNewViewRequest::isUserInitiated() const */ void QQuickWebEngineNewViewRequest::openIn(QQuickWebEngineView *view) { - if (!m_adapter) { + if (!m_adapter && !m_requestedUrl.isValid()) { qWarning("Trying to open an empty request, it was either already used or was invalidated." "\nYou must complete the request synchronously within the newViewRequested signal handler." " If a view hasn't been adopted before returning, the request will be invalidated."); @@ -100,6 +100,9 @@ void QQuickWebEngineNewViewRequest::openIn(QQuickWebEngineView *view) qWarning("Trying to open a WebEngineNewViewRequest in an invalid WebEngineView."); return; } - view->d_func()->adoptWebContents(m_adapter.data()); + if (m_adapter) + view->d_func()->adoptWebContents(m_adapter.data()); + else + view->setUrl(m_requestedUrl); m_adapter.reset(); } diff --git a/src/webengine/api/qquickwebenginenewviewrequest_p.h b/src/webengine/api/qquickwebenginenewviewrequest_p.h index f9fac13e9..b408812ba 100644 --- a/src/webengine/api/qquickwebenginenewviewrequest_p.h +++ b/src/webengine/api/qquickwebenginenewviewrequest_p.h @@ -73,6 +73,8 @@ private: QQuickWebEngineView::NewViewDestination m_destination; bool m_isUserInitiated; QExplicitlySharedDataPointer<QtWebEngineCore::WebContentsAdapter> m_adapter; + QUrl m_requestedUrl; + friend class QQuickWebEngineView; friend class QQuickWebEngineViewPrivate; }; diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index 68884f967..67c74c356 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -40,6 +40,7 @@ #include "qquickwebenginedownloaditem_p_p.h" #include "qquickwebengineprofile_p_p.h" #include "qquickwebenginesettings_p.h" +#include "qwebenginecookiestoreclient.h" #include <QQmlEngine> @@ -56,6 +57,9 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapt { m_browserContextRef->addClient(this); m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord()); + // Fullscreen API was implemented before the supported setting, so we must + // make it default true to avoid change in default API behavior. + m_settings->d_ptr->setAttribute(QtWebEngineCore::WebEngineSettings::FullScreenSupportEnabled, true); } QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate() @@ -384,6 +388,28 @@ void QQuickWebEngineProfile::setHttpCacheMaximumSize(int maximumSize) emit httpCacheMaximumSizeChanged(); } +/*! + \qmlproperty QString WebEngineProfile::httpAcceptLanguage + + The value of the Accept-Language HTTP request-header field. + + \since QtWebEngine 1.2 +*/ +QString QQuickWebEngineProfile::httpAcceptLanguage() const +{ + Q_D(const QQuickWebEngineProfile); + return d->browserContext()->httpAcceptLanguage(); +} + +void QQuickWebEngineProfile::setHttpAcceptLanguage(const QString &httpAcceptLanguage) +{ + Q_D(QQuickWebEngineProfile); + if (d->browserContext()->httpAcceptLanguage() == httpAcceptLanguage) + return; + d->browserContext()->setHttpAcceptLanguage(httpAcceptLanguage); + emit httpAcceptLanguageChanged(); +} + QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() { static QQuickWebEngineProfile *profile = new QQuickWebEngineProfile( @@ -398,4 +424,10 @@ QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const return d->settings(); } +void QQuickWebEngineProfile::setCookieStoreClient(QWebEngineCookieStoreClient* client) +{ + Q_D(QQuickWebEngineProfile); + d->browserContext()->setCookieStoreClient(client); +} + QT_END_NAMESPACE diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h index 323721bd0..af5762032 100644 --- a/src/webengine/api/qquickwebengineprofile_p.h +++ b/src/webengine/api/qquickwebengineprofile_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QQuickWebEngineDownloadItem; class QQuickWebEngineProfilePrivate; class QQuickWebEngineSettings; +class QWebEngineCookieStoreClient; class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject { Q_OBJECT @@ -74,6 +75,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(QString cachePath READ cachePath WRITE setCachePath NOTIFY cachePathChanged FINAL) Q_PROPERTY(QString httpUserAgent READ httpUserAgent WRITE setHttpUserAgent NOTIFY httpUserAgentChanged FINAL) Q_PROPERTY(HttpCacheType httpCacheType READ httpCacheType WRITE setHttpCacheType NOTIFY httpCacheTypeChanged FINAL) + Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL) Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL) Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL) public: @@ -115,8 +117,13 @@ public: int httpCacheMaximumSize() const; void setHttpCacheMaximumSize(int maxSize); + Q_REVISION(1) QString httpAcceptLanguage() const; + Q_REVISION(1) void setHttpAcceptLanguage(const QString &httpAcceptLanguage); + static QQuickWebEngineProfile *defaultProfile(); + Q_REVISION(1) Q_INVOKABLE void setCookieStoreClient(QWebEngineCookieStoreClient* client); + signals: void storageNameChanged(); void offTheRecordChanged(); @@ -126,6 +133,7 @@ signals: void httpCacheTypeChanged(); void persistentCookiesPolicyChanged(); void httpCacheMaximumSizeChanged(); + Q_REVISION(1) void httpAcceptLanguageChanged(); void downloadRequested(QQuickWebEngineDownloadItem *download); void downloadFinished(QQuickWebEngineDownloadItem *download); diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp index 248713543..539f211b0 100644 --- a/src/webengine/api/qquickwebenginesettings.cpp +++ b/src/webengine/api/qquickwebenginesettings.cpp @@ -206,6 +206,31 @@ bool QQuickWebEngineSettings::errorPageEnabled() const } /*! + \qmlproperty bool WebEngineSettings::pluginsEnabled + + Enables support for Pepper plugins, such as the Flash player. + + Disabled by default. +*/ +bool QQuickWebEngineSettings::pluginsEnabled() const +{ + return d_ptr->testAttribute(WebEngineSettings::PluginsEnabled); +} + +/*! + \qmlproperty bool WebEngineSettings::fullscreenSupportEnabled + \since QtWebEngine 1.2 + + Tells the web engine whether fullscreen is supported in this application or not. + + Enabled by default. +*/ +bool QQuickWebEngineSettings::fullScreenSupportEnabled() const +{ + return d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled); +} + +/*! \qmlproperty QString WebEngineSettings::defaultTextEncoding Sets the default encoding. The value must be a string describing an encoding such as "utf-8" or @@ -309,6 +334,22 @@ void QQuickWebEngineSettings::setErrorPageEnabled(bool on) Q_EMIT errorPageEnabledChanged(); } +void QQuickWebEngineSettings::setPluginsEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::PluginsEnabled); + d_ptr->setAttribute(WebEngineSettings::PluginsEnabled, on); + if (wasOn != on) + Q_EMIT pluginsEnabledChanged(); +} + +void QQuickWebEngineSettings::setFullScreenSupportEnabled(bool on) +{ + bool wasOn = d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled); + d_ptr->setAttribute(WebEngineSettings::FullScreenSupportEnabled, on); + if (wasOn != on) + Q_EMIT fullScreenSupportEnabledChanged(); +} + void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding) { const QString oldDefaultTextEncoding = d_ptr->defaultTextEncoding(); diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h index 213505078..604e5693d 100644 --- a/src/webengine/api/qquickwebenginesettings_p.h +++ b/src/webengine/api/qquickwebenginesettings_p.h @@ -71,6 +71,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject { Q_PROPERTY(bool localContentCanAccessFileUrls READ localContentCanAccessFileUrls WRITE setLocalContentCanAccessFileUrls NOTIFY localContentCanAccessFileUrlsChanged) Q_PROPERTY(bool hyperlinkAuditingEnabled READ hyperlinkAuditingEnabled WRITE setHyperlinkAuditingEnabled NOTIFY hyperlinkAuditingEnabledChanged) Q_PROPERTY(bool errorPageEnabled READ errorPageEnabled WRITE setErrorPageEnabled NOTIFY errorPageEnabledChanged) + Q_PROPERTY(bool pluginsEnabled READ pluginsEnabled WRITE setPluginsEnabled NOTIFY pluginsEnabledChanged) + Q_PROPERTY(bool fullScreenSupportEnabled READ fullScreenSupportEnabled WRITE setFullScreenSupportEnabled NOTIFY fullScreenSupportEnabledChanged REVISION 1) Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged) public: @@ -87,6 +89,8 @@ public: bool localContentCanAccessFileUrls() const; bool hyperlinkAuditingEnabled() const; bool errorPageEnabled() const; + bool pluginsEnabled() const; + bool fullScreenSupportEnabled() const; QString defaultTextEncoding() const; void setAutoLoadImages(bool on); @@ -100,6 +104,8 @@ public: void setLocalContentCanAccessFileUrls(bool on); void setHyperlinkAuditingEnabled(bool on); void setErrorPageEnabled(bool on); + void setPluginsEnabled(bool on); + void setFullScreenSupportEnabled(bool on); void setDefaultTextEncoding(QString encoding); signals: @@ -114,6 +120,8 @@ signals: void localContentCanAccessFileUrlsChanged(); void hyperlinkAuditingEnabledChanged(); void errorPageEnabledChanged(); + void pluginsEnabledChanged(); + Q_REVISION(1) void fullScreenSupportEnabledChanged(); void defaultTextEncodingChanged(); private: diff --git a/src/webengine/api/qquickwebenginetestsupport_p.h b/src/webengine/api/qquickwebenginetestsupport_p.h index 8d52dfa7c..9690e538d 100644 --- a/src/webengine/api/qquickwebenginetestsupport_p.h +++ b/src/webengine/api/qquickwebenginetestsupport_p.h @@ -78,6 +78,9 @@ public: QQuickWebEngineTestSupport(); QQuickWebEngineErrorPage *errorPage() const; +Q_SIGNALS: + void validationMessageShown(const QString &mainText, const QString &subText); + private: QScopedPointer<QQuickWebEngineErrorPage> m_errorPage; }; diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 6c3452a6a..65b98ca98 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -39,6 +39,7 @@ #include "browser_context_adapter.h" #include "certificate_error_controller.h" +#include "file_picker_controller.h" #include "javascript_dialog_controller.h" #include "qquickwebenginehistory_p.h" #include "qquickwebenginecertificateerror_p.h" @@ -63,7 +64,9 @@ #include "web_engine_settings.h" #include "web_engine_visited_links_manager.h" +#include <QClipboard> #include <QGuiApplication> +#include <QMimeData> #include <QQmlComponent> #include <QQmlContext> #include <QQmlEngine> @@ -102,8 +105,10 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , loadProgress(0) , m_isFullScreen(false) , isLoading(false) + , m_activeFocusOnPress(true) , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio()) , m_dpiScale(1.0) + , m_backgroundColor(Qt::white) { // The gold standard for mobile web content is 160 dpi, and the devicePixelRatio expected // is the (possibly quantized) ratio of device dpi to 160 dpi. @@ -175,31 +180,101 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu if (!menu) return false; + contextMenuData = data; + // Populate our menu MenuItemHandler *item = 0; + 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()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goBack); - ui()->addMenuItem(item, QObject::tr("Back"), QStringLiteral("go-previous"), q->canGoBack()); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Back"), QStringLiteral("go-previous"), q->canGoBack()); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::goForward); - ui()->addMenuItem(item, QObject::tr("Forward"), QStringLiteral("go-next"), q->canGoForward()); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Forward"), QStringLiteral("go-next"), q->canGoForward()); item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::reload); - ui()->addMenuItem(item, QObject::tr("Reload"), QStringLiteral("view-refresh")); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Reload"), QStringLiteral("view-refresh")); } else { - item = new CopyMenuItem(menu, data.selectedText); - ui()->addMenuItem(item, QObject::tr("Copy...")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::Copy); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy")); } - if (!data.linkText.isEmpty() && data.linkUrl.isValid()) { - item = new NavigateMenuItem(menu, adapter, data.linkUrl); - ui()->addMenuItem(item, QObject::tr("Navigate to...")); - item = new CopyMenuItem(menu, data.linkUrl.toString()); - ui()->addMenuItem(item, QObject::tr("Copy link address")); + if (!contextMenuData.linkText.isEmpty() && contextMenuData.linkUrl.isValid()) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyLinkToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Link URL")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadLinkToDisk); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Link...")); + } + if (contextMenuData.mediaUrl.isValid()) { + switch (contextMenuData.mediaType) { + case WebEngineContextMenuData::MediaTypeImage: + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageUrlToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image URL")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadImageToDisk); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Save Image")); + break; + case WebEngineContextMenuData::MediaTypeCanvas: + Q_UNREACHABLE(); // mediaUrl is invalid for canvases + break; + 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")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::DownloadMediaToDisk); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Download Media")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaPlayPause); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Play/Pause")); + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaLoop); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Looping")); + if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaMute); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Mute")); + } + if (contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ToggleMediaControls); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Toggle Media Controls")); + } + break; + default: + break; + } + } else if (contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::CopyImageToClipboard); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Copy Image")); + } + if (adapter->hasInspector()) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::InspectElement); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Inspect Element")); + } + if (isFullScreen()) { + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::ExitFullScreen); }); + ui()->addMenuItem(item, QQuickWebEngineView::tr("Exit Full Screen Mode")); } // FIXME: expose the context menu data as an attached property to make this more useful @@ -251,9 +326,9 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation); } -void QQuickWebEngineViewPrivate::runFileChooser(FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) +void QQuickWebEngineViewPrivate::runFileChooser(FilePickerController* controller) { - ui()->showFilePicker(mode, defaultFileName, acceptedMimeTypes, adapter); + ui()->showFilePicker(controller); } void QQuickWebEngineViewPrivate::passOnFocus(bool reverse) @@ -310,6 +385,11 @@ qreal QQuickWebEngineViewPrivate::dpiScale() const return m_dpiScale; } +QColor QQuickWebEngineViewPrivate::backgroundColor() const +{ + return m_backgroundColor; +} + void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage) { Q_Q(QQuickWebEngineView); @@ -581,7 +661,7 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent) Q_D(QQuickWebEngineView); d->e->q_ptr = d->q_ptr = this; this->setActiveFocusOnTab(true); - this->setFlag(QQuickItem::ItemIsFocusScope); + this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsInputMethod); #ifndef QT_NO_ACCESSIBILITY QQuickAccessibleAttached *accessible = QQuickAccessibleAttached::qmlAttachedProperties(this); @@ -754,8 +834,23 @@ void QQuickWebEngineView::setTestSupport(QQuickWebEngineTestSupport *testSupport Q_D(QQuickWebEngineView); d->m_testSupport = testSupport; } + #endif +/*! + * \qmlproperty bool WebEngineView::activeFocusOnPress + * \since QtWebEngine 1.2 + * + * This property specifies whether the view should gain active focus when pressed. + * The default value is true. + * + */ +bool QQuickWebEngineView::activeFocusOnPress() const +{ + Q_D(const QQuickWebEngineView); + return d->m_activeFocusOnPress; +} + void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVariant &result) { Q_Q(QQuickWebEngineView); @@ -774,6 +869,11 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount) } void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) { +#ifdef ENABLE_QML_TESTSUPPORT_API + if (m_testSupport) + Q_EMIT m_testSupport->validationMessageShown(mainText, subText); +#endif + ui()->showMessageBubble(anchor, mainText, subText); } @@ -849,6 +949,34 @@ qreal QQuickWebEngineView::zoomFactor() const return d->adapter->currentZoomFactor(); } +/*! + \qmlproperty bool WebEngineView::backgroundColor + \since QtWebEngine 1.2 + + Sets this property to change the color of the WebEngineView's background, + behing the document's body. You can set it to "transparent" or to a translucent + color to see through the document, or you can set this color to match your + web content in an hybrid app to prevent the white flashes that may appear + during loading. + + The default value is white. +*/ +QColor QQuickWebEngineView::backgroundColor() const +{ + Q_D(const QQuickWebEngineView); + return d->m_backgroundColor; +} + +void QQuickWebEngineView::setBackgroundColor(const QColor &color) +{ + Q_D(QQuickWebEngineView); + if (color == d->m_backgroundColor) + return; + d->m_backgroundColor = color; + d->ensureContentsAdapter(); + d->adapter->backgroundColorChanged(); + emit backgroundColorChanged(); +} bool QQuickWebEngineView::isFullScreen() const { @@ -943,6 +1071,16 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu } } +void QQuickWebEngineView::setActiveFocusOnPress(bool arg) +{ + Q_D(QQuickWebEngineView); + if (d->m_activeFocusOnPress == arg) + return; + + d->m_activeFocusOnPress = arg; + emit activeFocusOnPressChanged(arg); +} + void QQuickWebEngineView::goBackOrForward(int offset) { Q_D(QQuickWebEngineView); @@ -988,6 +1126,168 @@ void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &va QQuickItem::itemChange(change, value); } +void QQuickWebEngineView::triggerWebAction(WebAction action) +{ + Q_D(QQuickWebEngineView); + switch (action) { + case Back: + d->adapter->navigateToOffset(-1); + break; + case Forward: + d->adapter->navigateToOffset(1); + break; + case Stop: + d->adapter->stop(); + break; + case Reload: + d->adapter->reload(); + break; + case ReloadAndBypassCache: + d->adapter->reloadAndBypassCache(); + break; + case Cut: + d->adapter->cut(); + break; + case Copy: + d->adapter->copy(); + break; + case Paste: + d->adapter->paste(); + break; + case Undo: + d->adapter->undo(); + break; + case Redo: + d->adapter->redo(); + break; + case SelectAll: + d->adapter->selectAll(); + break; + case PasteAndMatchStyle: + d->adapter->pasteAndMatchStyle(); + break; + case OpenLinkInThisWindow: + if (d->contextMenuData.linkUrl.isValid()) + setUrl(d->contextMenuData.linkUrl); + break; + case OpenLinkInNewWindow: + if (d->contextMenuData.linkUrl.isValid()) { + QQuickWebEngineNewViewRequest request; + request.m_requestedUrl = d->contextMenuData.linkUrl; + request.m_isUserInitiated = true; + request.m_destination = NewViewInWindow; + Q_EMIT newViewRequested(&request); + } + break; + case OpenLinkInNewTab: + if (d->contextMenuData.linkUrl.isValid()) { + QQuickWebEngineNewViewRequest request; + request.m_requestedUrl = d->contextMenuData.linkUrl; + request.m_isUserInitiated = true; + request.m_destination = NewViewInBackgroundTab; + Q_EMIT newViewRequested(&request); + } + break; + case CopyLinkToClipboard: + if (d->contextMenuData.linkUrl.isValid()) { + QString urlString = d->contextMenuData.linkUrl.toString(QUrl::FullyEncoded); + QString title = d->contextMenuData.linkText.toHtmlEscaped(); + 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); + qApp->clipboard()->setMimeData(data); + } + break; + case DownloadLinkToDisk: + if (d->contextMenuData.linkUrl.isValid()) + d->adapter->download(d->contextMenuData.linkUrl, d->contextMenuData.suggestedFileName); + break; + case CopyImageToClipboard: + if (d->contextMenuData.hasImageContent && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeCanvas)) + { + d->adapter->copyImageAt(d->contextMenuData.pos); + } + break; + case CopyImageUrlToClipboard: + if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeImage) { + QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded); + QString title = d->contextMenuData.linkText; + if (!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); + qApp->clipboard()->setMimeData(data); + } + break; + case DownloadImageToDisk: + case DownloadMediaToDisk: + if (d->contextMenuData.mediaUrl.isValid()) + d->adapter->download(d->contextMenuData.mediaUrl, d->contextMenuData.suggestedFileName); + break; + case CopyMediaUrlToClipboard: + if (d->contextMenuData.mediaUrl.isValid() && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + { + QString urlString = d->contextMenuData.mediaUrl.toString(QUrl::FullyEncoded); + QMimeData *data = new QMimeData(); + data->setText(urlString); + if (d->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); + qApp->clipboard()->setMimeData(data); + } + break; + case ToggleMediaControls: + if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaCanToggleControls) { + bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaControls); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerControls, enable); + } + break; + case ToggleMediaLoop: + if (d->contextMenuData.mediaUrl.isValid() && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + { + bool enable = !(d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaLoop); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerLoop, enable); + } + break; + case ToggleMediaPlayPause: + if (d->contextMenuData.mediaUrl.isValid() && + (d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeAudio || + d->contextMenuData.mediaType == WebEngineContextMenuData::MediaTypeVideo)) + { + bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaPaused); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerPlay, enable); + } + break; + case ToggleMediaMute: + if (d->contextMenuData.mediaUrl.isValid() && d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { + bool enable = (d->contextMenuData.mediaFlags & WebEngineContextMenuData::MediaMuted); + d->adapter->executeMediaPlayerActionAt(d->contextMenuData.pos, WebContentsAdapter::MediaPlayerMute, enable); + } + break; + case InspectElement: + d->adapter->inspectElementAt(d->contextMenuData.pos); + break; + case ExitFullScreen: + d->adapter->exitFullScreen(); + break; + default: + Q_UNREACHABLE(); + } +} + void QQuickWebEngineViewPrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script) { Q_ASSERT(p && p->data); diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index f85bf64ad..ab2e6a566 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -84,6 +84,8 @@ private: bool m_toggleOn; }; +#define LATEST_WEBENGINEVIEW_REVISION 2 + class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_OBJECT Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) @@ -100,6 +102,8 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(QQuickWebEngineHistory *navigationHistory READ navigationHistory CONSTANT FINAL REVISION 1) Q_PROPERTY(QQmlWebChannel *webChannel READ webChannel WRITE setWebChannel NOTIFY webChannelChanged REVISION 1) Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL REVISION 1) + Q_PROPERTY(bool activeFocusOnPress READ activeFocusOnPress WRITE setActiveFocusOnPress NOTIFY activeFocusOnPressChanged REVISION 2) + Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged REVISION 2) #ifdef ENABLE_QML_TESTSUPPORT_API Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL) @@ -113,6 +117,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_ENUMS(Feature); Q_ENUMS(JavaScriptConsoleMessageLevel); Q_FLAGS(FindFlags); + Q_ENUMS(WebAction); public: QQuickWebEngineView(QQuickItem *parent = 0); @@ -129,6 +134,8 @@ public: bool isFullScreen() const; qreal zoomFactor() const; void setZoomFactor(qreal arg); + QColor backgroundColor() const; + void setBackgroundColor(const QColor &color); QQuickWebEngineViewExperimental *experimental() const; @@ -181,6 +188,47 @@ public: Geolocation }; + enum WebAction { + NoWebAction = - 1, + Back, + Forward, + Stop, + Reload, + + Cut, + Copy, + Paste, + + Undo, + Redo, + SelectAll, + ReloadAndBypassCache, + + PasteAndMatchStyle, + + OpenLinkInThisWindow, + OpenLinkInNewWindow, + OpenLinkInNewTab, + CopyLinkToClipboard, + DownloadLinkToDisk, + + CopyImageToClipboard, + CopyImageUrlToClipboard, + DownloadImageToDisk, + + CopyMediaUrlToClipboard, + ToggleMediaControls, + ToggleMediaLoop, + ToggleMediaPlayPause, + ToggleMediaMute, + DownloadMediaToDisk, + + InspectElement, + ExitFullScreen, + + WebActionCount + }; + // must match WebContentsAdapterClient::JavaScriptConsoleMessageLevel enum JavaScriptConsoleMessageLevel { InfoMessageLevel = 0, @@ -211,6 +259,8 @@ public: void setTestSupport(QQuickWebEngineTestSupport *testSupport); #endif + bool activeFocusOnPress() const; + public Q_SLOTS: void runJavaScript(const QString&, const QJSValue & = QJSValue()); void loadHtml(const QString &html, const QUrl &baseUrl = QUrl()); @@ -223,6 +273,8 @@ public Q_SLOTS: Q_REVISION(1) void findText(const QString &subString, FindFlags options = 0, const QJSValue &callback = QJSValue()); Q_REVISION(1) void fullScreenCancelled(); Q_REVISION(1) void grantFeaturePermission(const QUrl &securityOrigin, Feature, bool granted); + Q_REVISION(2) void setActiveFocusOnPress(bool arg); + Q_REVISION(2) void triggerWebAction(WebAction action); Q_SIGNALS: void titleChanged(); @@ -241,7 +293,8 @@ Q_SIGNALS: Q_REVISION(1) void zoomFactorChanged(qreal arg); Q_REVISION(1) void profileChanged(); Q_REVISION(1) void webChannelChanged(); - + Q_REVISION(2) void activeFocusOnPressChanged(bool); + Q_REVISION(2) void backgroundColorChanged(); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 60aa0d9f4..6db6b199e 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -134,6 +134,7 @@ public: virtual void selectionChanged() Q_DECL_OVERRIDE { } virtual QRectF viewportRect() const Q_DECL_OVERRIDE; virtual qreal dpiScale() const Q_DECL_OVERRIDE; + virtual QColor backgroundColor() const Q_DECL_OVERRIDE; virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) Q_DECL_OVERRIDE; virtual void loadCommitted() Q_DECL_OVERRIDE; virtual void loadVisuallyCommitted() Q_DECL_OVERRIDE; @@ -147,14 +148,14 @@ 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(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE; + virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE; virtual void didRunJavaScript(quint64, const QVariant&) Q_DECL_OVERRIDE; virtual void didFetchDocumentMarkup(quint64, const QString&) Q_DECL_OVERRIDE { } virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { } virtual void didFindText(quint64, int) Q_DECL_OVERRIDE; virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE; virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; - virtual void authenticationRequired(const QUrl&, const QString&, bool, const QString&, QString*, QString*) Q_DECL_OVERRIDE { } + virtual void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) Q_DECL_OVERRIDE { } virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE; virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE; #ifndef QT_NO_ACCESSIBILITY @@ -190,11 +191,13 @@ public: QQuickWebEngineTestSupport *m_testSupport; #endif QQmlComponent *contextMenuExtraItems; + QtWebEngineCore::WebEngineContextMenuData contextMenuData; QUrl explicitUrl; QUrl icon; int loadProgress; bool m_isFullScreen; bool isLoading; + bool m_activeFocusOnPress; qreal devicePixelRatio; QMap<quint64, QJSValue> m_callbacks; QList<QSharedPointer<CertificateErrorController> > m_certificateErrorControllers; @@ -203,6 +206,7 @@ private: QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager; QList<QQuickWebEngineScript *> m_userScripts; qreal m_dpiScale; + QColor m_backgroundColor; }; #ifndef QT_NO_ACCESSIBILITY diff --git a/src/webengine/doc/images/qtwebengine-architecture.png b/src/webengine/doc/images/qtwebengine-architecture.png Binary files differnew file mode 100644 index 000000000..37ca2da16 --- /dev/null +++ b/src/webengine/doc/images/qtwebengine-architecture.png diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index ad6898440..527983ca1 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -17,23 +17,49 @@ qhp.QtWebEngine.indexRoot = qhp.QtWebEngine.filterAttributes = qtwebengine $QT_VERSION qtrefdoc qhp.QtWebEngine.customFilters.Qt.name = QtWebEngine $QT_VERSION qhp.QtWebEngine.customFilters.Qt.filterAttributes = qtwebengine $QT_VERSION -qhp.QtWebEngine.subprojects = qmltypes examples + +qhp.QtWebEngine.subprojects = classes qmltypes examples + +qhp.QtWebEngine.subprojects.classes.title = C++ Classes +qhp.QtWebEngine.subprojects.classes.indexTitle = Qt WebEngine C++ Classes +qhp.QtWebEngine.subprojects.classes.selectors = class doc:headerfile +qhp.QtWebEngine.subprojects.classes.sortPages = true + qhp.QtWebEngine.subprojects.qmltypes.title = QML Types qhp.QtWebEngine.subprojects.qmltypes.indexTitle = Qt WebEngine QML Types -qhp.QtWebEngine.subprojects.qmltypes.selectors = qmlclass +qhp.QtWebEngine.subprojects.qmltypes.selectors = qmltype qhp.QtWebEngine.subprojects.qmltypes.sortPages = true + qhp.QtWebEngine.subprojects.examples.title = Examples qhp.QtWebEngine.subprojects.examples.indexTitle = Qt WebEngine Examples -qhp.QtWebEngine.subprojects.examples.selectors = fake:example +qhp.QtWebEngine.subprojects.examples.selectors = doc:example qhp.QtWebEngine.subprojects.examples.sortPages = true tagfile = ../../../doc/qtwebengine/qtwebengine.tags -depends += qtcore qtgui qtquick qtquickcontrols qtdoc +depends += qtcore \ + qtgui \ + qtqml \ + qtquick \ + qtquickcontrols \ + qtdoc \ + qtwebchannel \ + qtwebenginewidgets + +headerdirs += . \ + ../api \ + ../../core/api + +sourcedirs += . \ + ../api \ + ../../core/api \ + ../../core/doc/src -headerdirs += . ../api -sourcedirs += . ../api -exampledirs += ../../../examples/webengine . +exampledirs += . \ + ../../../examples/webengine \ + snippets \ + ../../core/doc/snippets navigation.landingpage = "Qt WebEngine" +navigation.cppclassespage = "Qt WebEngine C++ Classes" navigation.qmltypespage = "Qt WebEngine QML Types" diff --git a/src/webengine/doc/src/qtwebengine.qdoc b/src/webengine/doc/src/qtwebengine-examples.qdoc index e381178f6..ec49577e4 100644 --- a/src/webengine/doc/src/qtwebengine.qdoc +++ b/src/webengine/doc/src/qtwebengine-examples.qdoc @@ -24,22 +24,6 @@ */ /*! - \qmlmodule QtWebEngine 1.1 - \title Qt WebEngine QML Types - \brief Provides QML types for rendering web content within a QML application - - The QML types can be imported into your application using the following - import statement in your .qml file: - - \code - import QtQuick 2.0 - import QtWebEngine 1.1 - \endcode - - \sa {Qt WebEngine Examples} -*/ - -/*! \group webengine-examples \title Qt WebEngine Examples \brief Examples demonstrating the Qt WebEngine usage @@ -49,5 +33,6 @@ from displaying Web pages within a QML user interface to an implementation of a basic function Web browser. - \sa {Qt WebEngine QML Types} + For widget-based applications, Qt provides an integrated Web browser component based on + Chromium, the popular open source browser engine. */ diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc new file mode 100644 index 000000000..e6f071913 --- /dev/null +++ b/src/webengine/doc/src/qtwebengine-index.qdoc @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtwebengine-index.html + \title Qt WebEngine + \ingroup modules + + \brief Provides functionality for rendering regions of dynamic web content. + + \e {Qt WebEngine} provides functionality for rendering regions of dynamic web content. + + The functionality in Qt WebEngine is divided into the following modules: + + \annotatedlist qtwebengine-modules + + For Qt Quick applications, Qt WebEngine provides the following QML modules: + + \annotatedlist qtwebengine-qmlmodules + + \section1 Getting Started + + To include the definitions of the Qt WebEngineCore and Qt WebEngineWidgets modules' classes, use + the following directives: + + \badcode + #include <QtWebEngineCore> + #include <QtWebEngineWidgets> + \endcode + + To import the Qt WebEngine module's QML types, add the following import statement to your .qml + file: + + \badcode + import QtWebEngine 1.2 + \endcode + + To link against the modules, add QT variables to your qmake .pro file: + + \badcode + QT += webengine webenginecore webenginewidgets + \endcode + + \section1 Articles and Guides + + \list + \li \l{Qt WebEngine Overview} + \li \l{Porting from Qt WebKit to Qt WebEngine} + \endlist + + \section1 Examples + + \list + \li \l{Qt WebEngine Examples} + \li \l{Qt WebEngine Widgets Examples} + \endlist + + \section1 API References + + \list + \li \l{Qt WebEngine Core C++ Classes} + \li \l{Qt WebEngine Widgets C++ Classes} + \li \l{Qt WebEngine QML Types} + \endlist +*/ diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc new file mode 100644 index 000000000..656dd13f1 --- /dev/null +++ b/src/webengine/doc/src/qtwebengine-overview.qdoc @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtwebengine-overview.html + \title Qt WebEngine Overview + + The Qt WebEngine module provides a web browser engine that makes it easy to embed content from + the World Wide Web into your Qt application on platforms that do not have a native web engine. + The web engine is not intended to function as a \e {Web Runtime}; to display web content in a + QML application by using APIs native to the platform, use the \l{Qt WebView} module, instead. + + Qt WebEngine provides C++ classes and QML types for rendering HTML, XHTML, and SVG documents, + styled using Cascading Style Sheets (CSS) and scripted with JavaScript. HTML documents can be + made fully editable by the user through the use of the \c{contenteditable} attribute on HTML + elements. + + Qt WebEngine supercedes the \l{Qt WebKit Widgets}{Qt WebKit} module, which is based on the + WebKit project, but has not been actively synchronized with the upstream WebKit code since + Qt 5.2 and has been deprecated in Qt 5.5. For tips on how to change a Qt WebKit widgets + application to use Qt WebEngine widgets, see \l{Porting from Qt WebKit to Qt WebEngine}. For new + applications, we recommend using Qt Quick and the WebEngineView QML type. + + \section1 Qt WebEngine Architecture + + \image qtwebengine-architecture.png + + The functionality in Qt WebEngine is divided into the following modules: + + \list + \li \l{Qt WebEngine Widgets}, which provides a web browser engine and C++ classes to render + web content and to interact with it + \li \l{Qt WebEngine}, which provides QML types for rendering web content within a QML + application + \li \l{Qt WebEngine Core}, which provides common API used by Qt WebEngine and + Qt WebEngine Widgets + \endlist + + The Qt WebEngine core is based on the \l{http://www.chromium.org}{Chromium Project}. Chromium + provides its own network and painting engines and is developed tightly together with its + dependent modules, and therefore Qt WebEngine provides better and more reliable support for the + latest HTML5 specification than Qt WebKit. However, Qt WebEngine is thus heavier than Qt WebKit + and does not provide direct access to the network stack and the HTML document through C++ APIs. + + Chromium is tightly integrated to the \l{Qt Quick Scene Graph}{Qt Quick scene graph}, which is + based on OpenGL ES 2.0 or OpenGL 2.0 for its rendering. This provides you with one-pass + compositing of web content and all the Qt Quick UI. The integration to Chromium is transparent + to developers, who just work with Qt and JavaScript. + + To expose QObjects to JavaScript, developers can use the \l {Qt WebChannel} module. + + \section1 Embedding Web Content into Widget Based Applications + + Use the QWebEngineView class to display web pages in the simplest way. Because it is a widget, + you can embed QWebEngineView into your forms and use its convenience functions to download and + display web sites. + + \code + QWebEngineView *view = new QWebEngineView(parent); + view->load(QUrl("http://www.qt.io/")); + view->show(); + \endcode + + An instance of QWebEngineView has one QWebEnginePage. QWebEnginePage provides access to the + page's navigation history and the ability to run JavaScript code in the context of the page's + main frame and enables customization of handlers for specific events like showing custom + authentication dialogs. + + \section1 Embedding Web Content into Qt Quick Applications + + The WebEngineView QML type allows QML applications to render regions of dynamic web content. A + \e{WebEngineView} type may share the screen with other QML types or encompass the full screen + as specified within the QML application. + + An application can load pages into the WebEngineView, using either an URL or HTML string, and + navigate within session history. By default, links to different pages load within the same + WebEngineView object, but web sites may request them to be opened as a new tab, window, or + dialog. + + The following sample QML application loads a web page and responds to session history context: + + \code + import QtQuick 2.1 + import QtQuick.Controls 1.1 + import QtWebEngine 1.1 + + ApplicationWindow { + width: 1280 + height: 720 + visible: true + WebEngineView { + id: webview + url: "http://www.qt.io" + anchors.fill: parent + } + } + \endcode + + \section1 Using WebEngine Core + + Qt WebEngine Core provides an API shared by Qt WebEngine and Qt WebEngine Widgets. + + \section1 License Information + + Qt WebEngine module is a snapshot of the integration of Chromium into Qt. + + Qt Commercial Edition licensees that wish to distribute applications that + use the Qt WebEngine module need to be aware of their obligations under the + GNU Library General Public License (LGPLv2). + + Developers using the Open Source Edition can choose to redistribute + the module under the GNU LGPLv3 or GPLv2 and up. + + \legalese + + Chromium is licensed under the following license: + + Copyright (c) 2013 The Chromium Authors. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + \endlegalese +*/ diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc new file mode 100644 index 000000000..6d3d71896 --- /dev/null +++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc @@ -0,0 +1,39 @@ +/* + Copyright (C) 2015 The Qt Company Ltd. + Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*! + \qmlmodule QtWebEngine 1.1 + \title Qt WebEngine QML Types + \brief Provides QML types for rendering web content within a QML application + \ingroup qtwebengine-qmlmodules + + The QML types can be imported into your application using the following import statements in + your .qml file: + + \code + import QtQuick 2.0 + import QtWebEngine 1.1 + \endcode +*/ diff --git a/src/webengine/doc/src/qquickwebengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview.qdoc index 212d9010a..76c742aa0 100644 --- a/src/webengine/doc/src/qquickwebengineview_lgpl.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -24,54 +24,6 @@ // by its LGPL license. /*! - \page qtwebengine-index.html - \title Qt WebEngine - - The Qt WebEngine module provides the WebEngineView API which allows QML applications - to render regions of dynamic web content. A \e{WebEngineView} component may share - the screen with other QML components or encompass the full screen as - specified within the QML application. - - It allows an application to load pages into the WebEngineView, either by URL or with - an HTML string, and navigate within session history. By default, - links to different pages load within the same WebEngineView, but web sites may - request them to be opened as a new tab, window or dialog. - - The following sample QML application loads a web page, responds to session - history context. - - \code - import QtQuick 2.1 - import QtQuick.Controls 1.1 - import QtWebEngine 1.1 - - ApplicationWindow { - width: 1280 - height: 720 - visible: true - WebEngineView { - id: webview - url: "http://www.qt-project.org" - anchors.fill: parent - } - } - \endcode - - \section1 API References - - \list - \li \l{Qt WebEngine QML Types}{QML Types} - \endlist - - \section1 Examples - - There are several Qt WebEngine examples located in the - \l{Qt WebEngine Examples} page. - -*/ - - -/*! \qmltype WebEngineView \instantiates QQuickWebEngineView \inqmlmodule QtWebEngine 1.1 diff --git a/src/webengine/plugin/experimental/experimental.pro b/src/webengine/plugin/experimental/experimental.pro index 36162e359..d1b59326a 100644 --- a/src/webengine/plugin/experimental/experimental.pro +++ b/src/webengine/plugin/experimental/experimental.pro @@ -6,7 +6,7 @@ IMPORT_VERSION = 1.0 QT += webengine qml quick QT_PRIVATE += webengine-private -INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api +INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/core/api $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api SOURCES = plugin.cpp diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp index 29b5413f4..f9525e656 100644 --- a/src/webengine/plugin/experimental/plugin.cpp +++ b/src/webengine/plugin/experimental/plugin.cpp @@ -63,12 +63,12 @@ public: qmlRegisterExtendedType<QQuickWebEngineView, QQuickWebEngineViewExperimentalExtension>(uri, 1, 0, "WebEngineView"); qmlRegisterUncreatableType<QQuickWebEngineViewExperimental>(uri, 1, 0, "WebEngineViewExperimental", - QObject::tr("Cannot create a separate instance of WebEngineViewExperimental")); + tr("Cannot create a separate instance of WebEngineViewExperimental")); qmlRegisterUncreatableType<QQuickWebEngineViewport>(uri, 1, 0, "WebEngineViewport", - QObject::tr("Cannot create a separate instance of WebEngineViewport")); + tr("Cannot create a separate instance of WebEngineViewport")); // Use the latest revision of QQuickWebEngineView when importing QtWebEngine.experimental 1.0 - qmlRegisterRevision<QQuickWebEngineView, 1>(uri, 1, 0); + qmlRegisterRevision<QQuickWebEngineView, LATEST_WEBENGINEVIEW_REVISION>(uri, 1, 0); } }; diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index c5ef11a5e..c42eb63d5 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -65,24 +65,30 @@ public: Q_ASSERT(QLatin1String(uri) == QLatin1String("QtWebEngine")); qmlRegisterType<QQuickWebEngineView>(uri, 1, 0, "WebEngineView"); - qmlRegisterUncreatableType<QQuickWebEngineLoadRequest>(uri, 1, 0, "WebEngineLoadRequest", QObject::tr("Cannot create separate instance of WebEngineLoadRequest")); - qmlRegisterUncreatableType<QQuickWebEngineNavigationRequest>(uri, 1, 0, "WebEngineNavigationRequest", QObject::tr("Cannot create separate instance of WebEngineNavigationRequest")); + qmlRegisterUncreatableType<QQuickWebEngineLoadRequest>(uri, 1, 0, "WebEngineLoadRequest", tr("Cannot create separate instance of WebEngineLoadRequest")); + qmlRegisterUncreatableType<QQuickWebEngineNavigationRequest>(uri, 1, 0, "WebEngineNavigationRequest", tr("Cannot create separate instance of WebEngineNavigationRequest")); qmlRegisterType<QQuickWebEngineView, 1>(uri, 1, 1, "WebEngineView"); + qmlRegisterType<QQuickWebEngineView, 2>(uri, 1, 2, "WebEngineView"); qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile"); + qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript"); - qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", QObject::tr("Cannot create separate instance of WebEngineCertificateError")); + qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", tr("Cannot create separate instance of WebEngineCertificateError")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem", - QObject::tr("Cannot create a separate instance of WebEngineDownloadItem")); - qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", QObject::tr("Cannot create separate instance of WebEngineNewViewRequest")); - qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", QObject::tr("Cannot create a separate instance of WebEngineSettings")); + tr("Cannot create a separate instance of WebEngineDownloadItem")); + qmlRegisterUncreatableType<QQuickWebEngineNewViewRequest>(uri, 1, 1, "WebEngineNewViewRequest", tr("Cannot create separate instance of WebEngineNewViewRequest")); + qmlRegisterUncreatableType<QQuickWebEngineSettings>(uri, 1, 1, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); + qmlRegisterUncreatableType<QQuickWebEngineSettings, 1>(uri, 1, 2, "WebEngineSettings", tr("Cannot create a separate instance of WebEngineSettings")); qmlRegisterSingletonType<QQuickWebEngineSingleton>(uri, 1, 1, "WebEngine", webEngineSingletonProvider); qmlRegisterUncreatableType<QQuickWebEngineHistory>(uri, 1, 1, "NavigationHistory", - QObject::tr("Cannot create a separate instance of NavigationHistory")); + tr("Cannot create a separate instance of NavigationHistory")); qmlRegisterUncreatableType<QQuickWebEngineHistoryListModel>(uri, 1, 1, "NavigationHistoryListModel", - QObject::tr("Cannot create a separate instance of NavigationHistory")); + tr("Cannot create a separate instance of NavigationHistory")); qmlRegisterUncreatableType<QQuickWebEngineFullScreenRequest>(uri, 1, 1, "FullScreenRequest", - QObject::tr("Cannot create a separate instance of FullScreenRequest")); + tr("Cannot create a separate instance of FullScreenRequest")); + + // 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/plugin.pro b/src/webengine/plugin/plugin.pro index 123c45511..b6acc760f 100644 --- a/src/webengine/plugin/plugin.pro +++ b/src/webengine/plugin/plugin.pro @@ -1,12 +1,12 @@ CXX_MODULE = qml TARGET = qtwebengineplugin TARGETPATH = QtWebEngine -IMPORT_VERSION = 1.1 +IMPORT_VERSION = 1.2 QT += webengine qml quick QT_PRIVATE += webengine-private -INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api $$QTWEBENGINE_ROOT/include/QtWebEngine +INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/core/api $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api $$QTWEBENGINE_ROOT/include/QtWebEngine SOURCES = plugin.cpp diff --git a/src/webengine/plugin/testsupport/plugin.cpp b/src/webengine/plugin/testsupport/plugin.cpp index 98a1d3ca6..28001db54 100644 --- a/src/webengine/plugin/testsupport/plugin.cpp +++ b/src/webengine/plugin/testsupport/plugin.cpp @@ -54,7 +54,7 @@ public: qmlRegisterType<QQuickWebEngineTestSupport>(uri, 1, 0, "WebEngineTestSupport"); qmlRegisterUncreatableType<QQuickWebEngineErrorPage>(uri, 1, 0, "WebEngineErrorPage", - QObject::tr("Cannot create a separate instance of WebEngineErrorPage")); + tr("Cannot create a separate instance of WebEngineErrorPage")); } }; diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp index a3999ccab..9fc1ed3eb 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -64,10 +64,14 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW void RenderWidgetHostViewQtDelegateQuick::initAsChild(WebContentsAdapterClient* container) { - QQuickWebEngineViewPrivate *viewPrivate = static_cast<QQuickWebEngineViewPrivate *>(container); - setParentItem(viewPrivate->q_func()); - setSize(viewPrivate->q_func()->boundingRect().size()); + QQuickWebEngineView *view = static_cast<QQuickWebEngineViewPrivate *>(container)->q_func(); + setParentItem(view); + setSize(view->boundingRect().size()); + // Focus on creation if the view accepts it + if (view->activeFocusOnPress()) + setFocus(true); m_initialized = true; + } void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r) @@ -176,9 +180,11 @@ void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVis if (qApp->inputMethod()->isVisible() == editorVisible) return; - setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible); - qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints); - qApp->inputMethod()->setVisible(editorVisible); + if (parentItem() && parentItem()->flags() & QQuickItem::ItemAcceptsInputMethod) { + qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints); + qApp->inputMethod()->setVisible(editorVisible); + } + } void RenderWidgetHostViewQtDelegateQuick::focusInEvent(QFocusEvent *event) @@ -193,7 +199,7 @@ void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event) void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event) { - if (!m_isPopup) + if (!m_isPopup && (parentItem() && parentItem()->property("activeFocusOnPress").toBool())) forceActiveFocus(); m_client->forwardEvent(event); } @@ -225,7 +231,8 @@ void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event) void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event) { - if (event->type() == QEvent::TouchBegin && !m_isPopup) + if (event->type() == QEvent::TouchBegin && !m_isPopup + && (parentItem() && parentItem()->property("activeFocusOnPress").toBool())) forceActiveFocus(); m_client->forwardEvent(event); } diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h index ddd0e4d9e..eb2860b27 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h @@ -70,6 +70,8 @@ public: virtual void move(const QPoint&) Q_DECL_OVERRIDE { } virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE; virtual void setTooltip(const QString&) Q_DECL_OVERRIDE { } + // The QtQuick view doesn't have a backbuffer of its own and doesn't need this + virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { } protected: virtual void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE; diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h index cda51a1ab..a4b08482f 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h @@ -73,6 +73,7 @@ public: virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE; virtual void inputMethodStateChanged(bool) Q_DECL_OVERRIDE {} virtual void setTooltip(const QString &tooltip) Q_DECL_OVERRIDE; + virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { } private: QScopedPointer<RenderWidgetHostViewQtDelegate> m_realDelegate; diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index d22e6546f..95010d8cb 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -37,12 +37,14 @@ #include "ui_delegates_manager.h" #include "api/qquickwebengineview_p.h" +#include "file_picker_controller.h" #include "javascript_dialog_controller.h" #include <QAbstractListModel> #include <QClipboard> #include <QFileInfo> #include <QGuiApplication> +#include <QMimeData> #include <QQmlContext> #include <QQmlEngine> #include <QQmlProperty> @@ -107,32 +109,6 @@ MenuItemHandler::MenuItemHandler(QObject *parent) { } - -CopyMenuItem::CopyMenuItem(QObject *parent, const QString &textToCopy) - : MenuItemHandler(parent) - , m_textToCopy(textToCopy) -{ - connect(this, &MenuItemHandler::triggered, this, &CopyMenuItem::onTriggered); -} - -void CopyMenuItem::onTriggered() -{ - qApp->clipboard()->setText(m_textToCopy); -} - -NavigateMenuItem::NavigateMenuItem(QObject *parent, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter, const QUrl &targetUrl) - : MenuItemHandler(parent) - , m_adapter(adapter) - , m_targetUrl(targetUrl) -{ - connect(this, &MenuItemHandler::triggered, this, &NavigateMenuItem::onTriggered); -} - -void NavigateMenuItem::onTriggered() -{ - m_adapter->load(m_targetUrl); -} - #define COMPONENT_MEMBER_INIT(TYPE, COMPONENT) \ , COMPONENT##Component(0) @@ -272,15 +248,15 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d switch (dialogController->type()) { case WebContentsAdapterClient::AlertDialog: dialogComponentType = AlertDialog; - title = QObject::tr("Javascript Alert - %1").arg(m_view->url().toString()); + title = QCoreApplication::translate("UIDelegatesManager", "Javascript Alert - %1").arg(m_view->url().toString()); break; case WebContentsAdapterClient::ConfirmDialog: dialogComponentType = ConfirmDialog; - title = QObject::tr("Javascript Confirm - %1").arg(m_view->url().toString()); + title = QCoreApplication::translate("UIDelegatesManager", "Javascript Confirm - %1").arg(m_view->url().toString()); break; case WebContentsAdapterClient::PromptDialog: dialogComponentType = PromptDialog; - title = QObject::tr("Javascript Prompt - %1").arg(m_view->url().toString()); + title = QCoreApplication::translate("UIDelegatesManager", "Javascript Prompt - %1").arg(m_view->url().toString()); break; case WebContentsAdapterClient::InternalAuthorizationDialog: dialogComponentType = ConfirmDialog; @@ -341,50 +317,8 @@ void UIDelegatesManager::showDialog(QSharedPointer<JavaScriptDialogController> d QMetaObject::invokeMethod(dialog, "open"); } -namespace { -class FilePickerController : public QObject { - Q_OBJECT -public: - FilePickerController(WebContentsAdapterClient::FileChooserMode, const QExplicitlySharedDataPointer<WebContentsAdapter> &, QObject * = 0); - -public Q_SLOTS: - void accepted(const QVariant &files); - void rejected(); - -private: - QExplicitlySharedDataPointer<WebContentsAdapter> m_adapter; - WebContentsAdapterClient::FileChooserMode m_mode; - -}; - - -FilePickerController::FilePickerController(WebContentsAdapterClient::FileChooserMode mode, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter, QObject *parent) - : QObject(parent) - , m_adapter(adapter) - , m_mode(mode) -{ -} - -void FilePickerController::accepted(const QVariant &files) -{ - QStringList stringList; - Q_FOREACH (const QUrl &url, files.value<QList<QUrl> >()) - stringList.append(url.toLocalFile()); - m_adapter->filesSelectedInChooser(stringList, m_mode); -} - -void FilePickerController::rejected() -{ - m_adapter->filesSelectedInChooser(QStringList(), m_mode); -} - -} // namespace - - -void UIDelegatesManager::showFilePicker(WebContentsAdapterClient::FileChooserMode mode, const QString &defaultFileName, const QStringList &acceptedMimeTypes, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter) +void UIDelegatesManager::showFilePicker(FilePickerController *controller) { - Q_UNUSED(defaultFileName); - Q_UNUSED(acceptedMimeTypes); if (!ensureComponentLoaded(FilePicker)) return; @@ -397,23 +331,24 @@ void UIDelegatesManager::showFilePicker(WebContentsAdapterClient::FileChooserMod filePickerComponent->completeCreate(); // Fine-tune some properties depending on the mode. - switch (mode) { - case WebContentsAdapterClient::Open: + switch (controller->mode()) { + case FilePickerController::Open: break; - case WebContentsAdapterClient::Save: + case FilePickerController::Save: filePicker->setProperty("selectExisting", false); break; - case WebContentsAdapterClient::OpenMultiple: + case FilePickerController::OpenMultiple: filePicker->setProperty("selectMultiple", true); break; - case WebContentsAdapterClient::UploadFolder: + case FilePickerController::UploadFolder: filePicker->setProperty("selectFolder", true); break; default: Q_UNREACHABLE(); } - FilePickerController *controller = new FilePickerController(mode, adapter, filePicker); + controller->setParent(filePicker); + QQmlProperty filesPickedSignal(filePicker, QStringLiteral("onFilesSelected")); CHECK_QML_SIGNAL_PROPERTY(filesPickedSignal, filePickerComponent->url()); QQmlProperty rejectSignal(filePicker, QStringLiteral("onRejected")); @@ -464,5 +399,3 @@ void UIDelegatesManager::moveMessageBubble(const QRect &anchor) } } // namespace QtWebEngineCore - -#include "ui_delegates_manager.moc" diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h index f2b78f792..37cbb85df 100644 --- a/src/webengine/ui_delegates_manager.h +++ b/src/webengine/ui_delegates_manager.h @@ -73,6 +73,7 @@ QT_END_NAMESPACE namespace QtWebEngineCore { class JavaScriptDialogController; +class FilePickerController; const char *defaultPropertyName(QObject *obj); @@ -85,29 +86,6 @@ Q_SIGNALS: void triggered(); }; -class CopyMenuItem : public MenuItemHandler { - Q_OBJECT -public: - CopyMenuItem(QObject *parent, const QString &textToCopy); - -private: - void onTriggered(); - - QString m_textToCopy; -}; - -class NavigateMenuItem : public MenuItemHandler { - Q_OBJECT -public: - NavigateMenuItem(QObject *parent, const QExplicitlySharedDataPointer<WebContentsAdapter> &adapter, const QUrl &targetUrl); - -private: - void onTriggered(); - - QExplicitlySharedDataPointer<WebContentsAdapter> m_adapter; - QUrl m_targetUrl; -}; - class UIDelegatesManager { public: @@ -124,8 +102,7 @@ public: QObject *addMenu(QObject *parentMenu, const QString &title, const QPoint &pos = QPoint()); QQmlContext *creationContextForComponent(QQmlComponent *); void showDialog(QSharedPointer<JavaScriptDialogController>); - void showFilePicker(WebContentsAdapterClient::FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes - , const QExplicitlySharedDataPointer<WebContentsAdapter> &); + void showFilePicker(FilePickerController *controller); void showMessageBubble(const QRect &anchor, const QString &mainText, const QString &subText); void hideMessageBubble(); void moveMessageBubble(const QRect &anchor); diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 6cba9c5d9..8bb5a8e77 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -3,12 +3,12 @@ TARGET = QtWebEngine # For our export macros DEFINES += QT_BUILD_WEBENGINE_LIB -QT += qml quick -QT_PRIVATE += webenginecore quick-private gui-private core-private +QT += qml quick webenginecore +QT_PRIVATE += quick-private gui-private core-private QMAKE_DOCS = $$PWD/doc/qtwebengine.qdocconf -INCLUDEPATH += $$PWD api ../core +INCLUDEPATH += $$PWD api ../core ../core/api SOURCES = \ api/qquickwebenginecertificateerror.cpp \ |