diff --git a/src/contents/ui/Navigation.qml b/src/contents/ui/Navigation.qml index 7326a82..4f77054 100644 --- a/src/contents/ui/Navigation.qml +++ b/src/contents/ui/Navigation.qml @@ -1,168 +1,166 @@ /*************************************************************************** * * * 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.3 import QtQuick.Layouts 1.0 import QtWebEngine 1.4 import QtQuick.Controls 2.0 as Controls import org.kde.kirigami 2.5 as Kirigami import "regex-weburl.js" as RegexWebUrl Item { - id: errorHandler + id: navigation - property string errorCode: "" - - property bool navigationShown: errorCode != "" || webBrowser.url === "" || true + property bool navigationShown: true property alias textFocus: urlInput.activeFocus property alias text: urlInput.text - property int expandedHeight: Kirigami.Units.gridUnit * 2.5 + property int expandedHeight: Kirigami.Units.gridUnit * 3 property int buttonSize: Kirigami.Units.gridUnit * 2 Behavior on height { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad} } Rectangle { anchors.fill: parent; color: Kirigami.Theme.backgroundColor; } RowLayout { id: layout anchors.fill: parent anchors.leftMargin: Kirigami.Units.gridUnit / 2 anchors.rightMargin: Kirigami.Units.gridUnit / 2 visible: navigationShown spacing: Kirigami.Units.smallSpacing Controls.ToolButton { icon.name: "tab-duplicate" Layout.preferredWidth: buttonSize Layout.preferredHeight: buttonSize onClicked: { pageStack.layers.push("Tabs.qml") options.state = "hidden" } } Controls.ToolButton { id: backButton Layout.preferredWidth: buttonSize Layout.preferredHeight: buttonSize visible: currentWebView.canGoBack && !Kirigami.Settings.isMobile icon.name: "go-previous" onClicked: currentWebView.goBack() } Controls.ToolButton { id: forwardButton Layout.preferredWidth: buttonSize Layout.preferredHeight: buttonSize visible: currentWebView.canGoForward && !Kirigami.Settings.isMobile icon.name: "go-next" onClicked: currentWebView.goForward() } Controls.TextField { id: urlInput Layout.fillWidth: true text: currentWebView.url selectByMouse: true focus: false onAccepted: { if (text.match(RegexWebUrl.re_weburl)) { load(browserManager.urlFromUserInput(text)) } else { load(browserManager.urlFromUserInput(browserManager.searchBaseUrl + text)) } } } Controls.ToolButton { id: reloadButton Layout.preferredWidth: buttonSize Layout.preferredHeight: buttonSize visible: !Kirigami.Settings.isMobile icon.name: currentWebView.loading ? "process-stop" : "view-refresh" onClicked: currentWebView.loading ? currentWebView.stop() : currentWebView.reload() } Item { Layout.preferredWidth: buttonSize Layout.preferredHeight: buttonSize visible: currentWebView.loading Controls.BusyIndicator { width: buttonSize height: width anchors.centerIn: parent running: currentWebView.loading } } OptionButton { id: optionsButton property string targetState: "overview" Layout.fillWidth: false Layout.preferredWidth: buttonSize Layout.preferredHeight: buttonSize iconSource: "open-menu-symbolic" onClicked: options.state = (options.state != "hidden" ? "hidden" : targetState) } } states: [ State { name: "shown" when: navigationShown - PropertyChanges { target: errorHandler; x: -expandedHeight} + PropertyChanges { target: navigation; height: expandedHeight} }, State { name: "hidden" when: !navigationShown - PropertyChanges { target: errorHandler; x: 0} + PropertyChanges { target: navigation; height: 0} } ] } diff --git a/src/contents/ui/WebView.qml b/src/contents/ui/WebView.qml index f52ecd9..4925832 100644 --- a/src/contents/ui/WebView.qml +++ b/src/contents/ui/WebView.qml @@ -1,163 +1,172 @@ /*************************************************************************** * * * 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.3 import QtQuick.Controls 2.4 as Controls +import QtQuick.Window 2.1 import QtWebEngine 1.7 import org.kde.kirigami 2.4 as Kirigami WebEngineView { id: webEngineView property string errorCode: "" property string errorString: "" property string mobileUserAgent: "Mozilla/5.0 (Linux; Plasma Mobile, like Android 9.0 ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.128 Mobile Safari/537.36" property string desktopUserAgent: profile.httpUserAgent width: pageWidth height: pageHeight profile { httpUserAgent: { if (Kirigami.Settings.isMobile) return mobileUserAgent else return desktopUserAgent } onDownloadRequested: { showPassiveNotification(i18n("Do you want to download this file?"), "long", "Download", function() { download.accept }) } onDownloadFinished: showPassiveNotification(i18n("Download finished")) } settings { errorPageEnabled: false } Controls.Menu { property var request id: contextMenu Controls.MenuItem { text: i18n("Copy") enabled: (contextMenu.request.editFlags & ContextMenuRequest.CanCopy) != 0 onTriggered: webEngineView.triggerWebAction(WebEngineView.Copy) } Controls.MenuItem { text: i18n("Cut") enabled: (contextMenu.request.editFlags & ContextMenuRequest.CanCut) != 0 onTriggered: webEngineView.triggerWebAction(WebEngineView.Cut) } Controls.MenuItem { text: i18n("Paste") enabled: (contextMenu.request.editFlags & ContextMenuRequest.CanPaste) != 0 onTriggered: webEngineView.triggerWebAction(WebEngineView.Paste) } Controls.MenuItem { enabled: contextMenu.request.linkUrl !== "" text: i18n("Copy Url") onTriggered: webEngineView.triggerWebAction(WebEngineView.CopyLinkToClipboard) } Controls.MenuItem { text: i18n("View source") onTriggered: webEngineView.triggerWebAction(WebEngineView.ViewSource) } Controls.MenuItem { text: i18n("Download") onTriggered: webEngineView.triggerWebAction(WebEngineView.DownloadLinkToDisk) } Controls.MenuItem { enabled: contextMenu.request.linkUrl !== "" text: i18n("Open in new Tab") onTriggered: webEngineView.triggerWebAction(WebEngineView.OpenLinkInNewTab) } } //Rectangle { color: "yellow"; opacity: 0.3; anchors.fill: parent } focus: true onLoadingChanged: { // Doesn't work!?! //print("Loading: " + loading); print(" url: " + loadRequest.url) //print(" icon: " + webEngineView.icon) //print(" title: " + webEngineView.title) /* Handle * - WebEngineView::LoadStartedStatus, * - WebEngineView::LoadStoppedStatus, * - WebEngineView::LoadSucceededStatus and * - WebEngineView::LoadFailedStatus */ var ec = ""; var es = ""; //print("Load: " + loadRequest.errorCode + " " + loadRequest.errorString); //if (loadRequest.status == WebEngineView.LoadStartedStatus) { //} if (loadRequest.status == WebEngineView.LoadSucceededStatus) { // record history, set current page info //contentView.state = "hidden" //pageInfo.url = webEngineView.url; //pageInfo.title = webEngineView.title; //pageInfo.icon = webEngineView.icon; addHistoryEntry(); } if (loadRequest.status == WebEngineView.LoadFailedStatus) { print("Load failed: " + loadRequest.errorCode + " " + loadRequest.errorString); ec = loadRequest.errorCode; es = loadRequest.errorString; } errorCode = ec; errorString = es; } Component.onCompleted: { print("WebView completed."); var settings = webEngineView.settings; print("Settings: " + settings); } onIconChanged: { if (icon) browserManager.history.updateIcon(url, icon) } onNewViewRequested: { if (request.userInitiated) { newTab(request.requestedUrl.toString()) showPassiveNotification("Website was opened in a new tab") } else { newTabQuestion.url = request.requestedUrl newTabQuestion.visible = true } } + onFullScreenRequested: { + request.accept() + if (webBrowser.visibility !== Window.FullScreen) + webBrowser.showFullScreen() + else + webBrowser.showNormal() + } + onContextMenuRequested: { request.accepted = true; contextMenu.request = request contextMenu.x = request.x contextMenu.y = request.y contextMenu.open() } } diff --git a/src/contents/ui/webbrowser.qml b/src/contents/ui/webbrowser.qml index ff30eac..aec29f4 100644 --- a/src/contents/ui/webbrowser.qml +++ b/src/contents/ui/webbrowser.qml @@ -1,223 +1,215 @@ /*************************************************************************** * * * 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.1 +import QtQuick.Window 2.3 import org.kde.kirigami 2.4 as Kirigami Kirigami.ApplicationWindow { id: webBrowser title: "Angelfish Webbrowser" /** Pointer to the currently active view. * * Browser-level functionality should use this to refer to the current * view, rather than looking up views in the mode, as far as possible. */ property Item currentWebView: tabs.currentIndex < tabs.count ? tabs.currentItem : null onCurrentWebViewChanged: { print("Current WebView is now : " + tabs.currentIndex); } property int borderWidth: Math.round(Kirigami.Units.gridUnit / 18); property color borderColor: Kirigami.Theme.highlightColor; /** * Load a url in the current tab */ function load(url) { print("Loading url: " + url); currentWebView.url = url; currentWebView.forceActiveFocus() } width: Kirigami.Units.gridUnit * 20 height: Kirigami.Units.gridUnit * 30 function addHistoryEntry() { //print("Adding history"); var request = new Object;// FIXME request.url = currentWebView.url; request.title = currentWebView.title; request.icon = currentWebView.icon; browserManager.addToHistory(request); } property bool layerShown : pageStack.layers.depth > 1 pageStack.globalToolBar.style: layerShown ? Kirigami.ApplicationHeaderStyle.Auto : Kirigami.ApplicationHeaderStyle.None pageStack.initialPage: Kirigami.Page { leftPadding: 0 rightPadding: 0 topPadding: 0 bottomPadding: 0 ListWebView { id: tabs anchors { top: navigation.bottom left: parent.left right: parent.right bottom: parent.bottom } } ErrorHandler { id: errorHandler errorString: currentWebView.errorString errorCode: currentWebView.errorCode anchors { top: navigation.bottom left: parent.left right: parent.right } visible: !navigation.textFocus } Kirigami.InlineMessage { id: newTabQuestion type: Kirigami.MessageType.Warning text: i18n("Site wants to open a new tab: \n%1", url.toString()) showCloseButton: true anchors.top: navigation.bottom anchors.left: parent.left anchors.right: parent.right property var url actions: [ Kirigami.Action { iconName: "tab-new" text: i18n("Open") onTriggered: { tabs.newTab(newTabQuestion.url.toString()) newTabQuestion.visible = false } } ] } // Container for the progress bar Item { id: progressItem height: Math.round(Kirigami.Units.gridUnit / 6) z: navigation.z + 1 anchors { top: tabs.top topMargin: -Math.round(height / 2) left: tabs.left right: tabs.right } opacity: currentWebView.loading ? 1 : 0 Behavior on opacity { NumberAnimation { duration: Kirigami.Units.longDuration; easing.type: Easing.InOutQuad; } } Rectangle { color: Kirigami.Theme.highlightColor width: Math.round((currentWebView.loadProgress / 100) * parent.width) anchors { top: parent.top left: parent.left bottom: parent.bottom } } } // When clicked outside the menu, hide it MouseArea { id: optionsDismisser visible: options.state != "hidden" onClicked: options.state = "hidden" anchors.fill: parent } // The menu at the top right Options { id: options anchors { top: navigation.bottom } } Navigation { id: navigation - visible: !webappcontainer - - height: { - if (!webappcontainer) - return Kirigami.Units.gridUnit * 3 - else - return 0 - } + navigationShown: !webappcontainer && webBrowser.visibility !== Window.FullScreen anchors { top: parent.top left: parent.left right: parent.right } - onTextChanged: urlFilter.setFilterFixedString(text) } ListView { id: completion property string searchText: navigation.text anchors.top: navigation.bottom anchors.horizontalCenter: navigation.horizontalCenter width: 0.9 * navigation.width height: 0.5 * parent.height z: 10 visible: navigation.textFocus model: urlFilter delegate: UrlDelegate { showRemove: false onClicked: tabs.forceActiveFocus() highlightText: completion.searchText } clip: true } // Thin line underneath navigation Rectangle { height: webBrowser.borderWidth color: webBrowser.borderColor anchors { left: parent.left bottom: navigation.bottom right: options.left } } } }