summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.qmake.conf1
-rw-r--r--dist/changes-5.6.02
-rw-r--r--examples/examples.pro3
-rw-r--r--examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc3
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.cpp25
-rw-r--r--examples/webenginewidgets/markdowneditor/mainwindow.h2
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.cpp88
-rw-r--r--examples/webenginewidgets/simplebrowser/browser.h61
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.cpp437
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.h101
-rw-r--r--examples/webenginewidgets/simplebrowser/certificateerrordialog.ui133
-rw-r--r--examples/webenginewidgets/simplebrowser/data/addtab.pngbin0 -> 469 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/closetab.pngbin0 -> 516 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/defaulticon.pngbin0 -> 1473 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/go-next.pngbin0 -> 930 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/go-previous.pngbin0 -> 955 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/process-stop.pngbin0 -> 1272 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc12
-rw-r--r--examples/webenginewidgets/simplebrowser/data/simplebrowser.svg24
-rw-r--r--examples/webenginewidgets/simplebrowser/data/view-refresh.pngbin0 -> 1364 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.pngbin0 -> 10515 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.pngbin0 -> 70625 bytes
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel938
-rw-r--r--examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc263
-rw-r--r--examples/webenginewidgets/simplebrowser/main.cpp60
-rw-r--r--examples/webenginewidgets/simplebrowser/passworddialog.ui121
-rw-r--r--examples/webenginewidgets/simplebrowser/simplebrowser.pro33
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.cpp277
-rw-r--r--examples/webenginewidgets/simplebrowser/tabwidget.h95
-rw-r--r--examples/webenginewidgets/simplebrowser/urllineedit.cpp95
-rw-r--r--examples/webenginewidgets/simplebrowser/urllineedit.h70
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.cpp132
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.h61
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.cpp95
-rw-r--r--examples/webenginewidgets/simplebrowser/webpopupwindow.h71
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.cpp189
-rw-r--r--examples/webenginewidgets/simplebrowser/webview.h82
-rw-r--r--src/core/content_client_qt.cpp3
-rw-r--r--src/core/content_main_delegate_qt.cpp10
-rw-r--r--src/core/core_module.pro25
-rw-r--r--src/process/process.pro18
-rw-r--r--src/webengine/api/qquickwebenginecertificateerror.cpp15
-rw-r--r--src/webengine/doc/images/qtwebengine-architecture.pngbin11325 -> 8098 bytes
-rw-r--r--src/webengine/doc/images/qtwebengine-model.pngbin0 -> 8656 bytes
-rw-r--r--src/webengine/doc/images/qtwebenginewidgets-model.pngbin0 -> 9749 bytes
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf2
-rw-r--r--src/webengine/doc/src/qtwebengine-index.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-modules.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-overview.qdoc106
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc30
-rw-r--r--src/webengine/doc/src/webengineview.qdoc130
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h6
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp1
-rw-r--r--src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc13
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc50
-rw-r--r--src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc9
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp63
-rw-r--r--tools/qmake/mkspecs/features/default_pre.prf3
60 files changed, 3802 insertions, 163 deletions
diff --git a/.gitignore b/.gitignore
index ab40b145a..2a74d1302 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ examples/webenginewidgets/browser/browser
examples/webenginewidgets/browser/browser.app
examples/webenginewidgets/contentmanipulation/contentmanipulation
examples/webenginewidgets/contentmanipulation/contentmanipulation.app
+examples/webenginewidgets/simplebrowser/simplebrowser
tests/quicktestbrowser/quicktestbrowser
tests/**/tst_*
diff --git a/.qmake.conf b/.qmake.conf
index ccd743b86..3442ea6e1 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,5 +1,6 @@
QMAKEPATH += $$PWD/tools/qmake
load(qt_build_config)
CONFIG += qt_example_installs
+CONFIG += warning_clean
MODULE_VERSION = 5.7.0
diff --git a/dist/changes-5.6.0 b/dist/changes-5.6.0
index f6495942a..a4999f320 100644
--- a/dist/changes-5.6.0
+++ b/dist/changes-5.6.0
@@ -21,7 +21,7 @@ information about a particular change.
- Chromium Snapshot:
* The Chromium version has been updated to 45.0.2554.101.
- * In addition security fixes from Chromium 46, 47 and 48 have been merged.
+ * In addition security fixes from Chromium 46 - 49 have been merged.
- General:
* The WebEngineCore module now contains shared C++ API.
diff --git a/examples/examples.pro b/examples/examples.pro
index 342c2c311..0de2ec505 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -12,5 +12,6 @@ qtHaveModule(webenginewidgets) {
webenginewidgets/contentmanipulation \
webenginewidgets/cookiebrowser \
webenginewidgets/demobrowser \
- webenginewidgets/markdowneditor
+ webenginewidgets/markdowneditor \
+ webenginewidgets/simplebrowser \
}
diff --git a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
index 7909aaddd..3a9908ea6 100644
--- a/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
+++ b/examples/webenginewidgets/markdowneditor/doc/src/markdowneditor.qdoc
@@ -116,7 +116,8 @@
\printto connect
The constructor first calls \c setupUi to construct the widgets and menu
- actions according to the UI file. It then makes sure our custom
+ actions according to the UI file. The text editor font is set to one
+ with a fixed character width. It then makes sure our custom
\c PreviewPage is used by the QWebEngineView instance in \c{ui->preview}.
\printto ui->preview
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.cpp b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
index 34d436cc2..417858d8d 100644
--- a/examples/webenginewidgets/markdowneditor/mainwindow.cpp
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.cpp
@@ -54,6 +54,7 @@
#include <QFile>
#include <QFileDialog>
+#include <QFontDatabase>
#include <QMessageBox>
#include <QTextStream>
#include <QWebChannel>
@@ -63,6 +64,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow)
{
ui->setupUi(this);
+ ui->editor->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
PreviewPage *page = new PreviewPage(this);
ui->preview->setPage(page);
@@ -95,6 +97,19 @@ MainWindow::~MainWindow()
delete ui;
}
+void MainWindow::openFile(const QString &path)
+{
+ QFile f(path);
+ if (!f.open(QIODevice::ReadOnly)) {
+ QMessageBox::warning(this, windowTitle(),
+ tr("Could not open file %1: %2").arg(
+ QDir::toNativeSeparators(path), f.errorString()));
+ return;
+ }
+ m_filePath = path;
+ ui->editor->setPlainText(f.readAll());
+}
+
bool MainWindow::isModified() const
{
return ui->editor->document()->isModified();
@@ -128,15 +143,7 @@ void MainWindow::onFileOpen()
if (path.isEmpty())
return;
- QFile f(path);
- if (!f.open(QIODevice::ReadOnly)) {
- QMessageBox::warning(this, windowTitle(),
- tr("Could not open file %1: %2").arg(
- QDir::toNativeSeparators(path), f.errorString()));
- return;
- }
- m_filePath = path;
- ui->editor->setPlainText(f.readAll());
+ openFile(path);
}
void MainWindow::onFileSave()
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h
index 19b6cb036..ad0320373 100644
--- a/examples/webenginewidgets/markdowneditor/mainwindow.h
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.h
@@ -70,6 +70,8 @@ public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
+ void openFile(const QString &path);
+
private slots:
void onFileNew();
void onFileOpen();
diff --git a/examples/webenginewidgets/simplebrowser/browser.cpp b/examples/webenginewidgets/simplebrowser/browser.cpp
new file mode 100644
index 000000000..78b60b8f8
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browser.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 "browser.h"
+#include "browserwindow.h"
+#include "webview.h"
+#include <QAuthenticator>
+#include <QNetworkProxy>
+#include <QNetworkReply>
+
+Browser::Browser()
+{
+ // QTBUG-47967 , downloading favIcon support is coming in 5.7
+ QObject::connect(&WebView::networkAccessManager(), &QNetworkAccessManager::authenticationRequired,
+ [](QNetworkReply *, QAuthenticator *) {
+ qWarning("Authentication required for downloading favicon.");
+ });
+ QObject::connect(&WebView::networkAccessManager(), &QNetworkAccessManager::proxyAuthenticationRequired,
+ [](const QNetworkProxy &, QAuthenticator *) {
+ qWarning("Proxy authentication required for downloading favicon.");
+ });
+}
+
+Browser::~Browser()
+{
+ qDeleteAll(m_windows);
+ m_windows.clear();
+}
+
+Browser &Browser::instance()
+{
+ static Browser browser;
+ return browser;
+}
+
+QVector<BrowserWindow*> Browser::windows()
+{
+ return m_windows;
+}
+
+void Browser::addWindow(BrowserWindow *mainWindow)
+{
+ if (m_windows.contains(mainWindow))
+ return;
+ m_windows.prepend(mainWindow);
+ QObject::connect(mainWindow, &QObject::destroyed, [this, mainWindow]() {
+ m_windows.removeOne(mainWindow);
+ });
+ mainWindow->show();
+}
+
diff --git a/examples/webenginewidgets/simplebrowser/browser.h b/examples/webenginewidgets/simplebrowser/browser.h
new file mode 100644
index 000000000..0fdbd46a7
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browser.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef BROWSER_H
+#define BROWSER_H
+
+#include <QVector>
+
+class BrowserWindow;
+
+class Browser
+{
+public:
+ ~Browser();
+
+ QVector<BrowserWindow*> windows();
+ void addWindow(BrowserWindow* window);
+ static Browser &instance();
+
+private:
+ Browser();
+ QVector<BrowserWindow*> m_windows;
+};
+#endif // BROWSER_H
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
new file mode 100644
index 000000000..e7d5fd129
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+**
+** 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 "browser.h"
+#include "browserwindow.h"
+#include "tabwidget.h"
+#include "urllineedit.h"
+#include "webview.h"
+#include <QApplication>
+#include <QCloseEvent>
+#include <QDesktopWidget>
+#include <QFileDialog>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QProgressBar>
+#include <QStatusBar>
+#include <QToolBar>
+#include <QVBoxLayout>
+
+BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
+ : QMainWindow(parent, flags)
+ , m_tabWidget(new TabWidget(this))
+ , m_progressBar(new QProgressBar(this))
+ , m_historyBackAction(nullptr)
+ , m_historyForwardAction(nullptr)
+ , m_stopAction(nullptr)
+ , m_reloadAction(nullptr)
+ , m_stopReloadAction(nullptr)
+ , m_urlLineEdit(new UrlLineEdit(this))
+{
+ setToolButtonStyle(Qt::ToolButtonFollowStyle);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+
+ QToolBar *toolbar = createToolBar();
+ addToolBar(toolbar);
+ menuBar()->addMenu(createFileMenu(m_tabWidget));
+ menuBar()->addMenu(createViewMenu(toolbar));
+ menuBar()->addMenu(createWindowMenu(m_tabWidget));
+ menuBar()->addMenu(createHelpMenu());
+
+ QWidget *centralWidget = new QWidget(this);
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setSpacing(0);
+ layout->setMargin(0);
+ addToolBarBreak();
+
+ m_progressBar->setMaximumHeight(1);
+ m_progressBar->setTextVisible(false);
+ m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px } QProgressBar::chunk { background-color: red; }"));
+
+ layout->addWidget(m_progressBar);
+ layout->addWidget(m_tabWidget);
+ centralWidget->setLayout(layout);
+ setCentralWidget(centralWidget);
+
+ connect(m_tabWidget, &TabWidget::titleChanged, this, &BrowserWindow::handleWebViewTitleChanged);
+ connect(m_tabWidget, &TabWidget::linkHovered, [this](const QString& url) {
+ 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());
+ });
+
+ m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
+
+ handleWebViewTitleChanged(tr("Qt Simple Browser"));
+ m_tabWidget->createTab();
+}
+
+BrowserWindow::~BrowserWindow()
+{
+}
+
+QSize BrowserWindow::sizeHint() const
+{
+ QRect desktopRect = QApplication::desktop()->screenGeometry();
+ QSize size = desktopRect.size() * qreal(0.9);
+ return size;
+}
+
+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);
+ 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);
+ closeTabAction->setShortcuts(QKeySequence::Close);
+ closeTabAction->setIconVisibleInMenu(false);
+ connect(closeTabAction, &QAction::triggered, [tabWidget]() {
+ tabWidget->closeTab(tabWidget->currentIndex());
+ });
+ fileMenu->addAction(closeTabAction);
+
+ QAction *closeAction = new QAction(tr("&Quit"),this);
+ closeAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
+ connect(closeAction, &QAction::triggered, this, &QWidget::close);
+ fileMenu->addAction(closeAction);
+
+ connect(fileMenu, &QMenu::aboutToShow, [closeAction]() {
+ if (Browser::instance().windows().count() == 1)
+ closeAction->setText(tr("&Quit"));
+ else
+ closeAction->setText(tr("&Close Window"));
+ });
+ return fileMenu;
+}
+
+QMenu *BrowserWindow::createViewMenu(QToolBar *toolbar)
+{
+ QMenu *viewMenu = new QMenu(tr("&View"));
+ m_stopAction = viewMenu->addAction(tr("&Stop"));
+ QList<QKeySequence> shortcuts;
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Period));
+ shortcuts.append(Qt::Key_Escape);
+ m_stopAction->setShortcuts(shortcuts);
+ connect(m_stopAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Stop);
+ });
+
+ m_reloadAction = viewMenu->addAction(tr("Reload Page"));
+ m_reloadAction->setShortcuts(QKeySequence::Refresh);
+ connect(m_reloadAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Reload);
+ });
+
+ QAction *zoomIn = viewMenu->addAction(tr("Zoom &In"));
+ zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
+ connect(zoomIn, &QAction::triggered, [this]() {
+ if (currentTab())
+ currentTab()->setZoomFactor(currentTab()->zoomFactor() + 0.1);
+ });
+
+ QAction *zoomOut = viewMenu->addAction(tr("Zoom &Out"));
+ zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
+ connect(zoomOut, &QAction::triggered, [this]() {
+ if (currentTab())
+ currentTab()->setZoomFactor(currentTab()->zoomFactor() - 0.1);
+ });
+
+ QAction *resetZoom = viewMenu->addAction(tr("Reset &Zoom"));
+ resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
+ connect(resetZoom, &QAction::triggered, [this]() {
+ if (currentTab())
+ currentTab()->setZoomFactor(1.0);
+ });
+
+
+ viewMenu->addSeparator();
+ QAction *viewToolbarAction = new QAction(tr("Hide Toolbar"),this);
+ viewToolbarAction->setShortcut(tr("Ctrl+|"));
+ connect(viewToolbarAction, &QAction::triggered, [toolbar,viewToolbarAction]() {
+ if (toolbar->isVisible()) {
+ viewToolbarAction->setText(tr("Show Toolbar"));
+ toolbar->close();
+ } else {
+ viewToolbarAction->setText(tr("Hide Toolbar"));
+ toolbar->show();
+ }
+ });
+ viewMenu->addAction(viewToolbarAction);
+
+ QAction *viewStatusbarAction = new QAction(tr("Hide Status Bar"), this);
+ viewStatusbarAction->setShortcut(tr("Ctrl+/"));
+ connect(viewStatusbarAction, &QAction::triggered, [this, viewStatusbarAction]() {
+ if (statusBar()->isVisible()) {
+ viewStatusbarAction->setText(tr("Show Status Bar"));
+ statusBar()->close();
+ } else {
+ viewStatusbarAction->setText(tr("Hide Status Bar"));
+ statusBar()->show();
+ }
+ });
+ viewMenu->addAction(viewStatusbarAction);
+ return viewMenu;
+}
+
+QMenu *BrowserWindow::createWindowMenu(TabWidget *tabWidget)
+{
+ QMenu *menu = new QMenu(tr("&Window"));
+
+ QAction *nextTabAction = new QAction(tr("Show Next Tab"), this);
+ QList<QKeySequence> shortcuts;
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketRight));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less));
+ nextTabAction->setShortcuts(shortcuts);
+ connect(nextTabAction, &QAction::triggered, tabWidget, &TabWidget::nextTab);
+
+ QAction *previousTabAction = new QAction(tr("Show Previous Tab"), this);
+ shortcuts.clear();
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft));
+ shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater));
+ previousTabAction->setShortcuts(shortcuts);
+ connect(previousTabAction, &QAction::triggered, tabWidget, &TabWidget::previousTab);
+
+ connect(menu, &QMenu::aboutToShow, [this, menu, nextTabAction, previousTabAction]() {
+ menu->clear();
+ menu->addAction(nextTabAction);
+ menu->addAction(previousTabAction);
+ menu->addSeparator();
+
+ QVector<BrowserWindow*> windows = Browser::instance().windows();
+ int index(-1);
+ for (auto window : windows) {
+ QAction *action = menu->addAction(window->windowTitle(), this, &BrowserWindow::handleShowWindowTriggered);
+ action->setData(++index);
+ action->setCheckable(true);
+ if (window == this)
+ action->setChecked(true);
+ }
+ });
+ return menu;
+}
+
+QMenu *BrowserWindow::createHelpMenu()
+{
+ QMenu *helpMenu = new QMenu(tr("&Help"));
+ helpMenu->addAction(tr("About &Qt"), qApp, QApplication::aboutQt);
+ return helpMenu;
+}
+
+QToolBar *BrowserWindow::createToolBar()
+{
+ QToolBar *navigationBar = new QToolBar(tr("Navigation"));
+ navigationBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
+ navigationBar->toggleViewAction()->setEnabled(false);
+
+ m_historyBackAction = new QAction(this);
+ m_historyBackAction->setShortcuts(QKeySequence::Back);
+ m_historyBackAction->setIconVisibleInMenu(false);
+ m_historyBackAction->setIcon(QIcon(QStringLiteral(":go-previous.png")));
+ connect(m_historyBackAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Back);
+ });
+ navigationBar->addAction(m_historyBackAction);
+
+ m_historyForwardAction = new QAction(this);
+ m_historyForwardAction->setShortcuts(QKeySequence::Forward);
+ m_historyForwardAction->setIconVisibleInMenu(false);
+ m_historyForwardAction->setIcon(QIcon(QStringLiteral(":go-next.png")));
+ connect(m_historyForwardAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::Forward);
+ });
+ navigationBar->addAction(m_historyForwardAction);
+
+ m_stopReloadAction = new QAction(this);
+ connect(m_stopReloadAction, &QAction::triggered, [this]() {
+ m_tabWidget->triggerWebPageAction(QWebEnginePage::WebAction(m_stopReloadAction->data().toInt()));
+ });
+ navigationBar->addAction(m_stopReloadAction);
+ 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);
+}
+
+void BrowserWindow::handleWebViewUrlChanged(const QUrl &url)
+{
+ m_urlLineEdit->setUrl(url);
+ if (url.isEmpty())
+ m_urlLineEdit->setFocus();
+}
+
+void BrowserWindow::handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled)
+{
+ switch (action) {
+ case QWebEnginePage::Back:
+ m_historyBackAction->setEnabled(enabled);
+ break;
+ case QWebEnginePage::Forward:
+ m_historyForwardAction->setEnabled(enabled);
+ break;
+ case QWebEnginePage::Reload:
+ m_reloadAction->setEnabled(enabled);
+ break;
+ case QWebEnginePage::Stop:
+ m_stopAction->setEnabled(enabled);
+ break;
+ default:
+ qWarning("Unhandled webActionChanged singal");
+ }
+}
+
+void BrowserWindow::handleWebViewTitleChanged(const QString &title)
+{
+ if (title.isEmpty())
+ setWindowTitle(tr("Qt Simple Browser"));
+ else
+ setWindowTitle(tr("%1 - Qt Simple Browser").arg(title));
+}
+
+void BrowserWindow::handleNewWindowTriggered()
+{
+ BrowserWindow *window = new BrowserWindow();
+ Browser::instance().addWindow(window);
+ window->loadHomePage();
+}
+
+void BrowserWindow::handleFileOpenTriggered()
+{
+ QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(),
+ tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)"));
+ if (file.isEmpty())
+ return;
+ loadPage(file);
+}
+
+void BrowserWindow::closeEvent(QCloseEvent *event)
+{
+ if (m_tabWidget->count() > 1) {
+ int ret = QMessageBox::warning(this, tr("Confirm close"),
+ tr("Are you sure you want to close the window ?\n"
+ "There are %1 tabs open.").arg(m_tabWidget->count()),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+ if (ret == QMessageBox::No) {
+ event->ignore();
+ return;
+ }
+ }
+ event->accept();
+ 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;
+}
+
+WebView *BrowserWindow::currentTab() const
+{
+ return m_tabWidget->currentWebView();
+}
+
+void BrowserWindow::handleWebViewLoadProgress(int progress)
+{
+ static QIcon stopIcon(QStringLiteral(":process-stop.png"));
+ static QIcon reloadIcon(QStringLiteral(":view-refresh.png"));
+
+ if (progress < 100 && progress > 0) {
+ m_stopReloadAction->setData(QWebEnginePage::Stop);
+ m_stopReloadAction->setIcon(stopIcon);
+ m_stopReloadAction->setToolTip(tr("Stop loading the current page"));
+ } else {
+ m_stopReloadAction->setData(QWebEnginePage::Reload);
+ m_stopReloadAction->setIcon(reloadIcon);
+ m_stopReloadAction->setToolTip(tr("Reload the current page"));
+ }
+ 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();
+ windows.at(offset)->activateWindow();
+ windows.at(offset)->currentTab()->setFocus();
+ }
+}
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.h b/examples/webenginewidgets/simplebrowser/browserwindow.h
new file mode 100644
index 000000000..c947bed1d
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef BROWSERWINDOW_H
+#define BROWSERWINDOW_H
+
+#include <QMainWindow>
+#include <QWebEnginePage>
+
+QT_BEGIN_NAMESPACE
+class QProgressBar;
+QT_END_NAMESPACE
+
+class TabWidget;
+class UrlLineEdit;
+class WebView;
+
+class BrowserWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ BrowserWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
+ ~BrowserWindow();
+ QSize sizeHint() const override;
+ TabWidget *tabWidget() const;
+ WebView *currentTab() const;
+
+ void loadPage(const QString &url);
+ void loadPage(const QUrl &url);
+ void loadHomePage();
+
+protected:
+ void closeEvent(QCloseEvent *event) override;
+
+private slots:
+ void handleNewWindowTriggered();
+ void handleFileOpenTriggered();
+ 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:
+ QMenu *createFileMenu(TabWidget *tabWidget);
+ QMenu *createViewMenu(QToolBar *toolBar);
+ QMenu *createWindowMenu(TabWidget *tabWidget);
+ QMenu *createHelpMenu();
+ QToolBar *createToolBar();
+
+private:
+ TabWidget *m_tabWidget;
+ QProgressBar *m_progressBar;
+ QAction *m_historyBackAction;
+ QAction *m_historyForwardAction;
+ QAction *m_stopAction;
+ QAction *m_reloadAction;
+ QAction *m_stopReloadAction;
+ UrlLineEdit *m_urlLineEdit;
+};
+
+#endif // BROWSERWINDOW_H
diff --git a/examples/webenginewidgets/simplebrowser/certificateerrordialog.ui b/examples/webenginewidgets/simplebrowser/certificateerrordialog.ui
new file mode 100644
index 000000000..a97f25b6e
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/certificateerrordialog.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CertificateErrorDialog</class>
+ <widget class="QDialog" name="CertificateErrorDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>370</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>20</number>
+ </property>
+ <property name="rightMargin">
+ <number>20</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="m_iconLabel">
+ <property name="text">
+ <string>Icon</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_errorLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Error</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_infoLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>If you wish so, you may continue with an unverified certificate. Accepting an unverified certificate mean you may not be connected with the host you tried to connect to.
+
+Do you wish to override the security check and continue ? </string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::No|QDialogButtonBox::Yes</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>CertificateErrorDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>CertificateErrorDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/data/addtab.png b/examples/webenginewidgets/simplebrowser/data/addtab.png
new file mode 100644
index 000000000..20928fb40
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/addtab.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/closetab.png b/examples/webenginewidgets/simplebrowser/data/closetab.png
new file mode 100644
index 000000000..ab9d669ee
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/closetab.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/defaulticon.png b/examples/webenginewidgets/simplebrowser/data/defaulticon.png
new file mode 100644
index 000000000..01a0920c9
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/defaulticon.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/data/go-next.png b/examples/webenginewidgets/simplebrowser/data/go-next.png
new file mode 100644
index 000000000..6f3f65d33
--- /dev/null
+++ 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
new file mode 100644
index 000000000..93be3d1ee
--- /dev/null
+++ 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
new file mode 100644
index 000000000..b68290bf1
--- /dev/null
+++ 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
new file mode 100644
index 000000000..5795063ca
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc
@@ -0,0 +1,12 @@
+<RCC>
+ <qresource prefix="/">
+ <file>addtab.png</file>
+ <file>defaulticon.png</file>
+ <file>closetab.png</file>
+ <file>go-next.png</file>
+ <file>go-previous.png</file>
+ <file>process-stop.png</file>
+ <file>simplebrowser.svg</file>
+ <file>view-refresh.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg b/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg
new file mode 100644
index 000000000..9f39deb66
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg
@@ -0,0 +1,24 @@
+<?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/view-refresh.png b/examples/webenginewidgets/simplebrowser/data/view-refresh.png
new file mode 100644
index 000000000..cab4d02c7
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/data/view-refresh.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.png b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.png
new file mode 100644
index 000000000..2a1abce50
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser-model.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png
new file mode 100644
index 000000000..777309075
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png
Binary files differ
diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel
new file mode 100644
index 000000000..ce6f8ea2a
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser-model.qmodel
@@ -0,0 +1,938 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<qmt>
+ <project>
+ <uid>{fa2cc127-337e-4194-b272-fc8bb6c1e3b0}</uid>
+ <root-package>
+ <instance>
+ <MPackage>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{4ffa8932-4330-4845-af33-c26f0fcdecd7}</uid>
+ </MElement>
+ </base-MElement>
+ <name>simplebrowser-model</name>
+ <children>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{de670101-4064-4a81-bdf0-885b4cb09526}</uid>
+ <target>
+ <instance type="MCanvasDiagram">
+ <MCanvasDiagram>
+ <base-MDiagram>
+ <MDiagram>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{de670101-4064-4a81-bdf0-885b4cb09526}</uid>
+ </MElement>
+ </base-MElement>
+ <name>simplebrowser-model</name>
+ </MObject>
+ </base-MObject>
+ <elements>
+ <qlist>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</object>
+ <name>BrowserWindow</name>
+ <pos>x:190;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{8d3e6a00-ffa6-497a-a5a2-f1ba13deee76}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{72a2b731-3aad-430f-a76c-f43dd9b36462}</object>
+ <name>Browser</name>
+ <pos>x:5;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{5ab59ef4-3509-4ea3-900e-20d1cea16af1}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{e878ee71-b5d1-4943-b081-466851b0f721}</object>
+ <a>{8d3e6a00-ffa6-497a-a5a2-f1ba13deee76}</a>
+ <b>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1..*</cradinality>
+ <kind>2</kind>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{1ab2b778-127b-4661-ba2d-8f329f44d859}</object>
+ <name>TabWidget</name>
+ <pos>x:360;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{cc9dee75-9f9c-4599-acf8-35e14f75cd78}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{ee3a86b4-773d-4ea5-81c1-552501061629}</object>
+ <a>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</a>
+ <b>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</object>
+ <name>WebView</name>
+ <pos>x:550;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{1e82e3ce-c835-4b7a-99ec-ae40e07f0185}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{97fd8235-200e-4448-b173-51add1df8edc}</object>
+ <a>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</a>
+ <b>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1..*</cradinality>
+ <kind>2</kind>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{ed0a94cd-0abd-49f6-ac98-3da13fef9dff}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</object>
+ <name>WebPage</name>
+ <pos>x:720;y:100</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DAssociation">
+ <DAssociation>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{06ce5b46-b043-45b8-8718-0054d7baf939}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{772227ff-d0df-4ecd-97ea-89d1bd10a96f}</object>
+ <a>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</a>
+ <b>{ed0a94cd-0abd-49f6-ac98-3da13fef9dff}</b>
+ </DRelation>
+ </base-DRelation>
+ <a>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </a>
+ <b>
+ <DAssociationEnd>
+ <cradinality>1</cradinality>
+ </DAssociationEnd>
+ </b>
+ </DAssociation>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{cb588414-35d6-482f-a9df-2dddb7d72af1}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</object>
+ <name>QWebEngineView</name>
+ <pos>x:550;y:0</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{c9755d3b-0ed4-4821-95d3-64f4f4cdb458}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{6659de40-605d-4744-8654-73ae959dcb8a}</object>
+ <name>QWebEnginePage</name>
+ <pos>x:720;y:0</pos>
+ <rect>x:-50;y:-30;w:100;h:60</rect>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{6bdcd7e9-fa78-417d-9024-47796596e18d}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{1176aee6-be27-4b21-be22-33bca908a71e}</object>
+ <a>{9d909ab7-02a8-4582-89cd-b31bb794bc40}</a>
+ <b>{cb588414-35d6-482f-a9df-2dddb7d72af1}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{30abce68-7fa1-4b0c-8620-9f96c7392be7}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{20788ccc-cab0-406b-8cf4-d8062570085e}</object>
+ <a>{ed0a94cd-0abd-49f6-ac98-3da13fef9dff}</a>
+ <b>{c9755d3b-0ed4-4821-95d3-64f4f4cdb458}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{a372397b-316a-48c0-b99f-724372413a64}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</object>
+ <name>QTabWidget</name>
+ <pos>x:360;y:0</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{dce2499c-fdef-40e3-ba77-29b94f8beb1b}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{66fd2699-e4ea-4312-990a-7488c75fc850}</object>
+ <a>{487d395c-3f8b-422c-9568-d70a5d50a9d4}</a>
+ <b>{a372397b-316a-48c0-b99f-724372413a64}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ <item>
+ <instance type="DClass">
+ <DClass>
+ <base-DObject>
+ <DObject>
+ <base-DElement>
+ <DElement>
+ <uid>{35e8a91e-8192-4e17-b6c7-e44b3ba3a138}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</object>
+ <name>QMainWindow</name>
+ <pos>x:190;y:0</pos>
+ <rect>x:-55;y:-30;w:110;h:60</rect>
+ <auto-sized>false</auto-sized>
+ <visual-role>0</visual-role>
+ </DObject>
+ </base-DObject>
+ </DClass>
+ </instance>
+ </item>
+ <item>
+ <instance type="DInheritance">
+ <DInheritance>
+ <base-DRelation>
+ <DRelation>
+ <base-DElement>
+ <DElement>
+ <uid>{7dd17b0c-4256-463f-8852-c4faf0614997}</uid>
+ </DElement>
+ </base-DElement>
+ <object>{9f29593e-b0b5-4488-ae5d-2378857535a0}</object>
+ <a>{b7b131f9-5e56-484a-ba8b-c7a5fc34fb7b}</a>
+ <b>{35e8a91e-8192-4e17-b6c7-e44b3ba3a138}</b>
+ </DRelation>
+ </base-DRelation>
+ </DInheritance>
+ </instance>
+ </item>
+ </qlist>
+ </elements>
+ <last-modified>1456935246527</last-modified>
+ </MDiagram>
+ </base-MDiagram>
+ </MCanvasDiagram>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{72a2b731-3aad-430f-a76c-f43dd9b36462}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{72a2b731-3aad-430f-a76c-f43dd9b36462}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>Browser</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{736a9cc9-35f1-47c1-bdc4-c3033d14a33d}</uid>
+ <target>
+ <instance type="MDependency">
+ <MDependency>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{736a9cc9-35f1-47c1-bdc4-c3033d14a33d}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{72a2b731-3aad-430f-a76c-f43dd9b36462}</a>
+ <b>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</b>
+ </MRelation>
+ </base-MRelation>
+ </MDependency>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{e878ee71-b5d1-4943-b081-466851b0f721}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{e878ee71-b5d1-4943-b081-466851b0f721}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{72a2b731-3aad-430f-a76c-f43dd9b36462}</a>
+ <b>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1..*</cardinality>
+ <kind>2</kind>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>BrowserWindow</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{ee3a86b4-773d-4ea5-81c1-552501061629}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{ee3a86b4-773d-4ea5-81c1-552501061629}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</a>
+ <b>{1ab2b778-127b-4661-ba2d-8f329f44d859}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{9f29593e-b0b5-4488-ae5d-2378857535a0}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{9f29593e-b0b5-4488-ae5d-2378857535a0}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{ee93b67f-4caf-4d92-9303-f6c2582bf1b9}</a>
+ <b>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{1ab2b778-127b-4661-ba2d-8f329f44d859}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{1ab2b778-127b-4661-ba2d-8f329f44d859}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>TabWidget</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{97fd8235-200e-4448-b173-51add1df8edc}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{97fd8235-200e-4448-b173-51add1df8edc}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{1ab2b778-127b-4661-ba2d-8f329f44d859}</a>
+ <b>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1..*</cardinality>
+ <kind>2</kind>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{66fd2699-e4ea-4312-990a-7488c75fc850}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{66fd2699-e4ea-4312-990a-7488c75fc850}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{1ab2b778-127b-4661-ba2d-8f329f44d859}</a>
+ <b>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>WebPage</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{20788ccc-cab0-406b-8cf4-d8062570085e}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{20788ccc-cab0-406b-8cf4-d8062570085e}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</a>
+ <b>{6659de40-605d-4744-8654-73ae959dcb8a}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</uid>
+ <flags>1</flags>
+ </MElement>
+ </base-MElement>
+ <name>WebView</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{772227ff-d0df-4ecd-97ea-89d1bd10a96f}</uid>
+ <target>
+ <instance type="MAssociation">
+ <MAssociation>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{772227ff-d0df-4ecd-97ea-89d1bd10a96f}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</a>
+ <b>{320f3a48-12de-4bcb-b7f5-47b12c77dbee}</b>
+ </MRelation>
+ </base-MRelation>
+ <a>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </a>
+ <b>
+ <MAssociationEnd>
+ <cardinality>1</cardinality>
+ </MAssociationEnd>
+ </b>
+ </MAssociation>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{1176aee6-be27-4b21-be22-33bca908a71e}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{1176aee6-be27-4b21-be22-33bca908a71e}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</a>
+ <b>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QWebEngineView</name>
+ <relations>
+ <handles>
+ <handles>
+ <qlist>
+ <item>
+ <handle>
+ <uid>{5124d95d-73fb-4d70-aa89-1135f2202c2f}</uid>
+ <target>
+ <instance type="MInheritance">
+ <MInheritance>
+ <base-MRelation>
+ <MRelation>
+ <base-MElement>
+ <MElement>
+ <uid>{5124d95d-73fb-4d70-aa89-1135f2202c2f}</uid>
+ </MElement>
+ </base-MElement>
+ <a>{9b91aa7b-0fa3-4c78-9e8d-e1bfdfce9f7f}</a>
+ <b>{b8a281e2-4ee3-42cd-bb3d-d075a54ad358}</b>
+ </MRelation>
+ </base-MRelation>
+ </MInheritance>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </relations>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{6659de40-605d-4744-8654-73ae959dcb8a}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{6659de40-605d-4744-8654-73ae959dcb8a}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QWebEnginePage</name>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{32e677d2-4bfb-4f5d-93dc-67fdb1a0c8a1}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QTabWidget</name>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ <item>
+ <handle>
+ <uid>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</uid>
+ <target>
+ <instance type="MClass">
+ <MClass>
+ <base-MObject>
+ <MObject>
+ <base-MElement>
+ <MElement>
+ <uid>{988c1b8e-1e9a-4d03-b9b4-75ba5dcac6d7}</uid>
+ </MElement>
+ </base-MElement>
+ <name>QMainWindow</name>
+ </MObject>
+ </base-MObject>
+ </MClass>
+ </instance>
+ </target>
+ </handle>
+ </item>
+ </qlist>
+ </handles>
+ </handles>
+ </children>
+ </MObject>
+ </base-MObject>
+ </MPackage>
+ </instance>
+ </root-package>
+ </project>
+</qmt>
diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
new file mode 100644
index 000000000..b8df9b02a
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example webenginewidgets/simplebrowser
+ \title WebEngine Widgets Simple Browser Example
+ \ingroup webengine-widgetexamples
+ \brief A simple browser based on Qt WebEngine Widgets
+
+ \image simplebrowser.png
+
+ \e {Simple Browser} demonstrates how to use the
+ \l{Qt WebEngine Widgets C++ Classes}{Qt WebEngine C++ classes} to develop a
+ small Web browser application that contains the following elements:
+
+ \list
+ \li Menu bar for opening stored pages and managing windows and tabs.
+ \li Navigation bar for entering a URL and for moving backward and
+ forward in the web page browsing history.
+ \li Multi-tab area for displaying web content within tabs.
+ \li Status bar for displaying hovered links.
+ \endlist
+
+ The web content can be opened in new tabs or separate windows. HTTP and
+ proxy authentication can be used for accessing web pages.
+
+ \include examples-run.qdocinc
+
+ \section1 Class Hierarchy
+
+ We start with sketching a diagram of the 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{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
+ browser tabs.
+ \li \c{WebView} is a \l QWebEngineView, provides a view for \c{WebPage},
+ and is added as a tab in \c{TabWidget}.
+ \li \c{WebPage} is a \l QWebEnginePage that represents website content.
+ \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.
+
+ 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,
+ we open the \l{Qt Homepage}:
+
+ \quotefromfile webenginewidgets/simplebrowser/main.cpp
+ \skipto main
+ \printuntil }
+
+ \section1 Creating Tabs
+
+ The \c BrowserWindow constructor initializes all the necessary user interface
+ related objects. The \c centralWidget of \c BrowserWindow contains an instance of
+ \c TabWidget. The \c TabWidget contains one or several \c WebView instances as tabs,
+ and delegates it's signals and slots to the currently selected one:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.h
+ \skipto TabWidget :
+ \printuntil {
+ \dots
+ \skipto signals
+ \printuntil triggerWebPageAction
+ \skipto }
+ \dots
+ \printline };
+
+ Each tab contains an instance of \c WebView:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp
+ \skipto TabWidget::createTab(
+ \printuntil }
+
+ In \c TabWidget::setupView(), we make sure that the \c TabWidget always forwards
+ the signals of the currently selected \c WebView:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp
+ \skipto TabWidget::setupView
+ \printuntil emit loadProgress
+ \skipto closeTab
+ \skipto });
+ \printline }
+ \dots
+ \printline }
+
+ \section1 Implementing WebView Functionality
+
+ The \c WebView is derived from QWebEngineView to support the following
+ functionality:
+
+ \list
+ \li Downloading favicons
+ \li Displaying error messages in case \c renderProcess dies
+ \li Handling \c createWindow requests
+ \li Adding custom menu items to context menus
+ \endlist
+
+ First, we create the WebView with the necessary methods and signals:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.h
+ \skipto WebView :
+ \printuntil WebView(
+ \dots
+ \skipto protected:
+ \printuntil handleIconLoaded
+ \skipto }
+ \dots
+ \printline };
+
+ \section2 Downloading Favicons
+
+ To download a favicon, we use QNetworkAccessManager and create a
+ QNetworkRequest every time the URL specified by
+ QWebEngineView::iconUrlChanged is emitted:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto WebView::handleIconUrlChanged(
+ \printuntil }
+
+ \section2 Displaying Error Messages
+
+ If the render process is terminated, we display a QMessageBox with an error
+ code, and then we reload the page:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto WebView::WebView(QWidget *parent)
+ \printuntil {
+ \skipto renderProcessTerminated
+ \dots
+ \printuntil QTimer
+ \printline });
+ \printline }
+
+ \section2 Managing WebWindows
+
+ The loaded page might want to create windows of the type
+ QWebEnginePage::WebWindowType, for example, when a JavaScript program
+ requests to open a document in a new window or dialog.
+ This is handled by overriding \c QWebView::createWindow():
+
+ \skipto WebView::createWindow(
+ \printuntil return nullptr;
+ \printuntil }
+
+ In case of \c QWebEnginePage::WebDialog, we create an instance of a custom \c WebPopupWindow class:
+
+ \quotefromfile webenginewidgets/simplebrowser/webpopupwindow.h
+ \skipto class WebPopupWindow
+ \printuntil };
+
+ \section2 Adding Context Menu Items
+
+ We add menu items to the context menu, so that users can right-click a link
+ to have it opened in the same tab, a new window, or a new tab. We override
+ QWebEngineView::contextMenuEvent and use
+ QWebEnginePage::createStandardContextMenu to create a default QMenu with a
+ default list of QWebEnginePage::WebAction actions.
+
+ The default name for QWebEnginePage::OpenLinkInThisWindow action is
+ \uicontrol Follow. For clarity, we rename it
+ \uicontrol {Open Link in This Tab}. Also, we add the actions for opening
+ links in a separate window or in a new tab:
+
+ \quotefromfile webenginewidgets/simplebrowser/webview.cpp
+ \skipto WebView::contextMenuEvent(
+ \printuntil menu->popup
+ \printline }
+
+ \section1 Implementing WebPage Functionality
+
+ As mentioned earlier, each \c WebView contains a \c WebPage instance that
+ was created by using QWebEngineProfile::defaultProfile().
+
+ We implement \c WebPage as a subclass of QWebEnginePage to enable HTTP,
+ proxy authentication, and ignoring SSL certificate errors when accessing web
+ pages:
+
+ \quotefromfile webenginewidgets/simplebrowser/webpage.h
+ \skipto WebPage :
+ \printuntil }
+
+ In all the cases above, we display the appropriate dialog to the user. In
+ case of authentication, we need to set the correct credential values on the
+ QAuthenticator object:
+
+ \quotefromfile webenginewidgets/simplebrowser/webpage.cpp
+ \skipto WebPage::handleAuthenticationRequired(
+ \printuntil }
+ \printuntil }
+ \printline }
+
+ The \c handleProxyAuthenticationRequired signal handler implements the very same
+ steps for the authentication of HTTP proxies.
+
+ In case of SSL errors, we just need to return a boolean value indicating
+ whether the certificate should be ignored.
+
+ \quotefromfile webenginewidgets/simplebrowser/webpage.cpp
+ \skipto WebPage::certificateError(
+ \printuntil }
+ \printuntil }
+
+ \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:
+
+ \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 }
+
+ The call is forwarded to the currently selected tab:
+
+ \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp
+ \skipto TabWidget::setUrl(
+ \printuntil }
+ \printuntil }
+
+ 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.
+*/
diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp
new file mode 100644
index 000000000..761403fb5
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/main.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 "browser.h"
+#include "browserwindow.h"
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ app.setWindowIcon(QIcon(QLatin1String(":simplebrowser.svg")));
+
+ BrowserWindow *window = new BrowserWindow();
+ Browser::instance().addWindow(window);
+
+ QStringList args = QCoreApplication::arguments();
+ if (args.count() > 1)
+ window->loadPage(args.last());
+ else
+ window->loadHomePage();
+
+ return app.exec();
+}
diff --git a/examples/webenginewidgets/simplebrowser/passworddialog.ui b/examples/webenginewidgets/simplebrowser/passworddialog.ui
new file mode 100644
index 000000000..bbf5004f5
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/passworddialog.ui
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PasswordDialog</class>
+ <widget class="QDialog" name="PasswordDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>399</width>
+ <height>148</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Authentication Required</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" columnstretch="0,0" columnminimumwidth="0,0">
+ <item row="0" column="0">
+ <widget class="QLabel" name="m_iconLabel">
+ <property name="text">
+ <string>Icon</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="m_infoLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Info</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="userLabel">
+ <property name="text">
+ <string>Username:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="m_userNameLineEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="passwordLabel">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="m_passwordLineEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ <zorder>userLabel</zorder>
+ <zorder>m_userNameLineEdit</zorder>
+ <zorder>passwordLabel</zorder>
+ <zorder>m_passwordLineEdit</zorder>
+ <zorder>buttonBox</zorder>
+ <zorder>m_iconLabel</zorder>
+ <zorder>m_infoLabel</zorder>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>PasswordDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PasswordDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/examples/webenginewidgets/simplebrowser/simplebrowser.pro b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
new file mode 100644
index 000000000..ad8a9a2bd
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/simplebrowser.pro
@@ -0,0 +1,33 @@
+TEMPLATE = app
+TARGET = simplebrowser
+QT += webenginewidgets network
+CONFIG += c++11
+
+HEADERS += \
+ browser.h \
+ browserwindow.h \
+ tabwidget.h \
+ urllineedit.h \
+ webview.h \
+ webpage.h \
+ webpopupwindow.h
+
+SOURCES += \
+ browser.cpp \
+ browserwindow.cpp \
+ main.cpp \
+ tabwidget.cpp \
+ urllineedit.cpp \
+ webview.cpp \
+ webpage.cpp \
+ webpopupwindow.cpp
+
+FORMS += \
+ certificateerrordialog.ui \
+ passworddialog.ui
+
+RESOURCES += data/simplebrowser.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/simplebrowser
+INSTALLS += target
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
new file mode 100644
index 000000000..d9e0dea1b
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** 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 "tabwidget.h"
+#include "webpage.h"
+#include "webview.h"
+#include <QMenu>
+#include <QTabBar>
+#include <QWebEngineProfile>
+
+TabWidget::TabWidget(QWidget *parent)
+ : QTabWidget(parent)
+{
+ QTabBar *tabBar = this->tabBar();
+ tabBar->setTabsClosable(true);
+ tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
+ tabBar->setMovable(true);
+ tabBar->setContextMenuPolicy(Qt::CustomContextMenu);
+ 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();
+ });
+
+ setDocumentMode(true);
+ setElideMode(Qt::ElideRight);
+
+ connect(this, &QTabWidget::currentChanged, this, &TabWidget::handleCurrentChanged);
+}
+
+TabWidget::~TabWidget()
+{
+}
+
+void TabWidget::handleCurrentChanged(int index)
+{
+ if (index != -1) {
+ WebView *view = webView(index);
+ if (!view->url().isEmpty())
+ view->setFocus();
+ emit titleChanged(view->title());
+ emit loadProgress(view->loadProgress());
+ emit urlChanged(view->url());
+ emit iconChanged(view->icon());
+ emit webActionEnabledChanged(QWebEnginePage::Back, view->isWebActionEnabled(QWebEnginePage::Back));
+ emit webActionEnabledChanged(QWebEnginePage::Forward, view->isWebActionEnabled(QWebEnginePage::Forward));
+ emit webActionEnabledChanged(QWebEnginePage::Stop, view->isWebActionEnabled(QWebEnginePage::Stop));
+ emit webActionEnabledChanged(QWebEnginePage::Reload,view->isWebActionEnabled(QWebEnginePage::Reload));
+ } else {
+ emit titleChanged(QString());
+ emit loadProgress(0);
+ emit urlChanged(QUrl());
+ emit iconChanged(QIcon());
+ emit webActionEnabledChanged(QWebEnginePage::Back, false);
+ emit webActionEnabledChanged(QWebEnginePage::Forward, false);
+ emit webActionEnabledChanged(QWebEnginePage::Stop, false);
+ emit webActionEnabledChanged(QWebEnginePage::Reload, true);
+ }
+}
+
+void TabWidget::handleContextMenuRequested(const QPoint &pos)
+{
+ QMenu menu;
+ menu.addAction(tr("New &Tab"), this, &TabWidget::createTab, QKeySequence::AddTab);
+ int index = tabBar()->tabAt(pos);
+ if (index != -1) {
+ QAction *action = menu.addAction(tr("Clone Tab"));
+ connect(action, &QAction::triggered, this, [this,index]() {
+ cloneTab(index);
+ });
+ menu.addSeparator();
+ action = menu.addAction(tr("&Close Tab"));
+ action->setShortcut(QKeySequence::Close);
+ connect(action, &QAction::triggered, this, [this,index]() {
+ closeTab(index);
+ });
+ action = menu.addAction(tr("Close &Other Tabs"));
+ connect(action, &QAction::triggered, this, [this,index]() {
+ closeOtherTabs(index);
+ });
+ menu.addSeparator();
+ action = menu.addAction(tr("Reload Tab"));
+ action->setShortcut(QKeySequence::Refresh);
+ connect(action, &QAction::triggered, this, [this,index]() {
+ reloadTab(index);
+ });
+ } else {
+ menu.addSeparator();
+ }
+ menu.addAction(tr("Reload All Tabs"), this, &TabWidget::reloadAllTabs);
+ menu.exec(QCursor::pos());
+}
+
+WebView *TabWidget::currentWebView() const
+{
+ return webView(currentIndex());
+}
+
+WebView *TabWidget::webView(int index) const
+{
+ return qobject_cast<WebView*>(widget(index));
+}
+
+void TabWidget::setupView(WebView *webView)
+{
+ QWebEnginePage *webPage = webView->page();
+
+ connect(webView, &QWebEngineView::titleChanged, [this, webView](const QString &title) {
+ int index = indexOf(webView);
+ if (index != -1)
+ setTabText(index, title);
+ if (currentIndex() == index)
+ emit titleChanged(title);
+ });
+ connect(webView, &QWebEngineView::urlChanged, [this, webView](const QUrl &url) {
+ int index = indexOf(webView);
+ if (index != -1)
+ tabBar()->setTabData(index, url);
+ if (currentIndex() == index)
+ emit urlChanged(url);
+ });
+ connect(webView, &QWebEngineView::loadProgress, [this, webView](int progress) {
+ if (currentIndex() == indexOf(webView))
+ emit loadProgress(progress);
+ });
+ connect(webPage, &QWebEnginePage::linkHovered, [this, webView](const QString &url) {
+ if (currentIndex() == indexOf(webView))
+ emit linkHovered(url);
+ });
+ connect(webView, &WebView::iconChanged, [this, webView](const QIcon& icon) {
+ int index = indexOf(webView);
+ if (index != -1)
+ setTabIcon(index, icon);
+ if (currentIndex() == index)
+ emit iconChanged(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(":loading.gif"));
+ setTabIcon(index, icon);
+ }
+ });
+ connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() {
+ int index = indexOf(webView);
+ if (index >= 0)
+ closeTab(index);
+ });
+}
+
+WebView *TabWidget::createTab(bool makeCurrent)
+{
+ WebView *webView = new WebView;
+ WebPage *webPage = new WebPage(QWebEngineProfile::defaultProfile(), webView);
+ webView->setPage(webPage);
+ setupView(webView);
+ addTab(webView, tr("(Untitled)"));
+ if (makeCurrent)
+ setCurrentWidget(webView);
+ return webView;
+}
+
+void TabWidget::reloadAllTabs()
+{
+ for (int i = 0; i < count(); ++i)
+ webView(i)->reload();
+}
+
+void TabWidget::closeOtherTabs(int index)
+{
+ for (int i = count() - 1; i > index; --i)
+ closeTab(i);
+ for (int i = index - 1; i >= 0; --i)
+ closeTab(i);
+}
+
+void TabWidget::closeTab(int index)
+{
+ if (WebView *view = webView(index)) {
+ bool hasFocus = view->hasFocus();
+ removeTab(index);
+ if (hasFocus && count() > 0)
+ currentWebView()->setFocus();
+ if (count() == 0)
+ createTab();
+ view->deleteLater();
+ }
+}
+
+void TabWidget::cloneTab(int index)
+{
+ if (WebView *view = webView(index)) {
+ WebView *tab = createTab(false);
+ tab->setUrl(view->url());
+ }
+}
+
+void TabWidget::setUrl(const QUrl &url)
+{
+ if (WebView *view = currentWebView()) {
+ view->setUrl(url);
+ view->setFocus();
+ }
+}
+
+void TabWidget::triggerWebPageAction(QWebEnginePage::WebAction action)
+{
+ if (WebView *webView = currentWebView()) {
+ webView->triggerPageAction(action);
+ webView->setFocus();
+ }
+}
+
+void TabWidget::nextTab()
+{
+ int next = currentIndex() + 1;
+ if (next == count())
+ next = 0;
+ setCurrentIndex(next);
+}
+
+void TabWidget::previousTab()
+{
+ int next = currentIndex() - 1;
+ if (next < 0)
+ next = count() - 1;
+ setCurrentIndex(next);
+}
+
+void TabWidget::reloadTab(int index)
+{
+ if (WebView *view = webView(index))
+ view->reload();
+}
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.h b/examples/webenginewidgets/simplebrowser/tabwidget.h
new file mode 100644
index 000000000..830effa4e
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/tabwidget.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef TABWIDGET_H
+#define TABWIDGET_H
+
+#include <QTabWidget>
+#include <QWebEnginePage>
+
+QT_BEGIN_NAMESPACE
+class QUrl;
+QT_END_NAMESPACE
+
+class WebView;
+
+class TabWidget : public QTabWidget
+{
+ Q_OBJECT
+
+public:
+ TabWidget(QWidget *parent = nullptr);
+ ~TabWidget();
+
+ WebView *currentWebView() const;
+
+signals:
+ // current tab/page signals
+ void linkHovered(const QString &link);
+ void loadProgress(int progress);
+ void titleChanged(const QString &title);
+ void urlChanged(const QUrl &url);
+ void iconChanged(const QIcon &icon);
+ void webActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled);
+
+public slots:
+ // current tab/page slots
+ void setUrl(const QUrl &url);
+ void triggerWebPageAction(QWebEnginePage::WebAction action);
+
+ WebView *createTab(bool makeCurrent = true);
+ void closeTab(int index);
+ void nextTab();
+ void previousTab();
+
+private slots:
+ void handleCurrentChanged(int index);
+ void handleContextMenuRequested(const QPoint &pos);
+ void cloneTab(int index);
+ void closeOtherTabs(int index);
+ void reloadAllTabs();
+ void reloadTab(int index);
+
+private:
+ WebView *webView(int index) const;
+ void setupView(WebView *webView);
+};
+
+#endif // TABWIDGET_H
diff --git a/examples/webenginewidgets/simplebrowser/urllineedit.cpp b/examples/webenginewidgets/simplebrowser/urllineedit.cpp
new file mode 100644
index 000000000..7e67b635a
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/urllineedit.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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/urllineedit.h b/examples/webenginewidgets/simplebrowser/urllineedit.h
new file mode 100644
index 000000000..a01eb0e66
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/urllineedit.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef URLLINEEDIT_H
+#define URLLINEEDIT_H
+
+#include <QLineEdit>
+
+QT_BEGIN_NAMESPACE
+class QToolButton;
+QT_END_NAMESPACE
+
+class UrlLineEdit : public QLineEdit
+{
+ Q_OBJECT
+
+public:
+ UrlLineEdit(QWidget *parent = nullptr);
+
+public:
+ QUrl url() const;
+ void setUrl(const QUrl &url);
+ void setFavIcon(const QIcon &icon);
+
+protected:
+ void resizeEvent(QResizeEvent *event) override;
+
+private:
+ QToolButton *m_favButton;
+ QToolButton *m_clearButton;
+};
+
+#endif // URLLINEEDIT_H
diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp
new file mode 100644
index 000000000..ae0ef3f48
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpage.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** 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 "browserwindow.h"
+#include "tabwidget.h"
+#include "ui_certificateerrordialog.h"
+#include "ui_passworddialog.h"
+#include "webpage.h"
+#include "webview.h"
+#include <QAuthenticator>
+#include <QMessageBox>
+
+WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
+ : QWebEnginePage(profile, parent)
+{
+ connect(this, &QWebEnginePage::authenticationRequired, this, &WebPage::handleAuthenticationRequired);
+ connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, &WebPage::handleProxyAuthenticationRequired);
+}
+
+bool WebPage::certificateError(const QWebEngineCertificateError &error)
+{
+ QWidget *mainWindow = view()->window();
+ if (error.isOverridable()) {
+ QDialog dialog(mainWindow);
+ dialog.setModal(true);
+ dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ Ui::CertificateErrorDialog certificateDialog;
+ certificateDialog.setupUi(&dialog);
+ certificateDialog.m_iconLabel->setText(QString());
+ QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, mainWindow));
+ certificateDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
+ certificateDialog.m_errorLabel->setText(error.errorDescription());
+ dialog.setWindowTitle(tr("Certificate Error"));
+ return dialog.exec() == QDialog::Accepted;
+ }
+
+ QMessageBox::critical(mainWindow, tr("Certificate Error"), error.errorDescription());
+ return false;
+}
+
+void WebPage::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth)
+{
+ QWidget *mainWindow = view()->window();
+ QDialog dialog(mainWindow);
+ dialog.setModal(true);
+ dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ Ui::PasswordDialog passwordDialog;
+ passwordDialog.setupUi(&dialog);
+
+ passwordDialog.m_iconLabel->setText(QString());
+ QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow));
+ passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
+
+ QString introMessage(tr("Enter username and password for \"%1\" at %2")
+ .arg(auth->realm()).arg(requestUrl.toString().toHtmlEscaped()));
+ passwordDialog.m_infoLabel->setText(introMessage);
+ passwordDialog.m_infoLabel->setWordWrap(true);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ auth->setUser(passwordDialog.m_userNameLineEdit->text());
+ auth->setPassword(passwordDialog.m_passwordLineEdit->text());
+ } else {
+ // Set authenticator null if dialog is cancelled
+ *auth = QAuthenticator();
+ }
+}
+
+void WebPage::handleProxyAuthenticationRequired(const QUrl &, QAuthenticator *auth, const QString &proxyHost)
+{
+ QWidget *mainWindow = view()->window();
+ QDialog dialog(mainWindow);
+ dialog.setModal(true);
+ dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ Ui::PasswordDialog passwordDialog;
+ passwordDialog.setupUi(&dialog);
+
+ passwordDialog.m_iconLabel->setText(QString());
+ QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow));
+ passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
+
+ QString introMessage = tr("Connect to proxy \"%1\" using:");
+ introMessage = introMessage.arg(proxyHost.toHtmlEscaped());
+ passwordDialog.m_infoLabel->setText(introMessage);
+ passwordDialog.m_infoLabel->setWordWrap(true);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ auth->setUser(passwordDialog.m_userNameLineEdit->text());
+ auth->setPassword(passwordDialog.m_passwordLineEdit->text());
+ } else {
+ // Set authenticator null if dialog is cancelled
+ *auth = QAuthenticator();
+ }
+}
diff --git a/examples/webenginewidgets/simplebrowser/webpage.h b/examples/webenginewidgets/simplebrowser/webpage.h
new file mode 100644
index 000000000..521534b50
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpage.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef WEBPAGE_H
+#define WEBPAGE_H
+
+#include <QWebEnginePage>
+
+class WebPage : public QWebEnginePage
+{
+ Q_OBJECT
+
+public:
+ WebPage(QWebEngineProfile *profile, QObject *parent = nullptr);
+
+protected:
+ bool certificateError(const QWebEngineCertificateError &error) override;
+
+private slots:
+ void handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth);
+ void handleProxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth, const QString &proxyHost);
+};
+
+#endif // WEBPAGE_H
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
new file mode 100644
index 000000000..a3175e546
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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 "webpage.h"
+#include "webpopupwindow.h"
+#include "webview.h"
+#include <QIcon>
+#include <QVBoxLayout>
+
+WebPopupWindow::WebPopupWindow(QWebEngineProfile *profile)
+ : m_addressBar(new UrlLineEdit(this))
+ , m_view(new WebView(this))
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+ setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setMargin(0);
+ setLayout(layout);
+ layout->addWidget(m_addressBar);
+ 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")));
+
+ connect(m_view, &WebView::titleChanged, this, &QWidget::setWindowTitle);
+ connect(m_view, &WebView::urlChanged, this, &WebPopupWindow::setUrl);
+ connect(m_view, &WebView::iconChanged, this, &WebPopupWindow::handleIconChanged);
+ connect(m_view->page(), &WebPage::geometryChangeRequested, this, &WebPopupWindow::handleGeometryChangeRequested);
+ connect(m_view->page(), &WebPage::windowCloseRequested, this, &QWidget::close);
+}
+
+QWebEngineView *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());
+ move(newGeometry.topLeft() - m_view->pos());
+ // let the layout do the magic
+ resize(0, 0);
+ show();
+}
+
+void WebPopupWindow::handleIconChanged(const QIcon &icon)
+{
+ m_addressBar->setFavIcon(icon);
+}
diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.h b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
new file mode 100644
index 000000000..af97ef7fc
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef WEBPOPUPWINDOW_H
+#define WEBPOPUPWINDOW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QWebEngineProfile;
+class QWebEngineView;
+QT_END_NAMESPACE
+
+class WebView;
+class UrlLineEdit;
+
+class WebPopupWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ WebPopupWindow(QWebEngineProfile *profile);
+ QWebEngineView *view() const;
+ void setUrl(const QUrl &url);
+
+private slots:
+ void handleGeometryChangeRequested(const QRect &newGeometry);
+ void handleIconChanged(const QIcon &icon);
+
+private:
+ UrlLineEdit *m_addressBar;
+ WebView *m_view;
+};
+#endif // WEBPOPUPWINDOW_H
diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp
new file mode 100644
index 000000000..1fabcc69f
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webview.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** 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 "browser.h"
+#include "browserwindow.h"
+#include "tabwidget.h"
+#include "webpage.h"
+#include "webpopupwindow.h"
+#include "webview.h"
+#include <QContextMenuEvent>
+#include <QMenu>
+#include <QMessageBox>
+#include <QNetworkReply>
+#include <QTimer>
+
+WebView::WebView(QWidget *parent)
+ : QWebEngineView(parent)
+ , m_loadProgress(0)
+{
+ connect(this, &QWebEngineView::loadProgress, [this](int progress) {
+ m_loadProgress = progress;
+ });
+ connect(this, &QWebEngineView::loadFinished, [this](bool success) {
+ if (!success) {
+ qWarning() << "Could not load page: " << url();
+ m_loadProgress = 0;
+ }
+ });
+ connect(this, &QWebEngineView::iconUrlChanged, this, &WebView::handleIconUrlChanged);
+ connect(this, &QWebEngineView::renderProcessTerminated,
+ [this](QWebEnginePage::RenderProcessTerminationStatus termStatus, int statusCode) {
+ QString status;
+ switch (termStatus) {
+ case QWebEnginePage::NormalTerminationStatus:
+ status = tr("Render process normal exit");
+ break;
+ case QWebEnginePage::AbnormalTerminationStatus:
+ status = tr("Render process abnormal exit");
+ break;
+ case QWebEnginePage::CrashedTerminationStatus:
+ status = tr("Render process crashed");
+ break;
+ case QWebEnginePage::KilledTerminationStatus:
+ status = tr("Render process killed");
+ break;
+ }
+ QMessageBox::critical(window(), status, tr("Render process exited with code: %1").arg(statusCode));
+ QTimer::singleShot(0, [this] { reload(); });
+ });
+}
+
+void WebView::setPage(WebPage *page)
+{
+ createWebActionTrigger(page,QWebEnginePage::Forward);
+ createWebActionTrigger(page,QWebEnginePage::Back);
+ createWebActionTrigger(page,QWebEnginePage::Reload);
+ createWebActionTrigger(page,QWebEnginePage::Stop);
+ QWebEngineView::setPage(page);
+}
+
+QIcon WebView::icon() const
+{
+ if (!m_icon.isNull())
+ return m_icon;
+ return QIcon(QLatin1String(":defaulticon.png"));
+}
+
+int WebView::loadProgress() const
+{
+ return m_loadProgress;
+}
+
+void WebView::createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction webAction)
+{
+ QAction *action = page->action(webAction);
+ connect(action, &QAction::changed, [this, action, webAction]{
+ emit webActionEnabledChanged(webAction, action->isEnabled());
+ });
+}
+
+bool WebView::isWebActionEnabled(QWebEnginePage::WebAction webAction) const
+{
+ return page()->action(webAction)->isEnabled();
+}
+
+QNetworkAccessManager &WebView::networkAccessManager()
+{
+ static QNetworkAccessManager networkAccessManager;
+ return networkAccessManager;
+}
+
+QWebEngineView *WebView::createWindow(QWebEnginePage::WebWindowType type)
+{
+ switch (type) {
+ case QWebEnginePage::WebBrowserTab: {
+ BrowserWindow *mainWindow = qobject_cast<BrowserWindow*>(window());
+ return mainWindow->tabWidget()->createTab();
+ }
+ case QWebEnginePage::WebBrowserWindow: {
+ BrowserWindow *mainWindow = new BrowserWindow();
+ Browser::instance().addWindow(mainWindow);
+ return mainWindow->currentTab();
+ }
+ case QWebEnginePage::WebDialog: {
+ WebPopupWindow *popup = new WebPopupWindow(page()->profile());
+ return popup->view();
+ }
+ }
+ return nullptr;
+}
+
+void WebView::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu *menu = page()->createStandardContextMenu();
+ const QList<QAction*> actions = menu->actions();
+ auto it = std::find(actions.cbegin(), actions.cend(), page()->action(QWebEnginePage::OpenLinkInThisWindow));
+ if (it != actions.cend()) {
+ (*it)->setText(tr("Open Link in This Tab"));
+ ++it;
+ menu->insertAction(*it, page()->action(QWebEnginePage::OpenLinkInNewWindow));
+ menu->insertAction(*it, page()->action(QWebEnginePage::OpenLinkInNewTab));
+ }
+ menu->popup(event->globalPos());
+}
+
+void WebView::handleIconUrlChanged(const QUrl &url)
+{
+ QNetworkRequest iconRequest(url);
+#ifndef QT_NO_OPENSSL
+ QSslConfiguration conf = iconRequest.sslConfiguration();
+ conf.setPeerVerifyMode(QSslSocket::VerifyNone);
+ iconRequest.setSslConfiguration(conf);
+#endif
+ QNetworkReply *iconReply = networkAccessManager().get(iconRequest);
+ iconReply->setParent(this);
+ connect(iconReply, &QNetworkReply::finished, this, &WebView::handleIconLoaded);
+}
+
+void WebView::handleIconLoaded()
+{
+ QNetworkReply *iconReply = qobject_cast<QNetworkReply*>(sender());
+ if (iconReply && iconReply->error() == QNetworkReply::NoError) {
+ QByteArray data = iconReply->readAll();
+ QPixmap pixmap;
+ pixmap.loadFromData(data);
+ m_icon.addPixmap(pixmap);
+ iconReply->deleteLater();
+ } else {
+ m_icon = QIcon(QStringLiteral(":defaulticon.png"));
+ }
+ emit iconChanged(m_icon);
+}
diff --git a/examples/webenginewidgets/simplebrowser/webview.h b/examples/webenginewidgets/simplebrowser/webview.h
new file mode 100644
index 000000000..5450ee247
--- /dev/null
+++ b/examples/webenginewidgets/simplebrowser/webview.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef WEBVIEW_H
+#define WEBVIEW_H
+
+#include <QIcon>
+#include <QWebEngineView>
+
+class WebPage;
+
+class WebView : public QWebEngineView
+{
+ Q_OBJECT
+
+public:
+ WebView(QWidget *parent = nullptr);
+ void setPage(WebPage *page);
+
+ QIcon icon() const;
+ int loadProgress() const;
+ bool isWebActionEnabled(QWebEnginePage::WebAction webAction) const;
+ static QNetworkAccessManager &networkAccessManager();
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *event) override;
+ QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) override;
+
+signals:
+ void iconChanged(const QIcon &icon);
+ void webActionEnabledChanged(QWebEnginePage::WebAction webAction, bool enabled);
+
+private slots:
+ void handleIconUrlChanged(const QUrl &url);
+ void handleIconLoaded();
+
+private:
+ void createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction);
+
+private:
+ int m_loadProgress;
+ QIcon m_icon;
+};
+
+#endif
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 49f0e524d..7fc6556fb 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -156,10 +156,11 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins)
<< "/usr/lib64/chromium/PepperFlash/libpepflashplayer.so"; // OpenSuSE
pluginPaths << ppapiPluginsPath() + QStringLiteral("/libpepflashplayer.so");
#endif
+ std::string flash_version = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kPpapiFlashVersion);
for (auto it = pluginPaths.constBegin(); it != pluginPaths.constEnd(); ++it) {
if (!QFile::exists(*it))
continue;
- plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string()));
+ plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), flash_version));
}
}
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index 0560c3f6b..ee52dd23e 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -55,6 +55,10 @@
#include "renderer/content_renderer_client_qt.h"
#include "web_engine_library_info.h"
+#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
+#include "base/cpu.h"
+#endif
+
#include <QLocale>
namespace QtWebEngineCore {
@@ -69,6 +73,12 @@ static base::StringPiece PlatformResourceProvider(int key) {
void ContentMainDelegateQt::PreSandboxStartup()
{
+#if defined(ARCH_CPU_ARM_FAMILY) && (defined(OS_ANDROID) || defined(OS_LINUX))
+ // Create an instance of the CPU class to parse /proc/cpuinfo and cache
+ // cpu_brand info.
+ base::CPU cpu_info;
+#endif
+
net::NetModule::SetResourceProvider(PlatformResourceProvider);
ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getApplicationLocale(), 0, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 174c00afb..6d2d11d40 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -72,9 +72,13 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales
resources.CONFIG += no_check_exist
resources.path = $$[QT_INSTALL_DATA]/resources
- icu.CONFIG += no_check_exist
- icu.path = $$[QT_INSTALL_DATA]/resources
- INSTALLS += icu locales resources
+ INSTALLS += locales resources
+
+ !use?(system_icu) {
+ icu.CONFIG += no_check_exist
+ icu.path = $$[QT_INSTALL_DATA]/resources
+ INSTALLS += icu
+ }
}
!contains(QT_CONFIG, qt_framework):!force_independent {
@@ -82,11 +86,14 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
# Copy essential files to the qtbase build directory for non-prefix builds
#
- icudt2build.input = icu.files
- icudt2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
- icudt2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
- icudt2build.name = COPY ${QMAKE_FILE_IN}
- icudt2build.CONFIG = no_link no_clean target_predeps
+ !use?(system_icu) {
+ icudt2build.input = icu.files
+ icudt2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
+ icudt2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ icudt2build.name = COPY ${QMAKE_FILE_IN}
+ icudt2build.CONFIG = no_link no_clean target_predeps
+ QMAKE_EXTRA_COMPILERS += icudt2build
+ }
resources2build.input = resources.files
resources2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
@@ -94,7 +101,7 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
resources2build.name = COPY ${QMAKE_FILE_IN}
resources2build.CONFIG = no_link no_clean target_predeps
- QMAKE_EXTRA_COMPILERS += icudt2build resources2build
+ QMAKE_EXTRA_COMPILERS += resources2build
}
}
diff --git a/src/process/process.pro b/src/process/process.pro
index 6174e53bf..eab11189e 100644
--- a/src/process/process.pro
+++ b/src/process/process.pro
@@ -8,23 +8,9 @@ load(qt_build_paths)
contains(QT_CONFIG, qt_framework) {
# Deploy the QtWebEngineProcess app bundle into the QtWebEngineCore framework.
DESTDIR = $$MODULE_BASE_OUTDIR/lib/QtWebEngineCore.framework/Versions/5/Helpers
- # FIXME: remove the following workaround with proper rpath handling or
- # patching of the installed QtWebEngineProcess binary.
- # Since QtWebEngineCore is now built as a framework, we need to pull
- # in and fixup its dependencies as well.
+
QT += webenginecore
- QMAKE_POST_LINK = \
- "xcrun install_name_tool -change " \
- "`xcrun otool -X -L $(TARGET) | grep QtWebEngineCore | cut -d ' ' -f 1` " \
- "@executable_path/../../../../QtWebEngineCore " \
- "$(TARGET); "
- linked_frameworks = QtQuick QtQml QtNetwork QtCore QtGui QtWebChannel
- for (current_framework, linked_frameworks) {
- QMAKE_POST_LINK += "xcrun install_name_tool -change " \
- "`xcrun otool -X -L $(TARGET) | grep $${current_framework} | cut -d ' ' -f 1` " \
- "@executable_path/../../../../../../../$${current_framework}.framework/$${current_framework} " \
- "$(TARGET);"
- }
+ QMAKE_RPATHDIR += @loader_path/../../../../../../../../Frameworks
} else {
CONFIG -= app_bundle
win32: DESTDIR = $$MODULE_BASE_OUTDIR/bin
diff --git a/src/webengine/api/qquickwebenginecertificateerror.cpp b/src/webengine/api/qquickwebenginecertificateerror.cpp
index 9570add65..561d1daf4 100644
--- a/src/webengine/api/qquickwebenginecertificateerror.cpp
+++ b/src/webengine/api/qquickwebenginecertificateerror.cpp
@@ -69,8 +69,19 @@ public:
\brief A utility type for ignoring certificate errors or rejecting erroneous certificates.
- This QML type contains information about a certificate error that occurred and provides a way
- to ignore the error or reject the certificate.
+ This QML type contains information about a certificate error that occurred. The \l error
+ property holds the reason that the error occurred and the \l description property holds a
+ short localized description of the error. The \l url property holds the URL that triggered
+ the error.
+
+ The certificate can be rejected by calling \l rejectCertificate, which will stop loading the
+ web engine request. By default, an invalid certificate will be automatically rejected.
+
+ The certificate error can be ignored by calling \l ignoreCertificateError, which will
+ resume loading the request.
+
+ It is possible to defer the decision of rejecting a certificate by calling \l defer,
+ which is useful when waiting for user input.
\sa WebEngineView::certificateError
*/
diff --git a/src/webengine/doc/images/qtwebengine-architecture.png b/src/webengine/doc/images/qtwebengine-architecture.png
index 37ca2da16..1c94d385f 100644
--- a/src/webengine/doc/images/qtwebengine-architecture.png
+++ b/src/webengine/doc/images/qtwebengine-architecture.png
Binary files differ
diff --git a/src/webengine/doc/images/qtwebengine-model.png b/src/webengine/doc/images/qtwebengine-model.png
new file mode 100644
index 000000000..0bbd556f1
--- /dev/null
+++ b/src/webengine/doc/images/qtwebengine-model.png
Binary files differ
diff --git a/src/webengine/doc/images/qtwebenginewidgets-model.png b/src/webengine/doc/images/qtwebenginewidgets-model.png
new file mode 100644
index 000000000..c334b84c9
--- /dev/null
+++ b/src/webengine/doc/images/qtwebenginewidgets-model.png
Binary files differ
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index d2b8980c4..baa4a9859 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -70,7 +70,7 @@ exampledirs += . \
imagedirs += images
navigation.landingpage = "Qt WebEngine"
-navigation.cppclassespage = "Qt WebEngine C++ Classes"
+navigation.cppclassespage = "Qt WebEngine C++ Classes and Namespaces"
navigation.qmltypespage = "Qt WebEngine QML Types"
Cpp.ignoretokens += Q_WEBENGINE_EXPORT QWEBENGINEWIDGETS_EXPORT
diff --git a/src/webengine/doc/src/qtwebengine-index.qdoc b/src/webengine/doc/src/qtwebengine-index.qdoc
index fd6010da6..809e10c72 100644
--- a/src/webengine/doc/src/qtwebengine-index.qdoc
+++ b/src/webengine/doc/src/qtwebengine-index.qdoc
@@ -61,7 +61,7 @@
\section1 API References
\list
- \li \l{Qt WebEngine C++ Classes}
+ \li \l{Qt WebEngine C++ Classes and Namespaces}
\li \l{Qt WebEngine QML Types}
\endlist
*/
diff --git a/src/webengine/doc/src/qtwebengine-modules.qdoc b/src/webengine/doc/src/qtwebengine-modules.qdoc
index 4dbba5e4e..7b8ced728 100644
--- a/src/webengine/doc/src/qtwebengine-modules.qdoc
+++ b/src/webengine/doc/src/qtwebengine-modules.qdoc
@@ -27,7 +27,7 @@
/*!
\page qtwebengine-modules.html
- \title Qt WebEngine C++ Classes
+ \title Qt WebEngine C++ Classes and Namespaces
\brief Provides functionality for rendering regions of dynamic web content.
\e {Qt WebEngine} provides functionality for rendering regions of dynamic web content.
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index 70ecff56c..cf757a6d5 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -46,6 +46,13 @@
application to use Qt WebEngine widgets, see \l{Porting from Qt WebKit to Qt WebEngine}. For new
applications, we recommend using Qt Quick and the WebEngineView QML type.
+ For more information about the requirements for building Qt WebEngine from source on the
+ supported platforms and for other platform-specific information, see
+ \l{Qt WebEngine Platform Notes}.
+
+ The \l {Qt WebChannel} module can be used to create a bi-directional communication channel
+ between QObject objects on the C++ side and JavaScript on the QML side.
+
\section1 Qt WebEngine Architecture
\image qtwebengine-architecture.png
@@ -53,14 +60,38 @@
The functionality in Qt WebEngine is divided into the following modules:
\list
- \li \l{Qt WebEngine Widgets}, which provides a web browser engine and C++ classes to render
- web content and to interact with it
- \li \l{Qt WebEngine}, which provides QML types for rendering web content within a QML
- application
- \li \l{Qt WebEngine Core}, which provides common API used by Qt WebEngine and
- Qt WebEngine Widgets
+ \li \l{Qt WebEngine Widgets} for creating widget-based web applications
+ \li \l{Qt WebEngine} for creating Qt Quick based web applications
+ \li \l{Qt WebEngine Core} for interacting with Chromium
\endlist
+ Page rendering and JavaScript execution are separated from the GUI process into the Qt WebEngine
+ Process. It is a library that must be shipped with the application if the Qt libraries are
+ bundled into the application.
+
+ \section2 Qt WebEngine Widgets
+
+ \image qtwebenginewidgets-model.png
+
+ A \e {web engine view} is the main widget component of the Qt WebEngine module. It can be used
+ in various applications to load web content. Within a view, a \e {web engine page} holds a main
+ frame that is responsible for web content, the \e history of navigated links, and \e actions.
+ The view and page are quite similar, as they provide a set of common functions.
+
+ All pages belong to a \e {web engine profile} that contains shared \e settings, \e scripts, and
+ \e cookies. Profiles can be used to isolate pages from each other. A typical use case is a
+ dedicated profile for a \e {private browsing} mode, where no information is permanently saved.
+
+ \section2 Qt WebEngine
+
+ \image qtwebengine-model.png
+
+ The Qt WebEngine QML implementation contains the same elements as the C++ implementation,
+ except that there is no separately accessible web engine page. The supported page functionality
+ is integrated into the web engine view.
+
+ \section2 Qt WebEngine Core
+
The Qt WebEngine core is based on the \l {Chromium Project}. Chromium provides its own network
and painting engines and is developed tightly together with its dependent modules, and
therefore Qt WebEngine provides better and more reliable support for the latest HTML5
@@ -73,12 +104,32 @@
\l{https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md}{overview}
that is part of the documentation in the \l {Chromium Project} upstream source tree.
+ This version of Qt WebEngine is based on Chromium snapshot version 45.0.2554.101, with
+ additional security fixes from the 46, 47 and 48 branches of the \l {Chromium Project}.
+
+ \section2 Qt WebEngine Process
+
+ The Qt WebEngine Process renders web pages and executes JavaScript.
+
Chromium is tightly integrated to the \l{Qt Quick Scene Graph}{Qt Quick scene graph}, which is
based on OpenGL ES 2.0 or OpenGL 2.0 for its rendering. This provides you with one-pass
compositing of web content and all the Qt Quick UI. The integration to Chromium is transparent
to developers, who just work with Qt and JavaScript.
- To expose QObjects to JavaScript, developers can use the \l {Qt WebChannel} module.
+ The document object model (DOM) of a page is constructed when the document is ready, typically
+ when the page is completely loaded. Therefore, executing scripts as soon as a document is
+ created is not suitable for DOM operations, where one has to wait until the DOM is ready.
+
+ In addition, an injected script shares the same \e world as the other scripts executed on the
+ page, which might lead to conflicts. To avoid this, the Chromium API for
+ \e{Content Script Extensions} is implemented by \e {web engine script}. It specifies the
+ 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.
+
+ Because the render process is separated from the GUI process, they should ideally share an
+ OpenGL context to enable one process to access the resources uploaded by the other, such as
+ images or textures. However, some inter-process communication is needed for safety and
+ reliability, because it enables restarting a crashed process.
\section1 Embedding Web Content into Widget Based Applications
@@ -92,23 +143,48 @@
view->show();
\endcode
- An instance of QWebEngineView has one QWebEnginePage. QWebEnginePage provides access to the
- page's navigation history and the ability to run JavaScript code in the context of the page's
- main frame and enables customization of handlers for specific events like showing custom
- authentication dialogs.
+ An instance of QWebEngineView has one QWebEnginePage. QWebEnginePage can have a
+ QWebEngineHistory that provides access to the page's navigation history and several QAction
+ objects that apply actions on the web page. In addition, a QWebEnginePage has the ability to
+ run JavaScript code in the context of the page's main frame and to enable customization of
+ handlers for specific events like showing custom authentication dialogs.
+
+ Each QWebEnginePage belongs to a QWebEngineProfile that can have a QWebEngineSettings
+ for specifying page settings, a QWebEngineScriptCollection for running scripts on the page, and
+ a QWebEngineCookieStore for accessing the HTTP cookies of Chromium. A QWebEnginePage can also
+ directly point to a script collection or cookie store.
\section1 Embedding Web Content into Qt Quick Applications
- The WebEngineView QML type allows QML applications to render regions of dynamic web content. A
- \e{WebEngineView} type may share the screen with other QML types or encompass the full screen
- as specified within the QML application.
+ The WebEngineView QML type allows Qt Quick applications to render regions of dynamic web
+ content. A \e{WebEngineView} type may share the screen with other QML types or encompass the
+ full screen as specified within the Qt Quick application.
+
+ To make sure that OpenGL context can be shared between the GUI and render processes, the web
+ engine must be initialized by using \l QtWebEngine::initialize in the application main source
+ file, as illustrated by the following code snippet:
+
+ \code
+ int main(int argc, char **argv)
+ {
+ Application app(argc, argv);
+
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine appEngine;
+ appEngine.load(QUrl("qrc:/main.qml"));
+
+ return app.exec();
+ }
+ \endcode
An application can load pages into the WebEngineView, using either an URL or HTML string, and
navigate within session history. By default, links to different pages load within the same
WebEngineView object, but web sites may request them to be opened as a new tab, window, or
dialog.
- The following sample QML application loads a web page and responds to session history context:
+ The following sample QML application loads a web page using the \l{WebEngineView::}{url}
+ property:
\qml
import QtQuick 2.1
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 673215dd7..a8899a0cf 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -31,6 +31,19 @@
\brief Contains information about issues that are specific to the Qt WebEngine module.
+ \section1 Target Platforms
+
+ Qt WebEngine does try to support all \l{Supported Platforms} of Qt. However, due to
+ different requirements of Chromium this is not always possible. Known limitations are:
+
+ \list
+ \li Qt WebEngine currently supports only Windows, Linux, and OS X.
+
+ \li On Windows, Qt WebEngine only supports Windows Vista or newer as target platform.
+ Due to use of newer API in Chromium, Windows XP is not supported. WinRT is
+ not supported, either.
+ \endlist
+
\section1 Building Qt WebEngine from Source
The requirements for building Qt 5 modules from source are listed separately for each supported
@@ -72,11 +85,11 @@
The MIME type is important because it determines which embeds the plugin is used for.
- This process has been automated for the Adobe Flash Player Plugin.
+ This process has been automated for the Pepper Flash player plugin.
- \section2 Adobe Flash Player Plugin Support
+ \section2 Pepper Flash Player Plugin Support
- The Adobe Flash player plugin can be loaded automatically if it is installed in one of the
+ The Pepper Flash player plugin can be loaded automatically if it is installed in one of the
following locations, depending on the platform:
\list
@@ -97,12 +110,21 @@
\endcode
\endlist
- You can also load the Flash player from a specific location by using command line arguments:
+ You can also load the Pepper Flash player from a specific location by using command line
+ arguments:
\code
--ppapi-flash-path=./libpepflashplayer.so
\endcode
+ By default, the Flash version is set to \c{11.2.999.999}. You can use the
+ \c{ppapi-flash-version=} argument to set another Flash version in the
+ in the format \c{major.minor.build.revision}:
+
+ \code
+ --ppapi-flash-version=16.0.0.235
+ \endcode
+
\section1 Audio and Video Codec Support
Qt WebEngine supports the MPEG-4 Part 14 (MP4) file format only if the required proprietary
diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc
index 3af5e35da..bcabe2152 100644
--- a/src/webengine/doc/src/webengineview.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -34,11 +34,126 @@
may share the screen with other QML types, such as a TabView, or fill the screen, as specified
within the QML application.
- \section1 Rendering to OpenGL Surface
+ \section2 Initializing Web Engine
+
+ For the web engine view to be rendered, the web engine must be initialized by using
+ \l QtWebEngine::initialize in the application main source file, as illustrated by the
+ following code snippet:
+
+ \code
+ int main(int argc, char **argv)
+ {
+ Application app(argc, argv);
+
+ QtWebEngine::initialize();
+
+ QQmlApplicationEngine appEngine;
+ appEngine.load(QUrl("qrc:/main.qml"));
+
+ return app.exec();
+ }
+ \endcode
+
+ \section2 Loading Web Pages
+
+ An application can load pages into the WebEngineView, using either the \l url property or the
+ \l loadHtml method and navigate within the view's session history. The history is represented
+ by a WebEngineHistory data model that is held by the \l navigationHistory property.
+
+ The following sample QML application loads a web page using the \c url property:
+
+ \qml
+ import QtQuick 2.1
+ import QtQuick.Controls 1.1
+ import QtWebEngine 1.1
+
+ ApplicationWindow {
+ width: 1280
+ height: 720
+ visible: true
+ WebEngineView {
+ id: webview
+ url: "http://www.qt.io"
+ anchors.fill: parent
+ }
+ }
+ \endqml
+
+ The \l loadingChanged() signal is emitted when loading a page begins, ends, or fails. The
+ \l loading property holds whether the HTML page is currently loading and the load status is
+ reflected in the \l LoadStatus property.
+
+ The title of an HTML page can be accessed with the \l title property. Additionally, a web
+ page may specify an icon, which can be accessed using the \l icon property. The \l zoomFactor
+ property holds the overall size of the contents of the web page.
+
+ If a certificate error is raised while loading a web page, the \l certificateError() signal is
+ emitted. Certificate errors are handled by using the methods of the WebEngineCertificateError
+ type.
+
+ \section2 Interaction
+
+ By default, links to different pages load within the same WebEngineView object, but web sites
+ may request them to be opened as a new tab, window, or dialog. The \l newViewRequested() signal
+ is emitted when a request to load the page in a separate web engine view is issued. The
+ NewViewDestination property describes how the new view should be opened. In addition, the
+ WebEngineNewViewRequest utility type can be used to load web pages in separate web engine views.
+
+ The \l findText() method can be used to search for a string on a web page, using the options
+ described by \l FindFlags.
+
+ The \l setActiveFocusOnPress() method can be used to create a UI element that should not get
+ focus. This can be useful in a hybrid UI.
+
+ The \l linkHovered() signal is emitted when a mouse pointer passes over a link and thus
+ corresponds to the \c{mouseover} DOM event.
+
+ Actions, such as selecting and editing content, can be performed on a web page by using the
+ \l triggerWebAction() method. The available actions are described by the \l WebAction property.
+
+ The \l backgroundColorChanged() signal is emitted when the web page background color changes.
+
+ \section2 User Scripts
+
+ During the loading of a page, so called \e {user scripts} can be injected in the JavaScript
+ engine at different points. The script objects attached to the web engine view are held by the
+ \l userScripts property and injected by using the WebEngineScript type. Scripts can also be run
+ by using the runJavaScript() method in the same world as other scripts that are part of the
+ loaded site.
+
+ The \l webChannel property can be used to expose a WebChannel instance in the JavaScript context
+ of the page it is rendering as \c qt.webChannelTransport.
+
+ \section2 Fullscreen Mode
+
+ A web page can request through the JavaScript API to be loaded in fullscreen mode. The
+ \l fullScreenRequested() signal is emitted when the web page issues the request. The
+ WebEngineFullScreenRequest utility type can be used to toggle fullscreen requests. The
+ \l fullScreenCancelled method can be used to notify the browser engine when the windowing
+ system forces the application to leave fullscreen mode.
+
+ \section2 Profiles
+
+ Web engine views can be isolated from each other by using the WebEngineProfile type. A profile
+ contains settings, scripts, and the list of visited links shared by all views that belong to the
+ profile. For example, a dedicated profile could be created for a \e {private browsing} mode. The
+ current profile for the view is held by the \l profile property and the current settings are
+ held by the \l settings property. The settings are specified by using the WebEngineSettings
+ type.
+
+ \section2 Platform Features
+
+ Web pages can request access to platform features, such as geolocation or audio and video
+ capture devices. The \l featurePermissionRequested() signal is emitted when a web page requests
+ to make use of a resource. The supported platform features are described by the \l Feature
+ property. If users grant the permission, the \l grantFeaturePermission() method is used to set
+ it to \e granted.
+
+ \section2 Rendering to OpenGL Surface
When using a QQuickRenderControl to render a Qt Quick user interface to an OpenGL surface, the
WebEngineView type is not rendered correctly. The web engine view attempts to use a global
- OpenGL context created by \l QtWebEngine::initialize(), but there is no public API for accessing
+ OpenGL context created by \l QtWebEngine::initialize, but there is no public API for accessing
that context in order to share it with the \c QQuickRenderControl context.
To have the web engine view rendered correctly, it is possible to manually create a new
@@ -418,15 +533,8 @@
This signal is emitted when an invalid certificate error is raised while loading a given request.
- The certificate error can be rejected by calling WebEngineCertificateError::rejectCertificate,
- which will stop loading the request.
-
- The certificate error can be ignored by calling
- WebEngineCertificateError::ignoreCertificateError, which will resume loading the request.
-
- It is possible to defer the decision of rejecting the given certificate by calling
- WebEngineCertificateError::defer, which is useful when waiting for user input.
- By default, the invalid certificate will be automatically rejected.
+ The certificate error can be handled by using the methods of the WebEngineCertificateError
+ type.
The corresponding handler is \c onCertificateError.
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 27ed7fca6..7f7cba431 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -503,6 +503,7 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
/*!
\enum QWebEnginePage::RenderProcessTerminationStatus
+ \since 5.6
This enum describes the status with which the render process terminated:
@@ -518,6 +519,7 @@ QWebEnginePage::QWebEnginePage(QObject* parent)
/*!
\fn QWebEnginePage::renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode)
+ \since 5.6
This signal is emitted when the render process is terminated with a non-zero exit status.
\a terminationStatus is the termination status of the process and \a exitCode is the status code
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index ad399a7a5..8d6da4459 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -40,9 +40,9 @@
#ifndef QWEBENGINEPAGE_H
#define QWEBENGINEPAGE_H
-#include <qtwebenginewidgetsglobal.h>
-#include <qwebenginecertificateerror.h>
-#include <qwebenginecallback.h>
+#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
+#include <QtWebEngineWidgets/qwebenginecertificateerror.h>
+#include <QtWebEngineCore/qwebenginecallback.h>
#include <QtCore/qobject.h>
#include <QtCore/qurl.h>
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index f5e180541..add2000d1 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -114,6 +114,7 @@ QWebEngineViewPrivate::QWebEngineViewPrivate()
/*!
\fn QWebEngineView::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
+ \since 5.6
This signal is emitted when the render process is terminated with a non-zero exit status.
\a terminationStatus is the termination status of the process and \a exitCode is the status code
diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
index 99723c105..e6236ec98 100644
--- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc
@@ -94,8 +94,17 @@
\section1 QWebFrame Has Been Merged into QWebEnginePage
- It is not possible to access sub-frames. Methods of the main QWebFrame are
- now available directly through the QWebEnginePage itself.
+ HTML frames can be used to divide web pages into several areas where the content can be
+ represented individually.
+
+ In Qt WebKit, QWebFrame represents a frame inside a web page. Each QWebPage object contains at
+ least one frame, the main frame, obtained using QWebPage::mainFrame(). Additional frames will
+ be created for the HTML \c <frame> element, which defines the appearance and contents of a
+ single frame, or the \c <iframe> element, which inserts a frame within a block of text.
+
+ In Qt WebEngine, frame handling has been merged into the QWebEnginePage class. All child frames
+ are now considered part of the content, and only accessible through JavaScript. Methods of the
+ QWebFrame class, such as \c load() are now available directly through the QWebEnginePage itself.
\b {Qt WebKit}
\code
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 2d928b0f5..d6b89cb57 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -30,8 +30,8 @@
\since 5.4
\inmodule QtWebEngineWidgets
- A web engine page holds a main frame responsible for web content, the history
- of navigated links, and actions.
+ A \e {web engine page} holds the contents of an HTML document, the history of navigated
+ links, and actions.
QWebEnginePage's API is very similar to QWebEngineView, as you are still provided with
common functions like action() (known as
@@ -42,7 +42,7 @@
the HTML content readily available, you can use setHtml().
The QWebEnginePage class also offers methods to retrieve both the URL currently
- loaded by its main frame (see url()) as well as the URL originally requested
+ loaded by the page (see url()) as well as the URL originally requested
to be loaded (see requestedUrl()). These methods make possible the retrieval
of the URL before and after a DNS resolution or a redirection occurs during
the load process. The requestedUrl() also matches to the URL added to the
@@ -62,6 +62,22 @@
Its argument, either \c true or \c false, indicates whether or not the load
operation succeeded.
+ An HTML document is loaded in a \e {main frame} within the web page. If it references
+ \e {child frames} (as defined by the \c <frame> or \c <iframe> elements), they are considered
+ part of the content. Child frames are individually accessible only through JavaScript.
+
+ Web sites define \e {security origin} for safely accessing each other's resources for
+ client-side scripting or databases. An origin consist of a host name, a scheme, and a port
+ number. For example, the sites \c http://www.example.com/my/page.html and
+ \c http://www.example.com/my/overview.html are allowed to share the same database or access
+ each other's documents when used in HTML frame sets and JavaScript. At the same time,
+ \c http://www.malicious.com/evil.html is prevented from accessing the resources of
+ \c http://www.example.com/, because they are of a different security origin.
+ By default, local schemes like \c file:// and \c qrc:// are considered to be in the same
+ security origin, and can access each other's resources. Local resources are by default
+ restricted from accessing remote content, which means that \c file:// will not be able to
+ access \c http://domain.com/foo.html.
+
Scripts can be executed on the web page by using runJavaScript(), either in the main
JavaScript \e world, along with the rest of the JavaScript coming from the web contents, or in
their own isolated world. While the DOM of the page can be accessed from any world, JavaScript
@@ -292,7 +308,7 @@
\since 5.5
This function is called upon receiving a request to navigate to the specified \a url by means of
the specified navigation type \a type. \a isMainFrame indicates whether the request corresponds
- to the main frame or a sub frame. If the function returns \c true, the navigation request is
+ to the main frame or a child frame. If the function returns \c true, the navigation request is
accepted and \c url is loaded. The default implementation accepts all navigation requests.
This function is called for absolute URLs that are prefixed with \c {http://} or \c {https://}
@@ -543,14 +559,14 @@
/*!
\property QWebEnginePage::title
- \brief the title of the frame as defined by the HTML &lt;title&gt; element
+ \brief the title of the page as defined by the HTML \c <title> element
\sa titleChanged()
*/
/*!
\property QWebEnginePage::url
- \brief the URL of the frame currently viewed
+ \brief the URL of the page currently viewed
Setting this property clears the view and loads the URL.
@@ -561,14 +577,14 @@
/*!
\property QWebEnginePage::iconUrl
- \brief the URL of the icon associated with the frame currently viewed.
+ \brief the URL of the icon associated with the page currently viewed.
\sa iconUrlChanged()
*/
/*!
\property QWebEnginePage::requestedUrl
- \brief the URL that was originally requested to be loaded by the frame
+ \brief the URL that was originally requested to be loaded by the page
that is currently viewed
\note The URL may differ from the one returned by url(), which is the actual
@@ -579,7 +595,7 @@
/*!
\fn void QWebEnginePage::load(const QUrl &url)
- Loads \a url into this frame.
+ Loads \a url into this page.
\note The view remains the same until enough data has arrived to display the new URL.
@@ -588,7 +604,7 @@
/*!
\fn void QWebEnginePage::setHtml(const QString &html, const QUrl &baseUrl)
- Sets the content of this page's main frame to \a html. \a baseUrl is optional and used to resolve relative
+ Sets the content of this page to \a html. \a baseUrl is optional and used to resolve relative
URLs in the document, such as referenced images or stylesheets.
The \a html is loaded immediately; external objects are loaded asynchronously.
@@ -604,7 +620,7 @@
This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
- \note This method will not affect session or global history for the frame.
+ \note This method will not affect session or global history for the page.
\warning This function works only for HTML, for other mime types (such as XHTML and SVG)
setContent() should be used instead.
@@ -614,7 +630,7 @@
/*!
\fn void QWebEnginePage::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
- Sets the content of this page's main frame to the specified content \a data. If the \a mimeType argument
+ Sets the content of this page to \a data. If the \a mimeType argument
is empty, it is currently assumed that the content is HTML but in future versions we may introduce
auto-detection.
@@ -622,14 +638,14 @@
The \a data is loaded immediately; external objects are loaded asynchronously.
- \note This method will not affect session or global history for the frame.
+ \note This method will not affect session or global history for the page.
\sa toHtml(), setHtml()
*/
/*!
\property QWebEnginePage::zoomFactor
- \brief the zoom factor for the main frame
+ \brief the zoom factor for the page content
*/
/*!
@@ -724,7 +740,7 @@
/*!
\fn void QWebEnginePage::titleChanged(const QString &title)
- This signal is emitted whenever the title of the main frame changes.
+ This signal is emitted whenever the title of the page changes.
The \a title string specifies the new title.
\sa title()
@@ -733,7 +749,7 @@
/*!
\fn void QWebEnginePage::urlChanged(const QUrl &url)
- This signal is emitted with the URL of the main frame when the main frame's title is
+ This signal is emitted with the URL of the page when the page title is
received. The new URL is specified by \a url.
\sa url()
@@ -742,7 +758,7 @@
/*!
\fn void QWebEnginePage::iconUrlChanged(const QUrl &url)
- This signal is emitted when the icon ("favicon") associated with the main frame is
+ This signal is emitted when the icon ("favicon") associated with the page is
found or changed. The new URL is specified by \a url.
diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
index 07fb5f1cd..d7ecdb246 100644
--- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc
@@ -311,7 +311,7 @@
/*!
\fn void QWebEngineView::titleChanged(const QString &title)
- This signal is emitted whenever the \a title of the main frame changes.
+ This signal is emitted whenever the \a title of the view changes.
\sa title()
*/
@@ -360,10 +360,9 @@
/*!
\fn void QWebEngineView::loadProgress(int progress)
- This signal is emitted every time an element in the web page
- completes loading and the overall loading progress advances.
-
- This signal tracks the progress of all child frames.
+ This signal is emitted every time an element in the web view
+ completes loading, such as an embedded image or a script. Therefore, it
+ tracks the collective progress of loading the web view.
The current value is provided by \a progress and scales from 0 to 100,
which is the default range of QProgressBar.
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 4cfe4e580..8b93c7169 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -159,8 +159,6 @@ private Q_SLOTS:
void renderWidgetHostViewNotShowTopLevel();
void getUserMediaRequest();
- void viewModes();
-
void crashTests_LazyInitializationOfMainFrame();
void screenshot_data();
@@ -213,7 +211,6 @@ private Q_SLOTS:
void setHtmlWithStylesheetResource();
void setHtmlWithBaseURL();
void setHtmlWithJSAlert();
- void metaData();
void inputFieldFocus();
void hitTestContent();
void baseUrl_data();
@@ -670,25 +667,6 @@ void tst_QWebEnginePage::loadHtml5Video()
#endif
}
-void tst_QWebEnginePage::viewModes()
-{
-#if !defined(QWEBENGINEPAGE_VIEW_MODES)
- QSKIP("QWEBENGINEPAGE_VIEW_MODES");
-#else
- m_view->setHtml("<body></body>");
- m_page->setProperty("_q_viewMode", "minimized");
-
- QVariant empty = evaluateJavaScriptSync(m_page, "window.styleMedia.matchMedium(\"(-webengine-view-mode)\")");
- QVERIFY(empty.type() == QVariant::Bool && empty.toBool());
-
- QVariant minimized = evaluateJavaScriptSync(m_page, "window.styleMedia.matchMedium(\"(-webengine-view-mode: minimized)\")");
- QVERIFY(minimized.type() == QVariant::Bool && minimized.toBool());
-
- QVariant maximized = evaluateJavaScriptSync(m_page, "window.styleMedia.matchMedium(\"(-webengine-view-mode: maximized)\")");
- QVERIFY(maximized.type() == QVariant::Bool && !maximized.toBool());
-#endif
-}
-
void tst_QWebEnginePage::modified()
{
#if !defined(QWEBENGINEPAGE_ISMODIFIED)
@@ -4100,47 +4078,6 @@ void tst_QWebEnginePage::setHtmlWithJSAlert()
QCOMPARE(toHtmlSync(&page), html);
}
-void tst_QWebEnginePage::metaData()
-{
-#if !defined(QWEBENGINEPAGE_METADATA)
- QSKIP("QWEBENGINEPAGE_METADATA");
-#else
- m_view->setHtml("<html>"
- " <head>"
- " <meta name=\"description\" content=\"Test description\">"
- " <meta name=\"keywords\" content=\"HTML, JavaScript, Css\">"
- " </head>"
- "</html>");
-
- QMultiMap<QString, QString> metaData = m_view->page()->metaData();
-
- QCOMPARE(metaData.count(), 2);
-
- QCOMPARE(metaData.value("description"), QString("Test description"));
- QCOMPARE(metaData.value("keywords"), QString("HTML, JavaScript, Css"));
- QCOMPARE(metaData.value("nonexistent"), QString());
-
- m_view->setHtml("<html>"
- " <head>"
- " <meta name=\"samekey\" content=\"FirstValue\">"
- " <meta name=\"samekey\" content=\"SecondValue\">"
- " </head>"
- "</html>");
-
- metaData = m_view->page()->metaData();
-
- QCOMPARE(metaData.count(), 2);
-
- QStringList values = metaData.values("samekey");
- QCOMPARE(values.count(), 2);
-
- QVERIFY(values.contains("FirstValue"));
- QVERIFY(values.contains("SecondValue"));
-
- QCOMPARE(metaData.value("nonexistent"), QString());
-#endif
-}
-
void tst_QWebEnginePage::inputFieldFocus()
{
#if !defined(QWEBENGINEELEMENT)
diff --git a/tools/qmake/mkspecs/features/default_pre.prf b/tools/qmake/mkspecs/features/default_pre.prf
index 6506e67ad..cb0625c2e 100644
--- a/tools/qmake/mkspecs/features/default_pre.prf
+++ b/tools/qmake/mkspecs/features/default_pre.prf
@@ -19,6 +19,9 @@ load(functions)
equals(_PRO_FILE_, "$$QTWEBENGINE_ROOT/qtwebengine.pro"): CONFIG += root_project_file
root_project_file:isPlatformSupported() {
+ !exists($$QTWEBENGINE_ROOT/src/3rdparty/chromium) {
+ error("Submodule qtwebengine-chromium does not exist. Run 'git submodule update --init'.")
+ }
load(configure)
runConfigure()
}