From eb35f026446d433418bb85c43b2cb54921962f8a Mon Sep 17 00:00:00 2001 From: Evzen Gasta Date: Sat, 7 Oct 2023 20:05:57 +0200 Subject: [PATCH] Add mnemonics for better experience Fixes #643 --- src/app/qml/AboutDialog.qml | 6 ++ src/app/qml/CancelDialog.qml | 49 +++++++---- src/app/qml/DrivePage.qml | 65 ++++++++++++++ src/app/qml/MainPage.qml | 17 ++++ src/app/qml/VersionPage.qml | 40 ++++++++- src/app/qml/main.qml | 163 ++++++++++++++++++++++------------- 6 files changed, 263 insertions(+), 77 deletions(-) diff --git a/src/app/qml/AboutDialog.qml b/src/app/qml/AboutDialog.qml index 8a717b79..4b413ecd 100644 --- a/src/app/qml/AboutDialog.qml +++ b/src/app/qml/AboutDialog.qml @@ -39,6 +39,7 @@ ApplicationWindow { anchors.fill: parent anchors.margins: units.gridUnit spacing: units.gridUnit + focus: true Column { leftPadding: units.gridUnit @@ -95,5 +96,10 @@ ApplicationWindow { text: qsTr("Close") } } + + Keys.onPressed: (event)=> { + if (event.key == Qt.Key_I) + aboutDialog.close() + } } } diff --git a/src/app/qml/CancelDialog.qml b/src/app/qml/CancelDialog.qml index 933c8a82..050a1845 100644 --- a/src/app/qml/CancelDialog.qml +++ b/src/app/qml/CancelDialog.qml @@ -43,6 +43,7 @@ ApplicationWindow { anchors.fill: parent anchors.margins: units.gridUnit spacing: units.gridUnit + focus: true Column { leftPadding: units.gridUnit @@ -90,22 +91,7 @@ ApplicationWindow { Button { id: cancelButton - onClicked: { - cancelDialog.close() - // Store release state locally as drives.selected.cancel() makes - // it go to failed state if we cancel the writing process - var releaseState = releases.variant.status - if (drives.selected) - drives.selected.cancel() - if (mainWindow.selectedPage == Units.Page.DownloadPage && - (releaseState === Units.DownloadStatus.Writing || releaseState === Units.DownloadStatus.Write_Verifying || releaseState === Units.DownloadStatus.Writing_Not_Possible)) { - drives.lastRestoreable = drivesSelected - drives.lastRestoreable.setRestoreStatus(Units.RestoreStatus.Contains_Live) - } - releases.variant.resetStatus() - downloadManager.cancel() - selectedPage = Units.Page.MainPage - } + onClicked: cancelWrite() text: { if (releases.variant.status == Units.DownloadStatus.Downloading || releases.variant.status === Units.DownloadStatus.Download_Verifying) qsTr("Cancel Download") @@ -118,6 +104,37 @@ ApplicationWindow { } } } + Keys.onPressed: (event)=> { + switch (event.key) { + case (Qt.Key_Escape): + cancelDialog.close() + break + case (Qt.Key_Return): + case (Qt.Key_Enter): + if (cancelDialog.visible) + cancelWrite() + else + cancelDialog.show() + break + } + } + } + + function cancelWrite() { + cancelDialog.close() + // Store release state locally as drives.selected.cancel() makes + // it go to failed state if we cancel the writing process + var releaseState = releases.variant.status + if (drives.selected) + drives.selected.cancel() + if (mainWindow.selectedPage == Units.Page.DownloadPage && + (releaseState === Units.DownloadStatus.Writing || releaseState === Units.DownloadStatus.Write_Verifying || releaseState === Units.DownloadStatus.Writing_Not_Possible)) { + drives.lastRestoreable = drivesSelected + drives.lastRestoreable.setRestoreStatus(Units.RestoreStatus.Contains_Live) + } + releases.variant.resetStatus() + downloadManager.cancel() + selectedPage = Units.Page.MainPage } } diff --git a/src/app/qml/DrivePage.qml b/src/app/qml/DrivePage.qml index 8fade12a..7145403d 100644 --- a/src/app/qml/DrivePage.qml +++ b/src/app/qml/DrivePage.qml @@ -157,6 +157,7 @@ Page { } CheckBox { + id: deleteCheck text: qsTr("Delete download after writing") onCheckedChanged: mainWindow.eraseVariant = !mainWindow.eraseVariant } @@ -181,4 +182,68 @@ Page { PropertyChanges { target: nextButton; enabled: driveCombo.enabled && releases.localFile.iso } } ] + + Keys.onPressed: (event)=> { + if (drivePage.state == "Downloading") { + switch (event.key) { + case (Qt.Key_1): + closePopups() + if (!versionCombo.down) + versionCombo.popup.open() + break + case (Qt.Key_2): + closePopups() + if (!hwArchCombo.down) + hwArchCombo.popup.open() + break + case (Qt.Key_3): + closePopups() + if (!driveCombo.down && driveCombo.count) + driveCombo.popup.open() + break + case (Qt.Key_D): + case (Qt.Key_4): + deleteCheck.checked = !deleteCheck.checked + break + case (Qt.Key_Return): + case (Qt.Key_Enter): + closePopups() + break + case (Qt.Key_Up): + if (versionCombo.down && versionCombo.currentIndex > 0) + versionCombo.currentIndex -= 1 + else if (hwArchCombo.down && hwArchCombo.currentIndex > 0) + hwArchCombo.currentIndex -= 1 + else if (driveCombo.down && driveCombo.currentIndex > 0) + driveCombo.currentIndex -= 1 + break + case (Qt.Key_Down): + if (versionCombo.down && versionCombo.currentIndex < versionCombo.count - 1) + versionCombo.currentIndex += 1 + else if (hwArchCombo.down && hwArchCombo.currentIndex < hwArchCombo.count - 1) + hwArchCombo.currentIndex += 1 + else if (driveCombo.down && driveCombo.currentIndex < driveCombo.count - 1) + driveCombo.currentIndex += 1 + break + } + } else { + switch (event.key) { + case (Qt.Key_1): + if (portalFileDialog.isAvailable) + portalFileDialog.open() + else + fileDialog.open() + break + case (Qt.Key_2): + driveCombo.focus = true + break + } + } + } + + function closePopups() { + versionCombo.popup.close() + hwArchCombo.popup.close() + driveCombo.popup.close() + } } diff --git a/src/app/qml/MainPage.qml b/src/app/qml/MainPage.qml index b880e993..4b08ee09 100644 --- a/src/app/qml/MainPage.qml +++ b/src/app/qml/MainPage.qml @@ -62,6 +62,7 @@ Page { } RadioButton { + checked: mainWindow.selectedOption == Units.MainSelect.Write text: qsTr("Select .iso file") onClicked: { selectedOption = Units.MainSelect.Write @@ -73,6 +74,7 @@ Page { RadioButton { id: restoreRadio visible: drives.lastRestoreable + checked: mainWindow.selectedOption == Units.MainSelect.Restore text: drives.lastRestoreable ? qsTr("Restore %1").arg(drives.lastRestoreable.name) : "" onClicked: { selectedOption = Units.MainSelect.Restore @@ -91,4 +93,19 @@ Page { } } } + + Keys.onPressed: (event)=> { + switch (event.key) { + case (Qt.Key_1): + mainWindow.selectedOption = Units.MainSelect.Download + break + case (Qt.Key_2): + mainWindow.selectedOption = Units.MainSelect.Write + break + case (Qt.Key_3): + if (restoreRadio.visible) + mainWindow.selectedOption = Units.MainSelect.Restore + break + } + } } diff --git a/src/app/qml/VersionPage.qml b/src/app/qml/VersionPage.qml index 9e8c5c34..bb8777ac 100644 --- a/src/app/qml/VersionPage.qml +++ b/src/app/qml/VersionPage.qml @@ -26,6 +26,7 @@ import QtQml 6.2 Page { id: versionPage property int prevSource: 0 + property int prevIndex: 0 ColumnLayout { anchors.fill: parent @@ -49,25 +50,28 @@ Page { } RadioButton { - checked: true + checked: releases.filterSource == Units.Source.Product text: qsTr("Official Editions") onClicked: changeFilter(Units.Source.Product) ButtonGroup.group: radioGroup } RadioButton { + checked: releases.filterSource == Units.Source.Emerging text: qsTr("Emerging Editions") onClicked: changeFilter(Units.Source.Emerging) ButtonGroup.group: radioGroup } RadioButton { + checked: releases.filterSource == Units.Source.Spins text: qsTr("Spins") onClicked: changeFilter(Units.Source.Spins) ButtonGroup.group: radioGroup } RadioButton { + checked: releases.filterSource == Units.Source.Labs text: qsTr("Labs") onClicked: changeFilter(Units.Source.Labs) ButtonGroup.group: radioGroup @@ -102,4 +106,38 @@ Page { releases.selectedIndex = parseInt(selectFromComboBox.currentValue) } } + + Keys.onPressed: (event)=> { + switch (event.key) { + case (Qt.Key_1): + changeFilter(Units.Source.Product) + break + case (Qt.Key_2): + changeFilter(Units.Source.Emerging) + break + case (Qt.Key_3): + changeFilter(Units.Source.Spins) + break + case (Qt.Key_4): + changeFilter(Units.Source.Labs) + break + case (Qt.Key_Return): + case (Qt.Key_Enter): + if (selectFromComboBox.down) + selectFromComboBox.popup.close() + else + selectFromComboBox.popup.open() + break + case (Qt.Key_Up): + if (selectFromComboBox.down) + if (releases.firstSource < releases.selectedIndex) + selectFromComboBox.currentIndex -= 1 + break + case (Qt.Key_Down): + if (selectFromComboBox.down) + if (selectFromComboBox.count > selectFromComboBox.currentIndex + 1) + selectFromComboBox.currentIndex += 1 + break + } + } } diff --git a/src/app/qml/main.qml b/src/app/qml/main.qml index 5a2e228d..a6b466df 100644 --- a/src/app/qml/main.qml +++ b/src/app/qml/main.qml @@ -49,6 +49,7 @@ ApplicationWindow { StackView { id: stackView initialItem: "MainPage.qml" + focus: true Layout.fillHeight: true Layout.fillWidth: true @@ -119,21 +120,12 @@ ApplicationWindow { PropertyChanges { target: prevButton text: getPrevButtonText() - onClicked: aboutDialog.show() + onClicked: setPreviousPage() } PropertyChanges { target: nextButton visible: true - onClicked: { - if (selectedOption == Units.MainSelect.Write) { - if (releases.localFile.iso) - releases.selectLocalFile() - selectedPage = Units.Page.DrivePage - } else if (selectedOption == Units.MainSelect.Restore) - selectedPage = Units.Page.RestorePage - else - selectedPage = Units.Page.VersionPage - } + onClicked: setNextPage() } StateChangeScript { script: { @@ -152,8 +144,8 @@ ApplicationWindow { name: "versionPage" when: selectedPage == Units.Page.VersionPage PropertyChanges { target: mainWindow; title: qsTr("Select Fedora Version") } - PropertyChanges { target: nextButton; visible: true; onClicked: selectedPage += 1 } - PropertyChanges { target: prevButton; visible: true; onClicked: selectedPage -= 1 } + PropertyChanges { target: nextButton; visible: true; onClicked: setNextPage() } + PropertyChanges { target: prevButton; visible: true; onClicked: setPreviousPage() } StateChangeScript { script: { //state was pushing same page when returing from drivePage @@ -172,27 +164,12 @@ ApplicationWindow { PropertyChanges { target: nextButton; visible: true - onClicked: { - selectedPage = Units.Page.DownloadPage - if (selectedOption != Units.MainSelect.Write) - releases.variant.download() - if (drives.length) { - drives.selected.setImage(releases.variant) - drives.selected.write(releases.variant) - } - } + onClicked: setNextPage() } PropertyChanges { target: prevButton visible: true - onClicked: { - if (selectedOption == Units.MainSelect.Write) - selectedPage = Units.Page.MainPage - else { - selectedPage -= 1 - stackView.pop() - } - } + onClicked: setPreviousPage() } StateChangeScript { script: { @@ -214,32 +191,11 @@ ApplicationWindow { PropertyChanges { target: prevButton visible: true - onClicked: { - if (releases.variant.status === Units.DownloadStatus.Write_Verifying || releases.variant.status === Units.DownloadStatus.Writing || releases.variant.status === Units.DownloadStatus.Downloading || releases.variant.status === Units.DownloadStatus.Download_Verifying) { - cancelDialog.show() - } else { - releases.variant.resetStatus() - downloadManager.cancel() - mainWindow.selectedPage = Units.Page.MainPage - } - } + onClicked: setPreviousPage() } PropertyChanges { target: nextButton - onClicked: { - if (releases.variant.status === Units.DownloadStatus.Finished) { - drives.lastRestoreable = drives.selected - drives.lastRestoreable.setRestoreStatus(Units.RestoreStatus.Contains_Live) - releases.variant.resetStatus() - downloadManager.cancel() - selectedPage = Units.Page.MainPage - } else if ((releases.variant.status === Units.DownloadStatus.Failed && drives.length) || releases.variant.status === Units.DownloadStatus.Failed_Download || (releases.variant.status === Units.DownloadStatus.Failed_Verification && drives.length) || releases.variant.status === Units.DownloadStatus.Ready) { - if (selectedOption != Units.MainSelect.Write) - releases.variant.download() - drives.selected.setImage(releases.variant) - drives.selected.write(releases.variant) - } - } + onClicked: setNextPage() } }, State { @@ -252,23 +208,45 @@ ApplicationWindow { PropertyChanges { target: nextButton visible: true - onClicked: { - if (lastRestoreable && lastRestoreable.restoreStatus == Units.RestoreStatus.Restored) - selectedPage = Units.Page.MainPage - else - drives.lastRestoreable.restore() - } + onClicked: setNextPage() } PropertyChanges { target: prevButton visible: true - onClicked: selectedPage = Units.Page.MainPage + onClicked: setPreviousPage() } StateChangeScript { script: { stackView.push("RestorePage.qml") } } } ] + + Keys.onPressed: (event)=> { + switch (event.key) { + case (Qt.Key_I): + if (selectedPage != Units.Page.DownloadPage) + aboutDialog.show() + break + case (Qt.Key_Right): + case (Qt.Key_N): + if (selectedOption == Units.MainSelect.Write && selectedPage == Units.Page.DrivePage) { + if (drives.length && releases.localFile.iso) + mainWindow.setNextPage() + } else + mainWindow.setNextPage() + break + case (Qt.Key_Left): + case (Qt.Key_P): + if (!(lastRestoreable && lastRestoreable.restoreStatus == Units.RestoreStatus.Restoring)) + setPreviousPage() + break + case (Qt.Key_Enter): + case (Qt.Key_Return): + if (selectedPage == Units.Page.DownloadPage && releases.variant.status != Units.DownloadStatus.Finished) + cancelDialog.show() + break + } + } } Units { @@ -315,5 +293,70 @@ ApplicationWindow { return qsTr("Cancel") return qsTr("Previous") } + + function setNextPage() { + if (selectedPage == Units.Page.MainPage) { + if (selectedOption == Units.MainSelect.Write) { + if (releases.localFile.iso) + releases.selectLocalFile() + selectedPage = Units.Page.DrivePage + } else if (selectedOption == Units.MainSelect.Restore) + selectedPage = Units.Page.RestorePage + else + selectedPage = Units.Page.VersionPage + } else if (selectedPage == Units.Page.VersionPage) { + selectedPage += 1 + } else if (selectedPage == Units.Page.DrivePage) { + selectedPage = Units.Page.DownloadPage + if (selectedOption != Units.MainSelect.Write) + releases.variant.download() + if (drives.length) { + drives.selected.setImage(releases.variant) + drives.selected.write(releases.variant) + } + } else if (selectedPage == Units.Page.DownloadPage) { + if (releases.variant.status === Units.DownloadStatus.Finished) { + drives.lastRestoreable = drives.selected + drives.lastRestoreable.setRestoreStatus(Units.RestoreStatus.Contains_Live) + releases.variant.resetStatus() + downloadManager.cancel() + selectedPage = Units.Page.MainPage + } else if ((releases.variant.status === Units.DownloadStatus.Failed && drives.length) || releases.variant.status === Units.DownloadStatus.Failed_Download || (releases.variant.status === Units.DownloadStatus.Failed_Verification && drives.length) || releases.variant.status === Units.DownloadStatus.Ready) { + if (selectedOption != Units.MainSelect.Write) + releases.variant.download() + drives.selected.setImage(releases.variant) + drives.selected.write(releases.variant) + } + } else { + if (lastRestoreable && lastRestoreable.restoreStatus == Units.RestoreStatus.Restored) + selectedPage = Units.Page.MainPage + else + drives.lastRestoreable.restore() + } + } + + function setPreviousPage() { + if (selectedPage == Units.Page.MainPage) + aboutDialog.show() + else if (selectedPage == Units.Page.VersionPage) + selectedPage -= 1 + else if (selectedPage == Units.Page.DrivePage) { + if (selectedOption == Units.MainSelect.Write) + selectedPage = Units.Page.MainPage + else { + selectedPage -= 1 + stackView.pop() + } + } else if (selectedPage == Units.Page.DownloadPage) { + if (releases.variant.status === Units.DownloadStatus.Write_Verifying || releases.variant.status === Units.DownloadStatus.Writing || releases.variant.status === Units.DownloadStatus.Downloading || releases.variant.status === Units.DownloadStatus.Download_Verifying) { + cancelDialog.show() + } else { + releases.variant.resetStatus() + downloadManager.cancel() + mainWindow.selectedPage = Units.Page.MainPage + } + } else + selectedPage = Units.Page.MainPage + } }