summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-08-11 10:18:08 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-08-14 11:42:09 +0200
commit1ec53868363c41a4f08ca2660638da532eb56b10 (patch)
treeac982148b467a63e7d1ceb2a7f943c3f3f5bf8d0
parent49b94b14d3da42f945f6d49a3288c3ede5b98d36 (diff)
parent59e35e033b8c8327db5b3fdbfb5d6ecee48a4405 (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Includes sha1 bump of src/3rdparty to head of 58-based. Change-Id: I37743c3979c1b6fb21f71eab7048e82f7aa5d78b
-rw-r--r--examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc14
-rw-r--r--examples/webengine/recipebrowser/recipebrowser.pro4
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt16
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt (renamed from examples/webengine/recipebrowser/resources/pages/assets/3rdparty/3RDPARTY.md)4
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md12
-rw-r--r--examples/webengine/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json35
-rw-r--r--examples/webengine/recipebrowser/resources/resources.qrc1
-rw-r--r--examples/webengine/webengine.pro3
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc15
-rw-r--r--examples/webenginewidgets/markdowneditor/markdowneditor.pro3
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt16
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt (renamed from examples/webenginewidgets/markdowneditor/3RDPARTY.md)4
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css (renamed from examples/webenginewidgets/markdowneditor/resources/markdown.css)0
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.min.js (renamed from examples/webenginewidgets/markdowneditor/resources/marked.min.js)0
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json35
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/default.md2
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/index.html4
-rw-r--r--examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc4
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.cpp34
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.h14
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.cpp109
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.h18
-rw-r--r--examples/webenginewidgets/simplebrowser/data/AppLogoColor.pngbin0 -> 6113 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/addtab.pngbin469 -> 0 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/closetab.pngbin516 -> 0 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/defaulticon.pngbin1473 -> 0 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/dialog-error.pngbin0 -> 1645 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/edit-clear.pngbin0 -> 1682 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/go-bottom.pngbin0 -> 1263 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/go-next.pngbin930 -> 1219 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/go-previous.pngbin955 -> 1200 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/process-stop.pngbin1272 -> 1927 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc9
-rw-r--r--examples/webenginewidgets/simplebrowser/data/simplebrowser.svg24
-rw-r--r--examples/webenginewidgets/simplebrowser/data/text-html.pngbin0 -> 1759 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/view-refresh.pngbin1364 -> 2024 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.pngbin70625 -> 47620 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc69
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp86
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h (renamed from examples/webenginewidgets/simplebrowser/urllineedit.h)41
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui104
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadwidget.cpp148
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadwidget.h76
-rw-r--r--examples/webenginewidgets/simplebrowser/downloadwidget.ui80
-rw-r--r--examples/webenginewidgets/simplebrowser/main.cpp29
-rw-r--r--examples/webenginewidgets/simplebrowser/simplebrowser.pro18
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.cpp60
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.h6
-rw-r--r--examples/webenginewidgets/simplebrowser/urllineedit.cpp95
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.cpp35
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.h9
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.cpp44
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.h2
-rw-r--r--qtwebengine.pro11
m---------src/3rdparty0
-rw-r--r--src/core/api/core_api.pro4
-rw-r--r--src/core/api/qtbug-61521.cpp121
-rw-r--r--src/core/proxy_config_service_qt.cpp90
-rw-r--r--src/core/proxy_config_service_qt.h6
-rw-r--r--src/core/render_widget_host_view_qt.cpp5
-rw-r--r--src/core/web_contents_adapter.cpp16
-rw-r--r--src/core/web_engine_context.cpp28
-rw-r--r--src/core/web_engine_settings.cpp25
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf1
-rw-r--r--src/webengine/doc/src/external-resources.qdoc10
-rw-r--r--src/webengine/doc/src/qtwebengine-debugging.qdoc33
-rw-r--r--src/webengine/doc/src/qtwebengine-features.qdoc17
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc25
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc6
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc3
-rw-r--r--tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp3
-rw-r--r--tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp4
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp23
-rwxr-xr-xtools/scripts/take_snapshot.py1
74 files changed, 1271 insertions, 443 deletions
diff --git a/examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc b/examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc
index d33f6bf10..7b8c6d5d0 100644
--- a/examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc
+++ b/examples/webengine/recipebrowser/doc/src/recipebrowser.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -213,4 +213,16 @@
\quotefromfile webengine/recipebrowser/resources/pages/soup.html
\printuntil </html>
+ \section1 Files and Attributions
+
+ The example bundles the following code with third-party licenses:
+
+ \table
+ \row
+ \li \l{recipebrowser-marked}{Marked}
+ \li MIT License
+ \row
+ \li \l{recipebrowser-markdowncss}{Markdown.css}
+ \li Apache License 2.0
+ \endtable
*/
diff --git a/examples/webengine/recipebrowser/recipebrowser.pro b/examples/webengine/recipebrowser/recipebrowser.pro
index ea6db13fb..c7e4dcaf8 100644
--- a/examples/webengine/recipebrowser/recipebrowser.pro
+++ b/examples/webengine/recipebrowser/recipebrowser.pro
@@ -10,5 +10,9 @@ SOURCES += main.cpp
RESOURCES += resources/resources.qrc
+DISTFILES += \
+ resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt \
+ resources/pages/assets/3rdparty/MARKED-LICENSE.txt
+
target.path = $$[QT_INSTALL_EXAMPLES]/webengine/recipebrowser
INSTALLS += target
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt
new file mode 100644
index 000000000..23c52cc43
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/MARKDOWN-LICENSE.txt
@@ -0,0 +1,16 @@
+Copyright 2011 Kevin Burke unless otherwise noted.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Some content is copyrighted by Twitter, Inc., and also released under an
+Apache License; these sections are noted in the source.
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/3RDPARTY.md b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt
index 9e91ab302..a7b812ed6 100644
--- a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/3RDPARTY.md
+++ b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/MARKED-LICENSE.txt
@@ -1,6 +1,3 @@
-## markd license
-
-```
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -20,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-```
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md
deleted file mode 100644
index 8f9c807aa..000000000
--- a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/default.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## WebEngine Markdown Editor Example
-
-This example uses [QWebEngineView](http://doc.qt.io/qt-5/qwebengineview.html)
-to preview text written using the [Markdown](https://en.wikipedia.org/wiki/Markdown)
-syntax.
-
-### Acknowledgments
-
-The conversion from Markdown to HTML is done with the help of the
-[marked JavaScript library](https://github.com/chjj/marked) by _Christopher Jeffrey_.
-The [style sheet](http://kevinburke.bitbucket.org/markdowncss/markdown.css)
-was created by _Kevin Burke_.
diff --git a/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json
new file mode 100644
index 000000000..42947ca0b
--- /dev/null
+++ b/examples/webengine/recipebrowser/resources/pages/assets/3rdparty/qt_attribution.json
@@ -0,0 +1,35 @@
+[
+ {
+ "Id": "recipebrowser-marked",
+ "Name": "Marked (WebEngine RecipeBrowser example)",
+ "QDocModule": "qtwebengine",
+ "QtUsage": "Marked is used in the WebEngine RecipeBrowser example",
+ "QtParts": [ "examples" ],
+ "Files": "marked.min.js",
+ "Description": "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
+ "Homepage": "https://github.com/chjj/marked",
+ "Version": "0.3.6",
+ "DownloadLocation": "https://github.com/chjj/marked/blob/v0.3.6/marked.min.js",
+ "Copyright": "Copyright (c) 2011-2014, Christopher Jeffrey",
+ "License": "MIT License",
+ "LicenseId": "MIT",
+ "LicenseFile": "MARKED-LICENSE.txt"
+ },
+ {
+ "Id": "recipebrowser-markdowncss",
+ "Name": "Markdown.css (WebEngine RecipeBrowser example)",
+ "QDocModule": "qtwebengine",
+ "QtUsage": "markdown.css is used in the WebEngine RecipeBrowser example",
+ "QtParts": [ "examples" ],
+ "Files": "markdown.css",
+ "Description": "Markdown.css is better default styling for your Markdown files.",
+ "Homepage": "https://kevinburke.bitbucket.io/markdowncss/",
+ "Version": "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
+ "DownloadLocation": "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
+ "Copyright": "Copyright 2011 Kevin Burke
+ Copyright Twitter Inc.",
+ "License": "Apache License 2.0",
+ "LicenseId": "Apache-2.0",
+ "LicenseFile": "MARKDOWN-LICENSE.txt"
+ }
+]
diff --git a/examples/webengine/recipebrowser/resources/resources.qrc b/examples/webengine/recipebrowser/resources/resources.qrc
index ae5aa2ed3..88919159b 100644
--- a/examples/webengine/recipebrowser/resources/resources.qrc
+++ b/examples/webengine/recipebrowser/resources/resources.qrc
@@ -12,7 +12,6 @@
<file>pages/cupcakes.html</file>
<file>pages/assets/3rdparty/marked.min.js</file>
- <file>pages/assets/3rdparty/default.md</file>
<file>pages/assets/3rdparty/markdown.css</file>
<file>pages/assets/custom.css</file>
<file>pages/assets/custom.js</file>
diff --git a/examples/webengine/webengine.pro b/examples/webengine/webengine.pro
index 969681e9d..3f55888cb 100644
--- a/examples/webengine/webengine.pro
+++ b/examples/webengine/webengine.pro
@@ -3,4 +3,5 @@ TEMPLATE=subdirs
SUBDIRS += \
customdialogs \
minimal \
- quicknanobrowser
+ quicknanobrowser \
+ recipebrowser
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
index a20dc04c5..b06d4ee84 100644
--- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
+++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -166,5 +166,18 @@
Finally, we set up the web channel to access the \c content proxy object
and make sure that \c updateText() is called whenever \c content.text
changes.
+
+ \section1 Files and Attributions
+
+ The example bundles the following code with third-party licenses:
+
+ \table
+ \row
+ \li \l{markdowneditor-marked}{Marked}
+ \li MIT License
+ \row
+ \li \l{markdowneditor-markdowncss}{Markdown.css}
+ \li Apache License 2.0
+ \endtable
*/
diff --git a/examples/webenginewidgets/markdowneditor/markdowneditor.pro b/examples/webenginewidgets/markdowneditor/markdowneditor.pro
index bfd16698a..2f58ae061 100644
--- a/examples/webenginewidgets/markdowneditor/markdowneditor.pro
+++ b/examples/webenginewidgets/markdowneditor/markdowneditor.pro
@@ -21,7 +21,8 @@ FORMS += \
mainwindow.ui
DISTFILES += \
- 3RDPARTY.md
+ resources/3rdparty/MARKDOWN-LICENSE.txt \
+ resources/3rdparty/MARKED-LICENSE.txt
# install
target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/markdowneditor
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt
new file mode 100644
index 000000000..23c52cc43
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKDOWN-LICENSE.txt
@@ -0,0 +1,16 @@
+Copyright 2011 Kevin Burke unless otherwise noted.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Some content is copyrighted by Twitter, Inc., and also released under an
+Apache License; these sections are noted in the source.
diff --git a/examples/webenginewidgets/markdowneditor/3RDPARTY.md b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt
index 9e91ab302..a7b812ed6 100644
--- a/examples/webenginewidgets/markdowneditor/3RDPARTY.md
+++ b/examples/webenginewidgets/markdowneditor/resources/3rdparty/MARKED-LICENSE.txt
@@ -1,6 +1,3 @@
-## markd license
-
-```
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -20,4 +17,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-```
diff --git a/examples/webenginewidgets/markdowneditor/resources/markdown.css b/examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css
index 24fc2ffe2..24fc2ffe2 100644
--- a/examples/webenginewidgets/markdowneditor/resources/markdown.css
+++ b/examples/webenginewidgets/markdowneditor/resources/3rdparty/markdown.css
diff --git a/examples/webenginewidgets/markdowneditor/resources/marked.min.js b/examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.min.js
index f3542fff0..f3542fff0 100644
--- a/examples/webenginewidgets/markdowneditor/resources/marked.min.js
+++ b/examples/webenginewidgets/markdowneditor/resources/3rdparty/marked.min.js
diff --git a/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json b/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json
new file mode 100644
index 000000000..3400ef27a
--- /dev/null
+++ b/examples/webenginewidgets/markdowneditor/resources/3rdparty/qt_attribution.json
@@ -0,0 +1,35 @@
+[
+ {
+ "Id": "markdowneditor-marked",
+ "Name": "Marked (WebEngine Markdown Editor example)",
+ "QDocModule": "qtwebengine",
+ "QtUsage": "Marked is used in the WebEngine MarkDown Editor example",
+ "QtParts": [ "examples" ],
+ "Files": "marked.min.js",
+ "Description": "A full-featured markdown parser and compiler, written in JavaScript. Built for speed.",
+ "Homepage": "https://github.com/chjj/marked",
+ "Version": "0.3.6",
+ "DownloadLocation": "https://github.com/chjj/marked/blob/v0.3.6/marked.min.js",
+ "Copyright": "Copyright (c) 2011-2014, Christopher Jeffrey",
+ "License": "MIT License",
+ "LicenseId": "MIT",
+ "LicenseFile": "MARKED-LICENSE.txt"
+ },
+ {
+ "Id": "markdowneditor-markdowncss",
+ "Name": "Markdown.css (WebEngine Markdown Editor example)",
+ "QDocModule": "qtwebengine",
+ "QtUsage": "markdown.css is used in the WebEngine MarkDown Editor example",
+ "QtParts": [ "examples" ],
+ "Files": "markdown.css",
+ "Description": "Markdown.css is better default styling for your Markdown files.",
+ "Homepage": "https://kevinburke.bitbucket.io/markdowncss/",
+ "Version": "188530e4b5d020d7e237fc6b26be13ebf4a8def3",
+ "DownloadLocation": "https://bitbucket.org/kevinburke/markdowncss/src/188530e4b5d020d7e237fc6b26be13ebf4a8def3/markdown.css",
+ "Copyright": "Copyright 2011 Kevin Burke
+ Copyright Twitter Inc.",
+ "License": "Apache License 2.0",
+ "LicenseId": "Apache-2.0",
+ "LicenseFile": "MARKDOWN-LICENSE.txt"
+ }
+]
diff --git a/examples/webenginewidgets/markdowneditor/resources/default.md b/examples/webenginewidgets/markdowneditor/resources/default.md
index 8f9c807aa..af835fa4d 100644
--- a/examples/webenginewidgets/markdowneditor/resources/default.md
+++ b/examples/webenginewidgets/markdowneditor/resources/default.md
@@ -8,5 +8,5 @@ syntax.
The conversion from Markdown to HTML is done with the help of the
[marked JavaScript library](https://github.com/chjj/marked) by _Christopher Jeffrey_.
-The [style sheet](http://kevinburke.bitbucket.org/markdowncss/markdown.css)
+The [style sheet](https://kevinburke.bitbucket.io/markdowncss/)
was created by _Kevin Burke_.
diff --git a/examples/webenginewidgets/markdowneditor/resources/index.html b/examples/webenginewidgets/markdowneditor/resources/index.html
index 2f45479ed..8623a0642 100644
--- a/examples/webenginewidgets/markdowneditor/resources/index.html
+++ b/examples/webenginewidgets/markdowneditor/resources/index.html
@@ -2,8 +2,8 @@
<html lang="en">
<meta charset="utf-8">
<head>
- <link rel="stylesheet" type="text/css" href="markdown.css">
- <script src="marked.min.js"></script>
+ <link rel="stylesheet" type="text/css" href="3rdparty/markdown.css">
+ <script src="3rdparty/marked.min.js"></script>
<script src="qwebchannel.js"></script>
</head>
<body>
diff --git a/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
index 8b7471a9c..9a6bd3801 100644
--- a/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
+++ b/examples/webenginewidgets/markdowneditor/resources/markdowneditor.qrc
@@ -2,8 +2,8 @@
<qresource prefix="/">
<file>index.html</file>
<file>qwebchannel.js</file>
- <file>marked.min.js</file>
+ <file>3rdparty/marked.min.js</file>
<file>default.md</file>
- <file>markdown.css</file>
+ <file>3rdparty/markdown.css</file>
</qresource>
</RCC>
diff --git a/examples/webenginewidgets/simplebrowser/browser.cpp b/examples/webenginewidgets/simplebrowser/browser.cpp
index f1420c2a3..5eae4f3c1 100644
--- a/examples/webenginewidgets/simplebrowser/browser.cpp
+++ b/examples/webenginewidgets/simplebrowser/browser.cpp
@@ -40,38 +40,26 @@
#include "browser.h"
#include "browserwindow.h"
-#include "webview.h"
-#include <QAuthenticator>
-Browser::Browser()
-{
-}
-
-Browser::~Browser()
-{
- qDeleteAll(m_windows);
- m_windows.clear();
-}
+#include <QWebEngineProfile>
-Browser &Browser::instance()
+Browser::Browser()
{
- static Browser browser;
- return browser;
-}
+ // Quit application if the download manager window is the only remaining window
+ m_downloadManagerWidget.setAttribute(Qt::WA_QuitOnClose, false);
-QVector<BrowserWindow*> Browser::windows()
-{
- return m_windows;
+ QObject::connect(
+ QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested,
+ &m_downloadManagerWidget, &DownloadManagerWidget::downloadRequested);
}
-void Browser::addWindow(BrowserWindow *mainWindow)
+BrowserWindow *Browser::createWindow()
{
- if (m_windows.contains(mainWindow))
- return;
- m_windows.prepend(mainWindow);
+ auto mainWindow = new BrowserWindow(this);
+ m_windows.append(mainWindow);
QObject::connect(mainWindow, &QObject::destroyed, [this, mainWindow]() {
m_windows.removeOne(mainWindow);
});
mainWindow->show();
+ return mainWindow;
}
-
diff --git a/examples/webenginewidgets/simplebrowser/browser.h b/examples/webenginewidgets/simplebrowser/browser.h
index 0fdbd46a7..27e2aaf43 100644
--- a/examples/webenginewidgets/simplebrowser/browser.h
+++ b/examples/webenginewidgets/simplebrowser/browser.h
@@ -41,6 +41,8 @@
#ifndef BROWSER_H
#define BROWSER_H
+#include "downloadmanagerwidget.h"
+
#include <QVector>
class BrowserWindow;
@@ -48,14 +50,16 @@ class BrowserWindow;
class Browser
{
public:
- ~Browser();
+ Browser();
+
+ QVector<BrowserWindow*> windows() { return m_windows; }
- QVector<BrowserWindow*> windows();
- void addWindow(BrowserWindow* window);
- static Browser &instance();
+ BrowserWindow *createWindow();
+
+ DownloadManagerWidget &downloadManagerWidget() { return m_downloadManagerWidget; }
private:
- Browser();
QVector<BrowserWindow*> m_windows;
+ DownloadManagerWidget m_downloadManagerWidget;
};
#endif // BROWSER_H
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
index 0b85e2bb0..43c25e633 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
@@ -40,12 +40,13 @@
#include "browser.h"
#include "browserwindow.h"
+#include "downloadmanagerwidget.h"
#include "tabwidget.h"
-#include "urllineedit.h"
#include "webview.h"
#include <QApplication>
#include <QCloseEvent>
#include <QDesktopWidget>
+#include <QEvent>
#include <QFileDialog>
#include <QInputDialog>
#include <QMenuBar>
@@ -54,9 +55,10 @@
#include <QStatusBar>
#include <QToolBar>
#include <QVBoxLayout>
+#include <QWebEngineProfile>
-BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
- : QMainWindow(parent, flags)
+BrowserWindow::BrowserWindow(Browser *browser)
+ : m_browser(browser)
, m_tabWidget(new TabWidget(this))
, m_progressBar(new QProgressBar(this))
, m_historyBackAction(nullptr)
@@ -64,10 +66,11 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
, m_stopAction(nullptr)
, m_reloadAction(nullptr)
, m_stopReloadAction(nullptr)
- , m_urlLineEdit(new UrlLineEdit(this))
+ , m_urlLineEdit(nullptr)
+ , m_favAction(nullptr)
{
- setToolButtonStyle(Qt::ToolButtonFollowStyle);
setAttribute(Qt::WA_DeleteOnClose, true);
+ setFocusPolicy(Qt::ClickFocus);
QToolBar *toolbar = createToolBar();
addToolBar(toolbar);
@@ -85,7 +88,7 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
m_progressBar->setMaximumHeight(1);
m_progressBar->setTextVisible(false);
- m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px } QProgressBar::chunk { background-color: red; }"));
+ m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}"));
layout->addWidget(m_progressBar);
layout->addWidget(m_tabWidget);
@@ -97,15 +100,14 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
statusBar()->showMessage(url);
});
connect(m_tabWidget, &TabWidget::loadProgress, this, &BrowserWindow::handleWebViewLoadProgress);
- connect(m_tabWidget, &TabWidget::urlChanged, this, &BrowserWindow::handleWebViewUrlChanged);
- connect(m_tabWidget, &TabWidget::iconChanged, this, &BrowserWindow::handleWebViewIconChanged);
connect(m_tabWidget, &TabWidget::webActionEnabledChanged, this, &BrowserWindow::handleWebActionEnabledChanged);
- connect(m_urlLineEdit, &QLineEdit::returnPressed, this, [this]() {
- m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
- loadPage(m_urlLineEdit->url());
+ connect(m_tabWidget, &TabWidget::urlChanged, [this](const QUrl &url) {
+ m_urlLineEdit->setText(url.toDisplayString());
+ });
+ connect(m_tabWidget, &TabWidget::favIconChanged, m_favAction, &QAction::setIcon);
+ connect(m_urlLineEdit, &QLineEdit::returnPressed, [this]() {
+ m_tabWidget->setUrl(QUrl::fromUserInput(m_urlLineEdit->text()));
});
-
- m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
QAction *focusUrlLineEditAction = new QAction(this);
addAction(focusUrlLineEditAction);
@@ -114,14 +116,10 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
m_urlLineEdit->setFocus(Qt::ShortcutFocusReason);
});
- handleWebViewTitleChanged(tr("Qt Simple Browser"));
+ handleWebViewTitleChanged(QString());
m_tabWidget->createTab();
}
-BrowserWindow::~BrowserWindow()
-{
-}
-
QSize BrowserWindow::sizeHint() const
{
QRect desktopRect = QApplication::desktop()->screenGeometry();
@@ -134,18 +132,16 @@ QMenu *BrowserWindow::createFileMenu(TabWidget *tabWidget)
QMenu *fileMenu = new QMenu(tr("&File"));
fileMenu->addAction(tr("&New Window"), this, &BrowserWindow::handleNewWindowTriggered, QKeySequence::New);
- QAction *newTabAction = new QAction(QIcon(QLatin1String(":addtab.png")), tr("New &Tab"), this);
+ QAction *newTabAction = new QAction(tr("New &Tab"), this);
newTabAction->setShortcuts(QKeySequence::AddTab);
- newTabAction->setIconVisibleInMenu(false);
connect(newTabAction, &QAction::triggered, tabWidget, &TabWidget::createTab);
fileMenu->addAction(newTabAction);
fileMenu->addAction(tr("&Open File..."), this, &BrowserWindow::handleFileOpenTriggered, QKeySequence::Open);
fileMenu->addSeparator();
- QAction *closeTabAction = new QAction(QIcon(QLatin1String(":closetab.png")), tr("&Close Tab"), this);
+ QAction *closeTabAction = new QAction(tr("&Close Tab"), this);
closeTabAction->setShortcuts(QKeySequence::Close);
- closeTabAction->setIconVisibleInMenu(false);
connect(closeTabAction, &QAction::triggered, [tabWidget]() {
tabWidget->closeTab(tabWidget->currentIndex());
});
@@ -156,8 +152,8 @@ QMenu *BrowserWindow::createFileMenu(TabWidget *tabWidget)
connect(closeAction, &QAction::triggered, this, &QWidget::close);
fileMenu->addAction(closeAction);
- connect(fileMenu, &QMenu::aboutToShow, [closeAction]() {
- if (Browser::instance().windows().count() == 1)
+ connect(fileMenu, &QMenu::aboutToShow, [this, closeAction]() {
+ if (m_browser->windows().count() == 1)
closeAction->setText(tr("&Quit"));
else
closeAction->setText(tr("&Close Window"));
@@ -288,7 +284,7 @@ QMenu *BrowserWindow::createWindowMenu(TabWidget *tabWidget)
menu->addAction(previousTabAction);
menu->addSeparator();
- QVector<BrowserWindow*> windows = Browser::instance().windows();
+ QVector<BrowserWindow*> windows = m_browser->windows();
int index(-1);
for (auto window : windows) {
QAction *action = menu->addAction(window->windowTitle(), this, &BrowserWindow::handleShowWindowTriggered);
@@ -311,7 +307,7 @@ QMenu *BrowserWindow::createHelpMenu()
QToolBar *BrowserWindow::createToolBar()
{
QToolBar *navigationBar = new QToolBar(tr("Navigation"));
- navigationBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
+ navigationBar->setMovable(false);
navigationBar->toggleViewAction()->setEnabled(false);
m_historyBackAction = new QAction(this);
@@ -328,6 +324,7 @@ QToolBar *BrowserWindow::createToolBar()
m_historyBackAction->setShortcuts(backShortcuts);
m_historyBackAction->setIconVisibleInMenu(false);
m_historyBackAction->setIcon(QIcon(QStringLiteral(":go-previous.png")));
+ m_historyBackAction->setToolTip(tr("Go back in history"));
connect(m_historyBackAction, &QAction::triggered, [this]() {
m_tabWidget->triggerWebPageAction(QWebEnginePage::Back);
});
@@ -345,6 +342,7 @@ QToolBar *BrowserWindow::createToolBar()
m_historyForwardAction->setShortcuts(fwdShortcuts);
m_historyForwardAction->setIconVisibleInMenu(false);
m_historyForwardAction->setIcon(QIcon(QStringLiteral(":go-next.png")));
+ m_historyForwardAction->setToolTip(tr("Go forward in history"));
connect(m_historyForwardAction, &QAction::triggered, [this]() {
m_tabWidget->triggerWebPageAction(QWebEnginePage::Forward);
});
@@ -355,22 +353,22 @@ QToolBar *BrowserWindow::createToolBar()
m_tabWidget->triggerWebPageAction(QWebEnginePage::WebAction(m_stopReloadAction->data().toInt()));
});
navigationBar->addAction(m_stopReloadAction);
+
+ m_urlLineEdit = new QLineEdit(this);
+ m_favAction = new QAction(this);
+ m_urlLineEdit->addAction(m_favAction, QLineEdit::LeadingPosition);
+ m_urlLineEdit->setClearButtonEnabled(true);
navigationBar->addWidget(m_urlLineEdit);
- int size = m_urlLineEdit->sizeHint().height();
- navigationBar->setIconSize(QSize(size, size));
- return navigationBar;
-}
-void BrowserWindow::handleWebViewIconChanged(const QIcon &icon)
-{
- m_urlLineEdit->setFavIcon(icon);
-}
+ auto downloadsAction = new QAction(this);
+ downloadsAction->setIcon(QIcon(QStringLiteral(":go-bottom.png")));
+ downloadsAction->setToolTip(tr("Show downloads"));
+ navigationBar->addAction(downloadsAction);
+ connect(downloadsAction, &QAction::triggered, [this]() {
+ m_browser->downloadManagerWidget().show();
+ });
-void BrowserWindow::handleWebViewUrlChanged(const QUrl &url)
-{
- m_urlLineEdit->setUrl(url);
- if (url.isEmpty())
- m_urlLineEdit->setFocus();
+ return navigationBar;
}
void BrowserWindow::handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled)
@@ -389,7 +387,7 @@ void BrowserWindow::handleWebActionEnabledChanged(QWebEnginePage::WebAction acti
m_stopAction->setEnabled(enabled);
break;
default:
- qWarning("Unhandled webActionChanged singal");
+ qWarning("Unhandled webActionChanged signal");
}
}
@@ -403,9 +401,7 @@ void BrowserWindow::handleWebViewTitleChanged(const QString &title)
void BrowserWindow::handleNewWindowTriggered()
{
- BrowserWindow *window = new BrowserWindow();
- Browser::instance().addWindow(window);
- window->loadHomePage();
+ m_browser->createWindow();
}
void BrowserWindow::handleFileOpenTriggered()
@@ -414,7 +410,7 @@ void BrowserWindow::handleFileOpenTriggered()
tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)"));
if (file.isEmpty())
return;
- loadPage(file);
+ currentTab()->setUrl(file);
}
void BrowserWindow::handleFindActionTriggered()
@@ -450,24 +446,6 @@ void BrowserWindow::closeEvent(QCloseEvent *event)
deleteLater();
}
-void BrowserWindow::loadHomePage()
-{
- loadPage(QStringLiteral("http://www.qt.io"));
-}
-
-void BrowserWindow::loadPage(const QString &page)
-{
- loadPage(QUrl::fromUserInput(page));
-}
-
-void BrowserWindow::loadPage(const QUrl &url)
-{
- if (url.isValid()) {
- m_urlLineEdit->setUrl(url);
- m_tabWidget->setUrl(url);
- }
-}
-
TabWidget *BrowserWindow::tabWidget() const
{
return m_tabWidget;
@@ -483,23 +461,24 @@ void BrowserWindow::handleWebViewLoadProgress(int progress)
static QIcon stopIcon(QStringLiteral(":process-stop.png"));
static QIcon reloadIcon(QStringLiteral(":view-refresh.png"));
- if (progress < 100 && progress > 0) {
+ if (0 < progress && progress < 100) {
m_stopReloadAction->setData(QWebEnginePage::Stop);
m_stopReloadAction->setIcon(stopIcon);
m_stopReloadAction->setToolTip(tr("Stop loading the current page"));
+ m_progressBar->setValue(progress);
} else {
m_stopReloadAction->setData(QWebEnginePage::Reload);
m_stopReloadAction->setIcon(reloadIcon);
m_stopReloadAction->setToolTip(tr("Reload the current page"));
+ m_progressBar->setValue(0);
}
- m_progressBar->setValue(progress < 100 ? progress : 0);
}
void BrowserWindow::handleShowWindowTriggered()
{
if (QAction *action = qobject_cast<QAction*>(sender())) {
int offset = action->data().toInt();
- QVector<BrowserWindow*> windows = Browser::instance().windows();
+ QVector<BrowserWindow*> windows = m_browser->windows();
windows.at(offset)->activateWindow();
windows.at(offset)->currentTab()->setFocus();
}
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.h b/examples/webenginewidgets/simplebrowser/browserwindow.h
index 03c8d385b..745061691 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.h
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.h
@@ -42,14 +42,16 @@
#define BROWSERWINDOW_H
#include <QMainWindow>
+#include <QTime>
#include <QWebEnginePage>
QT_BEGIN_NAMESPACE
+class QLineEdit;
class QProgressBar;
QT_END_NAMESPACE
+class Browser;
class TabWidget;
-class UrlLineEdit;
class WebView;
class BrowserWindow : public QMainWindow
@@ -57,15 +59,11 @@ class BrowserWindow : public QMainWindow
Q_OBJECT
public:
- BrowserWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
- ~BrowserWindow();
+ BrowserWindow(Browser *browser);
QSize sizeHint() const override;
TabWidget *tabWidget() const;
WebView *currentTab() const;
-
- void loadPage(const QString &url);
- void loadPage(const QUrl &url);
- void loadHomePage();
+ Browser *browser() { return m_browser; }
protected:
void closeEvent(QCloseEvent *event) override;
@@ -77,8 +75,6 @@ private slots:
void handleShowWindowTriggered();
void handleWebViewLoadProgress(int);
void handleWebViewTitleChanged(const QString &title);
- void handleWebViewUrlChanged(const QUrl &url);
- void handleWebViewIconChanged(const QIcon &icon);
void handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled);
private:
@@ -90,6 +86,7 @@ private:
QToolBar *createToolBar();
private:
+ Browser *m_browser;
TabWidget *m_tabWidget;
QProgressBar *m_progressBar;
QAction *m_historyBackAction;
@@ -97,7 +94,8 @@ private:
QAction *m_stopAction;
QAction *m_reloadAction;
QAction *m_stopReloadAction;
- UrlLineEdit *m_urlLineEdit;
+ QLineEdit *m_urlLineEdit;
+ QAction *m_favAction;
QString m_lastSearch;
};
diff --git a/examples/webenginewidgets/simplebrowser/data/AppLogoColor.png b/examples/webenginewidgets/simplebrowser/data/AppLogoColor.png
new file mode 100644
index 000000000..2a4971782
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/AppLogoColor.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/addtab.png b/examples/webenginewidgets/simplebrowser/data/addtab.png
deleted file mode 100644
index 20928fb40..000000000
--- a/examples/webenginewidgets/simplebrowser/data/addtab.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/closetab.png b/examples/webenginewidgets/simplebrowser/data/closetab.png
deleted file mode 100644
index ab9d669ee..000000000
--- a/examples/webenginewidgets/simplebrowser/data/closetab.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/defaulticon.png b/examples/webenginewidgets/simplebrowser/data/defaulticon.png
deleted file mode 100644
index 01a0920c9..000000000
--- a/examples/webenginewidgets/simplebrowser/data/defaulticon.png
+++ /dev/null
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/dialog-error.png b/examples/webenginewidgets/simplebrowser/data/dialog-error.png
new file mode 100644
index 000000000..cdd95bade
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/dialog-error.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/edit-clear.png b/examples/webenginewidgets/simplebrowser/data/edit-clear.png
new file mode 100644
index 000000000..5542948bc
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/edit-clear.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/go-bottom.png b/examples/webenginewidgets/simplebrowser/data/go-bottom.png
new file mode 100644
index 000000000..bf973fedc
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/go-bottom.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/go-next.png b/examples/webenginewidgets/simplebrowser/data/go-next.png
index 6f3f65d33..a68e2db77 100644
--- a/examples/webenginewidgets/simplebrowser/data/go-next.png
+++ b/examples/webenginewidgets/simplebrowser/data/go-next.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/go-previous.png b/examples/webenginewidgets/simplebrowser/data/go-previous.png
index 93be3d1ee..c37bc0414 100644
--- a/examples/webenginewidgets/simplebrowser/data/go-previous.png
+++ b/examples/webenginewidgets/simplebrowser/data/go-previous.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/process-stop.png b/examples/webenginewidgets/simplebrowser/data/process-stop.png
index b68290bf1..e7a8d1722 100644
--- a/examples/webenginewidgets/simplebrowser/data/process-stop.png
+++ b/examples/webenginewidgets/simplebrowser/data/process-stop.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc b/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc
index 5795063ca..ec8716721 100644
--- a/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc
+++ b/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc
@@ -1,12 +1,13 @@
<RCC>
<qresource prefix="/">
- <file>addtab.png</file>
- <file>defaulticon.png</file>
- <file>closetab.png</file>
+ <file>AppLogoColor.png</file>
+ <file>dialog-error.png</file>
+ <file>edit-clear.png</file>
+ <file>go-bottom.png</file>
<file>go-next.png</file>
<file>go-previous.png</file>
<file>process-stop.png</file>
- <file>simplebrowser.svg</file>
+ <file>text-html.png</file>
<file>view-refresh.png</file>
</qresource>
</RCC>
diff --git a/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg b/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg
deleted file mode 100644
index 9f39deb66..000000000
--- a/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="94px" height="94px" viewBox="0 0 94 94" enable-background="new 0 0 94 94" xml:space="preserve">
-<g>
- <circle fill="none" cx="47" cy="47" r="47"/>
- <g>
- <path fill="#46A2DA" d="M47,92.979c-11.779,0-23.559-4.484-32.526-13.451C-3.461,61.591-3.461,32.409,14.472,14.474
- C32.41-3.463,61.592-3.461,79.526,14.473c17.935,17.936,17.935,47.119,0.002,65.054l-0.002,0.001
- C70.559,88.495,58.779,92.979,47,92.979z"/>
- </g>
- <path fill="#80C342" d="M93,47C93,21.595,72.405,1,47,1C34.297,1,22.797,6.149,14.473,14.473l65.054,65.054
- C87.851,71.203,93,59.703,93,47z"/>
- <g>
- <path fill="#46A2DA" d="M47,65c-4.808,0-9.328-1.873-12.728-5.272c-7.018-7.019-7.018-18.438,0-25.456
- C37.672,30.873,42.192,29,47,29s9.328,1.873,12.728,5.272c7.018,7.019,7.018,18.438,0,25.456C56.328,63.127,51.808,65,47,65z"/>
- <path fill="#FFFFFF" d="M62.248,59.919c6.671-7.858,6.312-19.644-1.105-27.061C57.237,28.953,52.118,27,47,27
- c-5.118,0-10.237,1.953-14.142,5.858c-7.81,7.81-7.81,20.474,0,28.284C36.763,65.047,41.882,67,47,67
- c4.379,0,8.752-1.441,12.372-4.3L77.88,81.209c0.989-0.895,1.935-1.837,2.843-2.814L62.248,59.919z M35.686,58.314
- c-6.238-6.238-6.238-16.389,0-22.627C38.708,32.664,42.726,31,47,31c4.274,0,8.292,1.664,11.314,4.686
- c6.238,6.238,6.238,16.389,0,22.627C55.292,61.336,51.274,63,47,63C42.726,63,38.708,61.336,35.686,58.314z"/>
- </g>
-</g>
-</svg>
diff --git a/examples/webenginewidgets/simplebrowser/data/text-html.png b/examples/webenginewidgets/simplebrowser/data/text-html.png
new file mode 100644
index 000000000..a896697d7
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/text-html.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/view-refresh.png b/examples/webenginewidgets/simplebrowser/data/view-refresh.png
index cab4d02c7..606ea9eba 100644
--- a/examples/webenginewidgets/simplebrowser/data/view-refresh.png
+++ b/examples/webenginewidgets/simplebrowser/data/view-refresh.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png
index 777309075..b09f7c853 100644
--- a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png
+++ b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
index e57ec80ec..2ca4bfc45 100644
--- a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
+++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
@@ -43,6 +43,7 @@
forward in the web page browsing history.
\li Multi-tab area for displaying web content within tabs.
\li Status bar for displaying hovered links.
+ \li A simple download manager.
\endlist
The web content can be opened in new tabs or separate windows. HTTP and
@@ -52,13 +53,13 @@
\section1 Class Hierarchy
- We start with sketching a diagram of the classes that we are going to
+ We start with sketching a diagram of the main classes that we are going to
implement:
\image simplebrowser-model.png
\list
- \li \c{Browser} is a singleton class managing the application windows.
+ \li \c{Browser} is a class managing the application windows.
\li \c{BrowserWindow} is a \l QMainWindow showing the menu, a navigation
bar, \c {TabWidget}, and a status bar.
\li \c{TabWidget} is a \l QTabWidget and contains one or multiple
@@ -68,11 +69,19 @@
\li \c{WebPage} is a \l QWebEnginePage that represents website content.
\endlist
+ Additionally, we will implement some auxiliary classes:
+
+ \list
+ \li \c{WebPopupWindow} is a \l QWidget for showing popup windows.
+ \li \c{DownloadManagerWidget} is a \l QWidget implementing the downloads
+ list.
+ \endlist
+
\section1 Creating the Browser Main Window
- This example supports multiple main windows that are owned by a
- \c Browser singleton object. This class could also be used for further
- functionality, such as downloading files, bookmarks, and history managers.
+ This example supports multiple main windows that are owned by a \c Browser
+ object. This class also owns the \c DownloadManagerWidget and could be used
+ for further functionality, such as bookmarks and history managers.
In \c main.cpp, we create the first \c BrowserWindow instance and add it
to the \c Browser object. If no arguments are passed on the command line,
@@ -104,6 +113,8 @@
\quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp
\skipto TabWidget::createTab(
\printuntil }
+ \skipto TabWidget::createBackgroundTab(
+ \printuntil }
In \c TabWidget::setupView(), we make sure that the \c TabWidget always forwards
the signals of the currently selected \c WebView:
@@ -225,20 +236,14 @@
\section1 Opening a Web Page
- This section describes the workflow for opening a new page.
- When the user enters a URL in the navigation bar and presses \uicontrol Enter,
- \c QLineEdit::returnPressed is emitted, which lets \c BrowserWindow
- load the requested page:
+ This section describes the workflow for opening a new page. When the user
+ enters a URL in the navigation bar and presses \uicontrol Enter, the \c
+ QLineEdit::returnPressed signal is emitted and the new URL is then handed
+ over to \c TabWidget::setUrl:
\quotefromfile webenginewidgets/simplebrowser/browserwindow.cpp
\skipto connect(m_urlLineEdit
- \printuntil });
-
- The \c loadPage() method calls the \c setUrl() method of \c TabWidget:
-
- \skipto void BrowserWindow::loadPage(const QUrl
- \printuntil }
- \printline }
+ \printline connect
The call is forwarded to the currently selected tab:
@@ -249,4 +254,36 @@
The \c setUrl() method of \c WebView just forwards the \c url to the associated \c WebPage,
which in turn starts the downloading of the page's content in the background.
+
+ \section1 Managing Downloads
+
+ Downloads are associated with a \l QWebEngineProfile. Whenever a download is
+ triggered on a web page the \l QWebEngineProfile::downloadRequested signal is
+ emitted with a \l QWebEngineDownloadItem, which in this example is forwarded
+ to \c DownloadManagerWidget::downloadRequested:
+
+ \quotefromfile webenginewidgets/simplebrowser/browser.cpp
+ \skipto Browser::Browser
+ \printuntil /^\}/
+
+ This method prompts the user for a file name (with a pre-filled suggestion)
+ and starts the download (unless the user cancels the \uicontrol {Save As}
+ dialog):
+
+ \quotefromfile webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
+ \skipto DownloadManagerWidget::downloadRequested
+ \printuntil /^\}/
+
+ The \l QWebEngineDownloadItem object will periodically emit the \l
+ {QWebEngineDownloadItem::}{downloadProgress} signal to notify potential
+ observers of the download progress and the \l
+ {QWebEngineDownloadItem::}{stateChanged} signal when the download is
+ finished or when an error occurs. See \c downloadmanagerwidget.cpp for an
+ example of how these signals can be handled.
+
+ \section1 Licensing
+
+ All icons used in the example, with the exception of \c{AppLogoColor.png},
+ originate from the public domain
+ \l{http://tango.freedesktop.org/Tango_Icon_Library}{Tango Icon Library}.
*/
diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
new file mode 100644
index 000000000..5f32294e8
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "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 The Qt Company Ltd 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."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "downloadmanagerwidget.h"
+
+#include "browser.h"
+#include "browserwindow.h"
+#include "downloadwidget.h"
+
+#include <QFileDialog>
+#include <QWebEngineDownloadItem>
+
+DownloadManagerWidget::DownloadManagerWidget(QWidget *parent)
+ : QWidget(parent)
+ , m_numDownloads(0)
+{
+ setupUi(this);
+}
+
+void DownloadManagerWidget::downloadRequested(QWebEngineDownloadItem *download)
+{
+ Q_ASSERT(download && download->state() == QWebEngineDownloadItem::DownloadRequested);
+
+ QString path = QFileDialog::getSaveFileName(this, tr("Save as"), download->path());
+ if (path.isEmpty())
+ return;
+
+ download->setPath(path);
+ download->accept();
+ add(new DownloadWidget(download));
+
+ show();
+}
+
+void DownloadManagerWidget::add(DownloadWidget *downloadWidget)
+{
+ connect(downloadWidget, &DownloadWidget::removeClicked, this, &DownloadManagerWidget::remove);
+ m_itemsLayout->insertWidget(0, downloadWidget, 0, Qt::AlignTop);
+ if (m_numDownloads++ == 0)
+ m_zeroItemsLabel->hide();
+}
+
+void DownloadManagerWidget::remove(DownloadWidget *downloadWidget)
+{
+ m_itemsLayout->removeWidget(downloadWidget);
+ downloadWidget->deleteLater();
+ if (--m_numDownloads == 0)
+ m_zeroItemsLabel->show();
+}
diff --git a/examples/webenginewidgets/simplebrowser/urllineedit.h b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
index a01eb0e66..597e6139a 100644
--- a/examples/webenginewidgets/simplebrowser/urllineedit.h
+++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
@@ -38,33 +38,36 @@
**
****************************************************************************/
-#ifndef URLLINEEDIT_H
-#define URLLINEEDIT_H
+#ifndef DOWNLOADMANAGERWIDGET_H
+#define DOWNLOADMANAGERWIDGET_H
-#include <QLineEdit>
+#include "ui_downloadmanagerwidget.h"
+
+#include <QWidget>
QT_BEGIN_NAMESPACE
-class QToolButton;
+class QWebEngineDownloadItem;
QT_END_NAMESPACE
-class UrlLineEdit : public QLineEdit
+class DownloadWidget;
+
+// Displays a list of downloads.
+class DownloadManagerWidget final : public QWidget, public Ui::DownloadManagerWidget
{
Q_OBJECT
-
public:
- UrlLineEdit(QWidget *parent = nullptr);
+ explicit DownloadManagerWidget(QWidget *parent = nullptr);
-public:
- QUrl url() const;
- void setUrl(const QUrl &url);
- void setFavIcon(const QIcon &icon);
-
-protected:
- void resizeEvent(QResizeEvent *event) override;
+ // Prompts user with a "Save As" dialog. If the user doesn't cancel it, then
+ // the QWebEngineDownloadItem will be accepted and the DownloadManagerWidget
+ // will be shown on the screen.
+ void downloadRequested(QWebEngineDownloadItem *webItem);
private:
- QToolButton *m_favButton;
- QToolButton *m_clearButton;
+ void add(DownloadWidget *downloadWidget);
+ void remove(DownloadWidget *downloadWidget);
+
+ int m_numDownloads;
};
-#endif // URLLINEEDIT_H
+#endif // DOWNLOADMANAGERWIDGET_H
diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui
new file mode 100644
index 000000000..b7544ac16
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DownloadManagerWidget</class>
+ <widget class="QWidget" name="DownloadManagerWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>212</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Downloads</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">#DownloadManagerWidget {
+ background: palette(button)
+}</string>
+ </property>
+ <layout class="QVBoxLayout" name="m_topLevelLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetNoConstraint</enum>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QScrollArea" name="m_scrollArea">
+ <property name="styleSheet">
+ <string notr="true">#m_scrollArea {
+ margin: 2px;
+ border: none;
+}</string>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOn</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <widget class="QWidget" name="m_items">
+ <property name="styleSheet">
+ <string notr="true">#m_items {background: palette(mid)}</string>
+ </property>
+ <layout class="QVBoxLayout" name="m_itemsLayout">
+ <property name="spacing">
+ <number>2</number>
+ </property>
+ <property name="leftMargin">
+ <number>3</number>
+ </property>
+ <property name="topMargin">
+ <number>3</number>
+ </property>
+ <property name="rightMargin">
+ <number>3</number>
+ </property>
+ <property name="bottomMargin">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="m_zeroItemsLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">color: palette(shadow)</string>
+ </property>
+ <property name="text">
+ <string>No downloads</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
new file mode 100644
index 000000000..cc16d245b
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "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 The Qt Company Ltd 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."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "downloadwidget.h"
+
+#include <QFileInfo>
+#include <QUrl>
+#include <QWebEngineDownloadItem>
+
+DownloadWidget::DownloadWidget(QWebEngineDownloadItem *download, QWidget *parent)
+ : QFrame(parent)
+ , m_download(download)
+ , m_timeAdded(QTime::currentTime())
+{
+ setupUi(this);
+ m_dstName->setText(QFileInfo(m_download->path()).fileName());
+ m_srcUrl->setText(m_download->url().toDisplayString());
+
+ connect(m_cancelButton, &QPushButton::clicked,
+ [this](bool) {
+ if (m_download->state() == QWebEngineDownloadItem::DownloadInProgress)
+ m_download->cancel();
+ else
+ emit removeClicked(this);
+ });
+
+ connect(m_download, &QWebEngineDownloadItem::downloadProgress,
+ this, &DownloadWidget::updateWidget);
+
+ connect(m_download, &QWebEngineDownloadItem::stateChanged,
+ this, &DownloadWidget::updateWidget);
+
+ updateWidget();
+}
+
+inline QString DownloadWidget::withUnit(qreal bytes)
+{
+ if (bytes < (1 << 10))
+ return tr("%L1 B").arg(bytes);
+ else if (bytes < (1 << 20))
+ return tr("%L1 KiB").arg(bytes / (1 << 10), 0, 'f', 2);
+ else if (bytes < (1 << 30))
+ return tr("%L1 MiB").arg(bytes / (1 << 20), 0, 'f', 2);
+ else
+ return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2);
+}
+
+void DownloadWidget::updateWidget()
+{
+ qreal totalBytes = m_download->totalBytes();
+ qreal receivedBytes = m_download->receivedBytes();
+ qreal bytesPerSecond = receivedBytes / m_timeAdded.elapsed() * 1000;
+
+ auto state = m_download->state();
+ switch (state) {
+ case QWebEngineDownloadItem::DownloadRequested:
+ Q_UNREACHABLE();
+ break;
+ case QWebEngineDownloadItem::DownloadInProgress:
+ if (totalBytes >= 0) {
+ m_progressBar->setValue(qRound(100 * receivedBytes / totalBytes));
+ m_progressBar->setDisabled(false);
+ m_progressBar->setFormat(
+ tr("%p% - %1 of %2 downloaded - %3/s")
+ .arg(withUnit(receivedBytes))
+ .arg(withUnit(totalBytes))
+ .arg(withUnit(bytesPerSecond)));
+ } else {
+ m_progressBar->setValue(0);
+ m_progressBar->setDisabled(false);
+ m_progressBar->setFormat(
+ tr("unknown size - %1 downloaded - %2/s")
+ .arg(withUnit(receivedBytes))
+ .arg(withUnit(bytesPerSecond)));
+ }
+ break;
+ case QWebEngineDownloadItem::DownloadCompleted:
+ m_progressBar->setValue(100);
+ m_progressBar->setDisabled(true);
+ m_progressBar->setFormat(
+ tr("completed - %1 downloaded - %2/s")
+ .arg(withUnit(receivedBytes))
+ .arg(withUnit(bytesPerSecond)));
+ break;
+ case QWebEngineDownloadItem::DownloadCancelled:
+ m_progressBar->setValue(0);
+ m_progressBar->setDisabled(true);
+ m_progressBar->setFormat(
+ tr("cancelled - %1 downloaded - %2/s")
+ .arg(withUnit(receivedBytes))
+ .arg(withUnit(bytesPerSecond)));
+ break;
+ case QWebEngineDownloadItem::DownloadInterrupted:
+ m_progressBar->setValue(0);
+ m_progressBar->setDisabled(true);
+ m_progressBar->setFormat(
+ tr("interrupted: %1")
+ .arg(m_download->interruptReasonString()));
+ break;
+ }
+
+ if (state == QWebEngineDownloadItem::DownloadInProgress) {
+ static QIcon cancelIcon(QStringLiteral(":process-stop.png"));
+ m_cancelButton->setIcon(cancelIcon);
+ m_cancelButton->setToolTip(tr("Stop downloading"));
+ } else {
+ static QIcon removeIcon(QStringLiteral(":edit-clear.png"));
+ m_cancelButton->setIcon(removeIcon);
+ m_cancelButton->setToolTip(tr("Remove from list"));
+ }
+}
diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.h b/examples/webenginewidgets/simplebrowser/downloadwidget.h
new file mode 100644
index 000000000..02c42fb44
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "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 The Qt Company Ltd 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."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DOWNLOADWIDGET_H
+#define DOWNLOADWIDGET_H
+
+#include "ui_downloadwidget.h"
+
+#include <QFrame>
+#include <QTime>
+
+QT_BEGIN_NAMESPACE
+class QWebEngineDownloadItem;
+QT_END_NAMESPACE
+
+// Displays one ongoing or finished download (QWebEngineDownloadItem).
+class DownloadWidget final : public QFrame, public Ui::DownloadWidget
+{
+ Q_OBJECT
+public:
+ // Precondition: The QWebEngineDownloadItem has been accepted.
+ explicit DownloadWidget(QWebEngineDownloadItem *download, QWidget *parent = nullptr);
+
+signals:
+ // This signal is emitted when the user indicates that they want to remove
+ // this download from the downloads list.
+ void removeClicked(DownloadWidget *self);
+
+private slots:
+ void updateWidget();
+
+private:
+ QString withUnit(qreal bytes);
+
+ QWebEngineDownloadItem *m_download;
+ QTime m_timeAdded;
+};
+
+#endif // DOWNLOADWIDGET_H
diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.ui b/examples/webenginewidgets/simplebrowser/downloadwidget.ui
new file mode 100644
index 000000000..ee45e0b10
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/downloadwidget.ui
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DownloadWidget</class>
+ <widget class="QFrame" name="DownloadWidget">
+ <property name="styleSheet">
+ <string notr="true">#DownloadWidget {
+ background: palette(button);
+ border: 1px solid palette(dark);
+ margin: 0px;
+}</string>
+ </property>
+ <layout class="QGridLayout" name="m_topLevelLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinAndMaxSize</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_dstName">
+ <property name="styleSheet">
+ <string notr="true">font-weight: bold
+</string>
+ </property>
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QPushButton" name="m_cancelButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed"/>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QPushButton {
+ margin: 1px;
+ border: none;
+}
+QPushButton:pressed {
+ margin: none;
+ border: 1px solid palette(shadow);
+ background: palette(midlight);
+}</string>
+ </property>
+ <property name="flat">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLabel" name="m_srcUrl">
+ <property name="maximumSize">
+ <size>
+ <width>350</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QProgressBar" name="m_progressBar">
+ <property name="styleSheet">
+ <string notr="true">font-size: 12px</string>
+ </property>
+ <property name="value">
+ <number>24</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="data/simplebrowser.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp
index fa9f44c34..93dfc8a8c 100644
--- a/examples/webenginewidgets/simplebrowser/main.cpp
+++ b/examples/webenginewidgets/simplebrowser/main.cpp
@@ -40,38 +40,35 @@
#include "browser.h"
#include "browserwindow.h"
+#include "webview.h"
#include <QApplication>
#include <QWebEngineSettings>
-QString getCommandLineUrlArgument()
+QUrl getCommandLineUrlArgument()
{
const QStringList args = QCoreApplication::arguments();
- if (args.count() > 1) {
- const QString lastArg = args.last();
- const bool isValidUrl = QUrl::fromUserInput(lastArg).isValid();
- if (isValidUrl)
- return lastArg;
- }
- return QString();
+ if (args.count() > 1)
+ return QUrl::fromUserInput(args.last());
+ return QUrl();
}
int main(int argc, char **argv)
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication app(argc, argv);
- app.setWindowIcon(QIcon(QLatin1String(":simplebrowser.svg")));
+ app.setWindowIcon(QIcon(QStringLiteral(":AppLogoColor.png")));
QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
- BrowserWindow *window = new BrowserWindow();
- Browser::instance().addWindow(window);
+ QUrl url = getCommandLineUrlArgument();
+ if (!url.isValid())
+ url = QStringLiteral("https://www.qt.io");
- const QString url = getCommandLineUrlArgument();
- if (!url.isEmpty())
- window->loadPage(url);
- else
- window->loadHomePage();
+ Browser browser;
+ BrowserWindow *window = browser.createWindow();
+ window->currentTab()->setUrl(url);
return app.exec();
}
diff --git a/examples/webenginewidgets/simplebrowser/simplebrowser.pro b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
index 197d68091..8120a2852 100644
--- a/examples/webenginewidgets/simplebrowser/simplebrowser.pro
+++ b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
@@ -6,25 +6,29 @@ CONFIG += c++11
HEADERS += \
browser.h \
browserwindow.h \
+ downloadmanagerwidget.h \
+ downloadwidget.h \
tabwidget.h \
- urllineedit.h \
- webview.h \
webpage.h \
- webpopupwindow.h
+ webpopupwindow.h \
+ webview.h
SOURCES += \
browser.cpp \
browserwindow.cpp \
+ downloadmanagerwidget.cpp \
+ downloadwidget.cpp \
main.cpp \
tabwidget.cpp \
- urllineedit.cpp \
- webview.cpp \
webpage.cpp \
- webpopupwindow.cpp
+ webpopupwindow.cpp \
+ webview.cpp
FORMS += \
certificateerrordialog.ui \
- passworddialog.ui
+ passworddialog.ui \
+ downloadmanagerwidget.ui \
+ downloadwidget.ui
RESOURCES += data/simplebrowser.qrc
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
index 33c3ac1dc..3f02cd3d8 100644
--- a/examples/webenginewidgets/simplebrowser/tabwidget.cpp
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
@@ -56,9 +56,8 @@ TabWidget::TabWidget(QWidget *parent)
connect(tabBar, &QTabBar::customContextMenuRequested, this, &TabWidget::handleContextMenuRequested);
connect(tabBar, &QTabBar::tabCloseRequested, this, &TabWidget::closeTab);
connect(tabBar, &QTabBar::tabBarDoubleClicked, [this](int index) {
- if (index != -1)
- return;
- createTab();
+ if (index == -1)
+ createTab();
});
setDocumentMode(true);
@@ -67,10 +66,6 @@ TabWidget::TabWidget(QWidget *parent)
connect(this, &QTabWidget::currentChanged, this, &TabWidget::handleCurrentChanged);
}
-TabWidget::~TabWidget()
-{
-}
-
void TabWidget::handleCurrentChanged(int index)
{
if (index != -1) {
@@ -80,11 +75,7 @@ void TabWidget::handleCurrentChanged(int index)
emit titleChanged(view->title());
emit loadProgress(view->loadProgress());
emit urlChanged(view->url());
- QIcon pageIcon = view->page()->icon();
- if (!pageIcon.isNull())
- emit iconChanged(pageIcon);
- else
- emit iconChanged(QIcon(QStringLiteral(":defaulticon.png")));
+ emit favIconChanged(view->favIcon());
emit webActionEnabledChanged(QWebEnginePage::Back, view->isWebActionEnabled(QWebEnginePage::Back));
emit webActionEnabledChanged(QWebEnginePage::Forward, view->isWebActionEnabled(QWebEnginePage::Forward));
emit webActionEnabledChanged(QWebEnginePage::Stop, view->isWebActionEnabled(QWebEnginePage::Stop));
@@ -93,7 +84,7 @@ void TabWidget::handleCurrentChanged(int index)
emit titleChanged(QString());
emit loadProgress(0);
emit urlChanged(QUrl());
- emit iconChanged(QIcon(QStringLiteral(":defaulticon.png")));
+ emit favIconChanged(QIcon());
emit webActionEnabledChanged(QWebEnginePage::Back, false);
emit webActionEnabledChanged(QWebEnginePage::Forward, false);
emit webActionEnabledChanged(QWebEnginePage::Stop, false);
@@ -150,8 +141,10 @@ void TabWidget::setupView(WebView *webView)
connect(webView, &QWebEngineView::titleChanged, [this, webView](const QString &title) {
int index = indexOf(webView);
- if (index != -1)
+ if (index != -1) {
setTabText(index, title);
+ setTabToolTip(index, title);
+ }
if (currentIndex() == index)
emit titleChanged(title);
});
@@ -170,26 +163,17 @@ void TabWidget::setupView(WebView *webView)
if (currentIndex() == indexOf(webView))
emit linkHovered(url);
});
- connect(webPage, &WebPage::iconChanged, [this, webView](const QIcon &icon) {
+ connect(webView, &WebView::favIconChanged, [this, webView](const QIcon &icon) {
int index = indexOf(webView);
- QIcon ico = icon.isNull() ? QIcon(QStringLiteral(":defaulticon.png")) : icon;
-
if (index != -1)
- setTabIcon(index, ico);
+ setTabIcon(index, icon);
if (currentIndex() == index)
- emit iconChanged(ico);
+ emit favIconChanged(icon);
});
connect(webView, &WebView::webActionEnabledChanged, [this, webView](QWebEnginePage::WebAction action, bool enabled) {
if (currentIndex() == indexOf(webView))
emit webActionEnabledChanged(action,enabled);
});
- connect(webView, &QWebEngineView::loadStarted, [this, webView]() {
- int index = indexOf(webView);
- if (index != -1) {
- QIcon icon(QLatin1String(":view-refresh.png"));
- setTabIcon(index, icon);
- }
- });
connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() {
int index = indexOf(webView);
if (index >= 0)
@@ -197,20 +181,24 @@ void TabWidget::setupView(WebView *webView)
});
}
-WebView *TabWidget::createTab(bool makeCurrent)
+WebView *TabWidget::createTab()
+{
+ WebView *webView = createBackgroundTab();
+ setCurrentWidget(webView);
+ return webView;
+}
+
+WebView *TabWidget::createBackgroundTab()
{
WebView *webView = new WebView;
WebPage *webPage = new WebPage(QWebEngineProfile::defaultProfile(), webView);
webView->setPage(webPage);
setupView(webView);
- addTab(webView, tr("(Untitled)"));
- if (makeCurrent) {
- setCurrentWidget(webView);
- } else {
- // Workaround for QTBUG-61770
- webView->resize(currentWidget()->size());
- webView->show();
- }
+ int index = addTab(webView, tr("(Untitled)"));
+ setTabIcon(index, webView->favIcon());
+ // Workaround for QTBUG-61770
+ webView->resize(currentWidget()->size());
+ webView->show();
return webView;
}
@@ -244,7 +232,7 @@ void TabWidget::closeTab(int index)
void TabWidget::cloneTab(int index)
{
if (WebView *view = webView(index)) {
- WebView *tab = createTab(false);
+ WebView *tab = createTab();
tab->setUrl(view->url());
}
}
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.h b/examples/webenginewidgets/simplebrowser/tabwidget.h
index 830effa4e..e5a1671ae 100644
--- a/examples/webenginewidgets/simplebrowser/tabwidget.h
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.h
@@ -56,7 +56,6 @@ class TabWidget : public QTabWidget
public:
TabWidget(QWidget *parent = nullptr);
- ~TabWidget();
WebView *currentWebView() const;
@@ -66,7 +65,7 @@ signals:
void loadProgress(int progress);
void titleChanged(const QString &title);
void urlChanged(const QUrl &url);
- void iconChanged(const QIcon &icon);
+ void favIconChanged(const QIcon &icon);
void webActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled);
public slots:
@@ -74,7 +73,8 @@ public slots:
void setUrl(const QUrl &url);
void triggerWebPageAction(QWebEnginePage::WebAction action);
- WebView *createTab(bool makeCurrent = true);
+ WebView *createTab();
+ WebView *createBackgroundTab();
void closeTab(int index);
void nextTab();
void previousTab();
diff --git a/examples/webenginewidgets/simplebrowser/urllineedit.cpp b/examples/webenginewidgets/simplebrowser/urllineedit.cpp
deleted file mode 100644
index 7e67b635a..000000000
--- a/examples/webenginewidgets/simplebrowser/urllineedit.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "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 The Qt Company Ltd 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."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "urllineedit.h"
-#include <QToolButton>
-#include <QUrl>
-
-UrlLineEdit::UrlLineEdit(QWidget *parent)
- : QLineEdit(parent)
- , m_favButton(new QToolButton(this))
- , m_clearButton(new QToolButton(this))
-{
- m_clearButton->setIcon(QIcon(QStringLiteral(":closetab.png")));
- m_clearButton->setVisible(false);
- m_clearButton->setCursor(Qt::ArrowCursor);
- QString style(QStringLiteral("QToolButton { border: none; padding: 1px; }"));
- m_clearButton->setStyleSheet(style);
- m_favButton->setStyleSheet(style);
- setStyleSheet(QStringLiteral("QLineEdit { padding-left: %1px; padding-right: %2px; } ")
- .arg(m_clearButton->sizeHint().width())
- .arg(m_favButton->sizeHint().width()));
- int minIconHeight = qMax(m_favButton->sizeHint().height(), m_clearButton->sizeHint().height());
- setMinimumSize(minimumSizeHint().width() +
- m_favButton->sizeHint().width() +
- m_clearButton->sizeHint().width(),
- qMax(minimumSizeHint().height(), minIconHeight));
-
- connect(m_clearButton, &QToolButton::clicked, this, &QLineEdit::clear);
- connect(this, &QLineEdit::textChanged, [this](const QString &text) {
- m_clearButton->setVisible(!text.isEmpty() && !isReadOnly());
- });
-}
-
-QUrl UrlLineEdit::url() const
-{
- return QUrl::fromUserInput(text());
-}
-
-void UrlLineEdit::setUrl(const QUrl &url)
-{
- setText(url.toString());
- setCursorPosition(0);
-}
-
-void UrlLineEdit::setFavIcon(const QIcon &icon)
-{
- QPixmap pixmap = icon.pixmap(16, 16);
- m_favButton->setIcon(pixmap);
-}
-
-void UrlLineEdit::resizeEvent(QResizeEvent *event)
-{
- QLineEdit::resizeEvent(event);
- QSize clearButtonSize = m_clearButton->sizeHint();
- m_clearButton->move(rect().right() - clearButtonSize.width(),
- (rect().bottom() - clearButtonSize.height()) / 2);
- m_favButton->move(rect().left(), (rect().bottom() - m_favButton->sizeHint().height()) / 2);
-}
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
index 8146dcfb7..63246ac1d 100644
--- a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
@@ -38,15 +38,17 @@
**
****************************************************************************/
-#include "urllineedit.h"
#include "webpage.h"
#include "webpopupwindow.h"
#include "webview.h"
+#include <QAction>
#include <QIcon>
+#include <QLineEdit>
#include <QVBoxLayout>
WebPopupWindow::WebPopupWindow(QWebEngineProfile *profile)
- : m_addressBar(new UrlLineEdit(this))
+ : m_urlLineEdit(new QLineEdit(this))
+ , m_favAction(new QAction(this))
, m_view(new WebView(this))
{
setAttribute(Qt::WA_DeleteOnClose);
@@ -55,31 +57,29 @@ WebPopupWindow::WebPopupWindow(QWebEngineProfile *profile)
QVBoxLayout *layout = new QVBoxLayout;
layout->setMargin(0);
setLayout(layout);
- layout->addWidget(m_addressBar);
+ layout->addWidget(m_urlLineEdit);
layout->addWidget(m_view);
m_view->setPage(new WebPage(profile, m_view));
m_view->setFocus();
- m_addressBar->setReadOnly(true);
- m_addressBar->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
+
+ m_urlLineEdit->setReadOnly(true);
+ m_urlLineEdit->addAction(m_favAction, QLineEdit::LeadingPosition);
connect(m_view, &WebView::titleChanged, this, &QWidget::setWindowTitle);
- connect(m_view, &WebView::urlChanged, this, &WebPopupWindow::setUrl);
- connect(m_view->page(), &WebPage::iconChanged, this, &WebPopupWindow::handleIconChanged);
+ connect(m_view, &WebView::urlChanged, [this](const QUrl &url) {
+ m_urlLineEdit->setText(url.toDisplayString());
+ });
+ connect(m_view, &WebView::favIconChanged, m_favAction, &QAction::setIcon);
connect(m_view->page(), &WebPage::geometryChangeRequested, this, &WebPopupWindow::handleGeometryChangeRequested);
connect(m_view->page(), &WebPage::windowCloseRequested, this, &QWidget::close);
}
-QWebEngineView *WebPopupWindow::view() const
+WebView *WebPopupWindow::view() const
{
return m_view;
}
-void WebPopupWindow::setUrl(const QUrl &url)
-{
- m_addressBar->setUrl(url);
-}
-
void WebPopupWindow::handleGeometryChangeRequested(const QRect &newGeometry)
{
m_view->setMinimumSize(newGeometry.width(), newGeometry.height());
@@ -87,12 +87,5 @@ void WebPopupWindow::handleGeometryChangeRequested(const QRect &newGeometry)
// let the layout do the magic
resize(0, 0);
show();
-}
-
-void WebPopupWindow::handleIconChanged(const QIcon &icon)
-{
- if (icon.isNull())
- m_addressBar->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
- else
- m_addressBar->setFavIcon(icon);
+ m_view->setFocus();
}
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.h b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
index af97ef7fc..c737b4abc 100644
--- a/examples/webenginewidgets/simplebrowser/webpopupwindow.h
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
@@ -44,12 +44,12 @@
#include <QWidget>
QT_BEGIN_NAMESPACE
+class QLineEdit;
class QWebEngineProfile;
class QWebEngineView;
QT_END_NAMESPACE
class WebView;
-class UrlLineEdit;
class WebPopupWindow : public QWidget
{
@@ -57,15 +57,14 @@ class WebPopupWindow : public QWidget
public:
WebPopupWindow(QWebEngineProfile *profile);
- QWebEngineView *view() const;
- void setUrl(const QUrl &url);
+ WebView *view() const;
private slots:
void handleGeometryChangeRequested(const QRect &newGeometry);
- void handleIconChanged(const QIcon &icon);
private:
- UrlLineEdit *m_addressBar;
+ QLineEdit *m_urlLineEdit;
+ QAction *m_favAction;
WebView *m_view;
};
#endif // WEBPOPUPWINDOW_H
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
index e4e7f5efa..4bd5c84ac 100644
--- a/examples/webenginewidgets/simplebrowser/webview.cpp
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -52,15 +52,21 @@
WebView::WebView(QWidget *parent)
: QWebEngineView(parent)
- , m_loadProgress(0)
+ , m_loadProgress(100)
{
+ connect(this, &QWebEngineView::loadStarted, [this]() {
+ m_loadProgress = 0;
+ emit favIconChanged(favIcon());
+ });
connect(this, &QWebEngineView::loadProgress, [this](int progress) {
m_loadProgress = progress;
});
connect(this, &QWebEngineView::loadFinished, [this](bool success) {
- if (!success) {
- m_loadProgress = 0;
- }
+ m_loadProgress = success ? 100 : -1;
+ emit favIconChanged(favIcon());
+ });
+ connect(this, &QWebEngineView::iconChanged, [this](const QIcon &) {
+ emit favIconChanged(favIcon());
});
connect(this, &QWebEngineView::renderProcessTerminated,
@@ -115,21 +121,39 @@ bool WebView::isWebActionEnabled(QWebEnginePage::WebAction webAction) const
return page()->action(webAction)->isEnabled();
}
+QIcon WebView::favIcon() const
+{
+ QIcon favIcon = icon();
+ if (!favIcon.isNull())
+ return favIcon;
+
+ if (m_loadProgress < 0) {
+ static QIcon errorIcon(QStringLiteral(":dialog-error.png"));
+ return errorIcon;
+ } else if (m_loadProgress < 100) {
+ static QIcon loadingIcon(QStringLiteral(":view-refresh.png"));
+ return loadingIcon;
+ } else {
+ static QIcon defaultIcon(QStringLiteral(":text-html.png"));
+ return defaultIcon;
+ }
+}
+
QWebEngineView *WebView::createWindow(QWebEnginePage::WebWindowType type)
{
+ BrowserWindow *mainWindow = qobject_cast<BrowserWindow*>(window());
+ if (!mainWindow)
+ return nullptr;
+
switch (type) {
case QWebEnginePage::WebBrowserTab: {
- BrowserWindow *mainWindow = qobject_cast<BrowserWindow*>(window());
return mainWindow->tabWidget()->createTab();
}
case QWebEnginePage::WebBrowserBackgroundTab: {
- BrowserWindow *mainWindow = qobject_cast<BrowserWindow*>(window());
- return mainWindow->tabWidget()->createTab(false);
+ return mainWindow->tabWidget()->createBackgroundTab();
}
case QWebEnginePage::WebBrowserWindow: {
- BrowserWindow *mainWindow = new BrowserWindow();
- Browser::instance().addWindow(mainWindow);
- return mainWindow->currentTab();
+ return mainWindow->browser()->createWindow()->currentTab();
}
case QWebEnginePage::WebDialog: {
WebPopupWindow *popup = new WebPopupWindow(page()->profile());
diff --git a/examples/webenginewidgets/simplebrowser/webview.h b/examples/webenginewidgets/simplebrowser/webview.h
index f06162ea3..23a9a29ee 100644
--- a/examples/webenginewidgets/simplebrowser/webview.h
+++ b/examples/webenginewidgets/simplebrowser/webview.h
@@ -56,6 +56,7 @@ public:
int loadProgress() const;
bool isWebActionEnabled(QWebEnginePage::WebAction webAction) const;
+ QIcon favIcon() const;
protected:
void contextMenuEvent(QContextMenuEvent *event) override;
@@ -63,6 +64,7 @@ protected:
signals:
void webActionEnabledChanged(QWebEnginePage::WebAction webAction, bool enabled);
+ void favIconChanged(const QIcon &icon);
private:
void createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction);
diff --git a/qtwebengine.pro b/qtwebengine.pro
index 5ae80ea8c..034e946c4 100644
--- a/qtwebengine.pro
+++ b/qtwebengine.pro
@@ -1,10 +1,13 @@
load(qt_parts)
isPlatformSupported() {
- !exists(src/3rdparty/chromium): \
- error("Submodule qtwebengine-chromium does not exist. Run 'git submodule update --init'.")
- load(configure)
- runConfigure()
+ !exists(src/3rdparty/chromium): \
+ error("Submodule qtwebengine-chromium does not exist. Run 'git submodule update --init'.")
+ WSPC = $$find(OUT_PWD, \\s)
+ !isEmpty(WSPC): \
+ error("QtWebEngine cannot be built in a path that contains whitespace characters.")
+ load(configure)
+ runConfigure()
}
!isEmpty(skipBuildReason) {
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 3deea958f1485b50940e7437c0a3b73ed29ee13
+Subproject 582c5493439ba9ac57c6c14c706f530741f5bfc
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index d3d47e03a..05166536e 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -50,6 +50,8 @@ SOURCES = \
qwebengineurlrequestjob.cpp \
qwebengineurlschemehandler.cpp
+### Qt6 Remove this workaround
unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!static {
- SOURCES += qtbug-60565.cpp
+ SOURCES += qtbug-60565.cpp \
+ qtbug-61521.cpp
}
diff --git a/src/core/api/qtbug-61521.cpp b/src/core/api/qtbug-61521.cpp
new file mode 100644
index 000000000..86d5998ef
--- /dev/null
+++ b/src/core/api/qtbug-61521.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdlib.h>
+#include <malloc.h>
+
+#define SHIM_ALIAS_SYMBOL(fn) __attribute__((weak, alias(#fn)))
+#define SHIM_SYMBOL_VERSION(fn) __asm__(".symver __" #fn "," #fn "@Qt_5")
+#define SHIM_HIDDEN __attribute__ ((visibility ("hidden")))
+
+extern "C" {
+
+SHIM_SYMBOL_VERSION(malloc);
+void* __malloc(size_t size)
+ SHIM_ALIAS_SYMBOL(ShimMalloc);
+
+SHIM_SYMBOL_VERSION(free);
+void __free(void* ptr)
+ SHIM_ALIAS_SYMBOL(ShimFree);
+
+SHIM_SYMBOL_VERSION(realloc);
+void* __realloc(void* ptr, size_t size)
+ SHIM_ALIAS_SYMBOL(ShimRealloc);
+
+SHIM_SYMBOL_VERSION(calloc);
+void* __calloc(size_t n, size_t size)
+ SHIM_ALIAS_SYMBOL(ShimCalloc);
+
+SHIM_SYMBOL_VERSION(cfree);
+void __cfree(void* ptr)
+ SHIM_ALIAS_SYMBOL(ShimCFree);
+
+SHIM_SYMBOL_VERSION(memalign);
+void* __memalign(size_t align, size_t s)
+ SHIM_ALIAS_SYMBOL(ShimMemalign);
+
+SHIM_SYMBOL_VERSION(valloc);
+void* __valloc(size_t size)
+ SHIM_ALIAS_SYMBOL(ShimValloc);
+
+SHIM_SYMBOL_VERSION(pvalloc);
+void* __pvalloc(size_t size)
+ SHIM_ALIAS_SYMBOL(ShimPvalloc);
+
+SHIM_SYMBOL_VERSION(posix_memalign);
+int __posix_memalign(void** r, size_t a, size_t s)
+ SHIM_ALIAS_SYMBOL(ShimPosixMemalign);
+
+SHIM_HIDDEN void* ShimMalloc(size_t size) {
+ return malloc(size);
+}
+
+SHIM_HIDDEN void ShimFree(void* ptr) {
+ free(ptr);
+}
+
+SHIM_HIDDEN void* ShimRealloc(void* ptr, size_t size) {
+ return realloc(ptr,size);
+}
+
+SHIM_HIDDEN void* ShimCalloc(size_t n, size_t size) {
+ return calloc(n,size);
+}
+
+SHIM_HIDDEN void ShimCFree(void* ptr) {
+ cfree(ptr);
+}
+
+SHIM_HIDDEN void* ShimMemalign(size_t align, size_t s) {
+ return memalign(align,s);
+}
+
+SHIM_HIDDEN void* ShimValloc(size_t size) {
+ return valloc(size);
+}
+
+SHIM_HIDDEN void* ShimPvalloc(size_t size) {
+ return pvalloc(size);
+}
+
+SHIM_HIDDEN int ShimPosixMemalign(void** r, size_t a, size_t s) {
+ return posix_memalign(r,a,s);
+}
+} // extern "C"
diff --git a/src/core/proxy_config_service_qt.cpp b/src/core/proxy_config_service_qt.cpp
index fed3da7f5..48f3593e6 100644
--- a/src/core/proxy_config_service_qt.cpp
+++ b/src/core/proxy_config_service_qt.cpp
@@ -36,6 +36,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+
+//================ Based on ChromeProxyConfigService =======================
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -60,17 +63,16 @@ net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qt
proxyScheme = net::ProxyServer::SCHEME_HTTP;
break;
case QNetworkProxy::NoProxy:
- default:
+ case QNetworkProxy::DefaultProxy:
proxyScheme = net::ProxyServer::SCHEME_DIRECT;
break;
}
return net::ProxyServer(proxyScheme, net::HostPortPair(qtProxy.hostName().toStdString(), qtProxy.port()));
}
-//================ Based on ChromeProxyConfigService =======================
-
ProxyConfigServiceQt::ProxyConfigServiceQt(std::unique_ptr<ProxyConfigService> baseService)
: m_baseService(baseService.release()),
+ m_usesSystemConfiguration(false),
m_registeredObserver(false)
{
}
@@ -83,7 +85,6 @@ ProxyConfigServiceQt::~ProxyConfigServiceQt()
void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer)
{
- RegisterObserver();
m_observers.AddObserver(observer);
}
@@ -94,26 +95,31 @@ void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *obs
net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfig *config)
{
- RegisterObserver();
-
- // Ask the base service if available.
- net::ProxyConfig systemConfig;
- ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
- if (m_baseService.get())
- systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
+ m_usesSystemConfiguration = QNetworkProxyFactory::usesSystemConfiguration();
+#endif
+ if (m_usesSystemConfiguration) {
+ // Use Chromium's base service to retrieve system settings
+ net::ProxyConfig systemConfig;
+ ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET;
+ if (m_baseService.get())
+ systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig);
+ *config = systemConfig;
+ // make sure to get updates via OnProxyConfigChanged
+ RegisterObserver();
+ return systemAvailability;
+ }
+ // Use QNetworkProxy::applicationProxy settings
const QNetworkProxy &qtProxy = QNetworkProxy::applicationProxy();
if (qtProxy == m_qtApplicationProxy && !m_qtProxyConfig.proxy_rules().empty()) {
+ // no changes
*config = m_qtProxyConfig;
return CONFIG_VALID;
}
+
m_qtApplicationProxy = qtProxy;
m_qtProxyConfig = net::ProxyConfig();
- if (qtProxy.type() == QNetworkProxy::NoProxy
- && QNetworkProxyFactory::usesSystemConfiguration()) {
- *config = systemConfig;
- return systemAvailability;
- }
net::ProxyConfig::ProxyRules qtRules;
net::ProxyServer server = fromQNetworkProxy(qtProxy);
@@ -143,31 +149,51 @@ net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxy
void ProxyConfigServiceQt::OnLazyPoll()
{
- if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()) {
- net::ProxyConfig unusedConfig;
- OnProxyConfigChanged(unusedConfig, CONFIG_VALID);
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
+ // We need to update if
+ // - setUseSystemConfiguration() was called in between
+ // - user changed application proxy
+ if (m_usesSystemConfiguration != QNetworkProxyFactory::usesSystemConfiguration()
+ || (!m_usesSystemConfiguration && m_qtApplicationProxy != QNetworkProxy::applicationProxy())) {
+ Update();
+ } else if (m_usesSystemConfiguration) {
+ if (m_baseService.get())
+ m_baseService->OnLazyPoll();
}
- if (m_baseService.get())
- m_baseService->OnLazyPoll();
+#else
+ if (m_qtApplicationProxy != QNetworkProxy::applicationProxy())
+ Update();
+#endif
}
-
+// Called when the base service changed
void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfig &config, ConfigAvailability availability)
{
- Q_UNUSED(config);
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ Q_UNUSED(config);
- if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()
- || m_qtApplicationProxy.type() == QNetworkProxy::NoProxy) {
- net::ProxyConfig actual_config;
- availability = GetLatestProxyConfig(&actual_config);
- if (availability == CONFIG_PENDING)
- return;
- for (net::ProxyConfigService::Observer &observer: m_observers)
- observer.OnProxyConfigChanged(actual_config, availability);
- }
+ if (!m_usesSystemConfiguration)
+ return;
+
+ Update();
+}
+
+// Update our observers
+void ProxyConfigServiceQt::Update()
+{
+ net::ProxyConfig actual_config;
+ ConfigAvailability availability = GetLatestProxyConfig(&actual_config);
+ if (availability == CONFIG_PENDING)
+ return;
+ for (net::ProxyConfigService::Observer &observer: m_observers)
+ observer.OnProxyConfigChanged(actual_config, availability);
}
+// Register ourselves as observer of the base service.
+// This has to be done on the IO thread, and therefore cannot be done
+// in the constructor.
void ProxyConfigServiceQt::RegisterObserver()
{
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/src/core/proxy_config_service_qt.h b/src/core/proxy_config_service_qt.h
index f2f9a2210..7be3289d0 100644
--- a/src/core/proxy_config_service_qt.h
+++ b/src/core/proxy_config_service_qt.h
@@ -69,13 +69,17 @@ private:
void OnProxyConfigChanged(const net::ProxyConfig& config,
ConfigAvailability availability) override;
+ // Retrieve new proxy settings and notify observers.
+ void Update();
+
// Makes sure that the observer registration with the base service is set up.
void RegisterObserver();
std::unique_ptr<net::ProxyConfigService> m_baseService;
base::ObserverList<net::ProxyConfigService::Observer, true> m_observers;
- // Keep the last QNetworkProxy::applicationProxy state around.
+ // Keep the last state around.
+ bool m_usesSystemConfiguration;
QNetworkProxy m_qtApplicationProxy;
net::ProxyConfig m_qtProxyConfig;
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index f90a44044..0c98c9e21 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -1124,8 +1124,9 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
if (keyDownTextInsertion) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
- // Make sure to skip the former on the way back. The same os_event will be set on both of them.
- webEvent.skip_in_browser = true;
+ // The RawKeyDown is skipped on the way back (see above).
+ // The same os_event will be set on both NativeWebKeyboardEvents.
+ webEvent.skip_in_browser = false;
webEvent.setType(blink::WebInputEvent::Char);
m_host->ForwardKeyboardEvent(webEvent);
}
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 995ba1b2e..c9b46b38a 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -72,6 +72,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/common/content_constants.h"
+#include "content/public/common/content_switches.h"
#include <content/public/common/drop_data.h>
#include "content/public/common/page_state.h"
#include "content/public/common/page_zoom.h"
@@ -81,6 +82,7 @@
#include "content/public/common/web_preferences.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "printing/features/features.h"
+#include "ui/gfx/font_render_params.h"
#include <QDir>
#include <QGuiApplication>
@@ -418,6 +420,20 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
rendererPrefs->caret_blink_interval = 0.5 * static_cast<double>(qtCursorFlashTime) / 1000;
rendererPrefs->user_agent_override = d->browserContextAdapter->httpUserAgent().toStdString();
rendererPrefs->accept_languages = d->browserContextAdapter->httpAcceptLanguageWithoutQualities().toStdString();
+#if defined(ENABLE_WEBRTC)
+ base::CommandLine* commandLine = base::CommandLine::ForCurrentProcess();
+ if (commandLine->HasSwitch(switches::kForceWebRtcIPHandlingPolicy))
+ rendererPrefs->webrtc_ip_handling_policy = commandLine->GetSwitchValueASCII(switches::kForceWebRtcIPHandlingPolicy);
+#endif
+ // Set web-contents font settings to the default font settings as Chromium constantly overrides
+ // the global font defaults with the font settings of the latest web-contents created.
+ CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params, (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL)));
+ rendererPrefs->should_antialias_text = params.antialiasing;
+ rendererPrefs->use_subpixel_positioning = params.subpixel_positioning;
+ rendererPrefs->hinting = params.hinting;
+ rendererPrefs->use_autohinter = params.autohinter;
+ rendererPrefs->use_bitmaps = params.use_bitmaps;
+ rendererPrefs->subpixel_rendering = params.subpixel_rendering;
d->webContents->GetRenderViewHost()->SyncRendererPrefs();
// Create and attach observers to the WebContents.
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index f8875f82e..54564718f 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -333,6 +333,17 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitch(switches::kDisablePepper3DImageChromium);
#endif
+#if defined(Q_OS_WIN)
+ // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
+ // an OpenGL Core Profile context. If the switch is not set, it would always try to create a
+ // Core Profile context, even if Qt uses a legacy profile, which causes
+ // "Could not share GL contexts" warnings, because it's not possible to share between Core and
+ // legacy profiles.
+ // Given that Core profile is not currently supported on Windows anyway, pass this switch to
+ // get rid of the warnings.
+ parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
+#endif
+
if (useEmbeddedSwitches) {
// Inspired by the Android port's default switches
if (!parsedCommandLine->HasSwitch(switches::kDisableOverlayScrollbar))
@@ -390,8 +401,23 @@ WebEngineContext::WebEngineContext()
}
}
} else {
- if (!qt_gl_global_share_context()->isOpenGLES())
+ if (!qt_gl_global_share_context()->isOpenGLES()) {
+ // Default to Desktop non-Core profile OpenGL.
glType = gl::kGLImplementationDesktopName;
+
+ // Check if Core profile was requested and is supported.
+ QSurfaceFormat globalSharedFormat = qt_gl_global_share_context()->format();
+ if (globalSharedFormat.profile() == QSurfaceFormat::CoreProfile) {
+#ifdef Q_OS_MACOS
+ // @TODO_FIXME_ADAPT_QT
+ // glType = gl::kGLImplementationCoreProfileName;
+#else
+ qWarning("An OpenGL Core Profile was requested, but it is not supported "
+ "on the current platform. Falling back to a non-Core profile. "
+ "Note that this might cause rendering issues.");
+#endif
+ }
+ }
}
if (qt_gl_global_share_context()->format().profile() == QSurfaceFormat::CompatibilityProfile)
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index fe40298bb..31d120899 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -48,6 +48,7 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/web_preferences.h"
+#include "ui/events/event_switches.h"
#include <QFont>
#include <QTimer>
@@ -97,6 +98,29 @@ static inline bool isTouchScreenAvailable() {
return touchScreenAvailable;
}
+static inline bool isTouchEventsAPIEnabled() {
+ static bool initialized = false;
+ static bool touchEventsAPIEnabled = false;
+ if (!initialized) {
+ base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
+
+ // By default the Touch Events API support (presence of 'ontouchstart' in 'window' object)
+ // will be determined based on the availability of touch screen devices.
+ const std::string touchEventsSwitchValue =
+ parsedCommandLine->HasSwitch(switches::kTouchEventFeatureDetection) ?
+ parsedCommandLine->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) :
+ switches::kTouchEventFeatureDetectionAuto;
+
+ if (touchEventsSwitchValue == switches::kTouchEventFeatureDetectionEnabled)
+ touchEventsAPIEnabled = true;
+ else if (touchEventsSwitchValue == switches::kTouchEventFeatureDetectionAuto)
+ touchEventsAPIEnabled = isTouchScreenAvailable();
+
+ initialized = true;
+ }
+ return touchEventsAPIEnabled;
+}
+
WebEngineSettings::WebEngineSettings(WebEngineSettings *_parentSettings)
: m_adapter(0)
@@ -298,6 +322,7 @@ void WebEngineSettings::doApply()
void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *prefs)
{
// Override for now
+ prefs->touch_event_feature_detection_enabled = isTouchEventsAPIEnabled();
prefs->device_supports_touch = isTouchScreenAvailable();
if (prefs->viewport_enabled) {
// We should enable viewport and viewport-meta together, but since 5.7 we
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index ea9c6f21b..7b1bad4e6 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -42,6 +42,7 @@ depends += qtcore \
qtgui \
qtlocation \
qtnetwork \
+ qtplatformheaders \
qtprintsupport \
qtpositioning \
qtqml \
diff --git a/src/webengine/doc/src/external-resources.qdoc b/src/webengine/doc/src/external-resources.qdoc
index a75c7aaed..6cced588c 100644
--- a/src/webengine/doc/src/external-resources.qdoc
+++ b/src/webengine/doc/src/external-resources.qdoc
@@ -136,3 +136,13 @@
\externalpage https://http2.akamai.com/demo
\title Akamai HTTP/2 Demo
*/
+
+/*!
+ \externalpage https://www.chromium.org/developers/design-documents/user-scripts
+ \title User Scripts
+*/
+
+/*!
+ \externalpage https://wiki.greasespot.net/Metadata_Block#.40name
+ \title Metadata Block
+*/
diff --git a/src/webengine/doc/src/qtwebengine-debugging.qdoc b/src/webengine/doc/src/qtwebengine-debugging.qdoc
index e929fabeb..5ff1c6342 100644
--- a/src/webengine/doc/src/qtwebengine-debugging.qdoc
+++ b/src/webengine/doc/src/qtwebengine-debugging.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -71,4 +71,35 @@
For a detailed explanation of the capabilities of developer tools, see the
\l {Chrome DevTools} page.
+
+ \section1 Using Command-Line Arguments
+
+ You can use the following command-line arguments while debugging to provide
+ input for bug reports:
+
+ \list
+ \li \c {--disable-gpu} disables GPU hardware acceleration. This is
+ useful when diagnosing OpenGL problems.
+ \li \c {--disable-logging} disables console logging, which might be
+ useful for debug builds.
+ \li \c {--enable-logging --log-level=0} enables console logging and sets
+ the logging level to 0, which means that messages of the severity
+ \c info and above are recorded in the log. This is the default for
+ debug builds. Other possible log levels are \c 1 for warnings, \c 2
+ for errors, and \c 3 for fatal errors.
+ \li \c {--no-sandbox} disables the sandbox for the renderer and plugin
+ processes. Keep in mind that disabling the sandbox might present a
+ security risk.
+ \li \c {--single-process} runs the renderer and plugins in the same
+ process as the browser. This is useful for getting stack traces for
+ renderer crashes.
+ \endlist
+
+ Alternatively, the environment variable QTWEBENGINE_CHROMIUM_FLAGS can be
+ set. For example, the following value could be set to disable logging while
+ debugging an application called \e mybrowser:
+
+ \code
+ QTWEBENGINE_CHROMIUM_FLAGS="--disable-logging" mybrowser
+ \endcode
*/
diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc
index a5e972023..7850ff35d 100644
--- a/src/webengine/doc/src/qtwebengine-features.qdoc
+++ b/src/webengine/doc/src/qtwebengine-features.qdoc
@@ -45,6 +45,7 @@
\li \l{Pepper Plugin API}
\li \l{Print to PDF}
\li \l{Spellchecker}
+ \li \l{Touch}
\li \l{View Source}
\li \l{WebRTC}
\endlist
@@ -343,6 +344,22 @@
Support for this feature was added in Qt 5.8.0.
+ \section1 Touch
+
+ Qt WebEngine supports touch devices for navigating and interacting with web pages.
+
+ Applications can prohibit the use of touch events in the following ways:
+
+ \list
+ \li Passing the flag \c --touch-events=disabled on the command line will disable touch event
+ support in JavaScript API (meaning \c ontouchstart and related handlers will not be present
+ in the \c document.window object). Touch events will still be delivered to web pages.
+
+ \li Installing an event filter object using \l {QObject::installEventFilter} on the WebEngine
+ view focus proxy object, and filtering out all touch events.
+
+ \endlist
+
\section1 View Source
Qt WebEngine supports viewing the HTML source of a web page.
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index e180b22c0..e9ca573b7 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -181,8 +181,29 @@
script to run, the injection point, and the world where the script is run. This enables
accessing the DOM to manipulate it within a world.
- The following \l Greasemonkey attributes are supported since Qt 5.8:
- \c @exclude, \c @include, \c @name, \c @match, and \c @run-at.
+ Since Qt 5.8, Qt WebEngine supports augmenting a script by using the
+ following \l{Metadata Block}{Greasemonkey-like attributes}:
+
+ \list
+ \li \c {@exclude <regexp>}
+ \li \c {@include <regexp>}
+ \li \c {@match <regexp>}
+ \li \c {@name <free text>}
+ \li \c {@run-at [document-start|document-end|document-idle]}
+ \endlist
+
+ The attributes determine if and when a \l {User Scripts}{user script} is
+ run. They must be placed immediately in the beginning of the script, inside
+ a \c ==UserScript== comment:
+
+ \code
+ // ==UserScript==
+ // @include http://*.qt.io/*
+ // @exclude http://wiki.qt.io/*
+ // ==/UserScript==
+
+ window.alert("Page is from qt.io, but not wiki.qt.io");
+ \endcode
\section1 Managing Certificates
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index ec678672c..068d395b6 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -182,4 +182,10 @@
It can be re-enabled by setting the \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
variable to a non-empty value.
+ \section1 Popups in Fullscreen Applications on Windows
+ Because of a limitation in the Windows compositor, applications that show a fullscreen web
+ engine view will not properly display popups or other top-level windows. The reason and
+ workaround for the issue can be found at \l {Fullscreen OpenGL Based Windows} and
+ \l {QWindowsWindowFunctions::setHasBorderInFullScreen}.
+
*/
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
index 959f96b10..3da554a81 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
@@ -28,8 +28,7 @@
/*!
\module QtWebEngineWidgets
\title Qt WebEngine Widgets C++ Classes
- \brief Provides a web browser engine as well as C++ classes to render and
- interact with web content
+ \brief Provides C++ classes for rendering web content in a QWidget based application
\ingroup modules
\ingroup qtwebengine-modules
\qtvariable webenginewidgets
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
index 3d44efa6a..2afaf03a3 100644
--- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp
@@ -110,6 +110,9 @@ QUrl tst_QQuickWebEngineDefaultSurfaceFormat::urlFromTestPath(const char *localF
void tst_QQuickWebEngineDefaultSurfaceFormat::customDefaultSurfaceFormat()
{
+#if !defined(Q_OS_MACOSX)
+ QSKIP("OpenGL Core Profile is currently only supported on macOS.");
+#endif
// Setting a new default QSurfaceFormat with a core OpenGL profile, before
// app instantiation should succeed, without abort() being called.
int argc = 1;
diff --git a/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp
index 3757a7842..1e8cc74e2 100644
--- a/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp
+++ b/tests/auto/widgets/qwebenginedefaultsurfaceformat/tst_qwebenginedefaultsurfaceformat.cpp
@@ -51,8 +51,8 @@ private Q_SLOTS:
void tst_QWebEngineDefaultSurfaceFormat::customDefaultSurfaceFormat()
{
-#if defined(Q_OS_WIN)
- QSKIP("Crashes on Windows");
+#if !defined(Q_OS_MACOSX)
+ QSKIP("OpenGL Core Profile is currently only supported on macOS.");
#endif
// Setting a new default QSurfaceFormat with a core OpenGL profile before
// app instantiation should succeed, without abort() being called.
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 0b49bd892..2ed461e57 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -451,16 +451,25 @@ void tst_QWebEngineView::unhandledKeyEventPropagation()
QTRY_COMPARE(parentWidget.releaseEvents.size(), 3);
QCOMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("second_div"));
+ // Focus the button and press 'y'.
+ evaluateJavaScriptSync(webView.page(), "document.getElementById('submit_button').focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("submit_button"));
+ QTest::sendKeyEvent(QTest::Press, webView.focusProxy(), Qt::Key_Y, 'y', Qt::NoModifier);
+ QTest::sendKeyEvent(QTest::Release, webView.focusProxy(), Qt::Key_Y, 'y', Qt::NoModifier);
+ QTRY_COMPARE(parentWidget.releaseEvents.size(), 4);
+
// The page will consume the Tab key to change focus between elements while the arrow
// keys won't be used.
- QCOMPARE(parentWidget.pressEvents.size(), 2);
+ QCOMPARE(parentWidget.pressEvents.size(), 3);
QCOMPARE(parentWidget.pressEvents[0].key(), (int)Qt::Key_Right);
QCOMPARE(parentWidget.pressEvents[1].key(), (int)Qt::Key_Left);
+ QCOMPARE(parentWidget.pressEvents[2].key(), (int)Qt::Key_Y);
// Key releases will all come back unconsumed.
QCOMPARE(parentWidget.releaseEvents[0].key(), (int)Qt::Key_Right);
QCOMPARE(parentWidget.releaseEvents[1].key(), (int)Qt::Key_Tab);
QCOMPARE(parentWidget.releaseEvents[2].key(), (int)Qt::Key_Left);
+ QCOMPARE(parentWidget.releaseEvents[3].key(), (int)Qt::Key_Y);
}
void tst_QWebEngineView::horizontalScrollbarTest()
@@ -2132,14 +2141,16 @@ void tst_QWebEngineView::imeCompositionQueryEvent()
QObject *input = nullptr;
QFETCH(QString, receiverObjectName);
- if (receiverObjectName == "focusObject")
+ if (receiverObjectName == "focusObject") {
+ QTRY_VERIFY(qApp->focusObject());
input = qApp->focusObject();
- else if (receiverObjectName == "focusProxy")
+ } else if (receiverObjectName == "focusProxy") {
+ QTRY_VERIFY(view.focusProxy());
input = view.focusProxy();
- else if (receiverObjectName == "focusWidget")
+ } else if (receiverObjectName == "focusWidget") {
+ QTRY_VERIFY(view.focusWidget());
input = view.focusWidget();
-
- QVERIFY(input);
+ }
QInputMethodQueryEvent srrndTextQuery(Qt::ImSurroundingText);
QInputMethodQueryEvent cursorPosQuery(Qt::ImCursorPosition);
diff --git a/tools/scripts/take_snapshot.py b/tools/scripts/take_snapshot.py
index 3cc1af618..2bd1ac5ed 100755
--- a/tools/scripts/take_snapshot.py
+++ b/tools/scripts/take_snapshot.py
@@ -148,6 +148,7 @@ def isInChromiumBlacklist(file_path):
or file_path.startswith('third_party/WebKit/Source/devtools/devtools-node-modules')
or file_path.startswith('third_party/WebKit/PerformanceTests')
or file_path.startswith('third_party/accessibility-audit')
+ or file_path.startswith('third_party/afl')
or file_path.startswith('third_party/android_')
or file_path.startswith('third_party/apache-win32')
or file_path.startswith('third_party/apple_sample_code')