summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-03-16 14:34:43 +0100
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-03-16 14:34:43 +0100
commit9ffb601435df46744b1f4a95b3a4b231f4bda64e (patch)
tree48b34f7ef1ef8aea962cf103d97ec8ab7b38291b /src
parent6e356d55c8eabcc96223e25182458b78378dd5a4 (diff)
parent9bec2760d44c944e7f6b43388924b5714d9e8e06 (diff)
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts: src/webengine/ui_delegates_manager.h Change-Id: I989280b6008fbc4844ed86d6d16f7e7aa6ba8db9
Diffstat (limited to 'src')
m---------src/3rdparty0
-rw-r--r--src/core/browser_context_adapter.cpp14
-rw-r--r--src/core/browser_context_adapter.h13
-rw-r--r--src/core/download_manager_delegate_qt.cpp18
-rw-r--r--src/core/web_contents_adapter_client.h3
-rw-r--r--src/core/web_contents_delegate_qt.cpp18
-rw-r--r--src/core/web_contents_delegate_qt.h3
-rw-r--r--src/core/web_engine_context.cpp10
-rw-r--r--src/core/web_engine_context.h11
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp26
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h2
-rw-r--r--src/webengine/api/qquickwebengineprofile_p_p.h5
-rw-r--r--src/webengine/api/qquickwebenginesettings.cpp109
-rw-r--r--src/webengine/api/qquickwebengineview.cpp14
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h3
-rw-r--r--src/webengine/ui/MessageBubble.qml147
-rw-r--r--src/webengine/ui/ui.pro4
-rw-r--r--src/webengine/ui_delegates_manager.cpp33
-rw-r--r--src/webengine/ui_delegates_manager.h8
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp25
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h3
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp28
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h2
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h5
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp8
-rw-r--r--src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc4
-rw-r--r--src/webenginewidgets/ui/messagebubblewidget.cpp221
-rw-r--r--src/webenginewidgets/ui/messagebubblewidget_p.h77
-rw-r--r--src/webenginewidgets/webenginewidgets.pro6
29 files changed, 760 insertions, 60 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject f3092dd031cffe3a6b5c41b868cad537df0f391
+Subproject c148371e72d900b48cc4790b9e78c6dc1703051
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index cb606a8b5..fa51575e3 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -72,7 +72,6 @@ BrowserContextAdapter::BrowserContextAdapter(bool offTheRecord)
, m_httpCacheType(DiskHttpCache)
, m_persistentCookiesPolicy(AllowPersistentCookies)
, m_visitedLinksPolicy(TrackVisitedLinksOnDisk)
- , m_client(0)
, m_httpCacheMaxSize(0)
{
}
@@ -133,9 +132,14 @@ DownloadManagerDelegateQt *BrowserContextAdapter::downloadManagerDelegate()
return m_downloadManagerDelegate.data();
}
-void BrowserContextAdapter::setClient(BrowserContextAdapterClient *adapterClient)
+void BrowserContextAdapter::addClient(BrowserContextAdapterClient *adapterClient)
{
- m_client = adapterClient;
+ m_clients.append(adapterClient);
+}
+
+void BrowserContextAdapter::removeClient(BrowserContextAdapterClient *adapterClient)
+{
+ m_clients.removeOne(adapterClient);
}
void BrowserContextAdapter::cancelDownload(quint32 downloadId)
@@ -148,9 +152,9 @@ BrowserContextAdapter* BrowserContextAdapter::defaultContext()
return WebEngineContext::current()->defaultBrowserContext();
}
-BrowserContextAdapter* BrowserContextAdapter::offTheRecordContext()
+QObject* BrowserContextAdapter::globalQObjectRoot()
{
- return WebEngineContext::current()->offTheRecordBrowserContext();
+ return WebEngineContext::current()->globalQObject();
}
QString BrowserContextAdapter::dataPath() const
diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h
index 0e5a3605d..42787bc23 100644
--- a/src/core/browser_context_adapter.h
+++ b/src/core/browser_context_adapter.h
@@ -39,15 +39,17 @@
#include "qtwebenginecoreglobal.h"
+#include <QList>
#include <QScopedPointer>
#include <QSharedData>
#include <QString>
#include <QVector>
+QT_FORWARD_DECLARE_CLASS(QObject)
+
namespace QtWebEngineCore {
class BrowserContextAdapterClient;
-
class BrowserContextQt;
class CustomUrlSchemeHandler;
class DownloadManagerDelegateQt;
@@ -62,14 +64,15 @@ public:
virtual ~BrowserContextAdapter();
static BrowserContextAdapter* defaultContext();
- static BrowserContextAdapter* offTheRecordContext();
+ static QObject* globalQObjectRoot();
WebEngineVisitedLinksManager *visitedLinksManager();
DownloadManagerDelegateQt *downloadManagerDelegate();
- BrowserContextAdapterClient* client() { return m_client; }
+ QList<BrowserContextAdapterClient*> clients() { return m_clients; }
+ void addClient(BrowserContextAdapterClient *adapterClient);
+ void removeClient(BrowserContextAdapterClient *adapterClient);
- void setClient(BrowserContextAdapterClient *adapterClient);
void cancelDownload(quint32 downloadId);
BrowserContextQt *browserContext();
@@ -144,7 +147,7 @@ private:
PersistentCookiesPolicy m_persistentCookiesPolicy;
VisitedLinksPolicy m_visitedLinksPolicy;
QVector<CustomUrlSchemeHandler*> m_customUrlSchemeHandlers;
- BrowserContextAdapterClient *m_client;
+ QList<BrowserContextAdapterClient*> m_clients;
int m_httpCacheMaxSize;
Q_DISABLE_COPY(BrowserContextAdapter)
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index e84ca5f2c..c01dcf63d 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -127,7 +127,8 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i
}
item->AddObserver(this);
- if (m_contextAdapter->client()) {
+ QList<BrowserContextAdapterClient*> clients = m_contextAdapter->clients();
+ if (!clients.isEmpty()) {
BrowserContextAdapterClient::DownloadItemInfo info = {
item->GetId(),
toQt(item->GetURL()),
@@ -137,7 +138,12 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i
suggestedFilePath,
false /* accepted */
};
- m_contextAdapter->client()->downloadRequested(info);
+
+ Q_FOREACH (BrowserContextAdapterClient *client, clients) {
+ client->downloadRequested(info);
+ if (info.accepted)
+ break;
+ }
suggestedFile.setFile(info.path);
@@ -173,7 +179,8 @@ void DownloadManagerDelegateQt::GetSaveDir(content::BrowserContext* browser_cont
void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *download)
{
- if (m_contextAdapter->client()) {
+ QList<BrowserContextAdapterClient*> clients = m_contextAdapter->clients();
+ if (!clients.isEmpty()) {
BrowserContextAdapterClient::DownloadItemInfo info = {
download->GetId(),
toQt(download->GetURL()),
@@ -183,7 +190,10 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *downloa
QString(),
true /* accepted */
};
- m_contextAdapter->client()->downloadUpdated(info);
+
+ Q_FOREACH (BrowserContextAdapterClient *client, clients) {
+ client->downloadUpdated(info);
+ }
}
}
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 9455572da..886f8bcc6 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -175,6 +175,9 @@ public:
virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0;
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
virtual WebEngineSettings *webEngineSettings() const = 0;
+ virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) = 0;
+ virtual void hideValidationMessage() = 0;
+ virtual void moveValidationMessage(const QRect &anchor) = 0;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index a2e6f192a..61eb7999c 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -357,4 +357,22 @@ void WebContentsDelegateQt::geolocationPermissionReply(const QUrl &origin, bool
}
}
+void WebContentsDelegateQt::ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text)
+{
+ Q_UNUSED(web_contents);
+ m_viewClient->showValidationMessage(toQt(anchor_in_root_view), toQt(main_text), toQt(sub_text));
+}
+
+void WebContentsDelegateQt::HideValidationMessage(content::WebContents *web_contents)
+{
+ Q_UNUSED(web_contents);
+ m_viewClient->hideValidationMessage();
+}
+
+void WebContentsDelegateQt::MoveValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view)
+{
+ Q_UNUSED(web_contents);
+ m_viewClient->moveValidationMessage(toQt(anchor_in_root_view));
+}
+
} // namespace QtWebEngineCore
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index a200ca4df..254177d24 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -86,6 +86,9 @@ public:
virtual void RequestMediaAccessPermission(content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) Q_DECL_OVERRIDE;
virtual void UpdateTargetURL(content::WebContents* source, const GURL& url) Q_DECL_OVERRIDE;
virtual void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) Q_DECL_OVERRIDE;
+ virtual void ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text) Q_DECL_OVERRIDE;
+ virtual void HideValidationMessage(content::WebContents *web_contents) Q_DECL_OVERRIDE;
+ virtual void MoveValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view) Q_DECL_OVERRIDE;
// WebContentsObserver overrides
virtual void DidStartProvisionalLoadForFrame(content::RenderFrameHost *render_frame_host, const GURL &validated_url, bool is_error_page, bool is_iframe_srcdoc) Q_DECL_OVERRIDE;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 5d8fe79e6..b830110a7 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -138,6 +138,9 @@ bool usingQtQuick2DRenderer()
WebEngineContext::~WebEngineContext()
{
+ m_defaultBrowserContext = 0;
+ delete m_globalQObject;
+ m_globalQObject = 0;
base::MessagePump::Delegate *delegate = m_runLoop->loop_;
// Flush the UI message loop before quitting.
while (delegate->DoWork()) { }
@@ -162,11 +165,9 @@ BrowserContextAdapter* WebEngineContext::defaultBrowserContext()
return m_defaultBrowserContext.data();
}
-BrowserContextAdapter* WebEngineContext::offTheRecordBrowserContext()
+QObject *WebEngineContext::globalQObject()
{
- if (!m_offTheRecordBrowserContext)
- m_offTheRecordBrowserContext = new BrowserContextAdapter(true);
- return m_offTheRecordBrowserContext.data();
+ return m_globalQObject;
}
#ifndef CHROMIUM_VERSION
@@ -178,6 +179,7 @@ WebEngineContext::WebEngineContext()
: m_mainDelegate(new ContentMainDelegateQt)
, m_contentRunner(content::ContentMainRunner::Create())
, m_browserRunner(content::BrowserMainRunner::Create())
+ , m_globalQObject(new QObject())
{
QList<QByteArray> args;
Q_FOREACH (const QString& arg, QCoreApplication::arguments())
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 5f45aad98..a3795b0a9 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -37,6 +37,8 @@
#ifndef WEB_ENGINE_CONTEXT_H
#define WEB_ENGINE_CONTEXT_H
+#include "qtwebenginecoreglobal.h"
+
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -51,19 +53,22 @@ class BrowserMainRunner;
class ContentMainRunner;
}
+QT_FORWARD_DECLARE_CLASS(QObject)
+
namespace QtWebEngineCore {
+
class BrowserContextAdapter;
class ContentMainDelegateQt;
class DevToolsHttpHandlerDelegateQt;
class SurfaceFactoryQt;
-}
+} // namespace
class WebEngineContext : public base::RefCounted<WebEngineContext> {
public:
static scoped_refptr<WebEngineContext> current();
QtWebEngineCore::BrowserContextAdapter *defaultBrowserContext();
- QtWebEngineCore::BrowserContextAdapter *offTheRecordBrowserContext();
+ QObject *globalQObject();
private:
friend class base::RefCounted<WebEngineContext>;
@@ -77,8 +82,8 @@ private:
#if defined(OS_ANDROID)
scoped_ptr<QtWebEngineCore::SurfaceFactoryQt> m_surfaceFactory;
#endif
+ QObject* m_globalQObject;
QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_defaultBrowserContext;
- QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_offTheRecordBrowserContext;
scoped_ptr<QtWebEngineCore::DevToolsHttpHandlerDelegateQt> m_devtools;
};
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 718007c35..545352861 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -50,20 +50,17 @@ using QtWebEngineCore::BrowserContextAdapter;
QT_BEGIN_NAMESPACE
-QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext)
+QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapter* browserContext)
: m_settings(new QQuickWebEngineSettings())
- , m_browserContext(browserContext)
+ , m_browserContextRef(browserContext)
{
- if (ownsContext)
- m_browserContextRef = browserContext;
-
- m_browserContext->setClient(this);
+ m_browserContextRef->addClient(this);
m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord());
}
QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
{
- m_browserContext->setClient(0);
+ m_browserContextRef->removeClient(this);
Q_FOREACH (QQuickWebEngineDownloadItem* download, m_ongoingDownloads) {
if (download)
@@ -75,7 +72,7 @@ QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
void QQuickWebEngineProfilePrivate::cancelDownload(quint32 downloadId)
{
- m_browserContext->cancelDownload(downloadId);
+ browserContext()->cancelDownload(downloadId);
}
void QQuickWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId)
@@ -161,13 +158,14 @@ void QQuickWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info
*/
QQuickWebEngineProfile::QQuickWebEngineProfile()
- : d_ptr(new QQuickWebEngineProfilePrivate(new BrowserContextAdapter(false), true))
+ : d_ptr(new QQuickWebEngineProfilePrivate(new BrowserContextAdapter(false)))
{
d_ptr->q_ptr = this;
}
-QQuickWebEngineProfile::QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *privatePtr)
- : d_ptr(privatePtr)
+QQuickWebEngineProfile::QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *privatePtr, QObject *parent)
+ : QObject(parent)
+ , d_ptr(privatePtr)
{
d_ptr->q_ptr = this;
}
@@ -399,8 +397,10 @@ void QQuickWebEngineProfile::setHttpCacheMaximumSize(int maximumSize)
QQuickWebEngineProfile *QQuickWebEngineProfile::defaultProfile()
{
- static QQuickWebEngineProfile profile(new QQuickWebEngineProfilePrivate(BrowserContextAdapter::defaultContext(), false));
- return &profile;
+ static QQuickWebEngineProfile *profile = new QQuickWebEngineProfile(
+ new QQuickWebEngineProfilePrivate(BrowserContextAdapter::defaultContext()),
+ BrowserContextAdapter::globalQObjectRoot());
+ return profile;
}
QQuickWebEngineSettings *QQuickWebEngineProfile::settings() const
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index ee91d7728..3978fc5e0 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -121,7 +121,7 @@ signals:
private:
Q_DECLARE_PRIVATE(QQuickWebEngineProfile)
- QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *);
+ QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *, QObject *parent = 0);
QQuickWebEngineSettings *settings() const;
friend class QQuickWebEngineSettings;
diff --git a/src/webengine/api/qquickwebengineprofile_p_p.h b/src/webengine/api/qquickwebengineprofile_p_p.h
index 0cf11acec..a702a8a1d 100644
--- a/src/webengine/api/qquickwebengineprofile_p_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p_p.h
@@ -52,10 +52,10 @@ class QQuickWebEngineSettings;
class QQuickWebEngineProfilePrivate : public QtWebEngineCore::BrowserContextAdapterClient {
public:
Q_DECLARE_PUBLIC(QQuickWebEngineProfile)
- QQuickWebEngineProfilePrivate(QtWebEngineCore::BrowserContextAdapter* browserContext, bool ownsContext);
+ QQuickWebEngineProfilePrivate(QtWebEngineCore::BrowserContextAdapter* browserContext);
~QQuickWebEngineProfilePrivate();
- QtWebEngineCore::BrowserContextAdapter *browserContext() const { return m_browserContext; }
+ QtWebEngineCore::BrowserContextAdapter *browserContext() const { return m_browserContextRef.data(); }
QQuickWebEngineSettings *settings() const { return m_settings.data(); }
void cancelDownload(quint32 downloadId);
@@ -68,7 +68,6 @@ private:
friend class QQuickWebEngineViewPrivate;
QQuickWebEngineProfile *q_ptr;
QScopedPointer<QQuickWebEngineSettings> m_settings;
- QtWebEngineCore::BrowserContextAdapter *m_browserContext;
QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_browserContextRef;
QMap<quint32, QPointer<QQuickWebEngineDownloadItem> > m_ongoingDownloads;
};
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 70a9d4b59..8a88bac68 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -49,64 +49,173 @@ QQuickWebEngineSettings::QQuickWebEngineSettings(QQuickWebEngineSettings *parent
: d_ptr(new WebEngineSettings(parentSettings ? parentSettings->d_ptr.data() : 0))
{ }
+/*!
+ \qmltype WebEngineSettings
+ \instantiates QQuickWebEngineSettings
+ \inqmlmodule QtWebEngine
+ \since QtWebEngine 1.1
+ \brief WebEngineSettings allows configuration of browser properties and attributes.
+
+ WebEngineSettings allows configuration of browser properties and generic attributes like for example
+ JavaScript, focus behavior and access to remote content.
+
+ Each WebEngineView can have individual settings.
+
+*/
+
+
QQuickWebEngineSettings::~QQuickWebEngineSettings()
{ }
+/*!
+ \qmlproperty bool WebEngineSettings::autoLoadImages
+
+ Specifies whether images are automatically loaded in web pages.
+
+ This is enabled by default.
+*/
bool QQuickWebEngineSettings::autoLoadImages() const
{
return d_ptr->testAttribute(WebEngineSettings::AutoLoadImages);
}
+/*!
+ \qmlproperty bool WebEngineSettings::javascriptEnabled
+
+ Enables or disables the running of JavaScript programs.
+
+ This is enabled by default.
+*/
bool QQuickWebEngineSettings::javascriptEnabled() const
{
return d_ptr->testAttribute(WebEngineSettings::JavascriptEnabled);
}
+/*!
+ \qmlproperty bool WebEngineSettings::javascriptCanOpenWindows
+
+ Specifies whether JavaScript programs can open new windows.
+
+ This is enabled by default.
+*/
bool QQuickWebEngineSettings::javascriptCanOpenWindows() const
{
return d_ptr->testAttribute(WebEngineSettings::JavascriptCanOpenWindows);
}
+/*!
+ \qmlproperty bool WebEngineSettings::javascriptCanAccessClipboard
+
+ Specifies whether JavaScript programs can read or write to the clipboard.
+
+ This is disabled by default.
+*/
bool QQuickWebEngineSettings::javascriptCanAccessClipboard() const
{
return d_ptr->testAttribute(WebEngineSettings::JavascriptCanAccessClipboard);
}
+/*!
+ \qmlproperty bool WebEngineSettings::linksIncludedInFocusChain
+
+ Specifies whether hyperlinks should be included in the keyboard focus chain.
+
+ This is enabled by default.
+*/
bool QQuickWebEngineSettings::linksIncludedInFocusChain() const
{
return d_ptr->testAttribute(WebEngineSettings::LinksIncludedInFocusChain);
}
+/*!
+ \qmlproperty bool WebEngineSettings::localStorageEnabled
+
+ Specifies whether support for the HTML 5 local storage feature is enabled or not.
+
+ This is enabled by default.
+*/
bool QQuickWebEngineSettings::localStorageEnabled() const
{
return d_ptr->testAttribute(WebEngineSettings::LocalStorageEnabled);
}
+/*!
+ \qmlproperty bool WebEngineSettings::localContentCanAccessRemoteUrls
+
+ Specifies whether locally loaded documents are allowed to access remote urls.
+ For more information about security origins and local vs. remote content see QWebEngineSecurityOrigin.
+
+ This is disabled by default.
+*/
bool QQuickWebEngineSettings::localContentCanAccessRemoteUrls() const
{
return d_ptr->testAttribute(WebEngineSettings::LocalContentCanAccessRemoteUrls);
}
+/*!
+ \qmlproperty bool WebEngineSettings::spatialNavigationEnabled
+
+ Enables or disables the Spatial Navigation feature, which consists in the
+ ability to navigate between focusable elements in a Web page, such as hyperlinks
+ and form controls, by using Left, Right, Up and Down arrow keys.
+
+ For example, if a user presses the Right key, heuristics determine whether there
+ is an element they might be trying to reach towards the right and which element
+ they probably want.
+
+ This is disabled by default.
+
+*/
bool QQuickWebEngineSettings::spatialNavigationEnabled() const
{
return d_ptr->testAttribute(WebEngineSettings::SpatialNavigationEnabled);
}
+/*!
+ \qmlproperty bool WebEngineSettings::localContentCanAccessFileUrls
+
+ Specifies whether locally loaded documents are allowed to access other local urls.
+ For more information about security origins and local vs. remote content see QWebEngineSecurityOrigin.
+
+ This is enabled by default.
+*/
bool QQuickWebEngineSettings::localContentCanAccessFileUrls() const
{
return d_ptr->testAttribute(WebEngineSettings::LocalContentCanAccessFileUrls);
}
+/*!
+ \qmlproperty bool WebEngineSettings::hyperlinkAuditingEnabled
+
+ This setting enables support for the ping attribute for hyperlinks.
+
+ It is disabled by default.
+*/
bool QQuickWebEngineSettings::hyperlinkAuditingEnabled() const
{
return d_ptr->testAttribute(WebEngineSettings::HyperlinkAuditingEnabled);
}
+/*!
+ \qmlproperty bool WebEngineSettings::errorPageEnabled
+
+ This setting enables built-in error pages of Chromium.
+
+ It is enabled by default.
+*/
bool QQuickWebEngineSettings::errorPageEnabled() const
{
return d_ptr->testAttribute(WebEngineSettings::ErrorPageEnabled);
}
+/*!
+ \qmlproperty QString WebEngineSettings::defaultTextEncoding
+
+ The \a encoding, must be a string describing an encoding such as "utf-8",
+ "iso-8859-1", etc.
+
+ If left empty a default value will be used.
+*/
QString QQuickWebEngineSettings::defaultTextEncoding() const
{
return d_ptr->defaultTextEncoding();
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 9a64b9ac6..87f75f549 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -767,6 +767,20 @@ void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount)
args.append(QJSValue(matchCount));
callback.call(args);
}
+void QQuickWebEngineViewPrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText)
+{
+ ui()->showMessageBubble(anchor, mainText, subText);
+}
+
+void QQuickWebEngineViewPrivate::hideValidationMessage()
+{
+ ui()->hideMessageBubble();
+}
+
+void QQuickWebEngineViewPrivate::moveValidationMessage(const QRect &anchor)
+{
+ ui()->moveMessageBubble(anchor);
+}
bool QQuickWebEngineView::isLoading() const
{
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index b3907d3a4..d05055cbb 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -165,6 +165,9 @@ public:
virtual QtWebEngineCore::WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController);
virtual void runGeolocationPermissionRequest(QUrl const&) Q_DECL_OVERRIDE;
+ virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE;
+ virtual void hideValidationMessage() Q_DECL_OVERRIDE;
+ virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
diff --git a/src/webengine/ui/MessageBubble.qml b/src/webengine/ui/MessageBubble.qml
new file mode 100644
index 000000000..4328eae40
--- /dev/null
+++ b/src/webengine/ui/MessageBubble.qml
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+
+Item {
+ id: bubble
+
+ width: 1
+ height: 1
+
+ property int maxWidth: 0
+ property string mainText: "";
+ property string subText: "";
+
+ property int border: 1
+
+ property int arrowWidth: 18
+ property int arrowHeight: 18
+ property int arrowOffset: 18
+
+ property int marginLeft: border + 8
+ property int marginTop: border + arrowHeight + 6
+ property int marginRight: border + 8
+ property int marginBottom: border + 6
+
+ Column {
+ id: messageColumn
+
+ x: bubble.marginLeft
+ y: bubble.marginTop
+ z: 1
+
+ spacing: 5
+
+ Text {
+ id: message
+ width: bubble.maxWidth
+
+ wrapMode: Text.WordWrap
+ elide: Text.ElideNone
+ clip: true
+
+ font.pointSize: subMessage.font.pointSize + 4
+
+ text: bubble.mainText
+ }
+
+ Text {
+ id: subMessage
+ width: bubble.maxWidth
+
+ wrapMode: Text.WordWrap
+ elide: Text.ElideNone
+ clip: true
+
+ text: bubble.subText
+ }
+ }
+
+ Canvas {
+ id: bubbleCanvas
+
+ property int textWidth: Math.min(bubble.maxWidth, Math.max(message.paintedWidth, subMessage.paintedWidth))
+ property int textHeight: message.paintedHeight + (subMessage.paintedWidth > 0 ? (messageColumn.spacing + subMessage.paintedHeight) : 0)
+
+ width: textWidth + bubble.marginLeft + bubble.marginRight
+ height: textHeight + bubble.marginTop + bubble.marginBottom
+
+ property int cornerRadius: 7
+
+ property int messageBoxLeft: 0
+ property int messageBoxTop: bubble.arrowHeight
+ property int messageBoxRight: width - border
+ property int messageBoxBottom: height - border
+
+ onPaint: {
+ var ctx = getContext("2d")
+
+ ctx.lineWidth = bubble.border
+ ctx.strokeStyle = "#555"
+ ctx.fillStyle = "#ffffe1"
+
+ ctx.beginPath()
+
+ ctx.moveTo(messageBoxLeft + cornerRadius, messageBoxTop)
+
+ // Arrow
+ ctx.lineTo(messageBoxLeft + bubble.arrowOffset, messageBoxTop)
+ ctx.lineTo(messageBoxLeft + bubble.arrowOffset, messageBoxTop - bubble.arrowHeight)
+ ctx.lineTo(messageBoxLeft + bubble.arrowOffset + bubble.arrowWidth, messageBoxTop)
+
+ // Message Box
+ ctx.lineTo(messageBoxRight - cornerRadius, messageBoxTop)
+ ctx.quadraticCurveTo(messageBoxRight, messageBoxTop, messageBoxRight, messageBoxTop + cornerRadius)
+ ctx.lineTo(messageBoxRight, messageBoxBottom - cornerRadius)
+ ctx.quadraticCurveTo(messageBoxRight, messageBoxBottom, messageBoxRight - cornerRadius, messageBoxBottom)
+ ctx.lineTo(messageBoxLeft + cornerRadius, messageBoxBottom)
+ ctx.quadraticCurveTo(messageBoxLeft, messageBoxBottom, messageBoxLeft, messageBoxBottom - cornerRadius)
+ ctx.lineTo(messageBoxLeft, messageBoxTop + cornerRadius)
+ ctx.quadraticCurveTo(messageBoxLeft, messageBoxTop, messageBoxLeft + cornerRadius, messageBoxTop)
+
+ ctx.closePath()
+
+ ctx.fill()
+ ctx.stroke()
+ }
+
+ onPainted: {
+ bubble.width = bubbleCanvas.width
+ bubble.height = bubbleCanvas.height
+ }
+ }
+}
diff --git a/src/webengine/ui/ui.pro b/src/webengine/ui/ui.pro
index a5ae648cb..fdf7a85bc 100644
--- a/src/webengine/ui/ui.pro
+++ b/src/webengine/ui/ui.pro
@@ -9,6 +9,8 @@ QML_FILES += \
# Menus. Based on Qt Quick Controls
Menu.qml \
MenuItem.qml \
- MenuSeparator.qml
+ MenuSeparator.qml \
+ # Message Bubble
+ MessageBubble.qml
load(qml_module)
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index 44c763f37..48466bfe2 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -139,6 +139,7 @@ void NavigateMenuItem::onTriggered()
UIDelegatesManager::UIDelegatesManager(QQuickWebEngineView *view)
: m_view(view)
+ , m_messageBubbleItem(0)
FOR_EACH_COMPONENT_TYPE(COMPONENT_MEMBER_INIT, NO_SEPARATOR)
{
}
@@ -390,4 +391,36 @@ void UIDelegatesManager::showFilePicker(FilePickerController *controller)
QMetaObject::invokeMethod(filePicker, "open");
}
+void UIDelegatesManager::showMessageBubble(const QRect &anchor, const QString &mainText, const QString &subText)
+{
+ if (!ensureComponentLoaded(MessageBubble))
+ return;
+
+ Q_ASSERT(m_messageBubbleItem.isNull());
+
+ QQmlContext *context = qmlContext(m_view);
+ m_messageBubbleItem.reset(qobject_cast<QQuickItem *>(messageBubbleComponent->beginCreate(context)));
+ m_messageBubbleItem->setParentItem(m_view);
+ messageBubbleComponent->completeCreate();
+
+ QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("maxWidth")).write(anchor.size().width());
+ QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("mainText")).write(mainText);
+ QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("subText")).write(subText);
+ QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("x")).write(anchor.x());
+ QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("y")).write(anchor.y() + anchor.size().height());
+}
+
+void UIDelegatesManager::hideMessageBubble()
+{
+ m_messageBubbleItem.reset();
+}
+
+void UIDelegatesManager::moveMessageBubble(const QRect &anchor)
+{
+ Q_ASSERT(!m_messageBubbleItem.isNull());
+
+ QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("x")).write(anchor.x());
+ QQmlProperty(m_messageBubbleItem.data(), QStringLiteral("y")).write(anchor.y() + anchor.size().height());
+}
+
} // namespace QtWebEngineCore
diff --git a/src/webengine/ui_delegates_manager.h b/src/webengine/ui_delegates_manager.h
index 9367bff30..745ae0dfd 100644
--- a/src/webengine/ui_delegates_manager.h
+++ b/src/webengine/ui_delegates_manager.h
@@ -54,7 +54,8 @@
F(AlertDialog, alertDialog) SEPARATOR \
F(ConfirmDialog, confirmDialog) SEPARATOR \
F(PromptDialog, promptDialog) SEPARATOR \
- F(FilePicker, filePicker) SEPARATOR
+ F(FilePicker, filePicker) SEPARATOR \
+ F(MessageBubble, messageBubble) SEPARATOR
#define COMMA_SEPARATOR ,
#define SEMICOLON_SEPARATOR ;
@@ -66,6 +67,7 @@
QT_BEGIN_NAMESPACE
class QObject;
class QQmlContext;
+class QQuickItem;
class QQuickWebEngineView;
QT_END_NAMESPACE
@@ -124,11 +126,15 @@ public:
QQmlContext *creationContextForComponent(QQmlComponent *);
void showDialog(QSharedPointer<JavaScriptDialogController>);
void showFilePicker(FilePickerController *controller);
+ void showMessageBubble(const QRect &anchor, const QString &mainText, const QString &subText);
+ void hideMessageBubble();
+ void moveMessageBubble(const QRect &anchor);
private:
bool ensureComponentLoaded(ComponentType);
QQuickWebEngineView *m_view;
+ QScopedPointer<QQuickItem> m_messageBubbleItem;
FOR_EACH_COMPONENT_TYPE(MEMBER_DECLARATION, SEMICOLON_SEPARATOR)
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 08976a291..0f79bbf47 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -39,6 +39,10 @@
#include "web_contents_adapter.h"
#include "web_engine_settings.h"
+#ifdef QT_UI_DELEGATES
+#include "ui/messagebubblewidget_p.h"
+#endif
+
#include <QAction>
#include <QApplication>
#include <QAuthenticator>
@@ -779,6 +783,27 @@ void QWebEnginePagePrivate::javaScriptConsoleMessage(JavaScriptConsoleMessageLev
q->javaScriptConsoleMessage(static_cast<QWebEnginePage::JavaScriptConsoleMessageLevel>(level), message, lineNumber, sourceID);
}
+void QWebEnginePagePrivate::showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText)
+{
+#ifdef QT_UI_DELEGATES
+ QtWebEngineWidgetUI::MessageBubbleWidget::showBubble(view, anchor, mainText, subText);
+#endif
+}
+
+void QWebEnginePagePrivate::hideValidationMessage()
+{
+#ifdef QT_UI_DELEGATES
+ QtWebEngineWidgetUI::MessageBubbleWidget::hideBubble();
+#endif
+}
+
+void QWebEnginePagePrivate::moveValidationMessage(const QRect &anchor)
+{
+#ifdef QT_UI_DELEGATES
+ QtWebEngineWidgetUI::MessageBubbleWidget::moveBubble(view, anchor);
+#endif
+}
+
namespace {
class SaveToClipboardFunctor
{
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index ccfdd5d0e..62ca16415 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -147,6 +147,9 @@ public:
#endif // QT_NO_ACCESSIBILITY
virtual QtWebEngineCore::WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE;
virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &controller) Q_DECL_OVERRIDE;
+ virtual void showValidationMessage(const QRect &anchor, const QString &mainText, const QString &subText) Q_DECL_OVERRIDE;
+ virtual void hideValidationMessage() Q_DECL_OVERRIDE;
+ virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE;
virtual QtWebEngineCore::BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index eb502d050..e63519d2c 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -102,15 +102,12 @@ using QtWebEngineCore::BrowserContextAdapter;
\sa QWebEngineDownloadItem
*/
-QWebEngineProfilePrivate::QWebEngineProfilePrivate(BrowserContextAdapter* browserContext, bool ownsContext)
+QWebEngineProfilePrivate::QWebEngineProfilePrivate(BrowserContextAdapter* browserContext)
: scriptCollection(new QWebEngineScriptCollectionPrivate(browserContext->userScriptController()))
, m_settings(new QWebEngineSettings())
- , m_browserContext(browserContext)
+ , m_browserContextRef(browserContext)
{
- if (ownsContext)
- m_browserContextRef = browserContext;
-
- m_browserContext->setClient(this);
+ m_browserContextRef->addClient(this);
m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord());
}
@@ -118,7 +115,7 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate()
{
delete m_settings;
m_settings = 0;
- m_browserContext->setClient(0);
+ m_browserContextRef->removeClient(this);
Q_FOREACH (QWebEngineDownloadItem* download, m_ongoingDownloads) {
if (download)
@@ -130,7 +127,7 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate()
void QWebEngineProfilePrivate::cancelDownload(quint32 downloadId)
{
- m_browserContext->cancelDownload(downloadId);
+ browserContext()->cancelDownload(downloadId);
}
void QWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId)
@@ -196,7 +193,7 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info)
*/
QWebEngineProfile::QWebEngineProfile(QObject *parent)
: QObject(parent)
- , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(true), true))
+ , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(false)))
{
d_ptr->q_ptr = this;
}
@@ -213,15 +210,16 @@ QWebEngineProfile::QWebEngineProfile(QObject *parent)
*/
QWebEngineProfile::QWebEngineProfile(const QString &storageName, QObject *parent)
: QObject(parent)
- , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(storageName), true))
+ , d_ptr(new QWebEngineProfilePrivate(new BrowserContextAdapter(storageName)))
{
d_ptr->q_ptr = this;
}
/*! \internal
*/
-QWebEngineProfile::QWebEngineProfile(QWebEngineProfilePrivate *privatePtr)
- : d_ptr(privatePtr)
+QWebEngineProfile::QWebEngineProfile(QWebEngineProfilePrivate *privatePtr, QObject *parent)
+ : QObject(parent)
+ , d_ptr(privatePtr)
{
d_ptr->q_ptr = this;
}
@@ -455,8 +453,10 @@ QWebEngineScriptCollection &QWebEngineProfile::scripts()
*/
QWebEngineProfile *QWebEngineProfile::defaultProfile()
{
- static QWebEngineProfile profile(new QWebEngineProfilePrivate(BrowserContextAdapter::defaultContext(), false));
- return &profile;
+ static QWebEngineProfile* profile = new QWebEngineProfile(
+ new QWebEngineProfilePrivate(BrowserContextAdapter::defaultContext()),
+ BrowserContextAdapter::globalQObjectRoot());
+ return profile;
}
/*!
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index a25cbcccd..d65db24ab 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -107,7 +107,7 @@ Q_SIGNALS:
private:
Q_DECLARE_PRIVATE(QWebEngineProfile)
- QWebEngineProfile(QWebEngineProfilePrivate *);
+ QWebEngineProfile(QWebEngineProfilePrivate *, QObject *parent = 0);
friend class QWebEnginePagePrivate;
friend class QWebEngineUrlSchemeHandler;
diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h
index 6ae9f9ca9..b0bfc88b9 100644
--- a/src/webenginewidgets/api/qwebengineprofile_p.h
+++ b/src/webenginewidgets/api/qwebengineprofile_p.h
@@ -55,10 +55,10 @@ class QWebEngineSettings;
class QWebEngineProfilePrivate : public QtWebEngineCore::BrowserContextAdapterClient {
public:
Q_DECLARE_PUBLIC(QWebEngineProfile)
- QWebEngineProfilePrivate(QtWebEngineCore::BrowserContextAdapter* browserContext, bool ownsContext);
+ QWebEngineProfilePrivate(QtWebEngineCore::BrowserContextAdapter* browserContext);
~QWebEngineProfilePrivate();
- QtWebEngineCore::BrowserContextAdapter *browserContext() const { return m_browserContext; }
+ QtWebEngineCore::BrowserContextAdapter *browserContext() const { return m_browserContextRef.data(); }
QWebEngineSettings *settings() const { return m_settings; }
void cancelDownload(quint32 downloadId);
@@ -76,7 +76,6 @@ public:
private:
QWebEngineProfile *q_ptr;
QWebEngineSettings *m_settings;
- QtWebEngineCore::BrowserContextAdapter *m_browserContext;
QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_browserContextRef;
QMap<quint32, QPointer<QWebEngineDownloadItem> > m_ongoingDownloads;
QMap<QByteArray, QPointer<QWebEngineUrlSchemeHandler> > m_urlSchemeHandlers;
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 039e18a16..a4a8dd760 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -40,6 +40,10 @@
#include "qwebenginepage_p.h"
#include "web_contents_adapter.h"
+#ifdef QT_UI_DELEGATES
+#include "ui/messagebubblewidget_p.h"
+#endif
+
#include <QAction>
#include <QMenu>
#include <QContextMenuEvent>
@@ -118,6 +122,10 @@ QWebEngineView::~QWebEngineView()
{
Q_D(QWebEngineView);
QWebEngineViewPrivate::bind(0, d->page);
+
+#ifdef QT_UI_DELEGATES
+ QtWebEngineWidgetUI::MessageBubbleWidget::hideBubble();
+#endif
}
QWebEnginePage* QWebEngineView::page() const
diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
index 545abedc6..82410a50f 100644
--- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc
@@ -107,8 +107,8 @@
feature, which consists in the ability to navigate between focusable
elements in a Web page, such as hyperlinks and form controls, by using
Left, Right, Up and Down arrow keys. For example, if a user presses the
- Right key, heuristics determine whether there is an element he might be
- trying to reach towards the right and which element he probably wants.
+ Right key, heuristics determine whether there is an element they might be
+ trying to reach towards the right and which element they probably want.
This is disabled by default.
\value LocalContentCanAccessFileUrls Specifies whether locally loaded documents are
allowed to access other local urls. This is enabled by default. For more information
diff --git a/src/webenginewidgets/ui/messagebubblewidget.cpp b/src/webenginewidgets/ui/messagebubblewidget.cpp
new file mode 100644
index 000000000..3465f4218
--- /dev/null
+++ b/src/webenginewidgets/ui/messagebubblewidget.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "messagebubblewidget_p.h"
+
+#include "api/qwebengineview.h"
+
+#include <QBitmap>
+#include <QHBoxLayout>
+#include <QIcon>
+#include <QLabel>
+#include <QStyle>
+
+namespace QtWebEngineWidgetUI {
+
+Q_GLOBAL_STATIC(MessageBubbleWidget, bubbleInstance)
+
+void MessageBubbleWidget::showBubble(QWebEngineView *view, const QRect &anchor, const QString &mainText, const QString &subText)
+{
+ hideBubble();
+ if (mainText.isEmpty())
+ return;
+
+ bubbleInstance->createBubble(anchor.size().width(), mainText, subText);
+ bubbleInstance->moveToAnchor(view, anchor);
+}
+
+void MessageBubbleWidget::hideBubble()
+{
+ bubbleInstance->hide();
+}
+
+void MessageBubbleWidget::moveBubble(QWebEngineView *view, const QRect &anchor)
+{
+ bubbleInstance->moveToAnchor(view, anchor);
+}
+
+MessageBubbleWidget::MessageBubbleWidget()
+ : QWidget(0, Qt::ToolTip)
+ , m_mainLabel(new QLabel)
+ , m_subLabel(new QLabel)
+{
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setAlignment(Qt::AlignTop);
+ hLayout->setSizeConstraint(QLayout::SetFixedSize);
+ hLayout->setMargin(3);
+
+ const int iconSize = 18;
+ QIcon si = style()->standardIcon(QStyle::SP_MessageBoxWarning);
+
+ if (!si.isNull()) {
+ QLabel *iconLabel = new QLabel(this);
+ iconLabel->setPixmap(si.pixmap(iconSize, iconSize));
+ iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ iconLabel->setMargin(2);
+ hLayout->addWidget(iconLabel, 0, Qt::AlignTop);
+ }
+
+ QVBoxLayout *vLayout = new QVBoxLayout;
+
+ m_mainLabel->installEventFilter(this);
+ m_mainLabel->setWordWrap(true);
+ m_mainLabel->setTextFormat(Qt::PlainText);
+ m_mainLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
+ vLayout->addWidget(m_mainLabel.data());
+
+ QFont mainFont = m_mainLabel->font();
+ mainFont.setPointSize(mainFont.pointSize() + 4);
+ m_mainLabel->setFont(mainFont);
+
+ m_subLabel->installEventFilter(this);
+ m_subLabel->setWordWrap(true);
+ m_subLabel->setTextFormat(Qt::PlainText);
+ m_subLabel->setAlignment(Qt::AlignBottom | Qt::AlignLeft);
+ vLayout->addWidget(m_subLabel.data());
+
+ hLayout->addLayout(vLayout);
+ setLayout(hLayout);
+
+ QPalette pal = palette();
+ pal.setColor(QPalette::Window, QColor(0xff, 0xff, 0xe1));
+ pal.setColor(QPalette::WindowText, Qt::black);
+ setPalette(pal);
+}
+
+MessageBubbleWidget::~MessageBubbleWidget()
+{
+}
+
+void MessageBubbleWidget::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ painter.drawPixmap(rect(), m_pixmap);
+}
+
+void MessageBubbleWidget::createBubble(const int maxWidth, const QString &mainText, const QString &subText)
+{
+ m_mainLabel->setText(mainText);
+ m_mainLabel->setMaximumWidth(maxWidth);
+
+ m_subLabel->setText(subText);
+ m_subLabel->setMaximumWidth(maxWidth);
+ m_subLabel->setVisible(!subText.isEmpty());
+
+ int border = 1;
+ int arrowHeight = 18;
+ bool roundedCorners = true;
+
+#if defined(QT_NO_XSHAPE) && defined(Q_WS_X11)
+ // XShape is required for setting the mask, so we just
+ // draw an ugly square when its not available
+ arrowHeight = 0;
+ roundedCorners = false;
+#endif
+
+ setContentsMargins(border + 3, border + arrowHeight + 2, border + 3, border + 2);
+ show(); // The widget should be visible for updateGeometry()
+ updateGeometry();
+ m_pixmap = QPixmap(sizeHint());
+
+ QPainterPath path = drawBoxPath(QPoint(0, arrowHeight), border, roundedCorners);
+
+ // Draw border and set background
+ QPainter painter(&m_pixmap);
+ painter.setPen(QPen(palette().color(QPalette::Window).darker(160), border));
+ painter.setBrush(palette().color(QPalette::Window));
+ painter.drawPath(path);
+}
+
+void MessageBubbleWidget::moveToAnchor(QWebEngineView *view, const QRect &anchor)
+{
+ QPoint topLeft = view->mapToGlobal(anchor.topLeft());
+ move(topLeft.x(), topLeft.y() + anchor.height());
+}
+
+QPainterPath MessageBubbleWidget::drawBoxPath(const QPoint &pos, int border, bool roundedCorners)
+{
+ const int arrowHeight = pos.y();
+ const int arrowOffset = 18;
+ const int arrowWidth = 18;
+
+ const int cornerRadius = roundedCorners ? 7 : 0;
+
+ const int messageBoxLeft = pos.x();
+ const int messageBoxTop = arrowHeight;
+ const int messageBoxRight = m_pixmap.width() - 1;
+ const int messageBoxBottom = m_pixmap.height() - 1;
+
+ QPainterPath path;
+ path.moveTo(messageBoxLeft + cornerRadius, messageBoxTop);
+
+ if (arrowHeight) {
+ path.lineTo(messageBoxLeft + arrowOffset, messageBoxTop);
+ path.lineTo(messageBoxLeft + arrowOffset, messageBoxTop - arrowHeight);
+ path.lineTo(messageBoxLeft + arrowOffset + arrowWidth, messageBoxTop);
+ }
+
+ if (roundedCorners) {
+ path.lineTo(messageBoxRight - cornerRadius, messageBoxTop);
+ path.quadTo(messageBoxRight, messageBoxTop, messageBoxRight, messageBoxTop + cornerRadius);
+ path.lineTo(messageBoxRight, messageBoxBottom - cornerRadius);
+ path.quadTo(messageBoxRight, messageBoxBottom, messageBoxRight - cornerRadius, messageBoxBottom);
+ path.lineTo(messageBoxLeft + cornerRadius, messageBoxBottom);
+ path.quadTo(messageBoxLeft, messageBoxBottom, messageBoxLeft, messageBoxBottom - cornerRadius);
+ path.lineTo(messageBoxLeft, messageBoxTop + cornerRadius);
+ path.quadTo(messageBoxLeft, messageBoxTop, messageBoxLeft + cornerRadius, messageBoxTop);
+ } else {
+ path.lineTo(messageBoxRight, messageBoxTop);
+ path.lineTo(messageBoxRight, messageBoxBottom);
+ path.lineTo(messageBoxLeft, messageBoxBottom);
+ path.moveTo(messageBoxLeft, messageBoxTop);
+ }
+
+ // Set mask
+ if (arrowHeight || roundedCorners) {
+ QBitmap bitmap = QBitmap(sizeHint());
+ bitmap.fill(Qt::color0);
+ QPainter painter(&bitmap);
+ painter.setPen(QPen(Qt::color1, border));
+ painter.setBrush(QBrush(Qt::color1));
+ painter.drawPath(path);
+ setMask(bitmap);
+ }
+
+ return path;
+}
+
+} // namespace QtWebEngineWidgetUI
diff --git a/src/webenginewidgets/ui/messagebubblewidget_p.h b/src/webenginewidgets/ui/messagebubblewidget_p.h
new file mode 100644
index 000000000..7b7a9e309
--- /dev/null
+++ b/src/webenginewidgets/ui/messagebubblewidget_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGEBUBBLEWIDGET_P_H
+#define MESSAGEBUBBLEWIDGET_P_H
+
+#include <QWidget>
+#include <QPainterPath>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+class QWebEngineView;
+QT_END_NAMESPACE
+
+namespace QtWebEngineWidgetUI {
+
+class MessageBubbleWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ MessageBubbleWidget();
+ ~MessageBubbleWidget();
+
+ static void showBubble(QWebEngineView *view, const QRect &anchor, const QString &mainText, const QString &subText = QString());
+ static void hideBubble();
+ static void moveBubble(QWebEngineView *view, const QRect &anchor);
+
+protected:
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+
+private:
+ void createBubble(const int maxWidth, const QString &mainText, const QString &subText);
+ void moveToAnchor(QWebEngineView *view, const QRect &anchor);
+
+ QPainterPath drawBoxPath(const QPoint &pos, int border, bool roundedCorners);
+
+ QScopedPointer<QLabel> m_mainLabel;
+ QScopedPointer<QLabel> m_subLabel;
+ QPixmap m_pixmap;
+};
+
+} // namespace QtWebEngineWidgetUI
+
+#endif // MESSAGEBUBBLEWIDGET_P_H
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 02e687c7c..1f7974bd2 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -45,4 +45,10 @@ HEADERS = \
api/qwebengineview_p.h \
render_widget_host_view_qt_delegate_widget.h
+!contains(WEBENGINE_CONFIG, no_ui_delegates) {
+ SOURCES += ui/messagebubblewidget.cpp
+ HEADERS += ui/messagebubblewidget_p.h
+ DEFINES += QT_UI_DELEGATES
+}
+
load(qt_module)