diff options
Diffstat (limited to 'src/webengine')
26 files changed, 461 insertions, 22 deletions
diff --git a/src/webengine/api/qquickwebenginecontextmenudata.cpp b/src/webengine/api/qquickwebenginecontextmenudata.cpp index 979d80e34..269d655a2 100644 --- a/src/webengine/api/qquickwebenginecontextmenudata.cpp +++ b/src/webengine/api/qquickwebenginecontextmenudata.cpp @@ -170,6 +170,34 @@ 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); @@ -198,6 +226,12 @@ void QQuickWebEngineContextMenuData::update(const QtWebEngineCore::WebEngineCont 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) diff --git a/src/webengine/api/qquickwebenginecontextmenudata_p.h b/src/webengine/api/qquickwebenginecontextmenudata_p.h index aa081cbe6..7175838db 100644 --- a/src/webengine/api/qquickwebenginecontextmenudata_p.h +++ b/src/webengine/api/qquickwebenginecontextmenudata_p.h @@ -92,6 +92,8 @@ public: 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; @@ -103,6 +105,9 @@ public: MediaType mediaType() const; bool isContentEditable() const; + QString misspelledWord() const; + QStringList spellCheckerSuggestions() const; + Q_SIGNALS: void isValidChanged(); void positionChanged(); @@ -112,6 +117,8 @@ Q_SIGNALS: void mediaUrlChanged(); void mediaTypeChanged(); void isContentEditableChanged(); + Q_REVISION(1) void misspelledWordChanged(); + Q_REVISION(1) void spellCheckerSuggestionsChanged(); private: void update(const QtWebEngineCore::WebEngineContextMenuData &update); diff --git a/src/webengine/api/qquickwebenginedownloaditem.cpp b/src/webengine/api/qquickwebenginedownloaditem.cpp index c26255e3a..c0bca8977 100644 --- a/src/webengine/api/qquickwebenginedownloaditem.cpp +++ b/src/webengine/api/qquickwebenginedownloaditem.cpp @@ -66,6 +66,7 @@ QQuickWebEngineDownloadItemPrivate::QQuickWebEngineDownloadItemPrivate(QQuickWeb , downloadId(-1) , downloadState(QQuickWebEngineDownloadItem::DownloadCancelled) , savePageFormat(QQuickWebEngineDownloadItem::UnknownSaveFormat) + , type(QQuickWebEngineDownloadItem::Attachment) , totalBytes(-1) , receivedBytes(0) { @@ -295,6 +296,29 @@ void QQuickWebEngineDownloadItem::setSavePageFormat(QQuickWebEngineDownloadItem: } } +/*! + \qmlproperty enumeration WebEngineDownloadItem::type + \readonly + \since QtWebEngine 1.4 + + Describes the requested download's type. + + \value Attachment The web server's response includes a \c Content-Disposition header with the \c attachment directive. + If \c Content-Disposition is present in the reply, the web server is indicating that + the client should prompt the user to save the content regardless of the content type. + See \l {RFC 2616 section 19.5.1} for details. + \value DownloadAttribute The user clicked the hyperlink. + See \l {HTML download Attribute} for details. + \value UserRequested The user initiated the download. + \value SavePage The user saved a web page. + */ + +QQuickWebEngineDownloadItem::DownloadType QQuickWebEngineDownloadItem::type() const +{ + Q_D(const QQuickWebEngineDownloadItem); + return d->type; +} + QQuickWebEngineDownloadItem::QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate *p, QObject *parent) : QObject(parent) , d_ptr(p) diff --git a/src/webengine/api/qquickwebenginedownloaditem_p.h b/src/webengine/api/qquickwebenginedownloaditem_p.h index 0b01fe6fc..61e019b9e 100644 --- a/src/webengine/api/qquickwebenginedownloaditem_p.h +++ b/src/webengine/api/qquickwebenginedownloaditem_p.h @@ -82,6 +82,14 @@ public: }; Q_ENUM(SavePageFormat) + enum DownloadType { + Attachment = 0, + DownloadAttribute, + UserRequested, + SavePage + }; + Q_ENUM(DownloadType) + Q_PROPERTY(quint32 id READ id CONSTANT FINAL) Q_PROPERTY(DownloadState state READ state NOTIFY stateChanged) Q_PROPERTY(SavePageFormat savePageFormat READ savePageFormat WRITE setSavePageFormat NOTIFY savePageFormatChanged REVISION 2 FINAL) @@ -89,6 +97,7 @@ public: Q_PROPERTY(qint64 receivedBytes READ receivedBytes NOTIFY receivedBytesChanged) Q_PROPERTY(QString mimeType READ mimeType NOTIFY mimeTypeChanged REVISION 1) Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) + Q_PROPERTY(DownloadType type READ type NOTIFY typeChanged REVISION 3 FINAL) Q_INVOKABLE void accept(); Q_INVOKABLE void cancel(); @@ -102,6 +111,7 @@ public: void setPath(QString path); SavePageFormat savePageFormat() const; void setSavePageFormat(SavePageFormat format); + DownloadType type() const; Q_SIGNALS: void stateChanged(); @@ -110,6 +120,7 @@ Q_SIGNALS: void totalBytesChanged(); Q_REVISION(1) void mimeTypeChanged(); void pathChanged(); + Q_REVISION(3) void typeChanged(); private: QQuickWebEngineDownloadItem(QQuickWebEngineDownloadItemPrivate*, QObject *parent = 0); diff --git a/src/webengine/api/qquickwebenginedownloaditem_p_p.h b/src/webengine/api/qquickwebenginedownloaditem_p_p.h index bdae54ca4..1789af462 100644 --- a/src/webengine/api/qquickwebenginedownloaditem_p_p.h +++ b/src/webengine/api/qquickwebenginedownloaditem_p_p.h @@ -73,6 +73,7 @@ public: quint32 downloadId; QQuickWebEngineDownloadItem::DownloadState downloadState; QQuickWebEngineDownloadItem::SavePageFormat savePageFormat; + QQuickWebEngineDownloadItem::DownloadType type; qint64 totalBytes; qint64 receivedBytes; QString mimeType; diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp index c1f8f3179..e4141c575 100644 --- a/src/webengine/api/qquickwebengineprofile.cpp +++ b/src/webengine/api/qquickwebengineprofile.cpp @@ -180,6 +180,7 @@ void QQuickWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) itemPrivate->downloadPath = info.path; itemPrivate->savePageFormat = static_cast<QQuickWebEngineDownloadItem::SavePageFormat>( info.savePageFormat); + itemPrivate->type = static_cast<QQuickWebEngineDownloadItem::DownloadType>(info.downloadType); QQuickWebEngineDownloadItem *download = new QQuickWebEngineDownloadItem(itemPrivate, q); @@ -613,6 +614,85 @@ QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile() } /*! + \property QQuickWebEngineProfile::spellCheckLanguage + \brief the language used by the spell checker. + + \since QtWebEngine 1.4 +*/ + +/*! + \qmlproperty QString WebEngineProfile::spellCheckLanguage + + This property holds the language used by the spell checker. + The language should match the name of the \c .bdic dictionary. + For example, the \a language \c en-US will load the \c en-US.bdic + dictionary file. + + The web engine checks for the \c qtwebengine_dictionaries subdirectory + first in the local directory and if it is not found in the Qt + installation directory: + + \list + \li QCoreApplication::applicationDirPath()/qtwebengine_dictionaries + \li [QLibraryInfo::DataPath]/qtwebengine_dictionaries + \endlist + + For more information about how to compile \c .bdic dictionaries, see the + \l{WebEngine Widgets Spellchecker Example}{Spellchecker Example}. + + \since QtWebEngine 1.4 +*/ +void QQuickWebEngineProfile::setSpellCheckLanguage(const QString &language) +{ + Q_D(QQuickWebEngineProfile); + if (language != d->browserContext()->spellCheckLanguage()) { + d->browserContext()->setSpellCheckLanguage(language); + emit spellCheckLanguageChanged(); + } +} + +/*! + \since 5.8 + + Returns the language used by the spell checker. +*/ +QString QQuickWebEngineProfile::spellCheckLanguage() const +{ + const Q_D(QQuickWebEngineProfile); + return d->browserContext()->spellCheckLanguage(); +} + +/*! + \property QQuickWebEngineProfile::spellCheckEnabled + \brief whether the web engine spell checker is enabled. + + \since QtWebEngine 1.4 +*/ + +/*! + \qmlproperty QString WebEngineProfile::spellCheckEnabled + + This property holds whether the web engine spell checker is enabled. + + \since QtWebEngine 1.4 +*/ +void QQuickWebEngineProfile::setSpellCheckEnabled(bool enable) +{ + Q_D(QQuickWebEngineProfile); + if (enable != isSpellCheckEnabled()) { + d->browserContext()->setSpellCheckEnabled(enable); + emit spellCheckEnabledChanged(); + } +} + +bool QQuickWebEngineProfile::isSpellCheckEnabled() const +{ + const Q_D(QQuickWebEngineProfile); + return d->browserContext()->isSpellCheckEnabled(); +} + +/*! + Returns the cookie store for this profile. */ QWebEngineCookieStore *QQuickWebEngineProfile::cookieStore() const diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h index dc5aa7df8..2b0dbf9d4 100644 --- a/src/webengine/api/qquickwebengineprofile.h +++ b/src/webengine/api/qquickwebengineprofile.h @@ -71,6 +71,8 @@ class Q_WEBENGINE_EXPORT QQuickWebEngineProfile : public QObject { Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY httpAcceptLanguageChanged FINAL REVISION 1) Q_PROPERTY(PersistentCookiesPolicy persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY persistentCookiesPolicyChanged FINAL) Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY httpCacheMaximumSizeChanged FINAL) + Q_PROPERTY(QString spellCheckLanguage READ spellCheckLanguage WRITE setSpellCheckLanguage NOTIFY spellCheckLanguageChanged FINAL REVISION 3) + Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY spellCheckEnabledChanged FINAL REVISION 3) public: QQuickWebEngineProfile(QObject *parent = Q_NULLPTR); @@ -129,6 +131,11 @@ public: Q_REVISION(2) Q_INVOKABLE void clearHttpCache(); + Q_REVISION(3) void setSpellCheckLanguage(const QString &language); + Q_REVISION(3) QString spellCheckLanguage() const; + Q_REVISION(3) void setSpellCheckEnabled(bool enabled); + Q_REVISION(3) bool isSpellCheckEnabled() const; + static QQuickWebEngineProfile *defaultProfile(); Q_SIGNALS: @@ -141,6 +148,8 @@ Q_SIGNALS: void persistentCookiesPolicyChanged(); void httpCacheMaximumSizeChanged(); Q_REVISION(1) void httpAcceptLanguageChanged(); + Q_REVISION(3) void spellCheckLanguageChanged(); + Q_REVISION(3) void spellCheckEnabledChanged(); void downloadRequested(QQuickWebEngineDownloadItem *download); void downloadFinished(QQuickWebEngineDownloadItem *download); diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 67a41f659..02484548b 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -233,7 +233,16 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu // Populate our menu MenuItemHandler *item = 0; - + if (contextMenuData.isContentEditable() && !contextMenuData.spellCheckerSuggestions().isEmpty()) { + const QPointer<QQuickWebEngineView> qRef(q); + for (int i=0; i < contextMenuData.spellCheckerSuggestions().count() && i < 4; i++) { + item = new MenuItemHandler(menu); + QString replacement = contextMenuData.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()) { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::OpenLinkInThisWindow); }); @@ -252,6 +261,10 @@ bool QQuickWebEngineViewPrivate::contextMenuRequested(const WebEngineContextMenu item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::reload); ui()->addMenuItem(item, QQuickWebEngineView::tr("Reload"), QStringLiteral("view-refresh")); + + item = new MenuItemHandler(menu); + QObject::connect(item, &MenuItemHandler::triggered, q, &QQuickWebEngineView::viewSource); + ui()->addMenuItem(item, QQuickWebEngineView::tr("View Page Source"), QStringLiteral("view-source"), q->canViewSource()); } else { item = new MenuItemHandler(menu); QObject::connect(item, &MenuItemHandler::triggered, [q] { q->triggerWebAction(QQuickWebEngineView::Copy); }); @@ -1131,6 +1144,11 @@ bool QQuickWebEngineViewPrivate::isEnabled() const return q->isEnabled(); } +void QQuickWebEngineViewPrivate::setToolTip(const QString &toolTipText) +{ + ui()->showToolTip(toolTipText); +} + bool QQuickWebEngineView::isLoading() const { Q_D(const QQuickWebEngineView); @@ -1292,6 +1310,24 @@ void QQuickWebEngineView::printToPdf(const QJSValue &callback, PrintedPageSizeId d->m_callbacks.insert(requestId, callback); } +void QQuickWebEngineView::replaceMisspelledWord(const QString &replacement) +{ + Q_D(QQuickWebEngineView); + d->adapter->replaceMisspelling(replacement); +} + +void QQuickWebEngineView::viewSource() +{ + Q_D(QQuickWebEngineView); + d->adapter->viewSource(); +} + +bool QQuickWebEngineView::canViewSource() const +{ + Q_D(const QQuickWebEngineView); + return d->adapter->canViewSource(); +} + bool QQuickWebEngineView::isFullScreen() const { Q_D(const QQuickWebEngineView); diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index b9555d2d9..dc693a94c 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -94,7 +94,7 @@ private: const bool m_toggleOn; }; -#define LATEST_WEBENGINEVIEW_REVISION 3 +#define LATEST_WEBENGINEVIEW_REVISION 4 class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_OBJECT @@ -119,6 +119,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(bool audioMuted READ isAudioMuted WRITE setAudioMuted NOTIFY audioMutedChanged FINAL REVISION 3) Q_PROPERTY(bool recentlyAudible READ recentlyAudible NOTIFY recentlyAudibleChanged FINAL REVISION 3) Q_PROPERTY(uint webChannelWorld READ webChannelWorld WRITE setWebChannelWorld NOTIFY webChannelWorldChanged REVISION 3) + Q_PROPERTY(bool canViewSource READ canViewSource FINAL REVISION 4) #ifdef ENABLE_QML_TESTSUPPORT_API Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL) @@ -145,6 +146,7 @@ public: void setBackgroundColor(const QColor &color); QSizeF contentsSize() const; QPointF scrollPosition() const; + bool canViewSource() const; QQuickWebEngineViewExperimental *experimental() const; @@ -472,6 +474,9 @@ public Q_SLOTS: Q_REVISION(2) void triggerWebAction(WebAction action); Q_REVISION(3) void printToPdf(const QString &filePath, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait); Q_REVISION(3) void printToPdf(const QJSValue &callback, PrintedPageSizeId pageSizeId = PrintedPageSizeId::A4, PrintedPageOrientation orientation = PrintedPageOrientation::Portrait); + Q_REVISION(4) void replaceMisspelledWord(const QString &replacement); + Q_REVISION(4) void viewSource(); + private Q_SLOTS: void lazyInitialize(); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 769e41a44..66952ca6e 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -190,6 +190,7 @@ public: void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) Q_DECL_OVERRIDE; virtual bool isEnabled() const Q_DECL_OVERRIDE; + virtual void setToolTip(const QString &toolTipText) Q_DECL_OVERRIDE; const QObject *holdingQObject() const Q_DECL_OVERRIDE; virtual QSharedPointer<QtWebEngineCore::BrowserContextAdapter> browserContextAdapter() Q_DECL_OVERRIDE; diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index 009902080..5e738f98d 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -66,6 +66,7 @@ exampledirs += . \ ../../core/doc/snippets \ ../../webenginewidgets/doc/snippets +examples.fileextensions += *.aff *.dic imagedirs += images diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc index c4cfe24af..2ef88e8a4 100644 --- a/src/webengine/doc/src/external-resources.qdoc +++ b/src/webengine/doc/src/external-resources.qdoc @@ -90,6 +90,11 @@ \title Shaka Player */ +/*! + \externalpage https://sourceforge.net/projects/hunspell/ + \title Hunspell Project +*/ + /* This prevents autolinking of each occurrence of 'WebEngine' To link to the WebEngine QML type, use explicit linking: @@ -101,3 +106,13 @@ \title WebEngine \internal */ + +/*! + \externalpage https://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1 + \title RFC 2616 section 19.5.1 +*/ + +/*! + \externalpage http://www.w3schools.com/tags/att_a_download.asp + \title HTML download Attribute +*/ diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index 66e733fa9..b66e7874d 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -117,8 +117,8 @@ On OS X, the following are required: \list - \li OS X 10.9 or later - \li Xcode 6.1 or later + \li OS X 10.10 or later + \li Xcode 6.3 or later \li OS X 10.10 SDK or later \endlist diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc index 87022262d..9d22d3f36 100644 --- a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc +++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc @@ -24,7 +24,7 @@ */ /*! - \qmlmodule QtWebEngine 1.3 + \qmlmodule QtWebEngine 1.4 \title Qt WebEngine QML Types \brief Provides QML types for rendering web content within a QML application \ingroup qtwebengine-modules @@ -33,7 +33,7 @@ your .qml file: \badcode - import QtWebEngine 1.3 + import QtWebEngine 1.4 \endcode To link against the module, add the following QT variable to your qmake .pro diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index 63b6e30d1..6fd9ba45b 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -1117,3 +1117,20 @@ Also if the audio is paused, this signal is emitted with an approximate \b{2 second delay}, from the moment the audio is paused. */ + +/*! + \qmlmethod void WebEngineView::viewSource() + \since QtWebEngine 1.4 + + Shows the source of the current page in a new tab. + + \sa canViewSource +*/ + +/*! + \qmlproperty bool WebEngineView::canViewSource + \brief This property holds whether the source for the current page can be viewed. + \since QtWebEngine 1.4 + + \sa viewSource() +*/ diff --git a/src/webengine/plugin/experimental/plugin.cpp b/src/webengine/plugin/experimental/plugin.cpp index c45bcee43..d4f68d142 100644 --- a/src/webengine/plugin/experimental/plugin.cpp +++ b/src/webengine/plugin/experimental/plugin.cpp @@ -72,9 +72,10 @@ public: 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, 0); + qmlRegisterRevision<QQuickWebEngineView, LATEST_WEBENGINEVIEW_REVISION>(uri, 1, 1); } }; diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index b71689a34..2f7d2c2c4 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -81,9 +81,11 @@ public: qmlRegisterType<QQuickWebEngineView, 1>(uri, 1, 1, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 2>(uri, 1, 2, "WebEngineView"); qmlRegisterType<QQuickWebEngineView, 3>(uri, 1, 3, "WebEngineView"); + qmlRegisterType<QQuickWebEngineView, 4>(uri, 1, 4, "WebEngineView"); qmlRegisterType<QQuickWebEngineProfile>(uri, 1, 1, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 1>(uri, 1, 2, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineProfile, 2>(uri, 1, 3, "WebEngineProfile"); + qmlRegisterType<QQuickWebEngineProfile, 3>(uri, 1, 4, "WebEngineProfile"); qmlRegisterType<QQuickWebEngineScript>(uri, 1, 1, "WebEngineScript"); qmlRegisterUncreatableType<QQuickWebEngineCertificateError>(uri, 1, 1, "WebEngineCertificateError", tr("Cannot create separate instance of WebEngineCertificateError")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem>(uri, 1, 1, "WebEngineDownloadItem", @@ -92,6 +94,8 @@ public: tr("Cannot create a separate instance of WebEngineDownloadItem")); qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 2>(uri, 1, 3, "WebEngineDownloadItem", tr("Cannot create a separate instance of WebEngineDownloadItem")); + qmlRegisterUncreatableType<QQuickWebEngineDownloadItem, 3>(uri, 1, 4, "WebEngineDownloadItem", + 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")); diff --git a/src/webengine/plugin/plugin.pro b/src/webengine/plugin/plugin.pro index 2fbadfc97..56eb7bd3c 100644 --- a/src/webengine/plugin/plugin.pro +++ b/src/webengine/plugin/plugin.pro @@ -1,7 +1,7 @@ CXX_MODULE = qml TARGET = qtwebengineplugin TARGETPATH = QtWebEngine -IMPORT_VERSION = 1.3 +IMPORT_VERSION = 1.4 QT += webengine qml quick QT_PRIVATE += webengine-private 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 d0bd67e6a..c04e20a5e 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -50,6 +50,11 @@ #include <private/qquickwindow_p.h> #include <private/qsgcontext_p.h> +#if (QT_VERSION < QT_VERSION_CHECK(5, 8, 0)) +#include <QSGSimpleRectNode> +#include <QSGSimpleTextureNode> +#endif + namespace QtWebEngineCore { RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup) @@ -177,10 +182,32 @@ QSGLayer *RenderWidgetHostViewQtDelegateQuick::createLayer() return renderContext->sceneGraphContext()->createLayer(renderContext); } -QSGImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode() +QSGInternalImageNode *RenderWidgetHostViewQtDelegateQuick::createImageNode() { QSGRenderContext *renderContext = QQuickWindowPrivate::get(QQuickItem::window())->context; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + return renderContext->sceneGraphContext()->createInternalImageNode(); +#else return renderContext->sceneGraphContext()->createImageNode(); +#endif +} + +QSGTextureNode *RenderWidgetHostViewQtDelegateQuick::createTextureNode() +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + return QQuickItem::window()->createImageNode(); +#else + return new QSGSimpleTextureNode(); +#endif +} + +QSGRectangleNode *RenderWidgetHostViewQtDelegateQuick::createRectangleNode() +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) + return QQuickItem::window()->createRectangleNode(); +#else + return new QSGSimpleRectNode(); +#endif } void RenderWidgetHostViewQtDelegateQuick::update() 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 c51ca3408..de3aff291 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h @@ -66,13 +66,14 @@ public: virtual QWindow* window() const Q_DECL_OVERRIDE; virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE; virtual QSGLayer *createLayer() Q_DECL_OVERRIDE; - virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE; + virtual QSGInternalImageNode *createImageNode() Q_DECL_OVERRIDE; + virtual QSGTextureNode *createTextureNode() Q_DECL_OVERRIDE; + virtual QSGRectangleNode *createRectangleNode() Q_DECL_OVERRIDE; virtual void update() Q_DECL_OVERRIDE; virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE; virtual void resize(int width, int height) Q_DECL_OVERRIDE; 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 { } diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp index 64839c9fa..7b7d32d67 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp @@ -111,11 +111,21 @@ QSGLayer *RenderWidgetHostViewQtDelegateQuickWindow::createLayer() return m_realDelegate->createLayer(); } -QSGImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createImageNode() +QSGInternalImageNode *RenderWidgetHostViewQtDelegateQuickWindow::createImageNode() { return m_realDelegate->createImageNode(); } +QSGTextureNode *RenderWidgetHostViewQtDelegateQuickWindow::createTextureNode() +{ + return m_realDelegate->createTextureNode(); +} + +QSGRectangleNode *RenderWidgetHostViewQtDelegateQuickWindow::createRectangleNode() +{ + return m_realDelegate->createRectangleNode(); +} + void RenderWidgetHostViewQtDelegateQuickWindow::update() { QQuickWindow::update(); @@ -138,9 +148,4 @@ void RenderWidgetHostViewQtDelegateQuickWindow::move(const QPoint &screenPos) QQuickWindow::setPosition(screenPos); } -void RenderWidgetHostViewQtDelegateQuickWindow::setTooltip(const QString &tooltip) -{ - Q_UNUSED(tooltip); -} - } // namespace QtWebEngineCore 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 699b4ce9e..d0a5e480c 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h @@ -69,13 +69,14 @@ public: virtual QWindow* window() const Q_DECL_OVERRIDE; virtual QSGTexture *createTextureFromImage(const QImage &) Q_DECL_OVERRIDE; virtual QSGLayer *createLayer() Q_DECL_OVERRIDE; - virtual QSGImageNode *createImageNode() Q_DECL_OVERRIDE; + virtual QSGInternalImageNode *createImageNode() Q_DECL_OVERRIDE; + virtual QSGTextureNode *createTextureNode() Q_DECL_OVERRIDE; + virtual QSGRectangleNode *createRectangleNode() Q_DECL_OVERRIDE; virtual void update() Q_DECL_OVERRIDE; virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE; virtual void resize(int width, int height) Q_DECL_OVERRIDE; 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: diff --git a/src/webengine/ui/ToolTip.qml b/src/webengine/ui/ToolTip.qml new file mode 100644 index 000000000..96033e8f1 --- /dev/null +++ b/src/webengine/ui/ToolTip.qml @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +import QtQuick 2.5 + +Item { + id: toolTipContainer + z: 9999 + width: content.width + height: content.height + visible: false + + property alias text: toolTip.text + property int delayTimerInterval: 1000 + property int hideTimerInterval: 1500 + + Timer { + id: delayTimer + interval: delayTimerInterval + onTriggered: { + toolTipContainer.visible = true + hideTimer.start() + } + } + + Timer { + id: hideTimer + interval: hideTimerInterval + onTriggered: toolTipContainer.visible = false + } + + Rectangle { + id: content + color: "#f8eabf" + border.color: "black" + anchors.centerIn: parent + width: toolTip.contentWidth + 10 + height: toolTip.contentHeight + 10 + radius: 3 + + Text { + id: toolTip + anchors {fill: parent; margins: 5} + wrapMode: Text.WrapAnywhere + } + } + + function open() { + delayTimer.start(); + } + + function hide() { + hideTimer.start(); + } +} diff --git a/src/webengine/ui/ui.pro b/src/webengine/ui/ui.pro index 249d7dcfd..60dab61d6 100644 --- a/src/webengine/ui/ui.pro +++ b/src/webengine/ui/ui.pro @@ -14,6 +14,7 @@ QML_FILES += \ MenuItem.qml \ MenuSeparator.qml \ # Message Bubble - MessageBubble.qml + MessageBubble.qml \ + ToolTip.qml load(qml_module) diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp index 6ff12b53f..769a30016 100644 --- a/src/webengine/ui_delegates_manager.cpp +++ b/src/webengine/ui_delegates_manager.cpp @@ -50,6 +50,10 @@ #include <QQmlContext> #include <QQmlEngine> #include <QQmlProperty> +#include <QCursor> +#include <QList> +#include <QScreen> +#include <QGuiApplication> // Uncomment for QML debugging //#define UI_DELEGATES_DEBUG @@ -93,6 +97,31 @@ static QString getUIDelegatesImportDir(QQmlEngine *engine) { return importDir; } +static QPoint calculateToolTipPosition(QPoint &position, QSize &toolTip) { + QRect screen; + QList<QScreen *> screens = QGuiApplication::screens(); + Q_FOREACH (const QScreen *src, screens) + if (src->availableGeometry().contains(position)) + screen = src->availableGeometry(); + + position += QPoint(2, 16); + + if (position.x() + toolTip.width() > screen.x() + screen.width()) + position.rx() -= 4 + toolTip.width(); + if (position.y() + toolTip.height() > screen.y() + screen.height()) + position.ry() -= 24 + toolTip.height(); + if (position.y() < screen.y()) + position.setY(screen.y()); + if (position.x() + toolTip.width() > screen.x() + screen.width()) + position.setX(screen.x() + screen.width() - toolTip.width()); + if (position.x() < screen.x()) + position.setX(screen.x()); + if (position.y() + toolTip.height() > screen.y() + screen.height()) + position.setY(screen.y() + screen.height() - toolTip.height()); + + return position; +} + const char *defaultPropertyName(QObject *obj) { const QMetaObject *metaObject = obj->metaObject(); @@ -116,6 +145,7 @@ MenuItemHandler::MenuItemHandler(QObject *parent) UIDelegatesManager::UIDelegatesManager(QQuickWebEngineView *view) : m_view(view) , m_messageBubbleItem(0) + , m_toolTip(nullptr) FOR_EACH_COMPONENT_TYPE(COMPONENT_MEMBER_INIT, NO_SEPARATOR) { } @@ -493,4 +523,38 @@ void UIDelegatesManager::moveMessageBubble(const QRect &anchor) QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("y")).write(anchor.y() + anchor.size().height()); } +void UIDelegatesManager::showToolTip(const QString &text) +{ + if (!ensureComponentLoaded(ToolTip)) + return; + + if (text.isEmpty()) { + m_toolTip.reset(); + return; + } + + if (!m_toolTip.isNull()) + return; + + QQmlContext *context = qmlContext(m_view); + m_toolTip.reset(toolTipComponent->beginCreate(context)); + if (QQuickItem *item = qobject_cast<QQuickItem *>(m_toolTip.data())) + item->setParentItem(m_view); + m_toolTip->setParent(m_view); + toolTipComponent->completeCreate(); + + QQmlProperty(m_toolTip.data(), QStringLiteral("text")).write(text); + + int height = QQmlProperty(m_toolTip.data(), QStringLiteral("height")).read().toInt(); + int width = QQmlProperty(m_toolTip.data(), QStringLiteral("width")).read().toInt(); + QSize toolTipSize(width, height); + QPoint position = m_view->cursor().pos(); + position = m_view->mapFromGlobal(calculateToolTipPosition(position, toolTipSize)).toPoint(); + + QQmlProperty(m_toolTip.data(), QStringLiteral("x")).write(position.x()); + QQmlProperty(m_toolTip.data(), QStringLiteral("y")).write(position.y()); + + QMetaObject::invokeMethod(m_toolTip.data(), "open"); +} + } // namespace QtWebEngineCore diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h index b63aa91f1..43d1e6985 100644 --- a/src/webengine/ui_delegates_manager.h +++ b/src/webengine/ui_delegates_manager.h @@ -59,7 +59,8 @@ F(PromptDialog, promptDialog) SEPARATOR \ F(FilePicker, filePicker) SEPARATOR \ F(MessageBubble, messageBubble) SEPARATOR \ - F(AuthenticationDialog, authenticationDialog) SEPARATOR + F(AuthenticationDialog, authenticationDialog) SEPARATOR \ + F(ToolTip, toolTip) SEPARATOR \ #define COMMA_SEPARATOR , #define SEMICOLON_SEPARATOR ; @@ -115,12 +116,14 @@ public: void showMessageBubble(const QRect &anchor, const QString &mainText, const QString &subText); void hideMessageBubble(); void moveMessageBubble(const QRect &anchor); + void showToolTip(const QString &text); private: bool ensureComponentLoaded(ComponentType); QQuickWebEngineView *m_view; QScopedPointer<QQuickItem> m_messageBubbleItem; + QScopedPointer<QObject> m_toolTip; FOR_EACH_COMPONENT_TYPE(MEMBER_DECLARATION, SEMICOLON_SEPARATOR) |