diff options
Diffstat (limited to 'basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src')
45 files changed, 4617 insertions, 0 deletions
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 Binary files differnew file mode 100644 index 0000000..2a49717 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoColor.png diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png Binary files differnew file mode 100644 index 0000000..b2baae5 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/AppLogoGrey.png 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 Binary files differnew file mode 100644 index 0000000..3c45c42 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Add.png 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 Binary files differnew file mode 100644 index 0000000..562c9f6 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Back.png 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 Binary files differnew file mode 100644 index 0000000..a6dbe6a --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Checked.png 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 Binary files differnew file mode 100644 index 0000000..a8b8b6b --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmark_Indicator.png 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 Binary files differnew file mode 100644 index 0000000..fc286cc --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Bookmarks.png 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 Binary files differnew file mode 100644 index 0000000..1c9870a --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Clear.png 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 Binary files differnew file mode 100644 index 0000000..2010838 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Delete.png 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 Binary files differnew file mode 100644 index 0000000..e4c96f8 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Forward.png 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 Binary files differnew file mode 100644 index 0000000..7358a59 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Home.png 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 Binary files differnew file mode 100644 index 0000000..cff41cd --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Reload.png 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 Binary files differnew file mode 100644 index 0000000..a6ef383 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Search.png 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 Binary files differnew file mode 100644 index 0000000..33d7400 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Settings.png 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 Binary files differnew file mode 100644 index 0000000..c007408 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Tabs.png 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 Binary files differnew file mode 100644 index 0000000..f70a78d --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Btn_Up.png 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 Binary files differnew file mode 100644 index 0000000..cf40696 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/Error_Icon.png 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 Binary files differnew file mode 100644 index 0000000..6901b0b --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/about_blank.png diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png Binary files differnew file mode 100644 index 0000000..6a22d2e --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/qt.png diff --git a/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png Binary files differnew file mode 100644 index 0000000..7649ee9 --- /dev/null +++ b/basicsuite/qtwebbrowser/tqtc-qtwebbrowser/src/qml/assets/icons/touchpoint.png 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 |