From 1a207776ac8273d4cf77ca285556ea8b8342b9cf Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Thu, 13 Jan 2022 18:04:28 -0800 Subject: [PATCH 1/3] Correctly position update notifications. --- resources/Constants/Constants.qml | 1 + resources/Constants/Globals.qml | 11 ++ resources/UpdateNotifications.qml | 222 ++++++++++++++++++++++++++++++ resources/UpdateTab.qml | 152 ++------------------ resources/console_resources.qrc | 1 + resources/view.qml | 4 + 6 files changed, 247 insertions(+), 144 deletions(-) create mode 100644 resources/UpdateNotifications.qml diff --git a/resources/Constants/Constants.qml b/resources/Constants/Constants.qml index 7c1b4fa3c..8a73cbdb3 100644 --- a/resources/Constants/Constants.qml +++ b/resources/Constants/Constants.qml @@ -41,6 +41,7 @@ QtObject { readonly property int staticTimerIntervalRate: 5 // 5 Hz readonly property int staticTableTimerIntervalRate: 10 // 10 Hz readonly property int staticTimerSlowIntervalRate: 2 // 2 Hz + readonly property int staticTimerNotificationIntervalRate: 1 // 1 Hz readonly property string monoSpaceFont: "Courier New" readonly property string fontFamily: "Roboto Condensed" property FontLoader robotoCondensedLightFont diff --git a/resources/Constants/Globals.qml b/resources/Constants/Globals.qml index abcf4790f..9ac9a3795 100644 --- a/resources/Constants/Globals.qml +++ b/resources/Constants/Globals.qml @@ -18,6 +18,7 @@ QtObject { property var tablesWithHighlights: [] property var currentSelectedTable: null property bool showFileConnection: false + property QtObject updateTabData function clearHighlightedRows() { for (var i in tablesWithHighlights) { @@ -25,4 +26,14 @@ QtObject { } } + updateTabData: QtObject { + property bool consoleOutdated: false + property bool fwV2Outdated: false + property bool fwOutdated: false + property string fwVersionCurrent: "" + property string fwVersionLatest: "" + property string consoleVersionCurrent: "" + property string consoleVersionLatest: "" + } + } diff --git a/resources/UpdateNotifications.qml b/resources/UpdateNotifications.qml new file mode 100644 index 000000000..d54159d4d --- /dev/null +++ b/resources/UpdateNotifications.qml @@ -0,0 +1,222 @@ +import "Constants" +import QtQuick 2.5 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import SwiftConsole 1.0 + +Item { + id: updateTab + + property bool consoleVersionDialogAlready: false + property bool firmwareVersionDialogAlready: false + property bool v2DownloadDialogAlready: false + property bool popupLock: false + property int dialogWidthDivisor: 3 + property int dialogHeightDivisor: 2 + + function consoleOutdatedDialogText(currentVersion, latestVersion) { + let text = ""; + text += "Current Console version:\n"; + text += "\t" + currentVersion + "\n"; + text += "Latest Console version:\n"; + text += "\t" + latestVersion; + return text; + } + + function firmwareV2OutdatedDialogText() { + let text = ""; + text += "Upgrading to firmware v2.1.0 or later requires that the device be running "; + text += "firmware v2.0.0 or later. Please upgrade to firmware version 2.0.0.\n\n"; + text += "Would you like to download firmware version v2.0.0 now?\n"; + return text; + } + + function firmwareOutdatedDialogText(latestVersion) { + let text = ""; + text += "New Piksi firmware available.\n\n"; + text += "Please use the Update tab to update.\n\n"; + text += "Newest Firmware Version:\n"; + text += "\t" + latestVersion + "\n"; + return text; + } + + Dialog { + id: v2DownloadDialog + + anchors.centerIn: parent + width: Globals.width / dialogWidthDivisor + height: Globals.height / dialogHeightDivisor + x: Globals.width / 2 - width / 2 + y: Globals.height / 2 - height / 2 + modal: true + focus: true + title: "Update to v2.0.0" + standardButtons: Dialog.Ok | Dialog.Cancel + onAccepted: { + let downloadLatestFirmware = true; + let updateFirmware = false; + let sendFileToDevice = false; + let serialPromptConfirm = false; + let updateLocalFilepath = null; + let downloadDirectory = null; + let fileioLocalFilepath = null; + let fileioDestinationFilepath = null; + let updateLocalFilename = null; + data_model.update_tab([downloadLatestFirmware, updateFirmware, sendFileToDevice, serialPromptConfirm], updateLocalFilepath, downloadDirectory, fileioLocalFilepath, fileioDestinationFilepath, updateLocalFilename); + } + + contentItem: Label { + text: firmwareV2OutdatedDialogText() + verticalAlignment: Qt.AlignVCenter + elide: Text.ElideRight + clip: true + wrapMode: Text.Wrap + } + + } + + Dialog { + id: consoleVersionDialog + + property alias versionText: versionTextLabel.text + + anchors.centerIn: parent + width: Globals.width / dialogWidthDivisor + height: Globals.height / dialogHeightDivisor + x: Globals.width / 2 - width / 2 + y: Globals.height / 2 - height / 2 + modal: true + focus: true + title: "Swift Console Outdated" + standardButtons: Dialog.Close + onRejected: { + popupLock = false; + } + + contentItem: ColumnLayout { + anchors.centerIn: parent + spacing: 0 + + Label { + Layout.fillWidth: true + wrapMode: Text.Wrap + text: { + let text = ``; + text += `Your console is out of date and may be incompatible with current firmware. `; + text += `We highly recommend upgrading to ensure proper behavior.`; + text; + } + } + + Label { + readonly property string website: Constants.logoPopup.aboutMe.supportWebsite + readonly property string websiteDisplay: website.slice(12) + + Layout.fillWidth: true + wrapMode: Text.Wrap + text: `Please visit ${websiteDisplay} to download the latest version.\n\n` + onLinkActivated: { + Qt.openUrlExternally(website); + } + } + + Label { + id: versionTextLabel + + Layout.fillWidth: true + wrapMode: Text.Wrap + } + + } + + } + + Dialog { + id: fwVersionDialog + + anchors.centerIn: parent + width: Globals.width / dialogWidthDivisor + height: Globals.height / dialogHeightDivisor + x: Globals.width / 2 - width / 2 + y: Globals.height / 2 - height / 2 + modal: true + focus: true + title: "Firmware Update" + standardButtons: Dialog.Close + onRejected: { + popupLock = false; + } + + contentItem: Label { + verticalAlignment: Qt.AlignVCenter + elide: Text.ElideRight + clip: true + wrapMode: Text.Wrap + } + + } + + Timer { + id: timer + + property var currentCallback: null + + function startTimer(callback) { + currentCallback = callback; + timer.start(); + } + + interval: Constants.updateTab.popupDelayMilliseconds + repeat: false + onTriggered: { + currentCallback(); + } + } + + Timer { + interval: Utils.hzToMilliseconds(Constants.staticTimerNotificationIntervalRate) + running: true + repeat: true + onTriggered: { + if (!popupLock) { + if (Globals.updateTabData.consoleVersionLatest) { + if (!consoleVersionDialogAlready) { + if (Globals.updateTabData.consoleOutdated) { + popupLock = true; + consoleVersionDialog.versionText = consoleOutdatedDialogText(Globals.updateTabData.consoleVersionCurrent, Globals.updateTabData.consoleVersionLatest); + timer.startTimer(consoleVersionDialog.open); + } + consoleVersionDialogAlready = true; + return ; + } + } + if (Globals.updateTabData.fwVersionCurrent) { + if (!v2DownloadDialogAlready) { + if (Globals.updateTabData.fwV2Outdated) { + popupLock = true; + timer.startTimer(v2DownloadDialog.open); + } + v2DownloadDialogAlready = true; + return ; + } + } else { + // This will clear between device connections. + v2DownloadDialogAlready = false; + firmwareVersionDialogAlready = false; + return ; + } + if (Globals.updateTabData.fwVersionCurrent && Globals.updateTabData.fwVersionLatest) { + if (!firmwareVersionDialogAlready && !Globals.updateTabData.fwV2Outdated) { + if (Globals.updateTabData.fwOutdated) { + popupLock = true; + fwVersionDialog.contentItem.text = firmwareOutdatedDialogText(Globals.updateTabData.fwVersionLatest); + timer.startTimer(fwVersionDialog.open); + } + firmwareVersionDialogAlready = true; + } + } + } + } + } + +} diff --git a/resources/UpdateTab.qml b/resources/UpdateTab.qml index 88b09c1b7..84478163e 100644 --- a/resources/UpdateTab.qml +++ b/resources/UpdateTab.qml @@ -8,22 +8,6 @@ import "UpdateTabComponents" as UpdateTabComponents MainTab { id: updateTab - property bool consoleVersionDialogAlready: false - property bool firmwareVersionDialogAlready: false - property bool v2DownloadDialogAlready: false - property bool popupLock: false - - function consoleOutdatedDialogText(currentVersion, latestVersion) { - let text = ""; - text += "Your console is out of date and may be incompatible with current firmware. We highly recommend upgrading to ensure proper behavior.\n\n"; - text += "Please visit support.swiftnav.com to download the latest version.\n\n"; - text += "Current Console version:\n"; - text += "\t" + currentVersion + "\n"; - text += "Latest Console version:\n"; - text += "\t" + latestVersion; - return text; - } - function upgradeSerialConfirmDialogText() { let text = ""; text += "Upgrading your device via UART / RS232 may take up to 30 minutes.\n\n"; @@ -33,24 +17,6 @@ MainTab { return text; } - function firmwareV2OutdatedDialogText() { - let text = ""; - text += "Upgrading to firmware v2.1.0 or later requires that the device be running firmware v2.0.0 or later. \ - Please upgrade to firmware version 2.0.0.\n\n"; - text += "Would you like to download firmware version v2.0.0 now?\n"; - return text; - } - - function firmwareOutdatedDialogText(latestVersion) { - let text = ""; - text += "New Piksi firmware available.\n\n"; - text += "Please use the Update \ - tab to update.\n\n"; - text += "Newest Firmware Version:\n"; - text += "\t" + latestVersion + "\n"; - return text; - } - UpdateTabData { id: updateTabData } @@ -177,40 +143,6 @@ MainTab { } - Dialog { - id: v2DownloadDialog - - x: (parent.width - Constants.sideNavBar.tabBarWidth - Constants.updateTab.v2DownloadDialogWidth) / 2 - y: parent.height / 2 - width: Constants.updateTab.v2DownloadDialogWidth - height: Constants.updateTab.popupSmallHeight - modal: true - focus: true - title: "Update to v2.0.0" - standardButtons: Dialog.Ok | Dialog.Cancel - onAccepted: { - let downloadLatestFirmware = true; - let updateFirmware = false; - let sendFileToDevice = false; - let serialPromptConfirm = false; - let updateLocalFilepath = null; - let downloadDirectory = null; - let fileioLocalFilepath = null; - let fileioDestinationFilepath = null; - let updateLocalFilename = null; - data_model.update_tab([downloadLatestFirmware, updateFirmware, sendFileToDevice, serialPromptConfirm], updateLocalFilepath, downloadDirectory, fileioLocalFilepath, fileioDestinationFilepath, updateLocalFilename); - } - - contentItem: Label { - text: firmwareV2OutdatedDialogText() - verticalAlignment: Qt.AlignVCenter - elide: Text.ElideRight - clip: true - wrapMode: Text.Wrap - } - - } - Dialog { id: upgradeSerialDialog @@ -245,54 +177,6 @@ MainTab { } - Dialog { - id: consoleVersionDialog - - x: (parent.width - Constants.sideNavBar.tabBarWidth - Constants.updateTab.consoleVersionDialogWidth) / 2 - y: parent.height / 2 - width: Constants.updateTab.consoleVersionDialogWidth - height: Constants.updateTab.popupLargeHeight - modal: true - focus: true - title: "Swift Console Outdated" - standardButtons: Dialog.Close - onRejected: { - popupLock = false; - } - - contentItem: Label { - verticalAlignment: Qt.AlignVCenter - elide: Text.ElideRight - clip: true - wrapMode: Text.Wrap - } - - } - - Dialog { - id: fwVersionDialog - - x: (parent.width - Constants.sideNavBar.tabBarWidth - Constants.updateTab.fwVersionDialogWidth) / 2 - y: parent.height / 2 - width: Constants.updateTab.fwVersionDialogWidth - height: Constants.updateTab.popupSmallHeight - modal: true - focus: true - title: "Firmware Update" - standardButtons: Dialog.Close - onRejected: { - popupLock = false; - } - - contentItem: Label { - verticalAlignment: Qt.AlignVCenter - elide: Text.ElideRight - clip: true - wrapMode: Text.Wrap - } - - } - Timer { id: timer @@ -316,39 +200,19 @@ MainTab { repeat: true onTriggered: { update_tab_model.fill_data(updateTabData); - if (updateTabData.console_version_latest) { - if (!consoleVersionDialogAlready) { - if (updateTabData.console_outdated && !popupLock) { - popupLock = true; - consoleVersionDialog.contentItem.text = consoleOutdatedDialogText(updateTabData.console_version_current, updateTabData.console_version_latest); - consoleVersionDialogAlready = true; - timer.startTimer(consoleVersionDialog.open); - } - } - } - if (!v2DownloadDialogAlready) { - if (updateTabData.fw_v2_outdated && !popupLock) { - popupLock = true; - v2DownloadDialogAlready = true; - timer.startTimer(v2DownloadDialog.open); - } - } + Globals.updateTabData.consoleOutdated = updateTabData.console_outdated; + Globals.updateTabData.fwV2Outdated = updateTabData.fw_v2_outdated; + Globals.updateTabData.fwOutdated = updateTabData.fw_outdated; + Globals.updateTabData.fwVersionCurrent = updateTabData.fw_version_current; + Globals.updateTabData.fwVersionLatest = updateTabData.fw_version_latest; + Globals.updateTabData.consoleVersionCurrent = updateTabData.console_version_current; + Globals.updateTabData.consoleVersionLatest = updateTabData.console_version_latest; if (updateTabData.fw_version_latest) { firmwareRevision.revision = updateTabData.hardware_revision; firmwareVersion.currentVersion = updateTabData.fw_version_current; firmwareVersion.latestVersion = updateTabData.fw_version_latest; - if (!firmwareVersionDialogAlready && !updateTabData.fw_v2_outdated && !popupLock) { - if (updateTabData.fw_outdated) { - popupLock = true; - fwVersionDialog.contentItem.text = firmwareOutdatedDialogText(updateTabData.fw_version_latest); - firmwareVersionDialogAlready = true; - timer.startTimer(fwVersionDialog.open); - } - } } - if (updateTabData.serial_prompt) - firmwareVersion.isSerialConnected = updateTabData.serial_prompt; - + firmwareVersion.isSerialConnected = updateTabData.serial_prompt; if (!updateTab.visible) return ; diff --git a/resources/console_resources.qrc b/resources/console_resources.qrc index feeda7f12..ee19378f1 100644 --- a/resources/console_resources.qrc +++ b/resources/console_resources.qrc @@ -63,6 +63,7 @@ LogoPopupComponents/AboutMe.qml LogoPopup.qml UpdateTab.qml + UpdateNotifications.qml UpdateTabComponents/FirmwareVersionAndDownloadLabels.qml UpdateTabComponents/FirmwareRevision.qml UpdateTabComponents/SelectLocalFile.qml diff --git a/resources/view.qml b/resources/view.qml index cb40564c2..21fd55a67 100644 --- a/resources/view.qml +++ b/resources/view.qml @@ -46,6 +46,10 @@ ApplicationWindow { anchors.fill: parent } + UpdateNotifications { + anchors.fill: parent + } + MouseArea { enabled: false anchors.top: parent.top From 367fdfdc4fa1730879b680ede34d12e55840118c Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Fri, 14 Jan 2022 13:00:57 -0800 Subject: [PATCH 2/3] Add command line flag to disable update notification prompts. --- console_backend/src/cli_options.rs | 4 ++++ resources/Constants/Globals.qml | 1 + resources/UpdateNotifications.qml | 2 +- resources/UpdateTabComponents/FirmwareVersion.qml | 11 ++++++++--- swiftnav_console/main.py | 5 ++++- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/console_backend/src/cli_options.rs b/console_backend/src/cli_options.rs index d77bd4734..bff4a151c 100644 --- a/console_backend/src/cli_options.rs +++ b/console_backend/src/cli_options.rs @@ -140,6 +140,10 @@ pub struct CliOptions { #[clap(long = "show-csv-log")] pub show_csv_log: bool, + /// Don't show prompts about firmware/console updates. + #[clap(long = "no-prompts")] + pub no_prompts: bool, + /// Set the height of the main window. #[clap(long)] pub height: Option, diff --git a/resources/Constants/Globals.qml b/resources/Constants/Globals.qml index 9ac9a3795..04edea0b7 100644 --- a/resources/Constants/Globals.qml +++ b/resources/Constants/Globals.qml @@ -5,6 +5,7 @@ QtObject { property string consoleVersion: "0.0.0" property int currentRefreshRate: 5 // 5 Hz property bool useOpenGL: true + property bool showPrompts: true property int initialMainTabIndex: 0 // Tracking property int initialSubTabIndex: -1 // Not triggered unless greater than -1. Defaults to first tab. property bool showCsvLog: false diff --git a/resources/UpdateNotifications.qml b/resources/UpdateNotifications.qml index d54159d4d..d41d71c19 100644 --- a/resources/UpdateNotifications.qml +++ b/resources/UpdateNotifications.qml @@ -178,7 +178,7 @@ Item { running: true repeat: true onTriggered: { - if (!popupLock) { + if (!popupLock && Globals.showPrompts) { if (Globals.updateTabData.consoleVersionLatest) { if (!consoleVersionDialogAlready) { if (Globals.updateTabData.consoleOutdated) { diff --git a/resources/UpdateTabComponents/FirmwareVersion.qml b/resources/UpdateTabComponents/FirmwareVersion.qml index 341e8b94f..bd239085a 100644 --- a/resources/UpdateTabComponents/FirmwareVersion.qml +++ b/resources/UpdateTabComponents/FirmwareVersion.qml @@ -115,9 +115,14 @@ Item { let fileioDestinationFilepath = null; let updateLocalFilename = null; data_model.update_tab([downloadLatestFirmware, updateFirmware, sendFileToDevice, serialPromptConfirm], updateLocalFilepath, downloadDirectory, fileioLocalFilepath, fileioDestinationFilepath, updateLocalFilename); - if (isSerialConnected) - dialog.open(); - + if (isSerialConnected) { + if (Globals.showPrompts) { + dialog.open(); + } else { + serialPromptConfirm = true; + data_model.update_tab([downloadLatestFirmware, updateFirmware, sendFileToDevice, serialPromptConfirm], updateLocalFilepath, downloadDirectory, fileioLocalFilepath, fileioDestinationFilepath, updateLocalFilename); + } + } } Label { diff --git a/swiftnav_console/main.py b/swiftnav_console/main.py index 08d665914..ab0a746d6 100644 --- a/swiftnav_console/main.py +++ b/swiftnav_console/main.py @@ -764,6 +764,8 @@ def handle_cli_arguments(args: argparse.Namespace, globals_: QObject): globals_.setProperty("showFileio", True) # type: ignore if args.no_opengl: globals_.setProperty("useOpenGL", False) # type: ignore + if args.no_prompts: + globals_.setProperty("showPrompts", False) # type: ignore if args.refresh_rate is not None: globals_.setProperty("currentRefreshRate", args.refresh_rate) # type: ignore if args.tab is not None: @@ -798,7 +800,8 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: parser = argparse.ArgumentParser(add_help=False, usage=argparse.SUPPRESS) parser.add_argument("--show-fileio", action="store_true") parser.add_argument("--show-file-connection", action="store_true") - parser.add_argument("--no-opengl", action="store_false") + parser.add_argument("--no-prompts", action="store_true") + parser.add_argument("--no-opengl", action="store_true") parser.add_argument("--refresh-rate", type=int) parser.add_argument("--tab") parser.add_argument("--show-csv-log", action="store_true") From aea7016798961cda241e654a435e6e641b05ef01 Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Fri, 14 Jan 2022 13:36:59 -0800 Subject: [PATCH 3/3] Fix serial upgrade prompt popping up for TCP. --- console_backend/src/cli_options.rs | 6 +++--- resources/Constants/Globals.qml | 2 +- resources/UpdateTab.qml | 5 ++++- swiftnav_console/main.py | 6 +++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/console_backend/src/cli_options.rs b/console_backend/src/cli_options.rs index bff4a151c..26ab9a41a 100644 --- a/console_backend/src/cli_options.rs +++ b/console_backend/src/cli_options.rs @@ -124,9 +124,9 @@ pub struct CliOptions { #[clap(long = "show-file-connection")] pub show_file_connection: bool, - /// Don't use opengl in plots. - #[clap(long = "no-opengl", parse(from_flag = Not::not))] - pub no_opengl: bool, + /// Use OpenGL, plots will become optimized for efficiency not aesthetics and require less system resources. + #[clap(long = "use-opengl", parse(from_flag = Not::not))] + pub use_opengl: bool, /// Change the refresh rate of the plots. #[clap(long = "refresh-rate", validator(is_refresh_rate))] diff --git a/resources/Constants/Globals.qml b/resources/Constants/Globals.qml index 04edea0b7..7de594260 100644 --- a/resources/Constants/Globals.qml +++ b/resources/Constants/Globals.qml @@ -4,7 +4,7 @@ pragma Singleton QtObject { property string consoleVersion: "0.0.0" property int currentRefreshRate: 5 // 5 Hz - property bool useOpenGL: true + property bool useOpenGL: false property bool showPrompts: true property int initialMainTabIndex: 0 // Tracking property int initialSubTabIndex: -1 // Not triggered unless greater than -1. Defaults to first tab. diff --git a/resources/UpdateTab.qml b/resources/UpdateTab.qml index 84478163e..56326965c 100644 --- a/resources/UpdateTab.qml +++ b/resources/UpdateTab.qml @@ -212,7 +212,10 @@ MainTab { firmwareVersion.currentVersion = updateTabData.fw_version_current; firmwareVersion.latestVersion = updateTabData.fw_version_latest; } - firmwareVersion.isSerialConnected = updateTabData.serial_prompt; + if (updateTabData.fw_version_current) + firmwareVersion.isSerialConnected = updateTabData.serial_prompt; + else + firmwareVersion.isSerialConnected = false; if (!updateTab.visible) return ; diff --git a/swiftnav_console/main.py b/swiftnav_console/main.py index ab0a746d6..b8dd93d70 100644 --- a/swiftnav_console/main.py +++ b/swiftnav_console/main.py @@ -762,8 +762,8 @@ def get_capnp_path() -> str: def handle_cli_arguments(args: argparse.Namespace, globals_: QObject): if args.show_fileio: globals_.setProperty("showFileio", True) # type: ignore - if args.no_opengl: - globals_.setProperty("useOpenGL", False) # type: ignore + if args.use_opengl: + globals_.setProperty("useOpenGL", True) # type: ignore if args.no_prompts: globals_.setProperty("showPrompts", False) # type: ignore if args.refresh_rate is not None: @@ -801,7 +801,7 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: parser.add_argument("--show-fileio", action="store_true") parser.add_argument("--show-file-connection", action="store_true") parser.add_argument("--no-prompts", action="store_true") - parser.add_argument("--no-opengl", action="store_true") + parser.add_argument("--use-opengl", action="store_true") parser.add_argument("--refresh-rate", type=int) parser.add_argument("--tab") parser.add_argument("--show-csv-log", action="store_true")