summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuho Annunen <juho.annunen@qt.io>2018-04-17 16:18:56 +0300
committerTeemu Holappa <teemu.holappa@qt.io>2018-05-07 09:29:52 +0000
commite513aed3b9cb8ff3124c21ed01e45128fa686eee (patch)
treee903fce6f49d184911c5a70dae2d4b6f12a708e8
parentf5c4c3a380f974aac954628d120ec3b0e028e36e (diff)
Update QtWebBrowser demo to new UI theme
Task-number: QTBUG-62793 Change-Id: I8e1a0dcb229dc1b445a1b3a7787e6b818f246249 Reviewed-by: Teemu Holappa <teemu.holappa@qt.io>
-rw-r--r--basicsuite/.gitignore6
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.pngbin0 -> 97167 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.pngbin0 -> 84637 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.pngbin0 -> 30856 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.pngbin0 -> 152513 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.pngbin0 -> 295182 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.pngbin0 -> 27642 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.pngbin0 -> 350083 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.pngbin0 -> 29019 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.pngbin0 -> 40493 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.pngbin0 -> 69875 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.pngbin0 -> 226165 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.pngbin0 -> 52933 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.pngbin0 -> 115301 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.pngbin0 -> 28289 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.pngbin0 -> 154532 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.pngbin0 -> 181823 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.pngbin0 -> 189989 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.pngbin0 -> 202098 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.pngbin0 -> 202229 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.pngbin0 -> 109443 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.pngbin0 -> 37796 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.pngbin0 -> 33185 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsxbin0 -> 14173 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdfbin0 -> 1635131 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro2
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp115
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h100
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp116
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp76
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h75
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml479
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml122
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml140
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml603
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml69
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml50
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml63
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml453
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml705
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml195
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js60
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml77
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml168
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.pngbin0 -> 6113 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.pngbin0 -> 5539 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.pngbin0 -> 1169 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.pngbin0 -> 1184 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.pngbin0 -> 1696 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.pngbin0 -> 1972 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.pngbin0 -> 1792 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.pngbin0 -> 1467 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.pngbin0 -> 2793 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.pngbin0 -> 1178 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.pngbin0 -> 1461 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.pngbin0 -> 1614 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.pngbin0 -> 1691 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.pngbin0 -> 1149 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.pngbin0 -> 1235 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.pngbin0 -> 1223 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.pngbin0 -> 4371 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg243
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.pngbin0 -> 6022 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.pngbin0 -> 7345 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.pngbin0 -> 1331 bytes
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc37
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro43
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp282
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h80
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp169
-rw-r--r--basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h97
71 files changed, 4625 insertions, 0 deletions
diff --git a/basicsuite/.gitignore b/basicsuite/.gitignore
new file mode 100644
index 0000000..3cb11b4
--- /dev/null
+++ b/basicsuite/.gitignore
@@ -0,0 +1,6 @@
+*.o
+moc_*
+Makefile
+*.pro.user
+*.so
+*.moc
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.png
new file mode 100644
index 0000000..cf7c69c
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.png
new file mode 100644
index 0000000..95441e4
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/00_HomePage_DeleteBookmarks.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.png
new file mode 100644
index 0000000..d93a211
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.png
new file mode 100644
index 0000000..0b880b8
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Bookmark.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.png
new file mode 100644
index 0000000..016b7f7
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Loading.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png
new file mode 100644
index 0000000..e330c6c
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_NoKb.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.png
new file mode 100644
index 0000000..50d1115
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_Browsing_Private.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.png
new file mode 100644
index 0000000..1d11050
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox+Bookmark.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.png
new file mode 100644
index 0000000..eec1ae1
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/01_URLbox.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.png
new file mode 100644
index 0000000..7edffa0
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Link.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.png
new file mode 100644
index 0000000..476fcbc
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_Text.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.png
new file mode 100644
index 0000000..861e774
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/02_Selection_URL.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.png
new file mode 100644
index 0000000..80a9a77
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_1.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.png
new file mode 100644
index 0000000..58c833e
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_10+.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.png
new file mode 100644
index 0000000..f4da8ae
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_2.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.png
new file mode 100644
index 0000000..4d89730
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_3.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.png
new file mode 100644
index 0000000..c4c74a0
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_4.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.png
new file mode 100644
index 0000000..ccfc920
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5+.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.png
new file mode 100644
index 0000000..451dec4
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_5.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.png
new file mode 100644
index 0000000..08ef407
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/03_Tabs_New.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.png
new file mode 100644
index 0000000..0de35da
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/04_Settings.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.png
new file mode 100644
index 0000000..83849d3
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/Bookmarks_Button.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsx b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsx
new file mode 100644
index 0000000..037813a
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowserFunctions.xlsx
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdf b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdf
new file mode 100644
index 0000000..8f77fe5
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/mockups/LightWebBrowser_Specs.pdf
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro
new file mode 100644
index 0000000..65d9262
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/qtwebbrowser.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = src
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp
new file mode 100644
index 0000000..7be0e5b
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "appengine.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QStandardPaths>
+#include <QStringBuilder>
+#include <QCoreApplication>
+
+AppEngine::AppEngine(QObject *parent)
+ : QObject(parent)
+ , m_settings(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) % QDir::separator() % "settings.ini", QSettings::IniFormat, this)
+{
+ foreach (const QString &arg, QCoreApplication::arguments().mid(1)) {
+ if (arg.startsWith('-'))
+ continue;
+ const QUrl url(arg);
+ if (url.isValid()) {
+ m_initialUrl = url.toString();
+ break;
+ }
+ }
+}
+
+QString AppEngine::settingsPath()
+{
+ return m_settings.fileName();
+}
+
+QString AppEngine::initialUrl() const
+{
+ return m_initialUrl;
+}
+
+QUrl AppEngine::fromUserInput(const QString& userInput)
+{
+ QFileInfo fileInfo(userInput);
+ if (fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ return QUrl::fromUserInput(userInput);
+}
+
+bool AppEngine::isUrl(const QString& userInput)
+{
+ if (userInput.startsWith(QStringLiteral("www."))
+ || userInput.startsWith(QStringLiteral("http"))
+ || userInput.startsWith(QStringLiteral("ftp"))
+ || userInput.contains(QStringLiteral("://"))
+ || userInput.endsWith(QStringLiteral(".com")))
+ return true;
+ return false;
+}
+
+QString AppEngine::domainFromString(const QString& urlString)
+{
+ return QUrl::fromUserInput(urlString).host();
+}
+
+QString AppEngine::fallbackColor()
+{
+ static QList<QString> colors = QList<QString>() << QStringLiteral("#46a2da")
+ << QStringLiteral("#18394c")
+ << QStringLiteral("#ff8c0a")
+ << QStringLiteral("#5caa15");
+ static int index = -1;
+ if (++index == colors.count())
+ index = 0;
+ return colors[index];
+}
+
+QString AppEngine::restoreSetting(const QString &name, const QString &defaultValue)
+{
+ return m_settings.value(name, defaultValue).toString();
+}
+
+void AppEngine::saveSetting(const QString &name, const QString &value)
+{
+ m_settings.setValue(name, value);
+}
+
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h
new file mode 100644
index 0000000..808f3b7
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/appengine.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef APPENGINE_H
+#define APPENGINE_H
+
+#include <QtCore/QEvent>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSettings>
+#include <QtCore/QUrl>
+#include <QtGui/QColor>
+#include <QtQuick/QQuickItemGrabResult>
+
+namespace utils {
+inline bool isTouchEvent(const QEvent* event)
+{
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool isMouseEvent(const QEvent* event)
+{
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ return true;
+ default:
+ return false;
+ }
+}
+
+}
+
+class AppEngine : public QObject {
+ Q_OBJECT
+
+ Q_PROPERTY(QString settingsPath READ settingsPath FINAL CONSTANT)
+ Q_PROPERTY(QString initialUrl READ initialUrl FINAL CONSTANT)
+
+public:
+ AppEngine(QObject *parent = 0);
+
+ QString settingsPath();
+ QString initialUrl() const;
+
+ Q_INVOKABLE bool isUrl(const QString& userInput);
+ Q_INVOKABLE QUrl fromUserInput(const QString& userInput);
+ Q_INVOKABLE QString domainFromString(const QString& urlString);
+ Q_INVOKABLE QString fallbackColor();
+ Q_INVOKABLE QString restoreSetting(const QString &name, const QString &defaultValue = QString());
+ Q_INVOKABLE void saveSetting(const QString &name, const QString &value);
+
+private:
+ QSettings m_settings;
+ QString m_initialUrl;
+};
+
+#endif // APPENGINE_H
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp
new file mode 100644
index 0000000..919629c
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/main.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "appengine.h"
+#include "navigationhistoryproxymodel.h"
+#include "touchtracker.h"
+
+#if defined(DESKTOP_BUILD)
+#include "touchmockingapplication.h"
+#endif
+
+#include <QGuiApplication>
+#include <QQmlContext>
+#include <QQmlEngine>
+#include <QQuickView>
+#include <QtWebEngine/qtwebengineglobal.h>
+
+static QObject *engine_factory(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine);
+ Q_UNUSED(scriptEngine);
+ AppEngine *eng = new AppEngine();
+ return eng;
+}
+
+int main(int argc, char **argv)
+{
+ qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
+
+ //do not use any plugins installed on the device
+ qputenv("QML2_IMPORT_PATH", QByteArray());
+
+ // We use touch mocking on desktop and apply all the mobile switches.
+ QByteArrayList args = QByteArrayList()
+ << QByteArrayLiteral("--enable-embedded-switches")
+ << QByteArrayLiteral("--log-level=0");
+ const int count = args.size() + argc;
+ QVector<char*> qargv(count);
+
+ qargv[0] = argv[0];
+ for (int i = 0; i < args.size(); ++i)
+ qargv[i + 1] = args[i].data();
+ for (int i = args.size() + 1; i < count; ++i)
+ qargv[i] = argv[i - args.size()];
+
+ int qAppArgCount = qargv.size();
+
+#if defined(DESKTOP_BUILD)
+ TouchMockingApplication app(qAppArgCount, qargv.data());
+#else
+ QGuiApplication app(qAppArgCount, qargv.data());
+#endif
+
+ qmlRegisterType<NavigationHistoryProxyModel>("WebBrowser", 1, 0, "SearchProxyModel");
+ qmlRegisterType<TouchTracker>("WebBrowser", 1, 0, "TouchTracker");
+ qmlRegisterSingletonType<AppEngine>("WebBrowser", 1, 0, "AppEngine", engine_factory);
+
+ QtWebEngine::initialize();
+
+ app.setOrganizationName("The Qt Company");
+ app.setOrganizationDomain("qt.io");
+ app.setApplicationName("qtwebbrowser");
+
+ QQuickView view;
+ view.setTitle("Yet Another Browser");
+ view.setFlags(Qt::Window | Qt::WindowTitleHint);
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.setColor(Qt::black);
+ view.setSource(QUrl("qrc:///qml/Main.qml"));
+
+ QObject::connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));
+
+#if defined(DESKTOP_BUILD)
+ view.show();
+ if (view.size().isEmpty())
+ view.setGeometry(0, 0, 800, 600);
+#else
+ view.showFullScreen();
+#endif
+
+ app.exec();
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp
new file mode 100644
index 0000000..d574ae5
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "navigationhistoryproxymodel.h"
+
+NavigationHistoryProxyModel::NavigationHistoryProxyModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+{
+
+}
+
+bool NavigationHistoryProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
+
+ // Use UrlRole and TitleRole instead of DisplayRole
+ return (sourceModel()->data(index, Qt::UserRole + 1).toString().contains(filterRegExp())
+ || sourceModel()->data(index, Qt::UserRole + 2).toString().contains(filterRegExp()));
+}
+
+void NavigationHistoryProxyModel::setEnabled(bool enabled)
+{
+ if (dynamicSortFilter() == enabled)
+ return;
+ setDynamicSortFilter(enabled);
+ emit enabledChanged();
+}
+
+QString NavigationHistoryProxyModel::searchString() const
+{
+ return m_searchString;
+}
+
+void NavigationHistoryProxyModel::setSearchString(const QString &pattern)
+{
+ if (m_searchString == pattern)
+ return;
+
+ m_searchString = pattern;
+ setFilterRegExp(QRegExp(pattern, Qt::CaseInsensitive, QRegExp::FixedString));
+ emit searchStringChanged();
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h
new file mode 100644
index 0000000..c2e3886
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/navigationhistoryproxymodel.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NAVIGATIONHISTORYPROXYMODEL_H
+#define NAVIGATIONHISTORYPROXYMODEL_H
+
+#include <QObject>
+#include <QAbstractItemModel>
+#include <QSortFilterProxyModel>
+
+class NavigationHistoryProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QAbstractItemModel * target READ sourceModel WRITE setSourceModel)
+ Q_PROPERTY(QString searchString READ searchString WRITE setSearchString NOTIFY searchStringChanged)
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+
+public:
+ explicit NavigationHistoryProxyModel(QObject *parent = 0);
+
+
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
+
+ bool enabled() const { return dynamicSortFilter(); }
+ void setEnabled(bool enabled);
+
+ void setTarget(QAbstractItemModel *t);
+
+ QString searchString() const ;
+ void setSearchString(const QString &pattern);
+
+signals:
+ void searchStringChanged();
+ void enabledChanged();
+
+private:
+ QString m_searchString;
+};
+
+#endif // NAVIGATIONHISTORYPROXYMODEL_H
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml
new file mode 100644
index 0000000..91dd074
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/BrowserWindow.qml
@@ -0,0 +1,479 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtWebEngine 1.1
+
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import QtQuick.Layouts 1.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Dialogs 1.2
+
+import "assets"
+import WebBrowser 1.0
+import "Utils.js" as Utils
+
+Item {
+ id: browserWindow
+
+ property Item currentWebView: {
+ return tabView.get(tabView.currentIndex) ? tabView.get(tabView.currentIndex).item.webView : null
+ }
+
+ property string googleSearchQuery: "https://www.google.com/search?sourceid=qtbrowser&ie=UTF-8&q="
+
+ property int toolBarSize: 80
+ property string uiColor: settingsView.privateBrowsingEnabled ? "#3a4055" : "#09102b"
+ //property string uiColor: "#09102b"
+
+ //property string uiSeparatorColor: settingsView.privateBrowsingEnabled ? "#717273" : "#7ebee5"
+ property string uiSeparatorColor: "#9d9faa"
+
+ //property string toolBarSeparatorColor: settingsView.privateBrowsingEnabled ? "#929495" : "#a3d1ed"
+ property string toolBarSeparatorColor: "#9d9faa"
+
+ property string toolBarFillColor: settingsView.privateBrowsingEnabled ? "#3a4055" : "#09102b"
+ //property string toolBarFillColor: "#09102b"
+
+ //property string buttonPressedColor: settingsView.privateBrowsingEnabled ? "#3b3c3e" : "#3f91c4"
+ property string buttonPressedColor: "#41cd52"
+ property string emptyBackgroundColor: "#09102b"
+ //property string uiHighlightColor: "#fddd5c"
+ property string uiHighlightColor: "#41cd52"
+ property string inactivePagerColor: "#bcbdbe"
+ property string textFieldStrokeColor: "#9d9faa"
+ property string placeholderColor: "#a0a1a2"
+ property string iconOverlayColor: "#0e202c"
+ property string iconStrokeColor: "#9d9faa"
+ property string defaultFontFamily: appFont //"Open Sans"
+
+ property int gridViewPageItemCount: 8
+ property int gridViewMaxBookmarks: 3 * gridViewPageItemCount
+ property int tabViewMaxTabs: 10
+ property int animationDuration: 200
+ property int velocityThreshold: 400
+ property int velocityY: 0
+ property real touchY: 0
+ property real touchReference: 0
+ property bool touchGesture: false
+
+ width: 1024
+ height: 600
+ visible: true
+
+ Action {
+ shortcut: "Ctrl+D"
+ onTriggered: {
+ downloadView.visible = !downloadView.visible
+ }
+ }
+
+ Action {
+ id: focus
+ shortcut: "Ctrl+L"
+ onTriggered: {
+ navigation.addressBar.forceActiveFocus();
+ navigation.addressBar.selectAll();
+ }
+ }
+ Action {
+ shortcut: "Ctrl+R"
+ onTriggered: {
+ if (currentWebView)
+ currentWebView.reload()
+ navigation.addressBar.forceActiveFocus()
+ }
+ }
+ Action {
+ id: newTabAction
+ shortcut: "Ctrl+T"
+ onTriggered: {
+ tabView.get(tabView.currentIndex).item.webView.takeSnapshot()
+ var tab = tabView.createEmptyTab()
+
+ if (!tab)
+ return
+
+ navigation.addressBar.selectAll();
+ tabView.makeCurrent(tabView.count - 1)
+ navigation.addressBar.forceActiveFocus()
+ }
+ }
+ Action {
+ shortcut: "Ctrl+W"
+ onTriggered: tabView.remove(tabView.currentIndex)
+ }
+
+ UIToolBar {
+ id: tabEditToolBar
+
+ source: "icons/Btn_Add.png"
+ indicator: tabView.count
+
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: navigation.top
+ }
+
+ visible: opacity != 0.0
+ opacity: tabView.viewState == "list" ? 1.0 : 0.0
+ onDoneClicked: tabView.viewState = "page"
+ onOptionClicked: newTabAction.trigger()
+ }
+
+ UIToolBar {
+ id: settingsToolBar
+ z: 5
+ title: qsTr("Settings")
+ visible: opacity != 0.0
+
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: navigation.top
+ }
+
+ onDoneClicked: {
+ settingsView.save()
+ settingsView.state = "disabled"
+ }
+ }
+
+ UIToolBar {
+ id: fullScreenBar
+ z: 6
+ title: qsTr("Leave Full Screen Mode")
+ visible: opacity != 0.0
+ opacity: tabView.viewState == "fullscreen" ? 1.0 : 0.0
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: navigation.top
+ }
+ onDoneClicked: {
+ navigation.webView.triggerWebAction(WebEngineView.ExitFullScreen);
+ }
+ }
+
+ NavigationBar {
+ id: navigation
+
+ anchors {
+ left: parent.left
+ right: parent.right
+ }
+ }
+ Rectangle{
+ anchors.bottom: navigation.bottom
+ anchors.left: navigation.left
+ anchors.right: navigation.right
+ height: 2
+ color: "#9d9faa"
+ }
+
+ PageView {
+ id: tabView
+ interactive: {
+ if (sslDialog.visible || homeScreen.state != "disabled" || urlDropDown.state == "enabled" || settingsView.state == "enabled")
+ return false
+ return true
+ }
+
+ anchors {
+ top: navigation.bottom
+ left: parent.left
+ right: parent.right
+ }
+
+ height: inputPanel.y
+
+ Component.onCompleted: {
+ var tab = createEmptyTab()
+
+ if (!tab)
+ return
+
+ navigation.webView = tab.webView
+ var url = AppEngine.initialUrl
+
+ navigation.load();
+ }
+ onCurrentIndexChanged: {
+ if (!tabView.get(tabView.currentIndex))
+ return
+ navigation.webView = tabView.get(tabView.currentIndex).item.webView
+ }
+ }
+
+ QtObject{
+ id: acceptedCertificates
+
+ property var acceptedUrls : []
+
+ function shouldAutoAccept(certificateError){
+ var domain = AppEngine.domainFromString(certificateError.url)
+ return acceptedUrls.indexOf(domain) >= 0
+ }
+ }
+
+ MessageDialog {
+ id: sslDialog
+
+ property var certErrors: []
+ property var currentError: null
+ visible: certErrors.length > 0
+ 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: {
+ var cert = certErrors.shift()
+ var domain = AppEngine.domainFromString(cert.url)
+ acceptedCertificates.acceptedUrls.push(domain)
+ cert.ignoreCertificateError()
+ presentError()
+ }
+ onNo: reject()
+ onRejected: reject()
+
+ function reject(){
+ certErrors.shift().rejectCertificate()
+ presentError()
+ }
+ function enqueue(error){
+ currentError = error
+ certErrors.push(error)
+ presentError()
+ }
+ function presentError(){
+ informativeText = "SSL error from URL\n\n" + currentError.url + "\n\n" + currentError.description + "\n"
+ }
+ }
+
+ Rectangle {
+ id: urlDropDown
+ color: "white"
+ visible: navigation.visible
+
+ property string searchString: navigation.addressBar.text
+
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: navigation.bottom
+ }
+
+ state: "disabled"
+
+ states: [
+ State {
+ name: "enabled"
+ PropertyChanges {
+ target: urlDropDown
+ height: browserWindow.height - toolBarSize - 3
+ }
+ },
+ State {
+ name: "disabled"
+ PropertyChanges {
+ target: urlDropDown
+ height: 0
+ }
+ }
+ ]
+
+ Rectangle {
+ anchors.fill: parent
+ color: emptyBackgroundColor
+ }
+
+ SearchProxyModel {
+ id: proxy
+ target: navigation.webView.navigationHistory.items
+ searchString: urlDropDown.searchString
+ enabled: urlDropDown.state == "enabled"
+ }
+
+ ListView {
+ id: historyList
+ property int remainingHeight: Math.min((historyList.count + 1) * toolBarSize, inputPanel.y - toolBarSize - 3)
+ model: proxy
+ clip: true
+ boundsBehavior: Flickable.StopAtBounds
+ footerPositioning: ListView.InlineFooter
+ visible: urlDropDown.state == "enabled"
+
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ }
+ height: remainingHeight
+ delegate: Rectangle {
+ id: wrapper
+ width: historyList.width
+ height: toolBarSize
+ color: "#09102b"
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (!url)
+ return
+ navigation.webView.url = url
+ navigation.webView.forceActiveFocus()
+ }
+ }
+
+ Column {
+ width: parent.width - 60
+ height: parent.height
+ anchors {
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ Text {
+ property string highlightTitle: title ? title : ""
+ height: wrapper.height / 2
+ width: parent.width
+ elide: Text.ElideRight
+ verticalAlignment: Text.AlignBottom
+ anchors{
+ leftMargin: 30
+ rightMargin: 30
+ }
+ id: titleLabel
+ font.family: defaultFontFamily
+ font.pixelSize: 23
+ color: "white"
+ text: Utils.highlight(highlightTitle, urlDropDown.searchString)
+ }
+ Text {
+ property string highlightUrl: url ? url : ""
+ height: wrapper.height / 2 - 1
+ width: parent.width
+ elide: Text.ElideRight
+ verticalAlignment: Text.AlignTop
+ font.family: defaultFontFamily
+ font.pixelSize: 23
+ color: "white" //uiColor
+ text: Utils.highlight(highlightUrl, urlDropDown.searchString)
+ }
+ Rectangle {
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: historyList.width
+ height: 1
+ color: iconStrokeColor
+ }
+ }
+ }
+ footer: Rectangle {
+ z: 5
+ width: historyList.width
+ height: toolBarSize
+ color: "#09102b"
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ var string = urlDropDown.searchString
+ var constructedUrl = ""
+ if (AppEngine.isUrl(string)) {
+ constructedUrl = AppEngine.fromUserInput(string)
+ } else {
+ constructedUrl = AppEngine.fromUserInput(googleSearchQuery + string)
+ }
+ navigation.webView.url = constructedUrl
+ navigation.webView.forceActiveFocus()
+ }
+ }
+ Row {
+ height: parent.height
+ Rectangle {
+ id: searchIcon
+ height: parent.height
+ width: height
+ color: "transparent"
+ Image {
+ anchors.centerIn: parent
+ source: "assets/icons/Btn_Search.png"
+ }
+ }
+ Text {
+ id: searchText
+ height: parent.height
+ width: historyList.width - searchIcon.width - 30
+ elide: Text.ElideRight
+ text: urlDropDown.searchString
+ verticalAlignment: Text.AlignVCenter
+ font.family: defaultFontFamily
+ font.pixelSize: 23
+ color: "white"
+ }
+ }
+ }
+ }
+
+ transitions: Transition {
+ PropertyAnimation { property: "height"; duration: animationDuration; easing.type : Easing.InSine }
+ }
+ }
+
+ HomeScreen {
+ id: homeScreen
+ height: parent.height - toolBarSize
+ anchors {
+ top: navigation.bottom
+ left: parent.left
+ right: parent.right
+ }
+ }
+
+ SettingsView {
+ id: settingsView
+ height: parent.height - toolBarSize
+ anchors {
+ top: navigation.bottom
+ left: parent.left
+ right: parent.right
+ }
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml
new file mode 100644
index 0000000..d73f940
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/CustomSwitch.qml
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Device Utilities module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+import QtDeviceUtilities.QtButtonImageProvider 1.0
+import QtQuick.Controls 2.1
+
+Switch {
+ id: control
+
+ property alias indicatorWidth: indicatorImg.width
+ property alias indicatorHeight: indicatorImg.height
+
+ indicator: Image {
+ id: indicatorImg
+ width: 200
+ height: 75
+ sourceSize: Qt.size(width, height)
+ anchors.horizontalCenter: control.horizontalCenter
+ y: parent.height / 2 - height / 2
+ source: "image://QtButton/10/#848895/transparent"
+ Text {
+ id: offText
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.075
+ anchors.verticalCenter: parent.verticalCenter
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 1
+ font.pixelSize: parent.height * 0.55
+ color: "#3b4155"
+ text: "OFF"
+ font.family: defaultFontFamily
+ }
+ Text {
+ id: onText
+ anchors.right: parent.right
+ anchors.rightMargin: parent.width * 0.1
+ anchors.verticalCenter: parent.verticalCenter
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 1
+ font.pixelSize: parent.height * 0.55
+ color: "#3b4155"
+ text: "ON"
+ font.family: defaultFontFamily
+ }
+
+ Binding {
+ target: qtHandle
+ property: "x"
+ value: control.checked ? indicatorImg.width - qtHandle.width - indicatorImg.width * 0.025 : indicatorImg.width * 0.025
+ when: !mousearea.drag.active
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: control.checked = !control.checked
+ }
+
+ QtButton {
+ id: qtHandle
+ anchors.verticalCenter: parent.verticalCenter
+ width: parent.width * 0.475
+ height: parent.height * 0.9
+ fillColor: control.checked ? "#41cd52" : "#9d9faa"//viewSettings.buttonGreenColor : viewSettings.buttonGrayColor
+ text: control.checked ? "ON" : "OFF"
+ borderColor: "transparent"
+ Behavior on x {
+ NumberAnimation { duration: 50 }
+ }
+
+ MouseArea {
+ id: mousearea
+ anchors.fill: parent
+ drag.target: qtHandle
+ drag.axis: Drag.XAxis
+ drag.minimumX: indicatorImg.width * 0.005
+ drag.maximumX: indicatorImg.width - width - indicatorImg.width * 0.005
+
+ onClicked: {
+ control.checked = !control.checked
+ }
+
+ onReleased: {
+ if (qtHandle.x > indicatorImg.width / 5 ) {
+ control.checked = true
+ } else {
+ control.checked = false
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml
new file mode 100644
index 0000000..8595724
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/FeaturePermissionBar.qml
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtWebEngine 1.1
+import QtQuick.Layouts 1.0
+
+import "assets"
+
+Rectangle {
+ property var requestedFeature;
+ property url securityOrigin;
+ property WebEngineView view;
+
+ id: permissionBar
+ visible: false
+ height: 50
+
+ onRequestedFeatureChanged: {
+ message.text = securityOrigin + " wants to access " + message.textForFeature(requestedFeature);
+ }
+
+
+ RowLayout {
+ spacing: 0
+ anchors {
+ fill: permissionBar
+ }
+ Rectangle {
+ color: uiColor
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ Layout.fillWidth: true
+
+ Text {
+ id: message
+ width: parent.width
+ elide: Text.ElideRight
+ horizontalAlignment: Text.AlignHCenter
+ anchors {
+ leftMargin: 15
+ rightMargin: 15
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ font.family: defaultFontFamily
+ font.pixelSize: 20
+ color: "white"
+ function textForFeature(feature) {
+ if (feature === WebEngineView.MediaAudioCapture)
+ return "your microphone"
+ if (feature === WebEngineView.MediaVideoCapture)
+ return "your camera"
+ if (feature === WebEngineView.MediaAudioVideoCapture)
+ return "your camera and microphone"
+ if (feature === WebEngineView.Geolocation)
+ return "your position"
+ }
+ }
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+
+ UIButton {
+ id: acceptButton
+ implicitHeight: permissionBar.height
+ implicitWidth: toolBarSize
+ buttonText: "Accept"
+ textSize: 18
+ Layout.alignment: Qt.AlignRight
+ onClicked: {
+ view.grantFeaturePermission(securityOrigin, requestedFeature, true);
+ permissionBar.visible = false;
+ }
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+
+ UIButton {
+ buttonText: "Deny"
+ textSize: 18
+ implicitHeight: permissionBar.height
+ implicitWidth: toolBarSize
+ Layout.alignment: Qt.AlignRight
+ onClicked: {
+ view.grantFeaturePermission(securityOrigin, requestedFeature, false);
+ permissionBar.visible = false
+ }
+ }
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml
new file mode 100644
index 0000000..9d29729
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/HomeScreen.qml
@@ -0,0 +1,603 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import WebBrowser 1.0
+import "assets"
+
+Rectangle {
+ id: homeScreen
+ property int padding: 60
+ property int cellSize: width / 5 - padding
+ property alias messageBox: messageBox
+ property alias count: gridView.count
+ property alias currentIndex: gridView.currentIndex
+ color: "#09102b"
+ function set(i) {
+ var p = (i - i % gridViewPageItemCount) / gridViewPageItemCount
+ gridView.contentX = p * gridView.page
+ }
+
+ state: "enabled"
+ onStateChanged: {
+ if (state == "enabled" && !gridView.count)
+ messageBox.state = "empty"
+ }
+
+ signal add(string title, string url, string iconUrl, string fallbackColor)
+ onAdd: {
+ if (listModel.count === gridViewMaxBookmarks) {
+ navigation.refresh()
+ messageBox.state = "full"
+ state = "enabled"
+ homeScreen.forceActiveFocus()
+ return
+ }
+ var icon = url.indexOf("qt.io") != -1 ? "assets/icons/qt.png" : iconUrl
+ var element = { "title": title, "url": url, "iconUrl": icon, "fallbackColor": fallbackColor }
+ listModel.append(element)
+ set(listModel.count - 1)
+ }
+
+ signal remove(string url, int idx)
+ onRemove: {
+ var index = idx < 0 ? contains(url) : idx
+ if (index < 0)
+ return
+
+ listModel.remove(index)
+ gridView.forceLayout()
+ navigation.refresh()
+ if (!listModel.count)
+ messageBox.state = "empty"
+ }
+
+ function get(index) {
+ return listModel.get(index)
+ }
+
+ function contains(url) {
+ for (var idx = 0; idx < listModel.count; ++idx) {
+ if (listModel.get(idx).url === url)
+ return idx;
+ }
+ return -1;
+ }
+
+ states: [
+ State {
+ name: "enabled"
+ AnchorChanges {
+ target: homeScreen
+ anchors.top: navigation.bottom
+ }
+ },
+ State {
+ name: "disabled"
+ AnchorChanges {
+ target: homeScreen
+ anchors.top: homeScreen.parent.bottom
+ }
+ },
+ State {
+ name: "edit"
+ }
+ ]
+
+ transitions: Transition {
+ AnchorAnimation { duration: animationDuration; easing.type : Easing.InSine }
+ }
+
+ ListModel {
+ id: listModel
+ property string defaultBookmarks: "[{\"fallbackColor\":\"#46a2da\",\"iconUrl\":\"assets/icons/qt.png\",\"title\":\"Qt - Home\",\"url\":\"http://www.qt.io/\"},{\"fallbackColor\":\"#18394c\",\"iconUrl\":\"http://www.topgear.com/sites/all/themes/custom/tg/apple-touch-icon-144x144.png\",\"title\":\"Top Gear\",\"url\":\"http://www.topgear.com/\"},{\"fallbackColor\":\"#46a2da\",\"iconUrl\":\"https://duckduckgo.com/assets/icons/meta/DDG-iOS-icon_152x152.png\",\"title\":\"DuckDuckGo\",\"url\":\"https://duckduckgo.com/\"},{\"fallbackColor\":\"#ff8c0a\",\"iconUrl\":\"http://www.blogsmithmedia.com/www.engadget.com/media/favicon-160x160.png\",\"title\":\"Engadget | Technology News, Advice and Features\",\"url\":\"http://www.engadget.com/\"},{\"fallbackColor\":\"#ff8c0a\",\"iconUrl\":\"https://www.openstreetmap.org/assets/favicon-194x194-32cdac24b02b88e09f0639bb92c760b2.png\",\"title\":\"OpenStreetMap\",\"url\":\"https://www.openstreetmap.org/\"},{\"fallbackColor\":\"#5caa15\",\"iconUrl\":\"http://www.redditstatic.com/icon.png\",\"title\":\"reddit: the front page of the internet\",\"url\":\"http://www.reddit.com/\"}]"
+
+ Component.onCompleted: {
+ listModel.clear()
+ var string = AppEngine.restoreSetting("bookmarks", defaultBookmarks)
+ if (!string)
+ return
+ var list = JSON.parse(string)
+ for (var i = 0; i < list.length; ++i) {
+ listModel.append(list[i])
+ }
+ navigation.refresh()
+ }
+ Component.onDestruction: {
+ var list = []
+ for (var i = 0; i < listModel.count; ++i) {
+ list[i] = listModel.get(i)
+ }
+ AppEngine.saveSetting("bookmarks", JSON.stringify(list))
+ }
+ }
+
+ GridView {
+ id: gridView
+
+ onCountChanged: {
+ if (!count)
+ messageBox.state = "empty"
+ else
+ messageBox.state = "disabled"
+ }
+
+ property real dragStart: 0
+ property real page: 4 * cellWidth
+
+ anchors.fill: parent
+ model: listModel
+ cellWidth: homeScreen.cellSize + homeScreen.padding
+ cellHeight: cellWidth
+ flow: GridView.FlowTopToBottom
+ boundsBehavior: Flickable.StopAtBounds
+ maximumFlickVelocity: 0
+ contentHeight: parent.height
+
+ MouseArea {
+ z: -1
+ enabled: homeScreen.state == "edit"
+ anchors.fill: parent
+ onClicked: homeScreen.state = "enabled"
+ }
+
+ rightMargin: {
+ var margin = (parent.width - 4 * gridView.cellWidth - homeScreen.padding) / 2
+ var padding = gridView.page - Math.round(gridView.count % gridViewPageItemCount / 2) * gridView.cellWidth
+
+ if (padding == gridView.page)
+ return margin
+
+ return margin + padding
+ }
+
+ anchors {
+ topMargin: toolBarSize
+ leftMargin: (parent.width - 4 * gridView.cellWidth + homeScreen.padding) / 2
+ }
+
+ Behavior on contentX {
+ NumberAnimation { duration: 1.5 * animationDuration; easing.type : Easing.InSine}
+ }
+
+ function snapToPage() {
+ if (dragging) {
+ dragStart = contentX
+ return
+ }
+ if (dragStart == 2 * page && contentX < 2 * page) {
+ contentX = page
+ return
+ }
+ if (dragStart == page) {
+ if (contentX < page) {
+ contentX = 0
+ return
+ }
+ if (page < contentX) {
+ contentX = 2 * page
+ return
+ }
+ }
+ if (dragStart == 0 && 0 < contentX) {
+ contentX = page
+ return
+ }
+ contentX = 0
+ }
+
+ onDraggingChanged: snapToPage()
+ delegate: Rectangle {
+ id: square
+ property string iconColor: "#f6f6f6"
+ width: homeScreen.cellSize
+ height: width
+ border.color: iconStrokeColor
+ border.width: 1
+
+ Rectangle {
+ id: bg
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ margins: 1
+ }
+ state: "fallback"
+ width: square.width - 2
+ height: width
+ states: [
+ State {
+ name: "fallback"
+ PropertyChanges {
+ target: square
+ color: fallbackColor
+ }
+ PropertyChanges {
+ target: bg
+ color: square.color
+ }
+ },
+ State {
+ name: "normal"
+ PropertyChanges {
+ target: square
+ color: iconColor
+ }
+ PropertyChanges {
+ target: bg
+ color: square.color
+ }
+ }
+ ]
+
+ Image {
+ id: icon
+ smooth: true
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ topMargin: width < bg.width ? 15 : 0
+ }
+ width: {
+ if (!icon.sourceSize.width)
+ return 0
+ if (icon.sourceSize.width < 100)
+ return 32
+
+ return bg.width
+ }
+ height: width
+ source: iconUrl
+ onStatusChanged: {
+ switch (status) {
+ case Image.Null:
+ case Image.Loading:
+ case Image.Error:
+ bg.state = "fallback"
+ break
+ case Image.Ready:
+ bg.state = "normal"
+ break
+ }
+ }
+ }
+ Text {
+ function cleanup(string) {
+ var t = string.replace("-", " ")
+ .replace("|", " ").replace(",", " ")
+ .replace(/\s\s+/g, "\n")
+ return t
+ }
+
+ visible: icon.width != bg.width
+ text: cleanup(title)
+ font.family: defaultFontFamily
+ font.pixelSize: 18
+ color: bg.state == "fallback" ? "white" : "black"
+ anchors {
+ top: icon.bottom
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ leftMargin: 15
+ rightMargin: 15
+ bottomMargin: 15
+ }
+ maximumLineCount: 3
+ elide: Text.ElideRight
+ wrapMode: Text.Wrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+
+ Rectangle {
+ id: overlay
+ visible: opacity != 0.0
+ anchors.fill: parent
+ color: iconOverlayColor
+ opacity: {
+ if (iconMouse.pressed) {
+ if (homeScreen.state != "edit")
+ return 0.1
+ return 0.4
+ }
+ if (homeScreen.state == "edit")
+ return 0.3
+ return 0.0
+ }
+ }
+ MouseArea {
+ id: iconMouse
+ anchors.fill: parent
+ onPressAndHold: {
+ if (homeScreen.state == "edit") {
+ homeScreen.state = "enabled"
+ return
+ }
+ homeScreen.state = "edit"
+ }
+ onClicked: {
+ if (homeScreen.state == "edit") {
+ homeScreen.state = "enabled"
+ return
+ }
+ navigation.load(url)
+ }
+ }
+ Rectangle {
+ enabled: homeScreen.state == "edit"
+ opacity: enabled ? 1.0 : 0.0
+ width: image.sourceSize.width
+ height: image.sourceSize.height - 2
+ radius: width / 2
+ color: iconOverlayColor
+ anchors {
+ horizontalCenter: parent.right
+ verticalCenter: parent.top
+ }
+ Image {
+ id: image
+ opacity: {
+ if (deleteButton.pressed)
+ return 0.70
+ return 1.0
+ }
+ anchors {
+ top: parent.top
+ left: parent.left
+ }
+ source: "assets/icons/Btn_Delete.png"
+ MouseArea {
+ id: deleteButton
+ anchors.fill: parent
+ onClicked: {
+ mouse.accepted = true
+ remove(url, index)
+ }
+ }
+ }
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration }
+ }
+ }
+ }
+ }
+ Rectangle {
+ width: homeScreen.cellSize - homeScreen.padding / 2 - 10
+ anchors {
+ left: parent.left
+ top: parent.top
+ bottom: parent.bottom
+ }
+ MouseArea {
+ enabled: homeScreen.state == "edit"
+ anchors.fill: parent
+ onClicked: homeScreen.state = "enabled"
+ }
+ color: "#09102b"
+ }
+ Rectangle {
+ width: homeScreen.cellSize - homeScreen.padding / 2 - 10
+ anchors {
+ right: parent.right
+ top: parent.top
+ bottom: parent.bottom
+ }
+ MouseArea {
+ enabled: homeScreen.state == "edit"
+ anchors.fill: parent
+ onClicked: homeScreen.state = "enabled"
+ }
+ color: "#09102b"
+ }
+ Row {
+ id: pageIndicator
+ spacing: 20
+ anchors {
+ bottomMargin: 40
+ bottom: parent.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ Repeater {
+ model: {
+ var c = gridView.count % gridViewPageItemCount
+ if (c > 0)
+ c = 1
+ return Math.floor(gridView.count / gridViewPageItemCount) + c
+ }
+ delegate: Rectangle {
+ property bool active: index * gridView.page <= gridView.contentX && gridView.contentX < (index + 1) * gridView.page
+ width: 10
+ height: width
+ radius: width / 2
+ color: !active ? inactivePagerColor : uiColor
+ anchors.verticalCenter: parent.verticalCenter
+ MouseArea {
+ anchors.fill: parent
+ onClicked: gridView.contentX = index * gridView.page
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: messageBox
+ color: "white"
+ anchors.fill: parent
+
+ Rectangle {
+ id: error
+ visible: messageBox.state != "empty"
+ height: childrenRect.height
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ topMargin: 50
+ }
+ Image {
+ id: errorIcon
+ source: "assets/icons/Error_Icon.png"
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ }
+ }
+ Text {
+ anchors {
+ topMargin: 30
+ top: errorIcon.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ font.family: defaultFontFamily
+ font.pixelSize: message.font.pixelSize
+ text: "Oops!..."
+ color: iconOverlayColor
+ }
+ }
+
+ Text {
+ id: message
+ anchors {
+ top: error.bottom
+ horizontalCenter: parent.horizontalCenter
+ }
+ color: iconOverlayColor
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ verticalAlignment: Text.AlignTop
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ Rectangle {
+ color: parent.color
+ anchors {
+ top: message.bottom
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ bottomMargin: 70
+ }
+ UIButton {
+ color: uiColor
+ implicitWidth: 180
+ implicitHeight: 70
+ buttonText: "OK"
+ visible: messageBox.state != "empty"
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ bottom: parent.bottom
+ }
+ onClicked: {
+ if (messageBox.state == "tabsfull") {
+ homeScreen.state = "disabled"
+ tabView.viewState = "list"
+ return
+ }
+ if (messageBox.state == "full") {
+ messageBox.state = "disabled"
+ homeScreen.state = "edit"
+ return
+ }
+ }
+ }
+ }
+
+ state: "disabled"
+
+ states: [
+ State {
+ name: "disabled"
+ PropertyChanges {
+ target: messageBox
+ visible: false
+ }
+ },
+ State {
+ name: "empty"
+ PropertyChanges {
+ target: message
+ text: qsTr("No bookmarks have been saved so far.")
+ }
+ PropertyChanges {
+ target: messageBox
+ color: emptyBackgroundColor
+ visible: true
+ }
+ PropertyChanges {
+ target: error
+ anchors.topMargin: 30
+ }
+ PropertyChanges {
+ target: navigation
+ state: "enabled"
+ }
+ },
+ State {
+ name: "full"
+ PropertyChanges {
+ target: message
+ text: qsTr("24 bookmarks is the maximum limit.\nTo bookmark a new page you must delete a bookmark first.")
+ }
+ PropertyChanges {
+ target: messageBox
+ visible: true
+ }
+ PropertyChanges {
+ target: navigation
+ state: "enabled"
+ }
+ },
+ State {
+ name: "tabsfull"
+ PropertyChanges {
+ target: message
+ text: qsTr("10 open tabs is the maximum limit.\nTo open a new tab you must close another one first.")
+ }
+ PropertyChanges {
+ target: messageBox
+ visible: true
+ }
+ PropertyChanges {
+ target: navigation
+ state: "enabled"
+ }
+ }
+ ]
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml
new file mode 100644
index 0000000..13ab64e
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Keyboard.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Enterprise.VirtualKeyboard 2.0
+
+InputPanel {
+ id: inputPanel
+ property int windowHeight: 0
+ property int animationDuration: 0
+
+ y: windowHeight
+ anchors {
+ left: parent.left
+ right: parent.right
+ }
+ states: State {
+ name: "visible"
+ when: Qt.inputMethod.visible
+ PropertyChanges {
+ target: inputPanel
+ y: windowHeight - inputPanel.height
+ }
+ }
+ transitions: Transition {
+ from: ""
+ to: "visible"
+ reversible: true
+ NumberAnimation {
+ properties: "y"
+ duration: animationDuration
+ easing.type: Easing.InOutQuad
+ }
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml
new file mode 100644
index 0000000..3f01ecc
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Main.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+
+Item {
+ BrowserWindow{
+ id: root
+ anchors.fill: parent
+ Keyboard{
+ id: inputPanel
+ windowHeight: root.height
+ animationDuration: root.animationDuration
+ }
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml
new file mode 100644
index 0000000..f7fa1b1
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/MockTouchPoint.qml
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: mockTouchPoint
+
+ property bool pressed: false
+ property int pointId: 0
+
+ Image {
+ source: "assets/icons/touchpoint.png"
+ x: -(width / 2)
+ y: -(height / 2)
+ height: parent.height
+ width: parent.width
+ opacity: parent.pressed ? 0.6 : 0.0
+
+ Behavior on opacity {
+ NumberAnimation { duration: 200 }
+ }
+
+ Text {
+ text: mockTouchPoint.pointId
+ anchors.centerIn: parent
+ }
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml
new file mode 100644
index 0000000..19efa0d
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/NavigationBar.qml
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.2
+import WebBrowser 1.0
+
+import "assets"
+
+ToolBar {
+ id: root
+
+ property alias addressBar: urlBar
+ property Item webView: null
+
+ onWebViewChanged: {
+
+ }
+
+ visible: opacity != 0.0
+ opacity: tabView.viewState == "page" ? 1.0 : 0.0
+
+ function load(url) {
+ if (url)
+ webView.url = url
+ homeScreen.state = "disabled"
+ }
+
+ function refresh() {
+ if (urlBar.text == "")
+ bookmarksButton.bookmarked = false
+ else
+ bookmarksButton.bookmarked = homeScreen.contains(urlBar.text) !== -1
+ }
+
+ state: "enabled"
+
+ style: ToolBarStyle {
+ background: Rectangle {
+ color: uiColor
+ implicitHeight: toolBarSize + 3
+ }
+ padding {
+ left: 0
+ right: 0
+ top: 0
+ bottom: 0
+ }
+ }
+
+ Behavior on y {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ states: [
+ State {
+ name: "enabled"
+ PropertyChanges {
+ target: root
+ y: 0
+ }
+ },
+ State {
+ name: "tracking"
+ PropertyChanges {
+ target: root
+ y: {
+ var diff = touchReference - touchY
+
+ if (velocityY > velocityThreshold) {
+ if (diff > 0)
+ return -root.height
+ else
+ return 0
+ }
+
+ if (!touchGesture || diff == 0) {
+ if (y < -root.height / 2)
+ return -root.height
+ else
+ return 0
+ }
+
+ if (diff > root.height)
+ return -root.height
+
+ if (diff > 0) {
+ if (y == -root.height)
+ return -root.height
+ return -diff
+ }
+
+ // diff < 0
+
+ if (y == 0)
+ return 0
+
+ diff = Math.abs(diff)
+ if (diff >= root.height)
+ return 0
+
+ return -root.height + diff
+ }
+ }
+ },
+ State {
+ name: "disabled"
+ PropertyChanges {
+ target: root
+ y: -root.height
+ }
+ }
+ ]
+
+ RowLayout {
+ height: toolBarSize
+ anchors {
+ top: parent.top
+ right: parent.right
+ left: parent.left
+ }
+ spacing: 0
+
+ UIButton {
+ id: backButton
+ source: "icons/Btn_Back.png"
+ color: uiColor
+ highlightColor: buttonPressedColor
+ onClicked: webView.goBack()
+ enabled: webView && webView.canGoBack
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: forwardButton
+ source: "icons/Btn_Forward.png"
+ color: uiColor
+ highlightColor: buttonPressedColor
+ onClicked: webView.goForward()
+ enabled: webView && webView.canGoForward
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ Rectangle {
+ Layout.fillWidth: true
+ implicitWidth: 10
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiColor
+ }
+ TextField {
+ id: urlBar
+ Layout.fillWidth: true
+ text: webView ? webView.url : ""
+ activeFocusOnPress: true
+ inputMethodHints: Qt.ImhUrlCharactersOnly | Qt.ImhNoPredictiveText | Qt.ImhNoAutoUppercase | Qt.ImhPreferLowercase
+ placeholderText: qsTr("Search or type a URL")
+
+ onActiveFocusChanged: {
+ if (activeFocus) {
+ urlBar.selectAll()
+ root.state = "enabled"
+ homeScreen.state = "disabled"
+ urlDropDown.state = "enabled"
+ } else {
+ urlDropDown.state = "disabled"
+ root.state = "tracking"
+ }
+ }
+
+ UIButton {
+ id: reloadButton
+ state: cancelButton.visible ? "edit" : "load"
+ states: [
+ State {
+ name: "load"
+ PropertyChanges {
+ target: reloadButton
+ source: webView && webView.loading ? "icons/Btn_Clear.png" : "icons/Btn_Reload.png"
+ height: 54
+ }
+ },
+ State {
+ name: "edit"
+ PropertyChanges {
+ target: reloadButton
+ source: "icons/Btn_Clear.png"
+ height: 45
+ visible: urlBar.text != ""
+ }
+ }
+ ]
+ height: 54
+ width: height
+ color: "transparent"
+ highlightColor: "#eeeeee"
+ radius: width / 2
+ anchors {
+ rightMargin: 1
+ right: parent.right
+ verticalCenter: addressBar.verticalCenter;
+ }
+ onClicked: {
+ if (state == "load") {
+ webView.loading ? webView.stop() : webView.reload()
+ webView.forceActiveFocus()
+ return
+ }
+ urlBar.selectAll()
+ urlBar.remove(urlBar.selectionStart, urlBar.selectionEnd)
+ }
+ }
+ style: TextFieldStyle {
+ textColor: "white"
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ selectionColor: uiHighlightColor
+ selectedTextColor: "white"
+ placeholderTextColor: placeholderColor
+ background: Rectangle {
+ implicitWidth: 514
+ implicitHeight: 56
+ border.color: textFieldStrokeColor
+ color: "#09102b"
+ border.width: 2
+ }
+ padding {
+ left: 15
+ right: reloadButton.width
+ }
+ }
+ onAccepted: {
+ webView.url = AppEngine.fromUserInput(text)
+ homeScreen.state = "disabled"
+ tabView.viewState = "page"
+ }
+
+ onTextChanged: refresh()
+ onEditingFinished: {
+ selectAll()
+ webView.forceActiveFocus()
+ }
+ }
+ Rectangle {
+ visible: !cancelButton.visible
+ Layout.fillWidth: true
+ implicitWidth: 10
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiColor
+ }
+
+ UIButton {
+ id: cancelButton
+ color: uiColor
+ visible: urlDropDown.state === "enabled"
+ highlightColor: buttonPressedColor
+ Text {
+ color: "white"
+ anchors.centerIn: parent
+ text: "Cancel"
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ }
+ implicitWidth: 120
+ onClicked: {
+ urlDropDown.state = "disabled"
+ webView.forceActiveFocus()
+ }
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: homeButton
+ source: "icons/Btn_Home.png"
+ color: uiColor
+ highlightColor: buttonPressedColor
+ onClicked: {
+ if (homeScreen.state == "disabled" || homeScreen.state == "edit") {
+ homeScreen.messageBox.state = "disabled"
+ homeScreen.state = "enabled"
+ homeScreen.forceActiveFocus()
+ } else if (homeScreen.state != "disabled") {
+ homeScreen.state = "disabled"
+ }
+ }
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: pageViewButton
+ source: "icons/Btn_Tabs.png"
+ color: uiColor
+ highlightColor: buttonPressedColor
+ onClicked: {
+ if (tabView.viewState == "list") {
+ tabView.viewState = "page"
+ } else {
+ tabView.get(tabView.currentIndex).item.webView.takeSnapshot()
+ homeScreen.state = "disabled"
+ tabView.viewState = "list"
+ }
+ }
+ Text {
+ anchors {
+ centerIn: parent
+ verticalCenterOffset: 4
+ }
+
+ text: tabView.count
+ font.family: defaultFontFamily
+ font.pixelSize: 16
+ font.weight: Font.DemiBold
+ color: "white"
+ }
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: bookmarksButton
+ color: uiColor
+ highlightColor: buttonPressedColor
+ enabled: urlBar.text != "" && !settingsView.privateBrowsingEnabled
+ property bool bookmarked: false
+ source: bookmarked ? "icons/Btn_Bookmark_Checked.png" : "icons/Btn_Bookmarks.png"
+ onClicked: {
+ if (!webView)
+ return
+ var icon = webView.loading ? "" : webView.icon
+ var idx = homeScreen.contains(webView.url.toString())
+ if (idx !== -1) {
+ homeScreen.remove("", idx)
+ return
+ }
+ var count = homeScreen.count
+ homeScreen.add(webView.title, webView.url, icon, AppEngine.fallbackColor())
+ if (count < homeScreen.count)
+ bookmarked = true
+ }
+ Component.onCompleted: refresh()
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: settingsButton
+ source: "icons/Btn_Settings.png"
+ color: uiColor
+ highlightColor: buttonPressedColor
+ onClicked: {
+ settingsView.state = "enabled"
+ }
+ }
+ }
+ ProgressBar {
+ id: progressBar
+ height: 3
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ right: parent.right
+ leftMargin: -10
+ rightMargin: -10
+ }
+ style: ProgressBarStyle {
+ background: Rectangle {
+ height: 3
+ color: emptyBackgroundColor
+ }
+ progress: Rectangle {
+ //color: settingsView.privateBrowsingEnabled ? "#46a2da" : "#317198"
+ color: "#41cd52"
+ }
+ }
+ minimumValue: 0
+ maximumValue: 100
+ value: (webView && webView.loadProgress < 100) ? webView.loadProgress : 0
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml
new file mode 100644
index 0000000..01445c6
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/PageView.qml
@@ -0,0 +1,705 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtWebEngine 1.1
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.2
+import QtGraphicalEffects 1.0
+
+import WebBrowser 1.0
+import "assets"
+
+Rectangle {
+ id: root
+
+ property int itemWidth: browserWindow.width / 2
+ property int itemHeight: browserWindow.height / 2
+
+ property bool interactive: true
+
+ property alias currentIndex: pathView.currentIndex
+ property alias count: pathView.count
+
+ property string viewState: "page"
+
+ onViewStateChanged: {
+ if (viewState == "page" || viewState == "fullscreen")
+ homeScreen.state = "disabled"
+ }
+
+ property QtObject otrProfile: WebEngineProfile {
+ offTheRecord: true
+ }
+
+ property QtObject defaultProfile: WebEngineProfile {
+ storageName: "YABProfile"
+ offTheRecord: false
+ }
+
+ Component {
+ id: tabComponent
+ Rectangle {
+ id: tabItem
+ property alias webView: webEngineView
+ property alias title: webEngineView.title
+
+ property var image: QtObject {
+ property var snapshot: null
+ property string url: "about:blank"
+ }
+
+ visible: opacity != 0.0
+
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ anchors.fill: parent
+
+ Action {
+ shortcut: "Ctrl+F"
+ onTriggered: {
+ findBar.visible = !findBar.visible
+ if (findBar.visible) {
+ findTextField.forceActiveFocus()
+ }
+ }
+ }
+
+ FeaturePermissionBar {
+ id: permBar
+ view: webEngineView
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: parent.top
+ }
+ z: 3
+ }
+
+ WebEngineView {
+ id: webEngineView
+
+ anchors {
+ fill: parent
+ top: permBar.bottom
+ }
+
+ profile: settingsView.privateBrowsingEnabled ? otrProfile : defaultProfile
+ enabled: root.interactive
+
+ function takeSnapshot() {
+ if (webEngineView.url == "" || webEngineView.url == "about:blank") {
+ tabItem.image.url = "about:blank"
+ tabItem.image.snapshot = null
+ return
+ }
+
+ if (tabItem.image.url == webEngineView.url || tabItem.opacity != 1.0)
+ return
+
+ tabItem.image.url = webEngineView.url
+ webEngineView.grabToImage(function(result) {
+ tabItem.image.snapshot = result;
+ console.log("takeSnapshot("+result.url+")")
+ });
+ }
+
+ // Trigger a refresh to check if the new url is bookmarked.
+ onUrlChanged: navigation.refresh()
+
+
+ settings.autoLoadImages: settingsView.autoLoadImages
+ settings.javascriptEnabled: !settingsView.javaScriptDisabled
+
+ // This should be enabled as we can switch to Qt 5.6 (i.e. import QtWebEngine 1.2)
+ // settings.pluginsEnabled: settingsView.pluginsEnabled
+
+ onLoadingChanged: {
+ if (loading)
+ navigation.state = "enabled"
+ }
+
+ onCertificateError: {
+ if (!acceptedCertificates.shouldAutoAccept(error)){
+ error.defer()
+ sslDialog.enqueue(error)
+ } else{
+ error.ignoreCertificateError()
+ }
+ }
+
+ onNewViewRequested: {
+ webEngineView.takeSnapshot()
+ var tab
+ if (!request.userInitiated) {
+ print("Warning: Blocked a popup window.")
+ return
+ }
+
+ tab = tabView.createEmptyTab()
+
+ if (!tab)
+ return
+
+ if (request.destination == WebEngineView.NewViewInTab) {
+ pathView.positionViewAtIndex(tabView.count - 1, PathView.Center)
+ request.openIn(tab.webView)
+ } else if (request.destination == WebEngineView.NewViewInBackgroundTab) {
+ var index = pathView.currentIndex
+ request.openIn(tab.webView)
+ pathView.positionViewAtIndex(index, PathView.Center)
+ } else if (request.destination == WebEngineView.NewViewInDialog) {
+ request.openIn(tab.webView)
+ } else {
+ request.openIn(tab.webView)
+ }
+ }
+
+ onFeaturePermissionRequested: {
+ permBar.securityOrigin = securityOrigin;
+ permBar.requestedFeature = feature;
+ permBar.visible = true;
+ }
+
+ onFullScreenRequested: {
+ if (request.toggleOn)
+ viewState = "fullscreen"
+ else
+ viewState = "page"
+ request.accept()
+ }
+ }
+
+ Desaturate {
+ id: desaturate
+ visible: desaturation != 0.0
+ anchors.fill: webEngineView
+ source: webEngineView
+ desaturation: root.interactive ? 0.0 : 1.0
+
+ Behavior on desaturation {
+ NumberAnimation { duration: animationDuration }
+ }
+ }
+
+ FastBlur {
+ id: blur
+ visible: radius != 0.0
+ anchors.fill: desaturate
+ source: desaturate
+ radius: desaturate.desaturation * 25
+ }
+
+ TouchTracker {
+ id: tracker
+ enabled: root.interactive
+ target: webEngineView
+ anchors.fill: parent
+ onTouchYChanged: browserWindow.touchY = tracker.touchY
+ onYVelocityChanged: browserWindow.velocityY = yVelocity
+ onTouchBegin: {
+ browserWindow.touchY = tracker.touchY
+ browserWindow.velocityY = yVelocity
+ browserWindow.touchReference = tracker.touchY
+ browserWindow.touchGesture = true
+ navigation.state = "tracking"
+ }
+ onTouchEnd: {
+ browserWindow.velocityY = yVelocity
+ browserWindow.touchGesture = false
+ navigation.state = "tracking"
+ }
+ onScrollDirectionChanged: {
+ browserWindow.velocityY = 0
+ browserWindow.touchReference = tracker.touchY
+ }
+ }
+
+ Rectangle {
+ opacity: {
+ if (inputPanel.state === "visible")
+ return 0.0
+ if (webEngineView.url == "" || webEngineView.url == "about:blank")
+ return 1.0
+ return 0.0
+ }
+ anchors.fill: parent
+ visible: opacity != 0.0
+ color: "#09102b"
+ Image {
+ id: placeholder
+ y: placeholder.height - navigation.y
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: "assets/icons/AppLogoColor.png"
+ }
+ Text {
+ id: label
+ anchors {
+ top: placeholder.bottom
+ topMargin: 20
+ horizontalCenter: placeholder.horizontalCenter
+ }
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ color: "white"
+ text: "Qt WebBrowser"
+ }
+
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration }
+ }
+ }
+
+ Rectangle {
+ id: findBar
+ anchors {
+ right: webEngineView.right
+ left: webEngineView.left
+ top: webEngineView.top
+ }
+ height: toolBarSize / 2 + 10
+ visible: false
+ color: uiColor
+
+ RowLayout {
+ spacing: 0
+ anchors.fill: parent
+ Rectangle {
+ width: 5
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiColor
+ }
+ TextField {
+ id: findTextField
+ Layout.fillWidth: true
+ onAccepted: {
+ webEngineView.findText(text)
+ }
+ style: TextFieldStyle {
+ textColor: "black"
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ selectionColor: uiHighlightColor
+ selectedTextColor: "black"
+ placeholderTextColor: placeholderColor
+ background: Rectangle {
+ implicitWidth: 514
+ implicitHeight: toolBarSize / 2
+ border.color: textFieldStrokeColor
+ border.width: 1
+ }
+ }
+ }
+ Rectangle {
+ width: 5
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiColor
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: findBackwardButton
+ iconSource: "assets/icons/Btn_Back.png"
+ implicitHeight: parent.height
+ onClicked: webEngineView.findText(findTextField.text, WebEngineView.FindBackward)
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: findForwardButton
+ iconSource: "assets/icons/Btn_Forward.png"
+ implicitHeight: parent.height
+ onClicked: webEngineView.findText(findTextField.text)
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: uiSeparatorColor
+ }
+ UIButton {
+ id: findCancelButton
+ iconSource: "assets/icons/Btn_Clear.png"
+ implicitHeight: parent.height
+ onClicked: findBar.visible = false
+ }
+ }
+ }
+ }
+ }
+
+ ListModel {
+ id: listModel
+ }
+
+ function makeCurrent(index) {
+ viewState = "list"
+ pathView.positionViewAtIndex(index, PathView.Center)
+ viewState = "page"
+ }
+
+ function createEmptyTab() {
+ var tab = add(tabComponent)
+ return tab
+ }
+
+ function add(component) {
+ if (listModel.count === tabViewMaxTabs) {
+ homeScreen.messageBox.state = "tabsfull"
+ homeScreen.state = "enabled"
+ homeScreen.forceActiveFocus()
+ return null
+ }
+
+ var element = {"item": null }
+ element.item = component.createObject(root, { "width": root.width, "height": root.height, "opacity": 0.0 })
+
+ if (element.item == null) {
+ console.log("PageView::add(): Error creating object");
+ return
+ }
+
+ listModel.append(element)
+ return element.item
+ }
+
+ function remove(index) {
+ pathView.interactive = false
+ pathView.currentItem.state = ""
+ pathView.currentItem.visible = false
+ listModel.remove(index)
+ pathView.decrementCurrentIndex()
+ pathView.interactive = true
+ }
+
+ function get(index) {
+ return listModel.get(index)
+ }
+
+ Component {
+ id: delegate
+
+ Rectangle {
+ id: wrapper
+
+ parent: item
+
+ property real visibility: 0.0
+ property bool isCurrentItem: PathView.isCurrentItem
+
+ visible: PathView.onPath && visibility != 0.0
+ state: isCurrentItem ? root.viewState : "list"
+
+ Behavior on scale {
+ NumberAnimation { duration: animationDuration }
+ }
+
+ states: [
+ State {
+ name: "page"
+ PropertyChanges { target: wrapper; width: root.width; height: root.height; visibility: 0.0 }
+ PropertyChanges { target: pathView; interactive: false }
+ PropertyChanges { target: item; opacity: 1.0 }
+ PropertyChanges { target: navigation; state: "enabled" }
+ },
+ State {
+ name: "list"
+ PropertyChanges { target: wrapper; width: itemWidth; height: itemHeight; visibility: 1.0 }
+ PropertyChanges { target: pathView; interactive: true }
+ PropertyChanges { target: item; opacity: 0.0 }
+ },
+ State {
+ name: "fullscreen"
+ PropertyChanges { target: wrapper; width: root.width; height: root.height; visibility: 0.0 }
+ PropertyChanges { target: pathView; interactive: false }
+ PropertyChanges { target: item; opacity: 1.0 }
+ PropertyChanges { target: navigation; state: "disabled" }
+ }
+ ]
+
+ transitions: Transition {
+ ParallelAnimation {
+ PropertyAnimation { property: "visibility"; duration: animationDuration; easing.type : Easing.InSine }
+ PropertyAnimation { properties: "x,y"; duration: animationDuration; easing.type: Easing.InSine }
+ PropertyAnimation { properties: "width,height"; duration: animationDuration; easing.type: Easing.InSine }
+ }
+ }
+
+ width: itemWidth; height: itemHeight
+ scale: {
+ if (pathView.count == 1)
+ return 1.0
+ if (pathView.count < 4)
+ return isCurrentItem ? 1.0 : 0.5
+
+ if (isCurrentItem)
+ return 1.0
+
+ var index1 = pathView.currentIndex - 2
+ var index2 = pathView.currentIndex - 1
+ var index4 = (pathView.currentIndex + 1) % pathView.count
+ var index5 = (pathView.currentIndex + 2) % pathView.count
+
+ if (index1 < 0)
+ index1 = pathView.count + index1
+ if (index2 < 0)
+ index2 = pathView.count + index2
+
+ switch (index) {
+ case index1 :
+ return 0.25
+ case index2:
+ return 0.5
+ case index4:
+ return 0.5
+ case index5:
+ return 0.25
+ }
+
+ return 0.25
+ }
+ z: PathView.itemZ
+
+ MouseArea {
+ enabled: pathView.interactive
+ anchors.fill: wrapper
+ onClicked: {
+ mouse.accepted = true
+ if (index < 0)
+ return
+
+ if (index == pathView.currentIndex) {
+ if (root.viewState == "list")
+ root.viewState = "page"
+ return
+ }
+ pathView.currentIndex = index
+ }
+ }
+ Rectangle {
+ id: shadow
+ visible: false
+ property real size: 24
+ anchors {
+ top: parent.top
+ topMargin: 9
+ horizontalCenter: parent.horizontalCenter
+ }
+ color: iconOverlayColor
+ radius: size / 2
+ width: snapshot.width
+ height: snapshot.height
+ }
+ GaussianBlur {
+ anchors.fill: shadow
+ source: shadow
+ radius: shadow.size
+ samples: shadow.size * 2
+ opacity: 0.3
+ transparentBorder: true
+ visible: wrapper.visibility == 1.0
+ }
+
+ Rectangle {
+ id: snapshot
+ color: uiColor
+
+ Image {
+ source: {
+ if (!item.image.snapshot)
+ return "assets/icons/about_blank.png"
+ return item.image.snapshot.url
+ }
+ anchors.fill: parent
+ Rectangle {
+ enabled: index == pathView.currentIndex && !pathView.moving && !pathView.flicking && wrapper.visibility == 1.0
+ opacity: enabled ? 1.0 : 0.0
+ visible: wrapper.visibility == 1.0 && listModel.count > 1
+ width: image.sourceSize.width
+ height: image.sourceSize.height - 2
+ radius: width / 2
+ color: iconOverlayColor
+ anchors {
+ horizontalCenter: parent.right
+ verticalCenter: parent.top
+ }
+ Image {
+ id: image
+ opacity: {
+ if (closeButton.pressed)
+ return 0.70
+ return 1.0
+ }
+ anchors {
+ top: parent.top
+ left: parent.left
+ }
+ source: "assets/icons/Btn_Delete.png"
+ MouseArea {
+ id: closeButton
+ anchors.fill: parent
+ onClicked: {
+ mouse.accepted = true
+ remove(pathView.currentIndex)
+ }
+ }
+ }
+ Behavior on opacity {
+ NumberAnimation { duration: animationDuration / 2 }
+ }
+ }
+ }
+ anchors.fill: wrapper
+ }
+
+ Text {
+ anchors {
+ topMargin: -25
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ }
+ horizontalAlignment: Text.AlignHCenter
+ width: parent.width - image.width
+ elide: Text.ElideRight
+ text: item.title
+ font.pixelSize: 16
+ font.family: defaultFontFamily
+ color: "white"
+ visible: wrapper.isCurrentItem && wrapper.visibility == 1.0
+ }
+ }
+ }
+
+ Rectangle {
+ color: "#09102b"
+ anchors.fill: parent
+ }
+
+ PathView {
+ id: pathView
+ pathItemCount: 5
+ anchors.fill: parent
+ model: listModel
+ delegate: delegate
+ highlightMoveDuration: animationDuration
+ highlightRangeMode: PathView.StrictlyEnforceRange
+ snapMode: PathView.SnapToItem
+ preferredHighlightBegin: 0.5
+ preferredHighlightEnd: 0.5
+
+ dragMargin: itemHeight
+
+ focus: pathView.interactive
+
+ property real offset: 30
+
+ property real margin: {
+ if (count == 2)
+ return root.width / 4 - offset
+ if (count == 3)
+ return root.width / 8 + offset
+ if (count == 4)
+ return root.width / 8 - offset
+
+ return offset
+ }
+
+ property real middle: {
+ if (currentItem)
+ return (pathView.height / 2) - (currentItem.visibility * 50)
+ return (pathView.height / 2 - 50)
+ }
+
+ path: Path {
+ startX: pathView.margin
+ startY: pathView.middle
+
+ PathPercent { value: 0.0 }
+ PathAttribute { name: "itemZ"; value: 0 }
+ PathLine {
+ x: (pathView.width - itemWidth) / 2 + 106
+ y: pathView.middle
+ }
+ PathPercent { value: 0.49 }
+ PathAttribute { name: "itemZ"; value: 6 }
+
+ PathLine { relativeX: 0; relativeY: 0 }
+
+ PathLine {
+ x: (pathView.width - itemWidth) / 2 + itemWidth - 106
+ y: pathView.middle
+ }
+ PathPercent { value: 0.51 }
+
+ PathLine { relativeX: 0; relativeY: 0 }
+
+ PathAttribute { name: "itemZ"; value: 4 }
+ PathLine {
+ x: pathView.width - pathView.margin
+ y: pathView.middle
+ }
+ PathPercent { value: 1 }
+ PathAttribute { name: "itemZ"; value: 2 }
+ }
+
+ Keys.onLeftPressed: decrementCurrentIndex()
+ Keys.onRightPressed: incrementCurrentIndex()
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml
new file mode 100644
index 0000000..678b966
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/SettingsView.qml
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import Qt.labs.settings 1.0
+
+import WebBrowser 1.0
+
+Rectangle {
+ id: root
+ color: "#09102b"
+ property bool privateBrowsingEnabled: appSettings[0].active
+ property bool httpDiskCacheEnabled: appSettings[1].active
+ property bool autoLoadImages: appSettings[2].active
+ property bool javaScriptDisabled: appSettings[3].active
+ // property bool pluginsEnabled: appSettings[4].active
+
+ property var appSettings: [
+ { "name": "Private Browsing", "active": false, "notify": function(v) { privateBrowsingEnabled = v; } },
+ { "name": "Enable HTTP Disk Cache", "active": true, "notify": function(v) { httpDiskCacheEnabled = v; } },
+ { "name": "Auto Load Images", "active": true, "notify": function(v) { autoLoadImages = v; } },
+ { "name": "Disable JavaScript", "active": false, "notify": function(v) { javaScriptDisabled = v; } },
+// { "name": "Enable Plugins", "active": false, "notify": function(v) { pluginsEnabled = v; } }
+ ]
+
+ function save() {
+ for (var i = 0; i < appSettings.length; ++i) {
+ var setting = appSettings[i]
+
+ listModel.get(i).active = setting.active
+ // Do not persist private browsing mode
+ if (setting.name === "Private Browsing")
+ continue
+ AppEngine.saveSetting(setting.name, setting.active)
+ }
+ }
+
+ Rectangle{
+ color: "#9d9faa"
+ height: 2
+ anchors.top: root.top
+ anchors.right: root.right
+ anchors.left: root.left
+ z: 100
+ }
+
+ state: "disabled"
+
+ states: [
+ State {
+ name: "enabled"
+ AnchorChanges {
+ target: root
+ anchors.top: navigation.bottom
+ }
+ PropertyChanges {
+ target: settingsToolBar
+ opacity: 1.0
+ }
+ },
+ State {
+ name: "disabled"
+ AnchorChanges {
+ target: root
+ anchors.top: root.parent.bottom
+ }
+ PropertyChanges {
+ target: settingsToolBar
+ opacity: 0.0
+ }
+ }
+ ]
+
+ transitions: Transition {
+ AnchorAnimation { duration: animationDuration; easing.type : Easing.InSine }
+ }
+
+ ListModel {
+ id: listModel
+ }
+
+ ListView {
+ id: listView
+ leftMargin: 230
+ rightMargin: leftMargin
+ anchors.fill: parent
+ model: listModel
+ delegate: Rectangle {
+ color: "transparent"
+ height: 100
+ width: 560
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ text: name
+ color: sw.enabled ? "white" : "#848895"
+ }
+ Rectangle {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ CustomSwitch {
+ id: sw
+ onCheckedChanged: {
+ var setting = appSettings[index]
+ setting.active = checked
+ setting.notify(checked)
+ }
+ enabled: {
+ var ok = appSettings[index].name.indexOf("Disk Cache") < 0
+ return ok || !privateBrowsingEnabled
+ }
+ anchors.centerIn: parent
+ checked: {
+ if (enabled)
+ return active
+ return false
+ }
+ /*style: SwitchStyle {
+ handle: Rectangle {
+ width: 42
+ height: 42
+ radius: height / 2
+ color: "white"
+ border.color: control.checked ? "#5caa14" : "#9b9b9b"
+ border.width: 1
+ }
+
+ groove: Rectangle {
+ implicitWidth: 72
+ height: 42
+ radius: height / 2
+ border.color: control.checked ? "#5caa14" : "#9b9b9b"
+ color: control.checked ? "#5cff14" : "white"
+ border.width: 1
+ }
+ }*/
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ for (var i = 0; i < appSettings.length; ++i) {
+ var setting = appSettings[i]
+ var active = JSON.parse(AppEngine.restoreSetting(setting.name, setting.active))
+ if (setting.active !== active) {
+ setting.active = active
+ setting.notify(active)
+ }
+ listModel.append(setting)
+ }
+ listView.forceLayout()
+ }
+ Component.onDestruction: root.save()
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js
new file mode 100644
index 0000000..88e2bbe
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/Utils.js
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+. pragma library
+
+function quote(str, delimiter) {
+ // discuss at: http://phpjs.org/functions/preg_quote/
+ // original by: booeyOH
+ // improved by: Ates Goral (http://magnetiq.com)
+ // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+ // improved by: Brett Zamir (http://brett-zamir.me)
+ // bugfixed by: Onno Marsman
+ // example 1: preg_quote("$40");
+ // returns 1: '\\$40'
+ // example 2: preg_quote("*RRRING* Hello?");
+ // returns 2: '\\*RRRING\\* Hello\\?'
+ // example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
+ // returns 3: '\\\\\\.\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:'
+
+ return String(str)
+ .replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
+}
+
+function highlight( text, search )
+{
+ return text.replace( new RegExp( "(" + quote( search ) + ")" , 'gi' ), "<b>$1</b>" );
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml
new file mode 100644
index 0000000..cc9351f
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIButton.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+import QtQuick.Layouts 1.2
+
+
+ToolButton {
+ id: root
+ implicitHeight: toolBarSize
+ implicitWidth: toolBarSize
+
+ property alias buttonText: label.text
+ property alias textColor: label.color
+ property alias textSize: label.font.pixelSize
+ property string source: ""
+ property real radius: 0.0
+ property string color: uiColor
+ property string highlightColor: buttonPressedColor
+ Text {
+ id: label
+ color: "white"
+ anchors.centerIn: parent
+ font.family: defaultFontFamily
+ font.pixelSize: 28
+ }
+ style: ButtonStyle {
+ background: Rectangle {
+ opacity: root.enabled ? 1.0 : 0.3
+ color: root.pressed || root.checked ? root.highlightColor : root.color
+ radius: root.radius
+ Image {
+ source: root.source
+ width: Math.min(sourceSize.width, root.width)
+ height: Math.min(sourceSize.height, root.height)
+ anchors.centerIn: parent
+ }
+ }
+ }
+}
+
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml
new file mode 100644
index 0000000..39a0974
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/UIToolBar.qml
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import QtQuick.Layouts 1.0
+
+ToolBar {
+ id: root
+
+ property alias title: titleBox.text
+ property alias source: toolBarButton.source
+ property alias indicator: indicatorText.text
+
+ property int indicatorWidth: 40
+ property int indicatorHeight: 32
+
+ signal optionClicked()
+ signal doneClicked()
+
+ height: navigation.height
+
+ style: ToolBarStyle {
+ background: Rectangle {
+ color: toolBarFillColor
+ }
+ padding {
+ left: 0
+ right: 0
+ top: 0
+ bottom: 0
+ }
+ }
+
+ RowLayout {
+ spacing: 0
+ height: toolBarSize
+ anchors.fill: parent
+ Rectangle {
+ width: childrenRect.width
+ anchors {
+ left: parent.left
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: toolBarFillColor
+ Text {
+ id: titleBox
+ visible: root.title !== ""
+ anchors {
+ leftMargin: visible ? 30 : 0
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+ color: "white"
+ font.pixelSize: 28
+ font.family: defaultFontFamily
+ }
+ Rectangle {
+ visible: toolBarButton.visible && titleBox.visible
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: toolBarSeparatorColor
+ }
+ UIButton {
+ id: toolBarButton
+ visible: root.source !== ""
+ color: toolBarFillColor
+ Component.onCompleted: toolBarButton.clicked.connect(root.optionClicked)
+ anchors.left: titleBox.right
+ }
+ }
+ Rectangle {
+ visible: toolBarButton.visible
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: toolBarSeparatorColor
+ }
+ Rectangle {
+ width: indicatorWidth
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: toolBarFillColor
+ }
+ Rectangle {
+ color: toolBarFillColor
+ Layout.fillWidth: true
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ Rectangle {
+ visible: root.indicator !== ""
+ color: "transparent"
+ border.color: "white"
+ border.width: 2
+ width: indicatorWidth
+ height: indicatorHeight
+ anchors.centerIn: parent
+ Text {
+ id: indicatorText
+ anchors.centerIn: parent
+ color: "white"
+ font.family: defaultFontFamily
+ font.pixelSize: 20
+ }
+ }
+ }
+ Rectangle {
+ width: 1
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ }
+ color: toolBarSeparatorColor
+ }
+ UIButton {
+ id: doneButton
+ color: toolBarFillColor
+ buttonText: "Done"
+ implicitWidth: 120
+ Component.onCompleted: doneButton.clicked.connect(root.doneClicked)
+ }
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png
new file mode 100644
index 0000000..2a49717
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png
new file mode 100644
index 0000000..b2baae5
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png
new file mode 100644
index 0000000..3c45c42
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png
new file mode 100644
index 0000000..562c9f6
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png
new file mode 100644
index 0000000..a6dbe6a
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png
new file mode 100644
index 0000000..a8b8b6b
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png
new file mode 100644
index 0000000..fc286cc
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png
new file mode 100644
index 0000000..1c9870a
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png
new file mode 100644
index 0000000..2010838
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png
new file mode 100644
index 0000000..e4c96f8
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png
new file mode 100644
index 0000000..7358a59
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png
new file mode 100644
index 0000000..cff41cd
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png
new file mode 100644
index 0000000..a6ef383
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png
new file mode 100644
index 0000000..33d7400
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png
new file mode 100644
index 0000000..c007408
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png
new file mode 100644
index 0000000..f70a78d
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png
new file mode 100644
index 0000000..cf40696
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg
new file mode 100644
index 0000000..fce4b40
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/LightWebBrowser_Icons.svg
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.1.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="1024px" height="768px" viewBox="0 0 1024 768" style="enable-background:new 0 0 1024 768;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill:none;}
+ .st1{fill:#FFFFFF;}
+ .st2{fill:#BDBEBF;}
+ .st3{opacity:0.25;}
+ .st4{fill:#3882AE;}
+ .st5{fill:#46A2DA;}
+ .st6{opacity:0.8;}
+ .st7{fill:#FDDD5C;}
+ .st8{fill:#80C342;}
+ .st9{fill:#D6D6D6;}
+</style>
+<g>
+ <rect class="st0" width="1024" height="768"/>
+ <g id="Layer_1_1_">
+ <rect x="512" width="512" height="768"/>
+ </g>
+ <g id="Layer_2">
+ <g>
+ <g>
+ <path class="st1" d="M569.6,71.1c-0.3,0-0.5-0.1-0.7-0.3L554,56l14.8-14.8c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4L556.8,56l13.4,13.4
+ c0.4,0.4,0.4,1,0,1.4C570.1,71,569.8,71.1,569.6,71.1z"/>
+ </g>
+ <g>
+ <rect x="524" y="16" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path class="st1" d="M640.4,71.1c0.3,0,0.5-0.1,0.7-0.3L656,56l-14.8-14.8c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4L653.2,56
+ l-13.4,13.4c-0.4,0.4-0.4,1,0,1.4C639.9,71,640.2,71.1,640.4,71.1z"/>
+ </g>
+ <g>
+ <rect x="606" y="16" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <path class="st1" d="M728,43.5l13,9.5v16h-26V53L728,43.5 M728,41l-15,11v19h30V52L728,41L728,41z"/>
+ <g>
+ <g>
+ <rect x="688" y="16" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ </g>
+ <g>
+ <g>
+ <g>
+ <rect x="770" y="16" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <path class="st1" d="M824,70h-28V48h28V70z M798,68h24V50h-24V68z"/>
+ <polygon class="st1" points="812,42 812,48 814,48 814,44 828,44 828,58 824,58 824,60 830,60 830,42 "/>
+ <polygon class="st1" points="796,58 792,58 792,44 806,44 806,48 808,48 808,42 790,42 790,60 796,60 "/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path class="st1" d="M901.9,72c-0.2,0-0.4,0-0.5-0.1l-9.4-5.8l-9.4,5.8c-0.3,0.2-0.8,0.2-1.1,0c-0.3-0.2-0.5-0.7-0.4-1.1
+ l2.7-10.5l-8.5-7c-0.3-0.3-0.4-0.7-0.3-1.1s0.5-0.7,0.9-0.7l11-0.8l4.1-10.1c0.2-0.4,0.5-0.6,0.9-0.6s0.8,0.2,0.9,0.6l4.1,10.1
+ l11,0.8c0.4,0,0.8,0.3,0.9,0.7c0.1,0.4,0,0.8-0.3,1.1l-8.5,7l2.7,10.5c0.1,0.4,0,0.8-0.4,1.1C902.3,71.9,902.1,72,901.9,72z
+ M892,63.9c0.2,0,0.4,0,0.5,0.1l7.8,4.8l-2.2-8.8c-0.1-0.4,0-0.8,0.3-1l7-5.8l-9.1-0.6c-0.4,0-0.7-0.3-0.9-0.6l-3.4-8.4
+ l-3.4,8.4c-0.1,0.4-0.5,0.6-0.9,0.6l-9.1,0.6l7,5.8c0.3,0.2,0.4,0.6,0.3,1l-2.2,8.8l7.8-4.8C891.6,63.9,891.8,63.9,892,63.9z"/>
+ </g>
+ <g>
+ <rect x="852" y="16" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <circle class="st1" cx="974" cy="44" r="3"/>
+ <circle class="st1" cx="974" cy="56" r="3"/>
+ <circle class="st1" cx="974" cy="68" r="3"/>
+ </g>
+ <g>
+ <rect x="934" y="16" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <rect x="42" y="16" class="st0" width="80" height="80"/>
+ </g>
+ <g>
+ <path class="st2" d="M78.5,43.5c5,0,9,4,9,9s-4,9-9,9s-9-4-9-9S73.5,43.5,78.5,43.5 M78.5,41C72.1,41,67,46.1,67,52.5
+ C67,58.9,72.1,64,78.5,64S90,58.9,90,52.5C90,46.1,84.9,41,78.5,41L78.5,41z"/>
+ <path class="st2" d="M96.8,67.9c0.3,0.3,0.3,0.8,0,1.2L95,70.8c-0.3,0.3-0.8,0.3-1.2,0l-9.1-9.1c-0.3-0.3-0.3-0.8,0-1.2l1.7-1.7
+ c0.3-0.3,0.8-0.3,1.2,0L96.8,67.9z"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <g>
+ <path class="st2" d="M259,41c-8.3,0-15,6.7-15,15s6.7,15,15,15s15-6.7,15-15S267.3,41,259,41z M266.8,62.4l-1.4,1.4l-6.4-6.4
+ l-6.4,6.4l-1.4-1.4l6.4-6.4l-6.4-6.4l1.4-1.4l6.4,6.4l6.4-6.4l1.4,1.4l-6.4,6.4L266.8,62.4z"/>
+ </g>
+ </g>
+ <rect x="232" y="29" class="st0" width="54" height="54"/>
+ </g>
+ <g>
+ <rect x="326" y="29" class="st0" width="54" height="54"/>
+ <g>
+ <path class="st2" d="M363.9,61.1C362,65.2,357.8,68,353,68c-6.6,0-12-5.4-12-12c0-6.6,5.4-12,12-12c4,0,7.5,2,9.7,5h2.4
+ c-2.4-4.2-6.9-7-12.1-7c-7.7,0-14,6.3-14,14s6.3,14,14,14c5.6,0,10.4-3.3,12.7-8.1L363.9,61.1z"/>
+ <polygon class="st2" points="367.4,52 357.5,52 367.4,42.2 "/>
+ </g>
+ </g>
+ <g>
+ <rect x="420" y="29" class="st0" width="54" height="54"/>
+ <g>
+ <g class="st3">
+ <circle cx="447" cy="57" r="25"/>
+ </g>
+ <g>
+ <path class="st1" d="M447,79.5c-13.5,0-24.5-11-24.5-24.5s11-24.5,24.5-24.5s24.5,11,24.5,24.5S460.5,79.5,447,79.5z"/>
+ <path class="st4" d="M447,31c13.2,0,24,10.8,24,24s-10.8,24-24,24s-24-10.8-24-24S433.8,31,447,31 M447,30
+ c-13.8,0-25,11.2-25,25s11.2,25,25,25s25-11.2,25-25S460.8,30,447,30L447,30z"/>
+ </g>
+ <g>
+
+ <rect x="433" y="54" transform="matrix(0.7071 0.7071 -0.7071 0.7071 169.8026 -299.9675)" class="st4" width="28" height="2"/>
+
+ <rect x="433" y="54" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 801.9339 -222.1632)" class="st4" width="28" height="2"/>
+ </g>
+ </g>
+ </g>
+ <g>
+ <g>
+ <rect x="563" y="162" class="st1" width="2" height="28"/>
+ <rect x="550" y="175" class="st1" width="28" height="2"/>
+ </g>
+ <g>
+ <rect x="524" y="136" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <g>
+ <path class="st1" d="M73,193c-2.8,0-5-2.2-5-5v-46c0-2.8,2.2-5,5-5h66c2.8,0,5,2.2,5,5v46c0,2.8-2.2,5-5,5H73z"/>
+ <path class="st5" d="M139,138c2.2,0,4,1.8,4,4v46c0,2.2-1.8,4-4,4H73c-2.2,0-4-1.8-4-4v-46c0-2.2,1.8-4,4-4H139 M139,136H73
+ c-3.3,0-6,2.7-6,6v46c0,3.3,2.7,6,6,6h66c3.3,0,6-2.7,6-6v-46C145,138.7,142.3,136,139,136L139,136z"/>
+ </g>
+ <polygon class="st1" points="109,187 93,187 93,194 108,211 108,194 "/>
+ <rect x="107" y="192" class="st5" width="2" height="20"/>
+ <polygon class="st5" points="107,209 107,212 91,192 93,192 "/>
+ </g>
+ <g>
+ <g>
+ <path class="st5" d="M109.6,165.2c0-3.5,0.5-6.7,1.5-9.7s2.5-5.6,4.4-7.9h2.2c-1.9,2.4-3.4,5.1-4.4,8.1s-1.5,6.2-1.5,9.5
+ c0,6.3,2,12.1,5.9,17.3h-2.2c-1.9-2.2-3.4-4.8-4.4-7.8S109.6,168.6,109.6,165.2z"/>
+ </g>
+ <g>
+ <g>
+ <path class="st5" d="M123.5,156c-1.1-1.8-3.2-2.8-5.7-2.8c-1.3,0-2.7,0.3-3.9,0.8c-0.2,0.6-0.5,1.1-0.7,1.7
+ c-0.1,0.4-0.2,0.7-0.3,1.1c0,0,0.1,0,0.1-0.1c1.5-1,3.2-1.5,4.8-1.5c1.8,0,3.3,0.7,4.1,1.9c1.5,2.4,0,6.1-3.4,8.2
+ c-1.5,1-3.2,1.5-4.8,1.5c-0.7,0-1.4-0.1-1.9-0.3c0,0.7,0.1,1.4,0.2,2c0.5,0.1,1.1,0.2,1.7,0.2c2,0,4.1-0.6,5.9-1.8
+ C123.8,164.2,125.6,159.3,123.5,156z"/>
+ </g>
+ <path class="st5" d="M118.6,159.3c-0.2-0.5-0.8-0.7-1.3-0.4l-5.4,2.7c-0.1,0.7-0.1,1.5-0.2,2.2l6.4-3.3
+ C118.7,160.4,118.9,159.8,118.6,159.3z"/>
+ </g>
+ <g>
+ <rect x="88" y="176" transform="matrix(0.7071 0.7071 -0.7071 0.7071 152.9725 -15.3456)" class="st5" width="14" height="2"/>
+
+ <rect x="88" y="176" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 287.3204 234.9828)" class="st5" width="14" height="2"/>
+ </g>
+ <g>
+ <rect x="88" y="152" transform="matrix(0.7071 0.7071 -0.7071 0.7071 136.003 -22.3749)" class="st5" width="14" height="2"/>
+
+ <rect x="88" y="152" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 270.3508 194.0141)" class="st5" width="14" height="2"/>
+ </g>
+ </g>
+ </g>
+ <g>
+ <g class="st6">
+ <rect x="185" y="136" class="st5" width="70" height="70"/>
+ </g>
+ <g>
+ <path class="st1" d="M204.9,177.6c0-0.3,0.1-0.5,0.3-0.7L220,162l14.8,14.8c0.4,0.4,0.4,1,0,1.4s-1,0.4-1.4,0L220,164.8
+ l-13.4,13.4c-0.4,0.4-1,0.4-1.4,0C205,178.1,204.9,177.8,204.9,177.6z"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path class="st7" d="M655.9,192c-0.2,0-0.4,0-0.5-0.1l-9.4-5.8l-9.4,5.8c-0.3,0.2-0.8,0.2-1.1,0c-0.3-0.2-0.5-0.7-0.4-1.1
+ l2.7-10.5l-8.5-7c-0.3-0.3-0.4-0.7-0.3-1.1c0.1-0.4,0.5-0.7,0.9-0.7l11-0.8l4.1-10.1c0.2-0.4,0.5-0.6,0.9-0.6s0.8,0.2,0.9,0.6
+ l4.1,10.1l11,0.8c0.4,0,0.8,0.3,0.9,0.7s0,0.8-0.3,1.1l-8.5,7l2.7,10.5c0.1,0.4,0,0.8-0.4,1.1C656.3,191.9,656.1,192,655.9,192z
+ "/>
+ </g>
+ <g>
+ <rect x="606" y="136" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path class="st2" d="M173.9,72c-0.2,0-0.4,0-0.5-0.1l-9.4-5.8l-9.4,5.8c-0.3,0.2-0.8,0.2-1.1,0s-0.5-0.7-0.4-1.1l2.7-10.5
+ l-8.5-7c-0.3-0.3-0.4-0.7-0.3-1.1c0.1-0.4,0.5-0.7,0.9-0.7l11-0.8l4.1-10.1c0.2-0.4,0.5-0.6,0.9-0.6s0.8,0.2,0.9,0.6l4.1,10.1
+ l11,0.8c0.4,0,0.8,0.3,0.9,0.7c0.1,0.4,0,0.8-0.3,1.1l-8.5,7l2.7,10.5c0.1,0.4,0,0.8-0.4,1.1C174.3,71.9,174.1,72,173.9,72z
+ M164,63.9c0.2,0,0.4,0,0.5,0.1l7.8,4.8l-2.2-8.8c-0.1-0.4,0-0.8,0.3-1l7-5.8l-9.1-0.6c-0.4,0-0.7-0.3-0.9-0.6l-3.4-8.4
+ l-3.4,8.4c-0.1,0.4-0.5,0.6-0.9,0.6l-9.1,0.6l7,5.8c0.3,0.2,0.4,0.6,0.3,1l-2.2,8.8l7.8-4.8C163.6,63.9,163.8,63.9,164,63.9z"/>
+ </g>
+ <g>
+ <rect x="124" y="16" class="st0" width="80" height="80"/>
+ </g>
+ </g>
+ <g>
+ <circle class="st0" cx="107" cy="317" r="47"/>
+ <g>
+ <path class="st5" d="M107,363c-11.8,0-23.6-4.5-32.5-13.5c-17.9-17.9-17.9-47.1,0-65.1c17.9-17.9,47.1-17.9,65.1,0
+ c17.9,17.9,17.9,47.1,0,65.1l0,0C130.6,358.5,118.8,363,107,363z"/>
+ </g>
+ <path class="st8" d="M153,317c0-25.4-20.6-46-46-46c-12.7,0-24.2,5.1-32.5,13.5l65.1,65.1C147.9,341.2,153,329.7,153,317z"/>
+ <g>
+ <path class="st5" d="M107,335c-4.8,0-9.3-1.9-12.7-5.3c-7-7-7-18.4,0-25.5c3.4-3.4,7.9-5.3,12.7-5.3s9.3,1.9,12.7,5.3
+ c7,7,7,18.4,0,25.5C116.3,333.1,111.8,335,107,335z"/>
+ <path class="st1" d="M122.2,329.9c6.7-7.9,6.3-19.6-1.1-27.1c-3.9-3.9-9-5.9-14.1-5.9s-10.2,2-14.1,5.9
+ c-7.8,7.8-7.8,20.5,0,28.3c3.9,3.9,9,5.9,14.1,5.9c4.4,0,8.8-1.4,12.4-4.3l18.5,18.5c1-0.9,1.9-1.8,2.8-2.8L122.2,329.9z
+ M95.7,328.3c-6.2-6.2-6.2-16.4,0-22.6c3-3,7-4.7,11.3-4.7s8.3,1.7,11.3,4.7c6.2,6.2,6.2,16.4,0,22.6c-3,3-7,4.7-11.3,4.7
+ S98.7,331.3,95.7,328.3z"/>
+ </g>
+ </g>
+ <g>
+ <circle class="st0" cx="232" cy="317" r="47"/>
+ <g>
+ <path class="st2" d="M232,363c-11.8,0-23.6-4.5-32.5-13.5c-17.9-17.9-17.9-47.1,0-65.1c17.9-17.9,47.1-17.9,65.1,0
+ c17.9,17.9,17.9,47.1,0,65.1l0,0C255.6,358.5,243.8,363,232,363z"/>
+ </g>
+ <path class="st9" d="M278,317c0-25.4-20.6-46-46-46c-12.7,0-24.2,5.1-32.5,13.5l65.1,65.1C272.9,341.2,278,329.7,278,317z"/>
+ <g>
+ <path class="st2" d="M232,335c-4.8,0-9.3-1.9-12.7-5.3c-7-7-7-18.4,0-25.5c3.4-3.4,7.9-5.3,12.7-5.3s9.3,1.9,12.7,5.3
+ c7,7,7,18.4,0,25.5C241.3,333.1,236.8,335,232,335z"/>
+ <path class="st1" d="M247.2,329.9c6.7-7.9,6.3-19.6-1.1-27.1c-3.9-3.9-9-5.9-14.1-5.9s-10.2,2-14.1,5.9
+ c-7.8,7.8-7.8,20.5,0,28.3c3.9,3.9,9,5.9,14.1,5.9c4.4,0,8.8-1.4,12.4-4.3l18.5,18.5c1-0.9,1.9-1.8,2.8-2.8L247.2,329.9z
+ M220.7,328.3c-6.2-6.2-6.2-16.4,0-22.6c3-3,7-4.7,11.3-4.7s8.3,1.7,11.3,4.7c6.2,6.2,6.2,16.4,0,22.6c-3,3-7,4.7-11.3,4.7
+ S223.7,331.3,220.7,328.3z"/>
+ </g>
+ </g>
+ </g>
+</g>
+</svg>
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png
new file mode 100644
index 0000000..6901b0b
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png
new file mode 100644
index 0000000..6a22d2e
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png
new file mode 100644
index 0000000..7649ee9
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png
Binary files differ
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc
new file mode 100644
index 0000000..451a67f
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/resources.qrc
@@ -0,0 +1,37 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/BrowserWindow.qml</file>
+ <file>qml/FeaturePermissionBar.qml</file>
+ <file>qml/MockTouchPoint.qml</file>
+ <file>qml/PageView.qml</file>
+ <file>qml/NavigationBar.qml</file>
+ <file>qml/HomeScreen.qml</file>
+ <file>qml/SettingsView.qml</file>
+ <file>qml/assets/UIButton.qml</file>
+ <file>qml/assets/UIToolBar.qml</file>
+ <file>qml/Utils.js</file>
+ <file>qml/assets/icons/Btn_Home.png</file>
+ <file>qml/assets/icons/Btn_Tabs.png</file>
+ <file>qml/assets/icons/Btn_Forward.png</file>
+ <file>qml/assets/icons/Btn_Back.png</file>
+ <file>qml/assets/icons/Btn_Reload.png</file>
+ <file>qml/assets/icons/Btn_Clear.png</file>
+ <file>qml/assets/icons/touchpoint.png</file>
+ <file>qml/assets/icons/Btn_Delete.png</file>
+ <file>qml/assets/icons/Btn_Bookmarks.png</file>
+ <file>qml/assets/icons/Btn_Bookmark_Checked.png</file>
+ <file>qml/assets/icons/Btn_Bookmark_Indicator.png</file>
+ <file>qml/assets/icons/Btn_Settings.png</file>
+ <file>qml/assets/icons/about_blank.png</file>
+ <file>qml/assets/icons/Btn_Add.png</file>
+ <file>qml/assets/icons/Btn_Up.png</file>
+ <file>qml/assets/icons/Btn_Search.png</file>
+ <file>qml/assets/icons/Error_Icon.png</file>
+ <file>qml/assets/icons/qt.png</file>
+ <file>qml/assets/icons/AppLogoColor.png</file>
+ <file>qml/assets/icons/AppLogoGrey.png</file>
+ <file>qml/Keyboard.qml</file>
+ <file>qml/Main.qml</file>
+ <file>qml/CustomSwitch.qml</file>
+ </qresource>
+</RCC>
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro
new file mode 100644
index 0000000..79e4bdc
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/src.pro
@@ -0,0 +1,43 @@
+TARGET = qtwebbrowser
+
+CONFIG += c++11
+CONFIG -= app_bundle
+
+SOURCES = \
+ appengine.cpp \
+ main.cpp \
+ navigationhistoryproxymodel.cpp \
+ touchtracker.cpp
+
+HEADERS = \
+ appengine.h \
+ navigationhistoryproxymodel.h \
+ touchtracker.h \
+
+OTHER_FILES = \
+ qml/assets/UIButton.qml \
+ qml/assets/UIToolBar.qml \
+ qml/ApplicationRoot.qml \
+ qml/BrowserWindow.qml \
+ qml/FeaturePermissionBar.qml \
+ qml/MockTouchPoint.qml \
+ qml/PageView.qml \
+ qml/NavigationBar.qml \
+ qml/HomeScreen.qml \
+ qml/SettingsView.qml \
+ qml/Keyboard.qml \
+ qml/Window.qml
+
+QT += qml quick webengine
+
+RESOURCES += resources.qrc
+
+!cross_compile {
+ DEFINES += DESKTOP_BUILD
+ SOURCES += touchmockingapplication.cpp
+ HEADERS += touchmockingapplication.h
+ QT += gui-private
+} else {
+ target.path =/data/user/qt/qtwebbrowser-app
+ INSTALLS += target
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp
new file mode 100644
index 0000000..256c45e
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "touchmockingapplication.h"
+#include "appengine.h"
+
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/QRegExp>
+#include <QtCore/QEvent>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QTouchEvent>
+#include <QtQuick/QQuickItem>
+#include <QtQuick/QQuickView>
+
+using namespace utils;
+
+static inline QRectF touchRectForPosition(QPointF centerPoint)
+{
+ QRectF touchRect(0, 0, 40, 40);
+ touchRect.moveCenter(centerPoint);
+ return touchRect;
+}
+
+TouchMockingApplication::TouchMockingApplication(int& argc, char** argv)
+ : QGuiApplication(argc, argv)
+ , m_realTouchEventReceived(false)
+ , m_pendingFakeTouchEventCount(0)
+ , m_holdingControl(false)
+{
+}
+
+bool TouchMockingApplication::notify(QObject* target, QEvent* event)
+{
+ // We try to be smart, if we received real touch event, we are probably on a device
+ // with touch screen, and we should not have touch mocking.
+
+ if (!event->spontaneous() || m_realTouchEventReceived)
+ return QGuiApplication::notify(target, event);
+
+ if (isTouchEvent(event)) {
+ if (m_pendingFakeTouchEventCount)
+ --m_pendingFakeTouchEventCount;
+ else
+ m_realTouchEventReceived = true;
+ return QGuiApplication::notify(target, event);
+ }
+
+ QQuickView* window = qobject_cast<QQuickView*>(target);
+ if (!window)
+ return QGuiApplication::notify(target, event);
+
+ m_holdingControl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
+
+ if (event->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(event)->key() == Qt::Key_Control) {
+ foreach (int id, m_heldTouchPoints)
+ if (m_touchPoints.contains(id) && !QGuiApplication::mouseButtons().testFlag(Qt::MouseButton(id))) {
+ m_touchPoints[id].setState(Qt::TouchPointReleased);
+ m_heldTouchPoints.remove(id);
+ } else
+ m_touchPoints[id].setState(Qt::TouchPointStationary);
+
+ sendTouchEvent(window, m_heldTouchPoints.isEmpty() ? QEvent::TouchEnd : QEvent::TouchUpdate, static_cast<QKeyEvent*>(event)->timestamp());
+ }
+
+ if (isMouseEvent(event)) {
+ const QMouseEvent* const mouseEvent = static_cast<QMouseEvent*>(event);
+
+ QTouchEvent::TouchPoint touchPoint;
+ touchPoint.setPressure(1);
+
+ QEvent::Type touchType = QEvent::None;
+
+ switch (mouseEvent->type()) {
+ case QEvent::MouseButtonPress:
+ touchPoint.setId(mouseEvent->button());
+ if (m_touchPoints.contains(touchPoint.id())) {
+ touchPoint.setState(Qt::TouchPointMoved);
+ touchType = QEvent::TouchUpdate;
+ } else {
+ touchPoint.setState(Qt::TouchPointPressed);
+ // Check if more buttons are held down than just the event triggering one.
+ if (mouseEvent->buttons() > mouseEvent->button())
+ touchType = QEvent::TouchUpdate;
+ else
+ touchType = QEvent::TouchBegin;
+ }
+ break;
+ case QEvent::MouseMove:
+ if (!mouseEvent->buttons()) {
+ // We have to swallow the event instead of propagating it,
+ // since we avoid sending the mouse release events and if the
+ // Flickable is the mouse grabber it would receive the event
+ // and would move the content.
+ event->accept();
+ return true;
+ }
+ touchType = QEvent::TouchUpdate;
+ touchPoint.setId(mouseEvent->buttons());
+ touchPoint.setState(Qt::TouchPointMoved);
+ break;
+ case QEvent::MouseButtonRelease:
+ // Check if any buttons are still held down after this event.
+ if (mouseEvent->buttons())
+ touchType = QEvent::TouchUpdate;
+ else
+ touchType = QEvent::TouchEnd;
+ touchPoint.setId(mouseEvent->button());
+ touchPoint.setState(Qt::TouchPointReleased);
+ break;
+ case QEvent::MouseButtonDblClick:
+ // Eat double-clicks, their accompanying press event is all we need.
+ event->accept();
+ return true;
+ default:
+ Q_ASSERT_X(false, "multi-touch mocking", "unhandled event type");
+ }
+
+ // A move can have resulted in multiple buttons, so we need check them individually.
+ if (touchPoint.id() & Qt::LeftButton)
+ updateTouchPoint(mouseEvent, touchPoint, Qt::LeftButton);
+ if (touchPoint.id() & Qt::MidButton)
+ updateTouchPoint(mouseEvent, touchPoint, Qt::MidButton);
+ if (touchPoint.id() & Qt::RightButton)
+ updateTouchPoint(mouseEvent, touchPoint, Qt::RightButton);
+
+ if (m_holdingControl && touchPoint.state() == Qt::TouchPointReleased) {
+ // We avoid sending the release event because the Flickable is
+ // listening to mouse events and would start a bounce-back
+ // animation if it received a mouse release.
+ event->accept();
+ return true;
+ }
+
+ // Update states for all other touch-points
+ for (QHash<int, QTouchEvent::TouchPoint>::iterator it = m_touchPoints.begin(), end = m_touchPoints.end(); it != end; ++it) {
+ if (!(it.value().id() & touchPoint.id()))
+ it.value().setState(Qt::TouchPointStationary);
+ }
+
+ Q_ASSERT(touchType != QEvent::None);
+
+ if (!sendTouchEvent(window, touchType, mouseEvent->timestamp()))
+ return QGuiApplication::notify(target, event);
+
+ event->accept();
+ return true;
+ }
+
+ return QGuiApplication::notify(target, event);
+}
+
+void TouchMockingApplication::updateTouchPoint(const QMouseEvent* mouseEvent, QTouchEvent::TouchPoint touchPoint, Qt::MouseButton mouseButton)
+{
+ // Ignore inserting additional touch points if Ctrl isn't held because it produces
+ // inconsistent touch events and results in assers in the gesture recognizers.
+ if (!m_holdingControl && m_touchPoints.size() && !m_touchPoints.contains(mouseButton))
+ return;
+
+ if (m_holdingControl && touchPoint.state() == Qt::TouchPointReleased) {
+ m_heldTouchPoints.insert(mouseButton);
+ return;
+ }
+
+ // Gesture recognition uses the screen position for the initial threshold
+ // but since the canvas translates touch events we actually need to pass
+ // the screen position as the scene position to deliver the appropriate
+ // coordinates to the target.
+ touchPoint.setRect(touchRectForPosition(mouseEvent->localPos()));
+ touchPoint.setSceneRect(touchRectForPosition(mouseEvent->screenPos()));
+
+ if (touchPoint.state() == Qt::TouchPointPressed)
+ touchPoint.setStartScenePos(mouseEvent->screenPos());
+ else {
+ const QTouchEvent::TouchPoint& oldTouchPoint = m_touchPoints[mouseButton];
+ touchPoint.setStartScenePos(oldTouchPoint.startScenePos());
+ touchPoint.setLastPos(oldTouchPoint.pos());
+ touchPoint.setLastScenePos(oldTouchPoint.scenePos());
+ }
+
+ // Update current touch-point.
+ touchPoint.setId(mouseButton);
+ m_touchPoints.insert(mouseButton, touchPoint);
+}
+
+bool TouchMockingApplication::sendTouchEvent(QQuickView* window, QEvent::Type type, ulong timestamp)
+{
+ static QTouchDevice* device = 0;
+ if (!device) {
+ device = new QTouchDevice;
+ device->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(device);
+ }
+
+ m_pendingFakeTouchEventCount++;
+
+ const QList<QTouchEvent::TouchPoint>& currentTouchPoints = m_touchPoints.values();
+ Qt::TouchPointStates touchPointStates = 0;
+ foreach (const QTouchEvent::TouchPoint& touchPoint, currentTouchPoints)
+ touchPointStates |= touchPoint.state();
+
+ QTouchEvent event(type, device, Qt::NoModifier, touchPointStates, currentTouchPoints);
+ event.setTimestamp(timestamp);
+ event.setAccepted(false);
+
+ QGuiApplication::notify(window, &event);
+
+ updateVisualMockTouchPoints(window,m_holdingControl ? currentTouchPoints : QList<QTouchEvent::TouchPoint>());
+
+ // Get rid of touch-points that are no longer valid
+ foreach (const QTouchEvent::TouchPoint& touchPoint, currentTouchPoints) {
+ if (touchPoint.state() == Qt::TouchPointReleased)
+ m_touchPoints.remove(touchPoint.id());
+ }
+
+ return event.isAccepted();
+}
+
+void TouchMockingApplication::updateVisualMockTouchPoints(QQuickView* window,const QList<QTouchEvent::TouchPoint>& touchPoints)
+{
+ if (touchPoints.isEmpty()) {
+ // Hide all touch indicator items.
+ foreach (QQuickItem* item, m_activeMockComponents.values())
+ item->setProperty("pressed", false);
+
+ return;
+ }
+
+ foreach (const QTouchEvent::TouchPoint& touchPoint, touchPoints) {
+ QQuickItem* mockTouchPointItem = m_activeMockComponents.value(touchPoint.id());
+
+ if (!mockTouchPointItem) {
+ QQmlComponent touchMockPointComponent(window->engine(), QUrl("qrc:///qml/MockTouchPoint.qml"));
+ mockTouchPointItem = qobject_cast<QQuickItem*>(touchMockPointComponent.create());
+ Q_ASSERT(mockTouchPointItem);
+ m_activeMockComponents.insert(touchPoint.id(), mockTouchPointItem);
+ mockTouchPointItem->setProperty("pointId", QVariant(touchPoint.id()));
+ mockTouchPointItem->setParent(window->rootObject());
+ mockTouchPointItem->setParentItem(window->rootObject());
+ }
+
+ QRectF touchRect = touchPoint.rect();
+ mockTouchPointItem->setX(touchRect.center().x());
+ mockTouchPointItem->setY(touchRect.center().y());
+ mockTouchPointItem->setWidth(touchRect.width());
+ mockTouchPointItem->setHeight(touchRect.height());
+ mockTouchPointItem->setProperty("pressed", QVariant(touchPoint.state() != Qt::TouchPointReleased));
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h
new file mode 100644
index 0000000..88c5e20
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchmockingapplication.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOUCHMOCKINGAPPLICATION_H
+#define TOUCHMOCKINGAPPLICATION_H
+
+#include <QtCore/QHash>
+#include <QtCore/QUrl>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QTouchEvent>
+
+QT_BEGIN_NAMESPACE
+class QQuickView;
+class QQuickItem;
+QT_END_NAMESPACE
+
+class TouchMockingApplication : public QGuiApplication
+{
+ Q_OBJECT
+
+public:
+ TouchMockingApplication(int &argc, char **argv);
+
+ virtual bool notify(QObject *, QEvent *) override;
+
+private:
+ void updateTouchPoint(const QMouseEvent *, QTouchEvent::TouchPoint, Qt::MouseButton);
+ bool sendTouchEvent(QQuickView *, QEvent::Type, ulong timestamp);
+ void updateVisualMockTouchPoints(QQuickView *,const QList<QTouchEvent::TouchPoint> &touchPoints);
+
+private:
+ bool m_realTouchEventReceived;
+ int m_pendingFakeTouchEventCount;
+
+ QPointF m_lastPos;
+ QPointF m_lastScreenPos;
+ QPointF m_startScreenPos;
+
+ QHash<int, QTouchEvent::TouchPoint> m_touchPoints;
+ QSet<int> m_heldTouchPoints;
+ QHash<int, QQuickItem*> m_activeMockComponents;
+
+ bool m_holdingControl;
+};
+
+#endif // TOUCHMOCKINGAPPLICATION_H
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp
new file mode 100644
index 0000000..52a028a
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "touchtracker.h"
+#include "appengine.h"
+
+#include <QDateTime>
+
+using namespace utils;
+
+TouchTracker::TouchTracker(QQuickItem *parent)
+ : QQuickItem(parent)
+ , m_blockEvents(false)
+ , m_diff(0)
+ , m_previousY(0)
+ , m_target(0)
+ , m_delegate(0)
+{
+ m_startPoint.ts = 0;
+ m_currentPoint.ts = 0;
+}
+
+QQuickItem *TouchTracker::target() const
+{
+ return m_target;
+}
+
+void TouchTracker::setTarget(QQuickItem * target)
+{
+ m_target = target;
+ emit targetChanged();
+}
+
+int TouchTracker::xVelocity() const
+{
+ qreal pos = qAbs(m_startPoint.x() - m_currentPoint.x());
+ qreal time = qAbs(m_startPoint.ts - m_currentPoint.ts);
+ return pos / time * 1000;
+}
+
+int TouchTracker::yVelocity() const
+{
+ qreal pos = qAbs(m_startPoint.y() - m_currentPoint.y());
+ qreal time = qAbs(m_startPoint.ts - m_currentPoint.ts);
+ return pos / time * 1000;
+}
+
+
+qreal TouchTracker::touchX() const
+{
+ return m_currentPoint.x();
+}
+
+qreal TouchTracker::touchY() const
+{
+ return m_currentPoint.y();
+}
+
+bool TouchTracker::blockEvents() const
+{
+ return m_blockEvents;
+}
+
+void TouchTracker::setBlockEvents(bool shouldBlock)
+{
+ if (m_blockEvents == shouldBlock)
+ return;
+ m_blockEvents = shouldBlock;
+ emit blockEventsChanged();
+}
+
+bool TouchTracker::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj != m_delegate)
+ return QQuickItem::eventFilter(obj, event);
+
+ if (event->type() == QEvent::Wheel)
+ return m_blockEvents;
+
+ if (!isTouchEvent(event))
+ return QQuickItem::eventFilter(obj, event);
+
+ const QTouchEvent *touch = static_cast<QTouchEvent*>(event);
+ const QList<QTouchEvent::TouchPoint> &points = touch->touchPoints();
+ m_previousY = m_currentPoint.y();
+ m_currentPoint.pos = m_target->mapToScene(points.at(0).pos());
+ m_currentPoint.ts = QDateTime::currentMSecsSinceEpoch();
+ int currentDiff = m_previousY - m_currentPoint.y();
+
+ if ((currentDiff > 0 && m_diff < 0) || (currentDiff < 0 && m_diff > 0))
+ emit scrollDirectionChanged();
+
+ m_diff = currentDiff;
+
+ emit touchChanged();
+ emit velocityChanged();
+
+ if (event->type() == QEvent::TouchEnd)
+ emit touchEnd();
+
+ return m_blockEvents;
+}
+
+void TouchTracker::touchEvent(QTouchEvent * event)
+{
+ if (!m_target) {
+ if (!m_blockEvents)
+ QQuickItem::touchEvent(event);
+
+ return;
+ }
+
+ event->setAccepted(false);
+
+ const QList<QTouchEvent::TouchPoint> &points = event->touchPoints();
+ m_currentPoint.pos = m_target->mapToScene(points.at(0).pos());
+ m_currentPoint.ts = QDateTime::currentMSecsSinceEpoch();
+
+ if (event->type() == QEvent::TouchBegin) {
+ m_startPoint = m_currentPoint;
+ emit touchBegin();
+ }
+
+ emit touchChanged();
+
+ // We have to find the delegate to be able to filter
+ // events from the WebEngineView.
+ // This is a hack and should preferably be made easier
+ // with the API in some way.
+ QQuickItem *child = m_target->childAt(m_currentPoint.x(), m_currentPoint.y());
+ if (child && m_delegate != child) {
+ child->installEventFilter(this);
+ m_delegate = child;
+ }
+}
diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h
new file mode 100644
index 0000000..3aaecd2
--- /dev/null
+++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/touchtracker.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBrowser project.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPLv2 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TOUCHTRACKER_H
+#define TOUCHTRACKER_H
+
+#include <QObject>
+#include <QQuickItem>
+
+class TouchTracker : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal touchX READ touchX NOTIFY touchChanged)
+ Q_PROPERTY(qreal touchY READ touchY NOTIFY touchChanged)
+ Q_PROPERTY(int xVelocity READ xVelocity NOTIFY velocityChanged)
+ Q_PROPERTY(int yVelocity READ yVelocity NOTIFY velocityChanged)
+ Q_PROPERTY(bool blockEvents READ blockEvents WRITE setBlockEvents NOTIFY blockEventsChanged)
+ Q_PROPERTY(QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged)
+
+ struct PositionInfo
+ {
+ QPointF pos;
+ qint64 ts;
+ qreal x() const { return pos.x(); }
+ qreal y() const { return pos.y(); }
+ };
+
+public:
+ TouchTracker(QQuickItem *parent = 0);
+
+ qreal touchX() const;
+ qreal touchY() const;
+ int xVelocity() const;
+ int yVelocity() const;
+ QQuickItem* target() const;
+ bool blockEvents() const;
+ void setBlockEvents(bool shouldBlock);
+ void setTarget(QQuickItem * target);
+
+signals:
+ void touchChanged();
+ void blockEventsChanged();
+ void targetChanged();
+ void touchBegin();
+ void touchEnd();
+ void velocityChanged();
+ void scrollDirectionChanged();
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event);
+ void touchEvent(QTouchEvent *event) override;
+
+private:
+ bool m_blockEvents;
+ int m_diff;
+ int m_previousY;
+ PositionInfo m_startPoint;
+ PositionInfo m_currentPoint;
+ QQuickItem *m_target;
+ QQuickItem *m_delegate;
+};
+
+#endif // TOUCHTRACKER_H