Merge branch 'webengine' into v1.3

This commit is contained in:
Andrei Yankovich 2019-09-19 10:25:31 +03:00
commit a866849315
24 changed files with 2706 additions and 17 deletions

View File

@ -18,11 +18,17 @@ SUBDIRS += QuasarAppLib \
tests/TestQMLWidgets
}
contains(DEFINES, WITH_ALL_TESTS) {
SUBDIRS += tests/quicknanobrowser
}
contains(DEFINES, WITHOUT_TESTS) {
SUBDIRS -= UnitTests \
tests/TestOnlyC \
tests/TestQtWidgets \
tests/TestQMLWidgets
tests/TestQMLWidgets \
tests/quicknanobrowser
}
CQtDeployer.depends=QuasarAppLib

View File

@ -35,6 +35,30 @@ bool Extracter::deployMSVC() {
return _fileManager->copyFile(msvcInstaller, DeployCore::_config->targetDir);
}
bool Extracter::extractWebEngine() {
auto test = static_cast<quint64>(_qtModules) & static_cast<quint64>(DeployCore::QtModule::QtWebEngineModule);
if (test) {
#ifdef Q_OS_UNIX
auto webEngeneBin = DeployCore::_config->qtDir + "/libexec/QtWebEngineProcess";
#else
auto webEngeneBin = DeployCore::_config->qtDir + "/bin/QtWebEngineProcess.exe";
#endif
auto destWebEngine = DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getBinOutDir();
auto resOut = DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getResOutDir();
auto res = DeployCore::_config->qtDir + "/resources/";
if (!_fileManager->copyFile(webEngeneBin, destWebEngine)) {
return false;
}
if (!_fileManager->copyFolder(res, resOut)) {
return false;
}
}
return true;
}
bool Extracter::copyPlugin(const QString &plugin) {
QStringList listItems;
@ -159,6 +183,10 @@ void Extracter::deploy() {
copyTr();
if (!extractWebEngine()) {
QuasarAppUtils::Params::verboseLog("deploy webEngine failed", QuasarAppUtils::Error);
}
if (!deployMSVC()) {
QuasarAppUtils::Params::verboseLog("deploy msvc failed");
}
@ -189,6 +217,14 @@ bool Extracter::copyTranslations(QStringList list) {
_fileManager->copyFile(i.absoluteFilePath(), DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getTrOutDir());
}
auto webEngine = static_cast<quint64>(_qtModules) & static_cast<quint64>(DeployCore::QtModule::QtWebEngineModule);
if (webEngine) {
auto trOut = DeployCore::_config->targetDir + DeployCore::_config->distroStruct.getTrOutDir();
auto tr = DeployCore::_config->qtDir + "/translations/qtwebengine_locales";
_fileManager->copyFolder(tr, trOut + "/qtwebengine_locales");
}
return true;
}

View File

@ -42,6 +42,7 @@ class DEPLOYSHARED_EXPORT Extracter {
void extractLib(const QString & file);
bool deployMSVC();
bool extractWebEngine();
bool copyPlugin(const QString &plugin);

View File

@ -52,6 +52,7 @@ bool MetaFileManager::createRunScriptLinux(const QString &target) {
"export QML_IMPORT_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getQmlOutDir() + ":QML_IMPORT_PATH\n"
"export QML2_IMPORT_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getQmlOutDir() + ":QML2_IMPORT_PATH\n"
"export QT_PLUGIN_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getPluginsOutDir() + ":QT_PLUGIN_PATH\n"
"export QTWEBENGINEPROCESS_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getBinOutDir() + "/QtWebEngineProcess\n"
"export QTDIR=\"$BASE_DIR\"\n"
"export "
"QT_QPA_PLATFORM_PLUGIN_PATH=\"$BASE_DIR\"" + DeployCore::_config->distroStruct.getPluginsOutDir() +
@ -113,11 +114,12 @@ bool MetaFileManager::createQConf() {
QString content =
"[Paths]\n"
"Prefix= ./\n"
"Libraries= ." + DeployCore::_config->distroStruct.getLibOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n"
"Plugins= ." + DeployCore::_config->distroStruct.getPluginsOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n"
"Imports= ." + DeployCore::_config->distroStruct.getQmlOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n"
"Qml2Imports= ." + DeployCore::_config->distroStruct.getQmlOutDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n";
"Prefix= ." + DeployCore::_config->distroStruct.getRootDir(DeployCore::_config->distroStruct.getBinOutDir()) + "\n"
"Libraries= ." + DeployCore::_config->distroStruct.getLibOutDir() + "\n"
"Plugins= ." + DeployCore::_config->distroStruct.getPluginsOutDir() + "\n"
"Imports= ." + DeployCore::_config->distroStruct.getQmlOutDir() + "\n"
"Translations= ." + DeployCore::_config->distroStruct.getTrOutDir() + "\n"
"Qml2Imports= ." + DeployCore::_config->distroStruct.getQmlOutDir() + "\n";
content.replace("//", "/");
@ -144,20 +146,15 @@ bool MetaFileManager::createQConf() {
}
void MetaFileManager::createRunMetaFiles() {
bool targetWindows = false;
for (auto i = DeployCore::_config->targets.cbegin(); i != DeployCore::_config->targets.cend(); ++i) {
if (QFileInfo(i.key()).completeSuffix().compare("exe", Qt::CaseInsensitive) == 0) {
targetWindows = true;
}
if (i.value() && !createRunScript(i.key())) {
qCritical() << "run script not created!";
}
}
if (targetWindows && !createQConf()) {
if (!createQConf()) {
QuasarAppUtils::Params::verboseLog("create qt.conf failr", QuasarAppUtils::Warning);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@ public:
static QSet<QString> qtLibs();
static QSet<QString> qmlLibs();
static QSet<QString> qtWithoutTr();
static QSet<QString> qtWebEngine();
};

View File

@ -107,6 +107,7 @@ private slots:
void testEmptyParamsString();
void testWebEngine();
};
bool deploytest::runProcess(const QString &DistroPath,
@ -450,8 +451,8 @@ void deploytest::testEmptyParamsString() {
QDir("./" + DISTRO_DIR).removeRecursively();
auto comapareTree = utils.createTree({
"./DistributionKit/UnitTests.sh",
"./DistributionKit/bin/UnitTests",
"./" + DISTRO_DIR + "/UnitTests.sh",
"./" + DISTRO_DIR + "/bin/UnitTests",
});
runTestParams({}, &comapareTree);
@ -462,8 +463,8 @@ void deploytest::testEmptyParamsString() {
runTestParams({"clear"}, &comapareTree);
comapareTree = utils.createTree({
"./DistributionKit/UnitTests.sh",
"./DistributionKit/bin/UnitTests",
"./" + DISTRO_DIR + "/UnitTests.sh",
"./" + DISTRO_DIR + "/bin/UnitTests",
});
@ -478,6 +479,31 @@ void deploytest::testEmptyParamsString() {
#endif
}
void deploytest::testWebEngine() {
#ifdef WITH_ALL_TESTS
TestUtils utils;
#ifdef Q_OS_UNIX
QString bin = TestBinDir + "quicknanobrowser";
QString qmake = TestQtDir + "bin/qmake";
#else
QString bin = TestBinDir + "quicknanobrowser.exe";
QString qmake = TestQtDir + "bin/qmake.exe";
#endif
auto comapareTree = Modules::qtWebEngine();
runTestParams({"-bin", bin, "clear" ,
"-qmake", qmake,
"-qmlDir", TestBinDir + "/../quicknanobrowser"}, &comapareTree);
#endif
}
void deploytest::testQmlExtrct() {
QmlCreator creator("./");
auto imports = creator.getQmlImports();
@ -635,6 +661,7 @@ void deploytest::testOverwrite() {
QFile f("./" + DISTRO_DIR + "/bin/TestOnlyC");
auto comapareTree = utils.createTree(
{"./" + DISTRO_DIR + "/bin/TestOnlyC",
"./" + DISTRO_DIR + "/bin/qt.conf",
"./" + DISTRO_DIR + "/TestOnlyC.sh"});
QString bin = TestBinDir + "TestOnlyC";
@ -689,6 +716,7 @@ void deploytest::testBinDir() {
#ifdef Q_OS_UNIX
auto comapareTree = utils.createTree(
{"./" + DISTRO_DIR + "/bin/TestOnlyC",
"./" + DISTRO_DIR + "/bin/qt.conf",
"./" + DISTRO_DIR + "/bin/QtWidgetsProject",
"./" + DISTRO_DIR + "/bin/TestQMLWidgets",
"./" + DISTRO_DIR + "/TestOnlyC.sh",
@ -715,6 +743,7 @@ void deploytest::testConfFile() {
#ifdef Q_OS_UNIX
auto comapareTree = utils.createTree(
{"./" + DISTRO_DIR + "/bin/TestOnlyC",
"./" + DISTRO_DIR + "/bin/qt.conf",
"./" + DISTRO_DIR + "/bin/QtWidgetsProject",
"./" + DISTRO_DIR + "/bin/TestQMLWidgets",
"./" + DISTRO_DIR + "/TestOnlyC.sh",
@ -728,6 +757,11 @@ void deploytest::testConfFile() {
"./" + DISTRO_DIR + "/qt.conf"});
#endif
#ifdef WITH_ALL_TESTS
auto comapareTree = comapareTree + utils.createTree(
{"./" + DISTRO_DIR + "/bin/quicknanobrowser",
"./" + DISTRO_DIR + "/quicknanobrowser.sh"});
#endif
runTestParams({"-bin", TestBinDir, "clear" ,
"-confFile", TestBinDir + "/TestConf.json"}, &comapareTree);
@ -843,7 +877,8 @@ void deploytest::testIgnore() {
auto comapareTree = utils.createTree(
{
"./" + DISTRO_DIR + "/QtWidgetsProject.sh",
"./" + DISTRO_DIR + "/QtWidgetsProject.sh"
"./" + DISTRO_DIR + "/bin/qt.conf",
"./" + DISTRO_DIR + "/bin/QtWidgetsProject",
"./" + DISTRO_DIR + "/lib/libicudata.so",
"./" + DISTRO_DIR + "/lib/libicui18n.so",
@ -893,6 +928,7 @@ void deploytest::testLibDir() {
auto comapareTree = utils.createTree(
{
"./" + DISTRO_DIR + "/TestOnlyC.sh",
"./" + DISTRO_DIR + "/bin/qt.conf"
"./" + DISTRO_DIR + "/bin/TestOnlyC"
});
@ -904,6 +940,7 @@ void deploytest::testLibDir() {
comapareTree = utils.createTree(
{
"./" + DISTRO_DIR + "/TestOnlyC.sh",
"./" + DISTRO_DIR + "/bin/qt.conf"
"./" + DISTRO_DIR + "/bin/TestOnlyC",
"./" + DISTRO_DIR + "/lib/libstdc++.so",
"./" + DISTRO_DIR + "/lib/libgcc_s.so"
@ -943,6 +980,7 @@ void deploytest::testExtraPlugins() {
auto pluginTree = utils.createTree(
{
"./" + DISTRO_DIR + "/bin/qt.conf",
"./" + DISTRO_DIR + "/plugins/sqldrivers/libqsqlodbc.so",
"./" + DISTRO_DIR + "/plugins/sqldrivers/libqsqlpsql.so",
"./" + DISTRO_DIR + "/plugins/sqldrivers/libqsqlite.so",
@ -972,6 +1010,7 @@ void deploytest::testTargetDir() {
auto comapareTree = utils.createTree(
{"./" + DISTRO_DIR + "Z/bin/TestOnlyC",
"./" + DISTRO_DIR + "Z/bin/qt.conf",
"./" + DISTRO_DIR + "Z/TestOnlyC.sh"});
runTestParams({"-bin", bin, "clear" ,
@ -994,6 +1033,7 @@ void deploytest::testSystemLib() {
auto comapareTree = utils.createTree(
{
"./" + DISTRO_DIR + "/TestOnlyC.sh",
"./" + DISTRO_DIR + "/bin/qt.conf"
"./" + DISTRO_DIR + "/bin/TestOnlyC",
"./" + DISTRO_DIR + "/lib/ld-linux-x86-64.so",
"./" + DISTRO_DIR + "/lib/libc.so",
@ -1020,6 +1060,7 @@ void deploytest::testSystemLib() {
comapareTree = utils.createTree(
{
"./" + DISTRO_DIR + "/TestOnlyC.sh",
"./" + DISTRO_DIR + "/bin/qt.conf"
"./" + DISTRO_DIR + "/bin/TestOnlyC",
"./" + DISTRO_DIR + "/lib/libgcc_s.so",
"./" + DISTRO_DIR + "/lib/libstdc++.so"

View File

@ -0,0 +1,89 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
import QtQuick 2.1
import QtWebEngine 1.9
QtObject {
id: root
property QtObject defaultProfile: WebEngineProfile {
storageName: "Profile"
offTheRecord: false
useForGlobalCertificateVerification: true
}
property QtObject otrProfile: WebEngineProfile {
offTheRecord: true
}
property Component browserWindowComponent: BrowserWindow {
applicationRoot: root
onClosing: destroy()
}
property Component browserDialogComponent: BrowserDialog {
onClosing: destroy()
}
function createWindow(profile) {
var newWindow = browserWindowComponent.createObject(root);
newWindow.currentWebView.profile = profile;
profile.downloadRequested.connect(newWindow.onDownloadRequested);
return newWindow;
}
function createDialog(profile) {
var newDialog = browserDialogComponent.createObject(root);
newDialog.currentWebView.profile = profile;
return newDialog;
}
function load(url) {
var browserWindow = createWindow(defaultProfile);
browserWindow.currentWebView.url = url;
}
}

View File

@ -0,0 +1,74 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Window 2.2
import QtWebEngine 1.9
Window {
id: window
property alias currentWebView: webView
flags: Qt.Dialog | Qt.WindowStaysOnTopHint
width: 800
height: 600
visible: true
onClosing: destroy()
WebEngineView {
id: webView
anchors.fill: parent
onGeometryChangeRequested: function(geometry) {
window.x = geometry.x
window.y = geometry.y
window.width = geometry.width
window.height = geometry.height
}
}
}

View File

@ -0,0 +1,654 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
import Qt.labs.settings 1.0
import QtQml 2.2
import QtQuick 2.2
import QtQuick.Controls 1.0
import QtQuick.Controls.Private 1.0 as QQCPrivate
import QtQuick.Controls.Styles 1.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.0
import QtQuick.Window 2.1
import QtWebEngine 1.9
ApplicationWindow {
id: browserWindow
property QtObject applicationRoot
property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
property int previousVisibility: Window.Windowed
width: 1300
height: 900
visible: true
title: currentWebView && currentWebView.title
// Make sure the Qt.WindowFullscreenButtonHint is set on OS X.
Component.onCompleted: flags = flags | Qt.WindowFullscreenButtonHint
// Create a styleItem to determine the platform.
// When using style "mac", ToolButtons are not supposed to accept focus.
QQCPrivate.StyleItem { id: styleItem }
property bool platformIsMac: styleItem.style == "mac"
Settings {
id : appSettings
property alias autoLoadImages: loadImages.checked
property alias javaScriptEnabled: javaScriptEnabled.checked
property alias errorPageEnabled: errorPageEnabled.checked
property alias pluginsEnabled: pluginsEnabled.checked
property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked
property alias autoLoadIconsForPage: autoLoadIconsForPage.checked
property alias touchIconsEnabled: touchIconsEnabled.checked
property alias webRTCPublicInterfacesOnly : webRTCPublicInterfacesOnly.checked
property alias devToolsEnabled: devToolsEnabled.checked
property alias pdfViewerEnabled: pdfViewerEnabled.checked
}
Action {
shortcut: "Ctrl+D"
onTriggered: {
downloadView.visible = !downloadView.visible;
}
}
Action {
id: focus
shortcut: "Ctrl+L"
onTriggered: {
addressBar.forceActiveFocus();
addressBar.selectAll();
}
}
Action {
shortcut: StandardKey.Refresh
onTriggered: {
if (currentWebView)
currentWebView.reload();
}
}
Action {
shortcut: StandardKey.AddTab
onTriggered: {
tabs.createEmptyTab(tabs.count != 0 ? currentWebView.profile : defaultProfile);
tabs.currentIndex = tabs.count - 1;
addressBar.forceActiveFocus();
addressBar.selectAll();
}
}
Action {
shortcut: StandardKey.Close
onTriggered: {
currentWebView.triggerWebAction(WebEngineView.RequestClose);
}
}
Action {
shortcut: "Escape"
onTriggered: {
if (currentWebView.state == "FullScreen") {
browserWindow.visibility = browserWindow.previousVisibility;
fullScreenNotification.hide();
currentWebView.triggerWebAction(WebEngineView.ExitFullScreen);
}
}
}
Action {
shortcut: "Ctrl+0"
onTriggered: currentWebView.zoomFactor = 1.0
}
Action {
shortcut: StandardKey.ZoomOut
onTriggered: currentWebView.zoomFactor -= 0.1
}
Action {
shortcut: StandardKey.ZoomIn
onTriggered: currentWebView.zoomFactor += 0.1
}
Action {
shortcut: StandardKey.Copy
onTriggered: currentWebView.triggerWebAction(WebEngineView.Copy)
}
Action {
shortcut: StandardKey.Cut
onTriggered: currentWebView.triggerWebAction(WebEngineView.Cut)
}
Action {
shortcut: StandardKey.Paste
onTriggered: currentWebView.triggerWebAction(WebEngineView.Paste)
}
Action {
shortcut: "Shift+"+StandardKey.Paste
onTriggered: currentWebView.triggerWebAction(WebEngineView.PasteAndMatchStyle)
}
Action {
shortcut: StandardKey.SelectAll
onTriggered: currentWebView.triggerWebAction(WebEngineView.SelectAll)
}
Action {
shortcut: StandardKey.Undo
onTriggered: currentWebView.triggerWebAction(WebEngineView.Undo)
}
Action {
shortcut: StandardKey.Redo
onTriggered: currentWebView.triggerWebAction(WebEngineView.Redo)
}
Action {
shortcut: StandardKey.Back
onTriggered: currentWebView.triggerWebAction(WebEngineView.Back)
}
Action {
shortcut: StandardKey.Forward
onTriggered: currentWebView.triggerWebAction(WebEngineView.Forward)
}
toolBar: ToolBar {
id: navigationBar
RowLayout {
anchors.fill: parent
ToolButton {
enabled: currentWebView && (currentWebView.canGoBack || currentWebView.canGoForward)
menu:Menu {
id: historyMenu
Instantiator {
model: currentWebView && currentWebView.navigationHistory.items
MenuItem {
text: model.title
onTriggered: currentWebView.goBackOrForward(model.offset)
checkable: !enabled
checked: !enabled
enabled: model.offset
}
onObjectAdded: function(index, object) {
historyMenu.insertItem(index, object)
}
onObjectRemoved: function(index, object) {
historyMenu.removeItem(object)
}
}
}
}
ToolButton {
id: backButton
iconSource: "icons/go-previous.png"
onClicked: currentWebView.goBack()
enabled: currentWebView && currentWebView.canGoBack
activeFocusOnTab: !browserWindow.platformIsMac
}
ToolButton {
id: forwardButton
iconSource: "icons/go-next.png"
onClicked: currentWebView.goForward()
enabled: currentWebView && currentWebView.canGoForward
activeFocusOnTab: !browserWindow.platformIsMac
}
ToolButton {
id: reloadButton
iconSource: currentWebView && currentWebView.loading ? "icons/process-stop.png" : "icons/view-refresh.png"
onClicked: currentWebView && currentWebView.loading ? currentWebView.stop() : currentWebView.reload()
activeFocusOnTab: !browserWindow.platformIsMac
}
TextField {
id: addressBar
Image {
anchors.verticalCenter: addressBar.verticalCenter;
x: 5
z: 2
id: faviconImage
width: 16; height: 16
sourceSize: Qt.size(width, height)
source: currentWebView && currentWebView.icon
}
style: TextFieldStyle {
padding {
left: 26;
}
}
focus: true
Layout.fillWidth: true
text: currentWebView && currentWebView.url
onAccepted: currentWebView.url = utils.fromUserInput(text)
}
ToolButton {
id: settingsMenuButton
menu: Menu {
MenuItem {
id: loadImages
text: "Autoload images"
checkable: true
checked: WebEngine.settings.autoLoadImages
}
MenuItem {
id: javaScriptEnabled
text: "JavaScript On"
checkable: true
checked: WebEngine.settings.javascriptEnabled
}
MenuItem {
id: errorPageEnabled
text: "ErrorPage On"
checkable: true
checked: WebEngine.settings.errorPageEnabled
}
MenuItem {
id: pluginsEnabled
text: "Plugins On"
checkable: true
checked: true
}
MenuItem {
id: fullScreenSupportEnabled
text: "FullScreen On"
checkable: true
checked: WebEngine.settings.fullScreenSupportEnabled
}
MenuItem {
id: offTheRecordEnabled
text: "Off The Record"
checkable: true
checked: currentWebView && currentWebView.profile === otrProfile
onToggled: function(checked) {
if (currentWebView) {
currentWebView.profile = checked ? otrProfile : defaultProfile;
}
}
}
MenuItem {
id: httpDiskCacheEnabled
text: "HTTP Disk Cache"
checkable: currentWebView && !currentWebView.profile.offTheRecord
checked: currentWebView && (currentWebView.profile.httpCacheType === WebEngineProfile.DiskHttpCache)
onToggled: function(checked) {
if (currentWebView) {
currentWebView.profile.httpCacheType = checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache;
}
}
}
MenuItem {
id: autoLoadIconsForPage
text: "Icons On"
checkable: true
checked: WebEngine.settings.autoLoadIconsForPage
}
MenuItem {
id: touchIconsEnabled
text: "Touch Icons On"
checkable: true
checked: WebEngine.settings.touchIconsEnabled
enabled: autoLoadIconsForPage.checked
}
MenuItem {
id: webRTCPublicInterfacesOnly
text: "WebRTC Public Interfaces Only"
checkable: true
checked: WebEngine.settings.webRTCPublicInterfacesOnly
}
MenuItem {
id: devToolsEnabled
text: "Open DevTools"
checkable: true
checked: false
}
MenuItem {
id: pdfViewerEnabled
text: "PDF viewer enabled"
checkable: true
checked: WebEngine.settings.pdfViewerEnabled
}
}
}
}
ProgressBar {
id: progressBar
height: 3
anchors {
left: parent.left
top: parent.bottom
right: parent.right
leftMargin: -parent.leftMargin
rightMargin: -parent.rightMargin
}
style: ProgressBarStyle {
background: Item {}
}
z: -2;
minimumValue: 0
maximumValue: 100
value: (currentWebView && currentWebView.loadProgress < 100) ? currentWebView.loadProgress : 0
}
}
TabView {
id: tabs
function createEmptyTab(profile) {
var tab = addTab("", tabComponent);
// We must do this first to make sure that tab.active gets set so that tab.item gets instantiated immediately.
tab.active = true;
tab.title = Qt.binding(function() { return tab.item.title });
tab.item.profile = profile;
return tab;
}
anchors.top: parent.top
anchors.bottom: devToolsView.top
anchors.left: parent.left
anchors.right: parent.right
Component.onCompleted: createEmptyTab(defaultProfile)
// Add custom tab view style so we can customize the tabs to include a close button
style: TabViewStyle {
property color frameColor: "#999"
property color fillColor: "#eee"
property color nonSelectedColor: "#ddd"
frameOverlap: 1
frame: Rectangle {
color: "#eee"
border.color: frameColor
}
tab: Rectangle {
id: tabRectangle
color: styleData.selected ? fillColor : nonSelectedColor
border.width: 1
border.color: frameColor
implicitWidth: Math.max(text.width + 30, 80)
implicitHeight: Math.max(text.height + 10, 20)
Rectangle { height: 1 ; width: parent.width ; color: frameColor}
Rectangle { height: parent.height ; width: 1; color: frameColor}
Rectangle { x: parent.width - 2; height: parent.height ; width: 1; color: frameColor}
Text {
id: text
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 6
text: styleData.title
elide: Text.ElideRight
color: styleData.selected ? "black" : frameColor
}
Button {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 4
height: 12
style: ButtonStyle {
background: Rectangle {
implicitWidth: 12
implicitHeight: 12
color: control.hovered ? "#ccc" : tabRectangle.color
Text {text: "x" ; anchors.centerIn: parent ; color: "gray"}
}}
onClicked: tabs.removeTab(styleData.index);
}
}
}
Component {
id: tabComponent
WebEngineView {
id: webEngineView
focus: true
onLinkHovered: function(hoveredUrl) {
if (hoveredUrl == "")
hideStatusText.start();
else {
statusText.text = hoveredUrl;
statusBubble.visible = true;
hideStatusText.stop();
}
}
states: [
State {
name: "FullScreen"
PropertyChanges {
target: tabs
frameVisible: false
tabsVisible: false
}
PropertyChanges {
target: navigationBar
visible: false
}
}
]
settings.autoLoadImages: appSettings.autoLoadImages
settings.javascriptEnabled: appSettings.javaScriptEnabled
settings.errorPageEnabled: appSettings.errorPageEnabled
settings.pluginsEnabled: appSettings.pluginsEnabled
settings.fullScreenSupportEnabled: appSettings.fullScreenSupportEnabled
settings.autoLoadIconsForPage: appSettings.autoLoadIconsForPage
settings.touchIconsEnabled: appSettings.touchIconsEnabled
settings.webRTCPublicInterfacesOnly: appSettings.webRTCPublicInterfacesOnly
settings.pdfViewerEnabled: appSettings.pdfViewerEnabled
onCertificateError: function(error) {
error.defer();
sslDialog.enqueue(error);
}
onNewViewRequested: function(request) {
if (!request.userInitiated)
print("Warning: Blocked a popup window.");
else if (request.destination === WebEngineView.NewViewInTab) {
var tab = tabs.createEmptyTab(currentWebView.profile);
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
} else if (request.destination === WebEngineView.NewViewInBackgroundTab) {
var backgroundTab = tabs.createEmptyTab(currentWebView.profile);
request.openIn(backgroundTab.item);
} else if (request.destination === WebEngineView.NewViewInDialog) {
var dialog = applicationRoot.createDialog(currentWebView.profile);
request.openIn(dialog.currentWebView);
} else {
var window = applicationRoot.createWindow(currentWebView.profile);
request.openIn(window.currentWebView);
}
}
onFullScreenRequested: function(request) {
if (request.toggleOn) {
webEngineView.state = "FullScreen";
browserWindow.previousVisibility = browserWindow.visibility;
browserWindow.showFullScreen();
fullScreenNotification.show();
} else {
webEngineView.state = "";
browserWindow.visibility = browserWindow.previousVisibility;
fullScreenNotification.hide();
}
request.accept();
}
onQuotaRequested: function(request) {
if (request.requestedSize <= 5 * 1024 * 1024)
request.accept();
else
request.reject();
}
onRegisterProtocolHandlerRequested: function(request) {
console.log("accepting registerProtocolHandler request for "
+ request.scheme + " from " + request.origin);
request.accept();
}
onRenderProcessTerminated: function(terminationStatus, exitCode) {
var status = "";
switch (terminationStatus) {
case WebEngineView.NormalTerminationStatus:
status = "(normal exit)";
break;
case WebEngineView.AbnormalTerminationStatus:
status = "(abnormal exit)";
break;
case WebEngineView.CrashedTerminationStatus:
status = "(crashed)";
break;
case WebEngineView.KilledTerminationStatus:
status = "(killed)";
break;
}
print("Render process exited with code " + exitCode + " " + status);
reloadTimer.running = true;
}
onWindowCloseRequested: {
if (tabs.count == 1)
browserWindow.close();
else
tabs.removeTab(tabs.currentIndex);
}
onSelectClientCertificate: function(selection) {
selection.certificates[0].select();
}
Timer {
id: reloadTimer
interval: 0
running: false
repeat: false
onTriggered: currentWebView.reload()
}
}
}
}
WebEngineView {
id: devToolsView
visible: devToolsEnabled.checked
height: visible ? 400 : 0
inspectedView: visible && tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
onNewViewRequested: function(request) {
var tab = tabs.createEmptyTab(currentWebView.profile);
tabs.currentIndex = tabs.count - 1;
request.openIn(tab.item);
}
}
MessageDialog {
id: sslDialog
property var certErrors: []
icon: StandardIcon.Warning
standardButtons: StandardButton.No | StandardButton.Yes
title: "Server's certificate not trusted"
text: "Do you wish to continue?"
detailedText: "If you wish so, you may continue with an unverified certificate. " +
"Accepting an unverified certificate means " +
"you may not be connected with the host you tried to connect to.\n" +
"Do you wish to override the security check and continue?"
onYes: {
certErrors.shift().ignoreCertificateError();
presentError();
}
onNo: reject()
onRejected: reject()
function reject(){
certErrors.shift().rejectCertificate();
presentError();
}
function enqueue(error){
certErrors.push(error);
presentError();
}
function presentError(){
visible = certErrors.length > 0
}
}
FullScreenNotification {
id: fullScreenNotification
}
DownloadView {
id: downloadView
visible: false
anchors.fill: parent
}
function onDownloadRequested(download) {
downloadView.visible = true;
downloadView.append(download);
download.accept();
}
Rectangle {
id: statusBubble
color: "oldlace"
property int padding: 8
visible: false
anchors.left: parent.left
anchors.bottom: parent.bottom
width: statusText.paintedWidth + padding
height: statusText.paintedHeight + padding
Text {
id: statusText
anchors.centerIn: statusBubble
elide: Qt.ElideMiddle
Timer {
id: hideStatusText
interval: 750
onTriggered: {
statusText.text = "";
statusBubble.visible = false;
}
}
}
}
}

View File

@ -0,0 +1,175 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.0
import QtWebEngine 1.9
import QtQuick.Layouts 1.0
Rectangle {
id: downloadView
color: "lightgray"
ListModel {
id: downloadModel
property var downloads: []
}
function append(download) {
downloadModel.append(download);
downloadModel.downloads.push(download);
}
Component {
id: downloadItemDelegate
Rectangle {
width: listView.width
height: childrenRect.height
anchors.margins: 10
radius: 3
color: "transparent"
border.color: "black"
Rectangle {
id: progressBar
property real progress: downloadModel.downloads[index]
? downloadModel.downloads[index].receivedBytes / downloadModel.downloads[index].totalBytes : 0
radius: 3
color: width == listView.width ? "green" : "#2b74c7"
width: listView.width * progress
height: cancelButton.height
Behavior on width {
SmoothedAnimation { duration: 100 }
}
}
Rectangle {
anchors {
left: parent.left
right: parent.right
leftMargin: 20
}
Label {
id: label
text: path
anchors {
verticalCenter: cancelButton.verticalCenter
left: parent.left
right: cancelButton.left
}
}
Button {
id: cancelButton
anchors.right: parent.right
iconSource: "icons/process-stop.png"
onClicked: {
var download = downloadModel.downloads[index];
download.cancel();
downloadModel.downloads = downloadModel.downloads.filter(function (el) {
return el.id !== download.id;
});
downloadModel.remove(index);
}
}
}
}
}
ListView {
id: listView
anchors {
topMargin: 10
top: parent.top
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
}
width: parent.width - 20
spacing: 5
model: downloadModel
delegate: downloadItemDelegate
Text {
visible: !listView.count
horizontalAlignment: Text.AlignHCenter
height: 30
anchors {
top: parent.top
left: parent.left
right: parent.right
}
font.pixelSize: 20
text: "No active downloads."
}
Rectangle {
color: "gray"
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
}
height: 30
Button {
id: okButton
text: "OK"
anchors.centerIn: parent
onClicked: {
downloadView.visible = false;
}
}
}
}
}

View File

@ -0,0 +1,109 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
import QtQuick 2.5
Rectangle {
id: fullScreenNotification
width: 500
height: 40
color: "white"
radius: 7
visible: false
opacity: 0
function show() {
visible = true;
opacity = 1;
reset.start();
}
function hide() {
reset.stop();
opacity = 0;
}
Behavior on opacity {
NumberAnimation {
duration: 750
onStopped: {
if (opacity == 0)
visible = false;
}
}
}
Timer {
id: reset
interval: 5000
onTriggered: hide()
}
anchors.horizontalCenter: parent.horizontalCenter
y: 125
Text {
id: message
width: parent.width
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
elide: Text.ElideNone
clip: true
text: qsTr("You are now in fullscreen mode. Press ESC to quit!")
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,149 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example webengine/quicknanobrowser
\title WebEngine Quick Nano Browser
\ingroup webengine-examples
\brief A web browser implemented using the WebEngineView QML type.
\image quicknanobrowser-demo.jpg
\e {Quick Nano Browser} demonstrates how to use the \l{Qt WebEngine QML Types}
{Qt WebEngine QML types} to develop a small web browser application that consists of a browser
window with a title bar, toolbar, tab view, and status bar. The web content is loaded in a web
engine view within the tab view. If certificate errors occur, users are prompted for action in a
message dialog. The status bar pops up to display the URL of a hovered link.
A web page can issue a request for being displayed in fullscreen mode. Users can allow full
screen mode by using a toolbar button. They can leave fullscreen mode by using a keyboard
shortcut. Additional toolbar buttons enable moving backwards and forwards in the browser
history, reloading tab content, and opening a settings menu for enabling the following features:
JavaScript, plugins, fullscreen mode, off the record, HTTP disk cache, autoloading images, and
ignoring certificate errors.
\include examples-run.qdocinc
\section1 Creating the Main Browser Window
When the browser main window is loaded, it creates an empty tab using the default profile. Each
tab is a web engine view that fills the main window.
We create the main window in the \e BrowserWindow.qml file using the ApplicationWindow type:
\quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
\skipto ApplicationWindow
\printuntil currentWebView
\dots
\skipto width
\printuntil title
We use the TabView Qt Quick control to create an empty tab view that fills the main window. We
set the tab active first, to make sure that the tab item is immediately instantiated:
\skipto TabView
\printuntil Component.onCompleted
The tab contains a web engine view that loads web content:
\printuntil focus
We use the \l Action type to create new tabs:
\quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
\skipto reload
\skipto Action
\printuntil }
We use the \l TextField Qt Quick Control within a \l ToolBar to create an address bar that
shows the current URL and where users can enter another URL:
\skipto toolBar
\printuntil anchors.fill
\dots
\skipto TextField
\printuntil addressBar
\dots
\skipto focus
\printuntil /^\ {16}\}/
\section1 Handling Certificate Errors
If the certificate of the site being loaded triggers a certificate error, we call the
\l{WebEngineCertificateError::}{defer()} QML method to pause the URL request and wait for user
input:
\quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
\skipto onCertificateError
\printuntil }
We use the MessageDialog type to prompt users to continue or cancel the loading of the web page.
If users select \uicontrol Yes, we call the
\l{WebEngineCertificateError::}{ignoreCertificateError()} method to ignore the error and
continue loading content from the URL. If users select \uicontrol No, we call the
\l{WebEngineCertificateError::}{rejectCertificate()} method to reject the request and stop
loading content from the URL:
\skipto MessageDialog
\printuntil /^\ {4}\}/
\section1 Entering and Leaving Fullscreen Mode
We create a menu item for allowing fullscreen mode in a settings menu that we place on the tool
bar. Also, we create an action for leaving fullscreen mode by using a keyboard shortcut.
We call the \l{FullScreenRequest::}{accept()} method to accept the fullscreen request.
The methdod sets the \l{WebEngineView::}{isFullScreen} property to be equal to the
\l{FullScreenRequest::}{toggleOn} property.
\quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
\skipto onFullScreenRequested
\printuntil /^\ {16}\}/
When entering fullscreen mode, we display a notification using the FullScreenNotification custom
type that we create in \e FullScreenNotification.qml.
We use the \l Action type in the settings menu to create a shortcut for leaving fullscreen mode
by pressing the escape key:
\quotefromfile webengine/quicknanobrowser/BrowserWindow.qml
\skipto Settings
\printuntil appSettings
\skipto fullScreenSupportEnabled
\printuntil Action
\skipto Escape
\printuntil /^\ {4}\}/
\section1 Files and Attributions
The example uses icons from the Tango Icon Library:
\table
\row
\li \l{quicknanobrowser-tango}{Tango Icon Library}
\li Public Domain
\endtable
*/

View File

@ -0,0 +1 @@
The icons in this repository are herefore released into the Public Domain.

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,24 @@
{
"Id": "quicknanobrowser-tango",
"Name": "Tango Icon Library",
"QDocModule": "qtwebengine",
"QtUsage": "Used in WebEngine Quick Nano Browser example.",
"QtParts": [ "examples" ],
"Description": "Selected icons from the Tango Icon Library",
"Homepage": "http://tango.freedesktop.org/Tango_Icon_Library",
"Version": "0.8.90",
"DownloadLocation": "http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz",
"LicenseId": "DocumentRef-PublicDomain",
"License": "Public Domain",
"LicenseFile": "COPYING",
"Copyright": "Ulisse Perusin <uli.peru@gmail.com>
Steven Garrity <sgarrity@silverorange.com>
Lapo Calamandrei <calamandrei@gmail.com>
Ryan Collier <rcollier@novell.com>
Rodney Dawes <dobey@novell.com>
Andreas Nilsson <nisses.mail@home.se>
Tuomas Kuosmanen <tigert@tigert.com>
Garrett LeSage <garrett@novell.com>
Jakub Steiner <jimmac@novell.com>"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,98 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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 "utils.h"
#ifndef QT_NO_WIDGETS
#include <QtWidgets/QApplication>
typedef QApplication Application;
#else
#include <QtGui/QGuiApplication>
typedef QGuiApplication Application;
#endif
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include <QtWebEngine/qtwebengineglobal.h>
static QUrl startupUrl()
{
QUrl ret;
QStringList args(qApp->arguments());
args.takeFirst();
for (const QString &arg : qAsConst(args)) {
if (arg.startsWith(QLatin1Char('-')))
continue;
ret = Utils::fromUserInput(arg);
if (ret.isValid())
return ret;
}
return QUrl(QStringLiteral("https://www.qt.io"));
}
int main(int argc, char **argv)
{
QCoreApplication::setOrganizationName("QtExamples");
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
Application app(argc, argv);
QtWebEngine::initialize();
QQmlApplicationEngine appEngine;
Utils utils;
appEngine.rootContext()->setContextProperty("utils", &utils);
appEngine.load(QUrl("qrc:/ApplicationRoot.qml"));
if (!appEngine.rootObjects().isEmpty())
QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl()));
else
qFatal("Failed to load sources");
return app.exec();
}

View File

@ -0,0 +1,24 @@
requires(qtConfig(accessibility))
TEMPLATE = app
TARGET = quicknanobrowser
HEADERS = utils.h
SOURCES = main.cpp
OTHER_FILES += ApplicationRoot.qml \
BrowserDialog.qml \
BrowserWindow.qml \
DownloadView.qml \
FullScreenNotification.qml
RESOURCES += resources.qrc
QT += qml quick webengine
qtHaveModule(widgets) {
QT += widgets # QApplication is required to get native styling with QtQuickControls
}
DESTDIR="$$PWD/../build"

View File

@ -0,0 +1,15 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
<file>ApplicationRoot.qml</file>
<file>BrowserDialog.qml</file>
<file>BrowserWindow.qml</file>
<file>DownloadView.qml</file>
<file>FullScreenNotification.qml</file>
</qresource>
<qresource prefix="icons">
<file alias="go-next.png">icons/3rdparty/go-next.png</file>
<file alias="go-previous.png">icons/3rdparty/go-previous.png</file>
<file alias="process-stop.png">icons/3rdparty/process-stop.png</file>
<file alias="view-refresh.png">icons/3rdparty/view-refresh.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,70 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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 UTILS_H
#define UTILS_H
#include <QtCore/QFileInfo>
#include <QtCore/QUrl>
class Utils : public QObject {
Q_OBJECT
public:
Q_INVOKABLE static QUrl fromUserInput(const QString& userInput);
};
inline QUrl Utils::fromUserInput(const QString& userInput)
{
QFileInfo fileInfo(userInput);
if (fileInfo.exists())
return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
return QUrl::fromUserInput(userInput);
}
#endif // UTILS_H