diff --git a/src/icons/16/document-open-remote.svg b/src/icons/16/document-open-remote.svg
new file mode 100644
index 00000000..86938c66
--- /dev/null
+++ b/src/icons/16/document-open-remote.svg
@@ -0,0 +1,13 @@
+
diff --git a/src/icons/icons.qrc b/src/icons/icons.qrc
index be18a6c6..b0bb7cec 100644
--- a/src/icons/icons.qrc
+++ b/src/icons/icons.qrc
@@ -32,6 +32,7 @@
%1", networkDialog.nextReloadTime) + onClicked: networkDialog.open() + flat: true + contentItem: Loader { sourceComponent: textComponent } + Layout.topMargin: -8 + Layout.bottomMargin: -32 + Layout.rightMargin: 3 + Layout.leftMargin: showSliderIcons ? 1 : 8 + } + } } } diff --git a/src/kirigami_ui/PrompterPage.qml b/src/kirigami_ui/PrompterPage.qml index aa8b34d0..8ef141c6 100644 --- a/src/kirigami_ui/PrompterPage.qml +++ b/src/kirigami_ui/PrompterPage.qml @@ -25,6 +25,7 @@ import QtQuick.Window 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtQuick.Dialogs 1.3 +import Qt.labs.settings 1.0 //import Qt.labs.platform 1.1 as Labs import com.cuperino.qprompt.markers 1.0 @@ -42,6 +43,7 @@ Kirigami.Page { property alias overlay: viewport.overlay property alias document: viewport.document property alias openDialog: viewport.openDialog + property alias networkDialog: networkDialog property alias prompterBackground: viewport.prompterBackground property alias find: viewport.find property alias keyConfigurationOverlay: keyConfigurationOverlay @@ -1003,6 +1005,174 @@ Kirigami.Page { } } + Settings { + category: "networkDialog" + property alias url: openUrl.text + property alias autoReload: networkDialog.autoReload + property alias autoReloadHours: autoReloadHours.value + property alias autoReloadMinutes: autoReloadMinutes.value + property alias autoReloadSeconds: autoReloadSeconds.value + } + Timer { + id: autoReloadTimer + running: networkDialog.autoReloadRunning + repeat: true + triggeredOnStart: false + interval: 1000 * (3600 * autoReloadHours.value + 60 * autoReloadMinutes.value + autoReloadSeconds.value) + onTriggered: networkDialog.openFromRemote(); + } + Kirigami.OverlaySheet { + id: networkDialog + header: Kirigami.Heading { + text: i18n("Open from network...") + level: 1 + } + property bool autoReload: false + property bool autoReloadRunning: false + property string nextReloadTime: "" + function updateNextReloadTime() { + const date = new Date(); + date.setTime(date.getTime() + autoReloadTimer.interval); + nextReloadTime = date.toLocaleTimeString(); + } + function openFromRemote() { + document.loadFromNetwork(openUrl.text); + if (!autoReloadRunning) + editor.lastDocument = "" + if (autoReload) { + autoReloadRunning = true; + updateNextReloadTime(); + } + } + function disableAutoReload() { + networkDialog.autoReloadRunning = false; + } + ColumnLayout { + width: parent.width + RowLayout { + Label { + text: i18n("URL:") + } + TextField { + id: openUrl + placeholderText: i18n("http, https, and ftp protocols supported") + Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.smallSpacing + Layout.rightMargin: Kirigami.Units.smallSpacing + onAccepted: networkDialog.openFromRemote() + } + } + RowLayout { + Button { + id: autoReloadToggle + flat: true + text: i18n("Auto reload") + checkable: true + checked: networkDialog.autoReload + onToggled: { + networkDialog.autoReload = checked; + if (!checked) + networkDialog.disableAutoReload(); + } + } + Label { + text: i18n("Hours:") + } + SpinBox { + id: autoReloadHours + Layout.fillWidth: true + Layout.leftMargin: Units.SmallSpacing + Layout.rightMargin: Units.SmallSpacing + enabled: networkDialog.autoReload + value: 0 + to: 168 + onValueModified: { + if (value === to) { + autoReloadMinutes.value = 0; + autoReloadSeconds.value = 0; + } + // Since this onValueModified will get called regardless of which SpinBox gets modified, this is where and when we update the nextReloadTime + networkDialog.updateNextReloadTime(); + } + } + Label { + text: i18n("Minutes:") + } + SpinBox { + id: autoReloadMinutes + Layout.fillWidth: true + Layout.leftMargin: Units.SmallSpacing + Layout.rightMargin: Units.SmallSpacing + enabled: networkDialog.autoReload + value: 5 + from: value>0 || autoReloadMinutes.value>0 || autoReloadHours.value>0 ? -1 : 0 + to: /*autoReloadHours.value===autoReloadHours.to ? 0 :*/ 60 + onValueModified: { + if (value < 0) { + value = 59; + --autoReloadHours.value; + } + else if (value > 59) { + value = 0; + ++autoReloadHours.value; + } + autoReloadHours.onValueModified(); + } + } + Label { + text: i18n("Seconds:") + } + SpinBox { + id: autoReloadSeconds + Layout.fillWidth: true + Layout.leftMargin: Units.SmallSpacing + Layout.rightMargin: Units.SmallSpacing + enabled: networkDialog.autoReload + value: 0 + from: value>0 || autoReloadMinutes.value>0 || autoReloadHours.value>0 ? -1 : 1 + to: /*autoReloadHours.value===autoReloadHours.to ? 0 :*/ 60 + onValueModified: { + if (value < 0) { + value = 59; + --autoReloadMinutes.value; + } + else if (value > 59) { + value = 0; + ++autoReloadMinutes.value; + } + autoReloadMinutes.onValueModified(); + } + } + } + RowLayout { + Label { + text: autoReloadTimer.running ? + i18nc("Next reload starts at 10:11:12", "Next reload starts at %1", networkDialog.nextReloadTime) + : i18n("Auto reload is not running") + horizontalAlignment: Text.AlignHCenter + Layout.fillWidth: true + } + Button { + enabled: openUrl.text !== "" + flat: true + text: i18n("Load from Network") + onClicked: { + networkDialog.openFromRemote(); + networkDialog.close(); + } + } + Button { + flat: true + text: i18n("Close") + onClicked: { + networkDialog.close(); + viewport.prompter.restoreFocus(); + } + } + } + } + } + //Kirigami.OverlaySheet { //id: stepsConfiguration //onSheetOpenChanged: { diff --git a/src/kirigami_ui/main.qml b/src/kirigami_ui/main.qml index 15f005a3..021e4fe3 100644 --- a/src/kirigami_ui/main.qml +++ b/src/kirigami_ui/main.qml @@ -197,6 +197,15 @@ Kirigami.ApplicationWindow { root.pageStack.currentItem.document.open() } }, + Kirigami.Action { + text: i18nc("Main menu and global menu actions", "&Open remote file") + //iconName: "document-open-remote" + iconSource: "qrc:/icons/document-open-remote.svg" + onTriggered: { + root.onDiscard = Prompter.CloseActions.Network + root.pageStack.currentItem.document.openFromNetwork() + } + }, Kirigami.Action { text: i18nc("Main menu and global menu actions", "&Save") //iconName: "document-save" @@ -397,6 +406,8 @@ Kirigami.ApplicationWindow { root.pageStack.currentItem.keyConfigurationOverlay.close() else if (root.pageStack.currentItem.namedMarkerConfiguration.sheetOpen) root.pageStack.currentItem.namedMarkerConfiguration.close() + else if (root.pageStack.currentItem.networkDialog.sheetOpen) + root.pageStack.currentItem.networkDialog.close() else if (wheelSettings.sheetOpen) wheelSettings.close() // Close find, compare against enabled instead of isOpen to prevent closing find while it is invisible. @@ -939,6 +950,9 @@ Kirigami.ApplicationWindow { case Prompter.CloseActions.Open: root.pageStack.currentItem.openDialog.open(); break; + case Prompter.CloseActions.Network: + root.pageStack.currentItem.networkDialog.open(); + break; case Prompter.CloseActions.Quit: Qt.quit(); break; diff --git a/src/prompter/Prompter.qml b/src/prompter/Prompter.qml index afeb85a8..8fca3d9c 100644 --- a/src/prompter/Prompter.qml +++ b/src/prompter/Prompter.qml @@ -95,6 +95,7 @@ Flickable { LoadNew, LoadGuide, Open, + Network, Ignore } enum AtEndActions { @@ -1101,14 +1102,21 @@ Flickable { editor.resetPosition = false; } } + function clearLastDocument() { + editor.lastDocument = "blank://"; + } + function close() { + networkDialog.autoReloadRunning = false; + document.load("qrc:/blank.html"); + } function newDocument() { root.onDiscard = Prompter.CloseActions.LoadNew if (document.modified) closeDialog.open() else { - document.load("qrc:/blank.html") + document.close() document.load("qrc:/untitled.html") - editor.lastDocument = "blank://" + clearLastDocument(); isNewFile = true resetDocumentPosition() if (root.passiveNotifications) @@ -1120,7 +1128,7 @@ Flickable { if (document.modified) closeDialog.open() else { - document.load("qrc:/blank.html") + document.close() document.load("qrc:/"+i18n("welcome_en.html")) editor.lastDocument = "" isNewFile = true @@ -1131,7 +1139,7 @@ Flickable { } function loadLastDocument() { root.onDiscard = Prompter.CloseActions.Open - document.load("qrc:/blank.html") + document.close() document.load(editor.lastDocument) isNewFile = false prompter.position = 0 @@ -1145,6 +1153,13 @@ Flickable { else openDialog.open() } + function openFromNetwork() { + root.onDiscard = Prompter.CloseActions.Network + if (document.modified) + closeDialog.open() + else + networkDialog.open() + } function saveAsDialog() { saveDialog.open(parseInt(root.onDiscard)===Prompter.CloseActions.Quit) } @@ -1169,6 +1184,7 @@ Flickable { case Prompter.CloseActions.LoadGuide: document.loadGuide(); break; case Prompter.CloseActions.LoadNew: document.newDocument(); break; case Prompter.CloseActions.Open: document.open(); break; + case Prompter.CloseActions.Network: document.openFromNetwork(); break; case Prompter.CloseActions.Quit: Qt.quit() } } @@ -1233,7 +1249,7 @@ Flickable { folder: shortcuts.documents //fileMode: Labs.FileDialog.OpenFile onAccepted: { - document.load("qrc:/blank.html") + document.close() document.load(openDialog.fileUrl) editor.lastDocument = document.fileUrl; editor.resetPosition = true; @@ -1279,6 +1295,7 @@ Flickable { case Prompter.CloseActions.LoadGuide: document.modified = false; document.loadGuide(); break; case Prompter.CloseActions.LoadNew: document.modified = false; document.newDocument(); break; case Prompter.CloseActions.Open: document.open(); /*openOpenDialog.start();*/ break; + case Prompter.CloseActions.Network: document.modified = false; document.openFromNetwork(); break; case Prompter.CloseActions.Quit: Qt.quit() //default: Qt.quit(); } diff --git a/src/prompter/documenthandler.cpp b/src/prompter/documenthandler.cpp index 7a199aa8..e7f72873 100644 --- a/src/prompter/documenthandler.cpp +++ b/src/prompter/documenthandler.cpp @@ -99,8 +99,10 @@ #include