From 6092d8839b83b33434bb49a9f74ab59ff43e61b0 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Thu, 26 Mar 2020 16:41:10 +0100 Subject: [PATCH] first experimental "webapp mode" --- src/CMakeLists.txt | 19 ++++ src/contents/webapp-ui/webapp.qml | 163 ++++++++++++++++++++++++++++++ src/webapp-resources.qrc | 5 + src/webappmain.cpp | 99 ++++++++++++++++++ 4 files changed, 286 insertions(+) create mode 100644 src/contents/webapp-ui/webapp.qml create mode 100644 src/webapp-resources.qrc create mode 100644 src/webappmain.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d8e489e..23045aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,3 +16,22 @@ add_executable(angelfish ${angelfish_SRCS} ${RESOURCES}) target_link_libraries(angelfish Qt5::Core Qt5::Qml Qt5::Quick Qt5::Sql Qt5::Svg Qt5::WebEngine KF5::I18n) install(TARGETS angelfish ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) + +set(angelfish_webapp_SRCS + webappmain.cpp + browsermanager.cpp + bookmarkshistorymodel.cpp + dbmanager.cpp + iconimageprovider.cpp + sqlquerymodel.cpp + urlutils.cpp + useragent.cpp + tabsmodel.cpp +) + +qt5_add_resources(WEBAPP_RESOURCES webapp-resources.qrc) + +add_executable(angelfish-webapp ${angelfish_webapp_SRCS} ${RESOURCES} ${WEBAPP_RESOURCES}) +target_link_libraries(angelfish-webapp Qt5::Core Qt5::Qml Qt5::Quick Qt5::Sql Qt5::Svg Qt5::WebEngine KF5::I18n) + +install(TARGETS angelfish-webapp ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/contents/webapp-ui/webapp.qml b/src/contents/webapp-ui/webapp.qml new file mode 100644 index 0000000..3b5f74f --- /dev/null +++ b/src/contents/webapp-ui/webapp.qml @@ -0,0 +1,163 @@ +/*************************************************************************** + * * + * Copyright 2014-2015 Sebastian Kügler * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + * * + ***************************************************************************/ + +import QtQuick 2.1 +import QtWebEngine 1.6 +import QtQuick.Window 2.3 +import QtGraphicalEffects 1.0 +import Qt.labs.settings 1.0 as QtSettings + +import org.kde.kirigami 2.7 as Kirigami +import org.kde.mobile.angelfish 1.0 + +import QtQuick.Layouts 1.2 + +Kirigami.ApplicationWindow { + id: webBrowser + title: webView.title + + // Pointer to the currently active list of tabs. + // + // As there are private and normal tabs, switch between + // them according to the current mode. + property ListWebView tabs: rootPage.privateMode ? privateTabs : regularTabs + + property WebView currentWebView: webView + + // Pointer to browser settings + property Settings settings: settings + + // Used to determine if the window is in landscape mode + property bool landscape: width > height + + property int borderWidth: Math.round(Kirigami.Units.gridUnit / 18); + property color borderColor: Kirigami.Theme.highlightColor; + + width: Kirigami.Units.gridUnit * 20 + height: Kirigami.Units.gridUnit * 30 + + pageStack.globalToolBar.showNavigationButtons: false + + // Main Page + pageStack.initialPage: Kirigami.Page { + id: rootPage + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + globalToolBarStyle: Kirigami.ApplicationHeaderStyle.None + Kirigami.ColumnView.fillWidth: true + Kirigami.ColumnView.pinned: true + Kirigami.ColumnView.preventStealing: true + + // Required to enforce active tab reload + // on start. As a result, mixed isMobile + // tabs will work correctly + property bool initialized: false + + WebView { + id: webView + anchors.fill: parent + url: BrowserManager.initialUrl + } + ErrorHandler { + id: errorHandler + + errorString: webView.errorString + errorCode: webView.errorCode + + anchors.fill: parent + visible: webView.errorCode !== "" + } + + Loader { + id: questionLoader + + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + } + + // Container for the progress bar + Item { + id: progressItem + + height: Math.round(Kirigami.Units.gridUnit / 6) + z: 99 + anchors { + bottom: parent.bottom + bottomMargin: -Math.round(height / 2) + left: tabs.left + right: tabs.right + } + + opacity: webView.loading ? 1 : 0 + Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad; } } + + Rectangle { + color: Kirigami.Theme.highlightColor + + width: Math.round((webView.loadProgress / 100) * parent.width) + anchors { + top: parent.top + left: parent.left + bottom: parent.bottom + } + } + } + + Loader { + id: sheetLoader + } + + // dealing with hiding and showing navigation bar + property point oldScrollPosition: Qt.point(0, 0) + } + + Connections { + target: webBrowser.pageStack + onCurrentIndexChanged: { + // drop all sub pages as soon as the browser window is the + // focussed one + if (webBrowser.pageStack.currentIndex === 0) + popSubPages(); + } + } + + QtSettings.Settings { + // kept separate to simplify definition of aliases + property alias x: webBrowser.x + property alias y: webBrowser.y + property alias width: webBrowser.width + property alias height: webBrowser.height + } + + Settings { + id: settings + } + + Component.onCompleted: rootPage.initialized = true + + function popSubPages() { + while (webBrowser.pageStack.depth > 1) + webBrowser.pageStack.pop(); + } +} diff --git a/src/webapp-resources.qrc b/src/webapp-resources.qrc new file mode 100644 index 0000000..aeaa78f --- /dev/null +++ b/src/webapp-resources.qrc @@ -0,0 +1,5 @@ + + + contents/webapp-ui/webapp.qml + + diff --git a/src/webappmain.cpp b/src/webappmain.cpp new file mode 100644 index 0000000..f1d16cd --- /dev/null +++ b/src/webappmain.cpp @@ -0,0 +1,99 @@ +/* + Copyright (C) 2019 Jonah Brüchert + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "bookmarkshistorymodel.h" +#include "browsermanager.h" +#include "iconimageprovider.h" +#include "tabsmodel.h" +#include "urlutils.h" +#include "useragent.h" + +Q_DECL_EXPORT int main(int argc, char *argv[]) +{ + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication::setAttribute(Qt::AA_ShareOpenGLContexts); + + // Setup QtWebEngine + qputenv("QTWEBENGINE_DIALOG_SET", "QtQuickControls2"); +#if QT_VERSION > QT_VERSION_CHECK(5, 14, 0) + QtWebEngine::initialize(); +#endif + + QApplication app(argc, argv); + QCoreApplication::setOrganizationName("KDE"); + QCoreApplication::setOrganizationDomain("mobile.kde.org"); + QCoreApplication::setApplicationName("angelfish"); + +#if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0) + QtWebEngine::initialize(); +#endif + + // Command line parser + QCommandLineParser parser; + parser.addPositionalArgument("url", i18n("URL to open"), "[url]"); + parser.addHelpOption(); + parser.process(app); + + // QML loading + QQmlApplicationEngine engine; + engine.rootContext()->setContextObject(new KLocalizedContext(&engine)); + + engine.addImageProvider(IconImageProvider::providerId(), new IconImageProvider(&engine)); + + // initial url command line parameter + QString initialUrl; + if (!parser.positionalArguments().isEmpty()) + initialUrl = QUrl::fromUserInput(parser.positionalArguments().first()).toString(); + + // Exported types + qmlRegisterType("org.kde.mobile.angelfish", 1, 0, "BookmarksHistoryModel"); + qmlRegisterType("org.kde.mobile.angelfish", 1, 0, "UserAgentGenerator"); + qmlRegisterType("org.kde.mobile.angelfish", 1, 0, "TabsModel"); + + // URL utils + qmlRegisterSingletonType("org.kde.mobile.angelfish", 1, 0, "UrlUtils", [](QQmlEngine *, QJSEngine *) -> QObject * { + return static_cast(new UrlUtils()); + }); + + BrowserManager::instance()->setInitialUrl(initialUrl); + + // Browser Manager + qmlRegisterSingletonType("org.kde.mobile.angelfish", 1, 0, "BrowserManager", [](QQmlEngine *, QJSEngine *) -> QObject * { + return static_cast(BrowserManager::instance()); + }); + + // Load QML + engine.load(QUrl(QStringLiteral("qrc:///webapp.qml"))); + + // Error handling + if (engine.rootObjects().isEmpty()) { + return -1; + } + + return app.exec(); +} -- GitLab