diff --git a/src/app/qml.qrc b/src/app/qml.qrc index d83c8436..97b0e7bf 100644 --- a/src/app/qml.qrc +++ b/src/app/qml.qrc @@ -1,14 +1,15 @@ - qml/main.qml - qml/VersionPage.qml - qml/DrivePage.qml + qml/AboutDialog.qml + qml/CancelDialog.qml qml/DownloadPage.qml - qml/Units.qml + qml/DrivePage.qml qml/Heading.qml qml/MainPage.qml - qml/AboutDialog.qml - qml/CancelDialog.qml + qml/Page.qml qml/RestorePage.qml + qml/Units.qml + qml/VersionPage.qml + qml/main.qml diff --git a/src/app/qml/AboutDialog.qml b/src/app/qml/AboutDialog.qml index 46edd787..e69f7163 100644 --- a/src/app/qml/AboutDialog.qml +++ b/src/app/qml/AboutDialog.qml @@ -21,7 +21,6 @@ import QtQuick 6.6 import QtQuick.Controls 6.6 import QtQuick.Window 6.6 import QtQuick.Layouts 6.6 -import QtQml 6.6 ApplicationWindow { id: aboutDialog diff --git a/src/app/qml/CancelDialog.qml b/src/app/qml/CancelDialog.qml index 4e59c0ab..b090c300 100644 --- a/src/app/qml/CancelDialog.qml +++ b/src/app/qml/CancelDialog.qml @@ -21,7 +21,6 @@ import QtQuick 6.6 import QtQuick.Controls 6.6 import QtQuick.Window 6.6 import QtQuick.Layouts 6.6 -import QtQml 6.6 ApplicationWindow { id: cancelDialog diff --git a/src/app/qml/DownloadPage.qml b/src/app/qml/DownloadPage.qml index 22492960..bb2831d1 100644 --- a/src/app/qml/DownloadPage.qml +++ b/src/app/qml/DownloadPage.qml @@ -1,5 +1,6 @@ /* * Fedora Media Writer + * Copyright (C) 2024 Jan Grulich * Copyright (C) 2021-2022 Evžen Gasta * * This program is free software; you can redistribute it and/or @@ -18,203 +19,169 @@ */ import QtQuick 6.6 -import QtQuick.Controls 6.6 -import QtQuick.Window 6.6 +import QtQuick.Controls 6.6 as QQC2 import QtQuick.Layouts 6.6 -import QtQml 6.6 - Page { id: downloadPage property int availableDrives: drives.length property int currentStatus: releases.variant.status + property string file: mainWindow.selectedOption == Units.MainSelect.Write ? (String)(releases.localFile.iso).split("/").slice(-1)[0] : releases.selected.name + " " + releases.selected.version.number - ColumnLayout { - id: mainColumn - anchors.fill: parent - spacing: units.gridUnit - - Image { - source: "qrc:/downloadPageImage" - Layout.fillHeight: true - Layout.fillWidth: true - fillMode: Image.PreserveAspectFit - sourceSize.width: parent.width - sourceSize.height: parent.height - smooth: true - antialiasing: true - } + imageSource: "qrc:/downloadPageImage" + layoutSpacing: units.gridUnit + text: { + if (currentStatus === Units.DownloadStatus.Finished) + qsTr("%1 Successfully Written").arg(file) + else if (currentStatus === Units.DownloadStatus.Writing) + qsTr("Writing %1").arg(file) + else if (currentStatus === Units.DownloadStatus.Downloading) + qsTr("Downloading %1").arg(file) + else if (currentStatus === Units.DownloadStatus.Preparing) + qsTr("Preparing %1").arg(file) + else if (currentStatus === Units.DownloadStatus.Ready) + qsTr("Ready to write %1").arg(file) + else if (currentStatus == Units.DownloadStatus.Failed_Download) + qsTr("Failed to download %1").arg(file) + else + releases.variant.statusString + } + textLevel: 4 + + property double leftSize: releases.variant.progress.to - releases.variant.progress.value + property string rightStr: leftSize <= 0 ? "" : + (leftSize < 1024) ? qsTr(" B left)") : + (leftSize < (1024 * 1024)) ? qsTr(" KB left)") : + (leftSize < (1024 * 1024 * 1024)) ? qsTr(" MB left)") : + qsTr(" GB left)") + + property string leftStr: leftSize <= 0 ? "" : + (leftSize < 1024) ? qsTr(" (%1").arg(leftSize) : + (leftSize < (1024 * 1024)) ? qsTr(" (%1").arg((leftSize / 1024).toFixed(1)) : + (leftSize < (1024 * 1024 * 1024)) ? qsTr(" (%1").arg((leftSize / 1024 / 1024).toFixed(1)) : + qsTr(" (%1").arg((leftSize / 1024 / 1024 / 1024).toFixed(1)) + RowLayout { + Layout.alignment: Qt.AlignHCenter + spacing: 0 - Heading { - id: heading - property string file: mainWindow.selectedOption == Units.MainSelect.Write ? (String)(releases.localFile.iso).split("/").slice(-1)[0] : releases.selected.name + " " + releases.selected.version.number - - Layout.alignment: Qt.AlignHCenter + QQC2.Label { + id: refLabel text: { - if (currentStatus === Units.DownloadStatus.Finished) - qsTr("%1 Successfully Written").arg(file) - else if (currentStatus === Units.DownloadStatus.Writing) - qsTr("Writing %1").arg(file) - else if (currentStatus === Units.DownloadStatus.Downloading) - qsTr("Downloading %1").arg(file) - else if (currentStatus === Units.DownloadStatus.Preparing) - qsTr("Preparing %1").arg(file) - else if (currentStatus === Units.DownloadStatus.Ready) - qsTr("Ready to write %1").arg(file) - else if (currentStatus == Units.DownloadStatus.Failed_Download) - qsTr("Failed to download %1").arg(file) + if ((currentStatus == Units.DownloadStatus.Failed_Verification || + currentStatus == Units.DownloadStatus.Failed) && !availableDrives) + qsTr("Your drive was unplugged during the process") else releases.variant.statusString } - level: 4 - Layout.preferredWidth: mainColumn.width - elide: Label.ElideRight - horizontalAlignment: Label.AlignHCenter + visible: text !== downloadPage.text } - - ColumnLayout { - id: progressColumn - property double leftSize: releases.variant.progress.to - releases.variant.progress.value - property string rightStr: leftSize <= 0 ? "" : - (leftSize < 1024) ? qsTr(" B left)") : - (leftSize < (1024 * 1024)) ? qsTr(" KB left)") : - (leftSize < (1024 * 1024 * 1024)) ? qsTr(" MB left)") : - qsTr(" GB left)") - property string leftStr: leftSize <= 0 ? "" : - (leftSize < 1024) ? qsTr(" (%1").arg(leftSize) : - (leftSize < (1024 * 1024)) ? qsTr(" (%1").arg((leftSize / 1024).toFixed(1)) : - (leftSize < (1024 * 1024 * 1024)) ? qsTr(" (%1").arg((leftSize / 1024 / 1024).toFixed(1)) : - qsTr(" (%1").arg((leftSize / 1024 / 1024 / 1024).toFixed(1)) - - TextMetrics { - id: fontMetrics - text: progressColumn.leftStr.replace(/[1-9]/g, '0') - } + QQC2.Label { + visible: currentStatus == Units.DownloadStatus.Downloading + text: downloadPage.leftStr + } - RowLayout { - Layout.alignment: Qt.AlignHCenter - spacing: 0 + QQC2.Label { + visible: currentStatus == Units.DownloadStatus.Downloading + text: downloadPage.rightStr + } + } - Label { - id: refLabel - text: { - if ((currentStatus == Units.DownloadStatus.Failed_Verification || - currentStatus == Units.DownloadStatus.Failed) && !availableDrives) - qsTr("Your drive was unplugged during the process") - else - releases.variant.statusString - } - visible: text !== heading.text - } + QQC2.ProgressBar { + id: progressBar + Layout.fillWidth: true + value: 0.0 + } - Label { - visible: currentStatus == Units.DownloadStatus.Downloading - text: progressColumn.leftStr - } + Column { + id: infoColumn + width: downloadPage.width - (units.gridUnit * 8) + spacing: units.gridUnit / 2 - Label { - visible: currentStatus == Units.DownloadStatus.Downloading - text: progressColumn.rightStr - } - } + QQC2.Label { + id: messageDownload + visible: currentStatus === Units.DownloadStatus.Downloading || + currentStatus === Units.DownloadStatus.Download_Verifying + text: qsTr("Downloads are saved to the downloads folder.") + width: infoColumn.width + wrapMode: QQC2.Label.Wrap + } - ProgressBar { - id: progressBar - Layout.topMargin: units.gridUnit / 2 - Layout.fillWidth: true - value: 0.0 - } + QQC2.Label { + id: messageLoseData + visible: availableDrives && (currentStatus === Units.DownloadStatus.Failed || + currentStatus === Units.DownloadStatus.Failed_Verification || + currentStatus === Units.DownloadStatus.Ready) + text: qsTr("By writing, you will lose all of the data on %1.").arg(drives.selected.name) + width: infoColumn.width + wrapMode: QQC2.Label.Wrap } - - Column { - id: infoColumn - spacing: units.gridUnit / 2 - - Label { - id: messageDownload - visible: false - text: qsTr("Downloads are saved to the downloads folder.") - wrapMode: Label.Wrap - width: mainColumn.width - } - Label { - id: messageLoseData - visible: false - text: qsTr("By writing, you will lose all of the data on %1.").arg(drives.selected.name) - wrapMode: Label.Wrap - width: mainColumn.width - } + QQC2.Label { + id: messageInsertDrive + visible: currentStatus === Units.DownloadStatus.Ready && !availableDrives + text: qsTr("Please insert an USB drive.") + width: infoColumn.width + wrapMode: QQC2.Label.Wrap + } - Label { - id: messageInsertDrive - visible: false - text: qsTr("Please insert an USB drive.") - wrapMode: Label.Wrap - width: mainColumn.width - } + QQC2.Label { + id: messageRestore + visible: currentStatus === Units.DownloadStatus.Write_Verifying || + currentStatus === Units.DownloadStatus.Writing + text: qsTr("Your drive will be resized to a smaller capacity. You may resize it back to normal by using Fedora Media Writer. This will remove installation media from your drive.") + width: infoColumn.width + wrapMode: QQC2.Label.Wrap + } - Label { - id: messageRestore - visible: false - text: qsTr("Your drive will be resized to a smaller capacity. You may resize it back to normal by using Fedora Media Writer. This will remove installation media from your drive.") - wrapMode: Label.Wrap - width: mainColumn.width - } + QQC2.Label { + id: messageSelectedImage + visible: releases.selected.isLocal + text: "" + qsTr("Selected:") + " " + (releases.variant.iso ? (((String)(releases.variant.iso)).split("/").slice(-1)[0]) : ("" + qsTr("None") + "")) + width: infoColumn.width + wrapMode: QQC2.Label.Wrap + } - Label { - id: messageSelectedImage - visible: releases.selected.isLocal - text: "" + qsTr("Selected:") + " " + (releases.variant.iso ? (((String)(releases.variant.iso)).split("/").slice(-1)[0]) : ("" + qsTr("None") + "")) - wrapMode: Label.Wrap - width: mainColumn.width - } + QQC2.Label { + id: messageArmBoard + visible: false //boardCombo.otherSelected + text: qsTr("Your board or device is not supported by Fedora Media Writer yet. Please check this page for more information about its compatibility with Fedora and how to create bootable media for it.").arg("https://fedoraproject.org/wiki/Architectures/ARM") + width: infoColumn.width + wrapMode: QQC2.Label.Wrap + } - Label { - id: messageArmBoard - visible: false //boardCombo.otherSelected - text: qsTr("Your board or device is not supported by Fedora Media Writer yet. Please check this page for more information about its compatibility with Fedora and how to create bootable media for it.").arg("https://fedoraproject.org/wiki/Architectures/ARM") - wrapMode: Label.Wrap - width: mainColumn.width - } + QQC2.Label { + id: messageDriveSize + enabled: currentStatus != Units.DownloadStatus.Writing && + currentStatus != Units.DownloadStatus.Write_Verifying && + currentStatus != Units.DownloadStatus.Finished + visible: enabled && drives.selected && drives.selected.size > 160 * 1024 * 1024 * 1024 // warn when it's more than 160GB + text: qsTr("The selected drive's size is %1. It's possible you have selected an external drive by accident!").arg(drives.selected ? drives.selected.readableSize : "N/A") + width: infoColumn.width + wrapMode: QQC2.Label.Wrap + } - Label { - id: messageDriveSize - enabled: true - visible: enabled && drives.selected && drives.selected.size > 160 * 1024 * 1024 * 1024 // warn when it's more than 160GB - text: qsTr("The selected drive's size is %1. It's possible you have selected an external drive by accident!").arg(drives.selected ? drives.selected.readableSize : "N/A") - wrapMode: Label.Wrap - width: mainColumn.width - } - - Label { - id: messageFinished - enabled: true - visible: false - text: qsTr("Restart and boot from %1 to start using %2.").arg(drives.selected ? drives.selected.name : "N/A").arg(mainWindow.selectedOption == Units.MainSelect.Write ? (String)(releases.localFile.iso).split("/").slice(-1)[0] : releases.selected.name) - wrapMode: Label.Wrap - width: mainColumn.width - } + QQC2.Label { + id: messageFinished + visible: currentStatus === Units.DownloadStatus.Finished + text: qsTr("Restart and boot from %1 to start using %2.").arg(drives.selected ? drives.selected.name : "N/A").arg(mainWindow.selectedOption == Units.MainSelect.Write ? (String)(releases.localFile.iso).split("/").slice(-1)[0] : releases.selected.name) + width: infoColumn.width + wrapMode: QQC2.Label.Wrap + } - Label { - visible: releases.variant && releases.variant.errorString.length > 0 - text: releases.variant ? releases.variant.errorString : "" - wrapMode: Label.Wrap - width: mainColumn.width - } + QQC2.Label { + visible: releases.variant && releases.variant.errorString.length > 0 + text: releases.variant ? releases.variant.errorString : "" + width: infoColumn.width + wrapMode: QQC2.Label.Wrap } } - + states: [ State { name: "downloading" when: currentStatus === Units.DownloadStatus.Downloading - PropertyChanges { - target: messageDownload - visible: true - } PropertyChanges { target: progressBar; value: releases.variant.progress.ratio @@ -223,42 +190,14 @@ Page { State { name: "download_verifying" when: currentStatus === Units.DownloadStatus.Download_Verifying - PropertyChanges { - target: messageDownload - visible: true - } PropertyChanges { target: progressBar; value: releases.variant.progress.ratio } }, - State { - name: "ready_no_drives" - when: currentStatus === Units.DownloadStatus.Ready && !availableDrives - PropertyChanges { - target: messageInsertDrive - visible: true - } - }, - State { - name: "ready" - when: currentStatus === Units.DownloadStatus.Ready && availableDrives - PropertyChanges { - target: messageLoseData; - visible: true - } - }, State { name: "writing" when: currentStatus === Units.DownloadStatus.Writing - PropertyChanges { - target: messageDriveSize - enabled: false - } - PropertyChanges { - target: messageRestore; - visible: true - } PropertyChanges { target: progressBar; value: drives.selected.progress.ratio; @@ -267,14 +206,6 @@ Page { State { name: "write_verifying" when: currentStatus === Units.DownloadStatus.Write_Verifying - PropertyChanges { - target: messageDriveSize - enabled: false - } - PropertyChanges { - target: messageRestore; - visible: true - } PropertyChanges { target: progressBar; value: drives.selected.progress.ratio; @@ -283,14 +214,6 @@ Page { State { name: "finished" when: currentStatus === Units.DownloadStatus.Finished - PropertyChanges { - target: messageDriveSize; - enabled: false - } - PropertyChanges { - target: messageFinished; - visible: true - } PropertyChanges { target: progressBar; value: 100; @@ -305,60 +228,66 @@ Page { releases.variant } } - }, - State { - name: "failed_verification" - when: currentStatus === Units.DownloadStatus.Failed_Verification && availableDrives - PropertyChanges { - target: messageLoseData; - visible: true - } - }, - State { - name: "failed" - when: currentStatus === Units.DownloadStatus.Failed && availableDrives - PropertyChanges { - target: messageLoseData; - visible: true - } } - // Unhandled states: - // preparing. writing_not_possible, failed_verification_no_drives,failed_download, failed_no_drives ] - onCurrentStatusChanged: { - // Not sure it's necessary, but it doesn't hurt to be safe - if (mainWindow.selectedPage == Units.Page.DownloadPage) { - prevButton.visible = getPrevButtonState() - nextButton.visible = getNextButtonState() - } - } - - onAvailableDrivesChanged: { - // Not sure it's necessary, but it doesn't hurt to be safe - if (mainWindow.selectedPage == Units.Page.DownloadPage) { - nextButton.visible = getNextButtonState() + // There will be only [Finish] button on the right side so [Cancel] button + // is not necessary + previousButtonVisible: currentStatus != Units.DownloadStatus.Finished + previousButtonText: qsTr("Cancel") + onPreviousButtonClicked: { + 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 } } - function getPrevButtonState() { - // There will be only [Finish] button on the right side so [Cancel] button - // is not necessary - return currentStatus != Units.DownloadStatus.Finished - } - - function getNextButtonState() { - // This will be [Finish] button to successfully go to the main page + nextButtonVisible: { if (currentStatus == Units.DownloadStatus.Finished) return true // This will be [Retry] button to start the process again if there is a drive plugged in else if (currentStatus == Units.DownloadStatus.Ready || - currentStatus == Units.DownloadStatus.Failed_Verification || - currentStatus == Units.DownloadStatus.Failed) { + currentStatus == Units.DownloadStatus.Failed_Verification || + currentStatus == Units.DownloadStatus.Failed) { return availableDrives } - return false } -} + nextButtonText: { + 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) + return qsTr("Cancel") + else if (releases.variant.status == Units.DownloadStatus.Ready) + return qsTr("Write") + else if (releases.variant.status === Units.DownloadStatus.Finished) + return qsTr("Finish") + else + return qsTr("Retry") + } + onNextButtonClicked: { + 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_Verification && drives.length) || + releases.variant.status === Units.DownloadStatus.Failed_Download || + releases.variant.status === Units.DownloadStatus.Ready) { + if (selectedOption != Units.MainSelect.Write) + releases.variant.download() + drives.selected.setImage(releases.variant) + drives.selected.write(releases.variant) + } + } +} diff --git a/src/app/qml/DrivePage.qml b/src/app/qml/DrivePage.qml index c5dc0ee8..0d8b5a50 100644 --- a/src/app/qml/DrivePage.qml +++ b/src/app/qml/DrivePage.qml @@ -1,5 +1,6 @@ /* * Fedora Media Writer + * Copyright (C) 2024 Jan Grulich * Copyright (C) 2021-2022 Evžen Gasta * * This program is free software; you can redistribute it and/or @@ -18,153 +19,137 @@ */ import QtQuick 6.6 -import QtQuick.Controls 6.6 -import QtQuick.Window 6.6 -import QtQuick.Layouts 6.6 -import QtQml 6.6 +import QtQuick.Controls 6.6 as QQC2 import QtQuick.Dialogs 6.6 +import QtQuick.Layouts 6.6 Page { id: drivePage - ColumnLayout { - anchors.fill: parent - spacing: units.gridUnit + layoutSpacing: units.gridUnit + text: qsTr("Write Options") + ColumnLayout { + id: versionCol + visible: selectedOption != Units.MainSelect.Write + Heading { - Layout.alignment: Qt.AlignHCenter - text: qsTr("Write Options") - level: 5 + text: qsTr("Version") } - - ColumnLayout { - id: versionCol - visible: selectedOption != Units.MainSelect.Write - - Heading { - text: qsTr("Version") - } - - ComboBox { - id: versionCombo - Layout.fillWidth: true - model: releases.selected.versions - textRole: "name" - onCurrentIndexChanged: releases.selected.versionIndex = currentIndex - Component.onCompleted: { - if (releases.selected.version.status != Units.Status.FINAL && releases.selected.versions.length > 1) { - currentIndex++ - } + + QQC2.ComboBox { + id: versionCombo + Layout.fillWidth: true + model: releases.selected.versions + textRole: "name" + onCurrentIndexChanged: releases.selected.versionIndex = currentIndex + Component.onCompleted: { + if (releases.selected.version.status != Units.Status.FINAL && releases.selected.versions.length > 1) { + currentIndex++ } } } - - ColumnLayout { - id: architectureCol - visible: selectedOption != Units.MainSelect.Write - - Heading { - text: qsTr("Hardware Architecture") - } - - ComboBox { - id: hwArchCombo - Layout.fillWidth: true - model: releases.selected.version.variants - textRole: "name" - onCurrentIndexChanged: releases.selected.version.variantIndex = currentIndex - } + } + + ColumnLayout { + id: architectureCol + visible: selectedOption != Units.MainSelect.Write + + Heading { + text: qsTr("Hardware Architecture") } - - ColumnLayout { - id: selectFileColumn - visible: selectedOption == Units.MainSelect.Write - - Heading { - text: qsTr("Selected file") + + QQC2.ComboBox { + id: hwArchCombo + Layout.fillWidth: true + model: releases.selected.version.variants + textRole: "name" + onCurrentIndexChanged: releases.selected.version.variantIndex = currentIndex + } + } + + ColumnLayout { + id: selectFileColumn + visible: selectedOption == Units.MainSelect.Write + + Heading { + text: qsTr("Selected file") + } + + RowLayout { + id: fileCol + + QQC2.Label { + text: releases.localFile.iso ? (String)(releases.localFile.iso).split("/").slice(-1)[0] : ("" + qsTr("None") + "") + Layout.fillWidth: true + elide: QQC2.Label.ElideRight } - - RowLayout { - id: fileCol - - Label { - text: releases.localFile.iso ? (String)(releases.localFile.iso).split("/").slice(-1)[0] : ("" + qsTr("None") + "") - Layout.fillWidth: true - elide: Label.ElideRight + + QQC2.Button { + id: selectFileButton + Layout.alignment: Qt.AlignRight + text: qsTr("Select...") + onClicked: { + if (portalFileDialog.isAvailable) + portalFileDialog.open() + else + fileDialog.open() } - - Button { - id: selectFileButton - Layout.alignment: Qt.AlignRight - text: qsTr("Select...") - onClicked: { - if (portalFileDialog.isAvailable) - portalFileDialog.open() - else - fileDialog.open() - } - Connections { - target: portalFileDialog - function onFileSelected(fileName) { - releases.selectLocalFile(fileName) - } + Connections { + target: portalFileDialog + function onFileSelected(fileName) { + releases.selectLocalFile(fileName) } - - FileDialog { - id: fileDialog - nameFilters: [ qsTr("Image files") + " (*.iso *.raw *.xz)", qsTr("All files (*)")] - onAccepted: { - releases.selectLocalFile(currentFile) - } + } + + FileDialog { + id: fileDialog + nameFilters: [ qsTr("Image files") + " (*.iso *.raw *.xz)", qsTr("All files (*)")] + onAccepted: { + releases.selectLocalFile(currentFile) } } } } - - ColumnLayout { - Heading { - text: qsTr("USB Drive") - } - - ComboBox { - id: driveCombo - Layout.fillWidth: true - model: drives - enabled: !(currentIndex === -1 || !currentText) - displayText: currentIndex === -1 || !currentText ? qsTr("There are no portable drives connected") : currentText - textRole: "display" - - Binding on currentIndex { - when: drives - value: drives.selectedIndex - } - Binding { - target: drives - property: "selectedIndex" - value: driveCombo.currentIndex - } - } + } + + ColumnLayout { + Heading { + text: qsTr("USB Drive") } - - ColumnLayout { - visible: selectedOption != Units.MainSelect.Write - Layout.bottomMargin: units.gridUnit * 5 - - Heading { - text: qsTr("Download") - level: 1 + + QQC2.ComboBox { + id: driveCombo + Layout.fillWidth: true + model: drives + enabled: !(currentIndex === -1 || !currentText) + displayText: currentIndex === -1 || !currentText ? qsTr("There are no portable drives connected") : currentText + textRole: "display" + + Binding on currentIndex { + when: drives + value: drives.selectedIndex } - - CheckBox { - text: qsTr("Delete download after writing") - onCheckedChanged: mainWindow.eraseVariant = !mainWindow.eraseVariant + Binding { + target: drives + property: "selectedIndex" + value: driveCombo.currentIndex } } - - Item { - visible: selectedOption == Units.MainSelect.Write - Layout.fillHeight: true + } + + ColumnLayout { + visible: selectedOption != Units.MainSelect.Write + + Heading { + text: qsTr("Download") + level: 1 + } + + QQC2.CheckBox { + text: qsTr("Delete download after writing") + onCheckedChanged: mainWindow.eraseVariant = !mainWindow.eraseVariant } } @@ -172,13 +157,37 @@ Page { State { name: "Downloading" when: selectedOption != Units.MainSelect.Write && selectedPage == Units.Page.DrivePage - PropertyChanges { target: nextButton; enabled: true } StateChangeScript { script: releases.setSelectedVariantIndex = 0 } - }, - State { - name: "WritingISO" - when: selectedOption == Units.MainSelect.Write && selectedPage == Units.Page.DrivePage - PropertyChanges { target: nextButton; enabled: driveCombo.enabled && releases.localFile.iso } } ] + + nextButtonEnabled: (selectedOption != Units.MainSelect.Write && selectedPage == Units.Page.DrivePage) || + (selectedOption == Units.MainSelect.Write && selectedPage == Units.Page.DrivePage) + + nextButtonText: { + if (selectedOption == Units.MainSelect.Write || downloadManager.isDownloaded(releases.selected.version.variant.url)) + return qsTr("Write") + if (Qt.platform.os === "windows" || Qt.platform.os === "osx") + return qsTr("Download && Write") + return qsTr("Download & Write") + } + + onPreviousButtonClicked: { + if (selectedOption == Units.MainSelect.Write) + selectedPage = Units.Page.MainPage + else { + selectedPage -= 1 + stackView.pop() + } + } + + onNextButtonClicked: { + 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) + } + } } diff --git a/src/app/qml/MainPage.qml b/src/app/qml/MainPage.qml index ec851b16..90612c85 100644 --- a/src/app/qml/MainPage.qml +++ b/src/app/qml/MainPage.qml @@ -1,5 +1,6 @@ /* * Fedora Media Writer + * Copyright (C) 2024 Jan Grulich * Copyright (C) 2021-2022 Evžen Gasta * * This program is free software; you can redistribute it and/or @@ -18,81 +19,64 @@ */ import QtQuick 6.6 -import QtQuick.Controls 6.6 -import QtQuick.Window 6.6 +import QtQuick.Controls 6.6 as QQC2 import QtQuick.Layouts 6.6 -import QtQml 6.6 -import QtQuick.Dialogs 6.6 Page { id: mainPage - - ColumnLayout { - anchors.fill: parent - spacing: units.gridUnit - - Image { - source: "qrc:/mainPageImage" - Layout.fillHeight: true - Layout.fillWidth: true - fillMode: Image.PreserveAspectFit - sourceSize.width: parent.width - sourceSize.height: parent.height - smooth: true - antialiasing: true + + imageSource: "qrc:/mainPageImage" + text: qsTr("Select Image Source") + + QQC2.RadioButton { + checked: selectedOption == Units.MainSelect.Download + text: qsTr("Download automatically") + onClicked: { + selectedOption = Units.MainSelect.Download } + } - Heading { - Layout.alignment: Qt.AlignHCenter - text: qsTr("Select Image Source") - level: 5 + QQC2.RadioButton { + text: qsTr("Select .iso file") + onClicked: { + selectedOption = Units.MainSelect.Write + releases.selectLocalFile("") } - - ButtonGroup { - id: radioGroup + } + + QQC2.RadioButton { + id: restoreRadio + visible: drives.lastRestoreable + text: drives.lastRestoreable ? qsTr("Restore %1").arg(drives.lastRestoreable.name) : "" + onClicked: { + selectedOption = Units.MainSelect.Restore } - ColumnLayout { - id: radioColumn - Layout.bottomMargin: drives.lastRestoreable ? 0 : restoreRadio.height + 5 - - RadioButton { - checked: mainWindow.selectedOption == Units.MainSelect.Download - text: qsTr("Download automatically") - onClicked: { - selectedOption = Units.MainSelect.Download - } - ButtonGroup.group: radioGroup - } - - RadioButton { - text: qsTr("Select .iso file") - onClicked: { - selectedOption = Units.MainSelect.Write - releases.selectLocalFile("") - } - ButtonGroup.group: radioGroup - } - - RadioButton { - id: restoreRadio - visible: drives.lastRestoreable - text: drives.lastRestoreable ? qsTr("Restore %1").arg(drives.lastRestoreable.name) : "" - onClicked: { - selectedOption = Units.MainSelect.Restore - } - ButtonGroup.group: radioGroup - - Connections { - target: drives - function onLastRestoreableChanged() { - if (drives.lastRestoreable != null && !restoreRadio.visible) - restoreRadio.visible = true - if (!drives.lastRestoreable) - restoreRadio.visible = false - } - } + Connections { + target: drives + function onLastRestoreableChanged() { + if (drives.lastRestoreable != null && !restoreRadio.visible) + restoreRadio.visible = true + if (!drives.lastRestoreable) + restoreRadio.visible = false } } } + + previousButtonText: qsTr("About") + + onPreviousButtonClicked: { + aboutDialog.show() + } + + onNextButtonClicked: { + 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 + } } diff --git a/src/app/qml/Page.qml b/src/app/qml/Page.qml new file mode 100644 index 00000000..1e4ae714 --- /dev/null +++ b/src/app/qml/Page.qml @@ -0,0 +1,118 @@ +/* + * Fedora Media Writer + * Copyright (C) 2024 Jan Grulich + * Copyright (C) 2021-2022 Evžen Gasta + * + * 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 6.6 +import QtQuick.Controls 6.6 as QQC2 +import QtQuick.Layouts 6.6 + +QQC2.Page { + default property alias content: layout.children + + property alias imageSource: image.source + + property alias text: heading.text + property alias textLevel: heading.level + + property alias layoutSpacing: layout.spacing + + // Button.Text + property alias previousButtonText: prevButton.text + property alias nextButtonText: nextButton.text + + // Button.Visible + property alias previousButtonVisible: prevButton.visible + property alias nextButtonVisible: nextButton.visible + + // Button.Enabled + property alias previousButtonEnabled: prevButton.enabled + property alias nextButtonEnabled: nextButton.enabled + + // Button.Clicked + signal previousButtonClicked() + signal nextButtonClicked() + + Image { + id: image + anchors { + left: parent.left + right: parent.right + top: parent.top + } + width: visible ? 280 : 0 + height: visible ? 210 : 0 + source: "" + fillMode: Image.PreserveAspectFit + sourceSize.width: parent.width + sourceSize.height: parent.height + smooth: true + antialiasing: true + visible: source != "" + } + + ColumnLayout { + id: mainLayout + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + top: image.bottom + topMargin: units.gridUnit + } + spacing: units.gridUnit + + Heading { + id: heading + Layout.alignment: Qt.AlignHCenter + level: 5 + visible: text + } + + ColumnLayout { + id: layout + Layout.alignment: Qt.AlignTop + Layout.fillHeight: true + Layout.fillWidth: true + Layout.leftMargin: units.gridUnit * 4 + Layout.rightMargin: units.gridUnit * 4 + } + + RowLayout { + id: buttonRow + + Layout.alignment: Qt.AlignBottom + + QQC2.Button { + id: prevButton + text: qsTr("Previous") + onClicked: previousButtonClicked() + } + + Item { + Layout.fillWidth: true + } + + QQC2.Button { + id: nextButton + text: qsTr("Next") + onClicked: nextButtonClicked(); + } + } + } +} diff --git a/src/app/qml/RestorePage.qml b/src/app/qml/RestorePage.qml index 534195d6..c642c8dd 100644 --- a/src/app/qml/RestorePage.qml +++ b/src/app/qml/RestorePage.qml @@ -1,5 +1,6 @@ /* * Fedora Media Writer + * Copyright (C) 2024 Jan Grulich * Copyright (C) 2021-2022 Evžen Gasta * * This program is free software; you can redistribute it and/or @@ -18,165 +19,112 @@ */ import QtQuick 6.6 -import QtQuick.Controls 6.6 -import QtQuick.Window 6.6 +import QtQuick.Controls 6.6 as QQC2 import QtQuick.Layouts 6.6 -import QtQml 6.6 Page { id: restorePage - - ColumnLayout { - id: mainColumn - anchors.fill: parent - spacing: units.gridUnit - - Column { - Label { - Layout.alignment: Qt.AlignHCenter | Qt.AlignTop - text: qsTr("Restore Drive %1").arg(mainWindow.lastRestoreable.name) - wrapMode: Label.Wrap - width: mainColumn.width - horizontalAlignment: Label.AlignHCenter - } + + Column { + QQC2.Label { + Layout.alignment: Qt.AlignHCenter | Qt.AlignTop + text: qsTr("Restore Drive %1").arg(lastRestoreable.name) + wrapMode: QQC2.Label.Wrap + width: mainWindow.width - (units.gridUnit * 4) + horizontalAlignment: QQC2.Label.AlignHCenter } - - Column { - Label { - id: warningText - visible: false - Layout.alignment: Qt.AlignHCenter - text: qsTr("

To reclaim all space available on the drive, it has to be restored to its factory settings. The live system and all saved data will be deleted.

You don't need to restore the drive if you want to write another live system to it. -

Do you want to restore it to factory settings?

" ) - textFormat: Text.RichText - horizontalAlignment: Text.AlignHCenter - wrapMode: Label.Wrap - width: mainColumn.width - } - - ColumnLayout { - id: progress - visible: false - - Column{ - Label { - Layout.alignment: Qt.AlignHCenter - horizontalAlignment: Label.AlignHCenter - wrapMode: Label.Wrap - width: warningText.width - text: qsTr("

Please wait while Fedora Media Writer restores your portable drive.

") - } - } - - ProgressBar { - id: progressIndicator - width: units.gridUnit * 14 + } + + Column { + QQC2.Label { + id: warningText + visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Contains_Live + Layout.alignment: Qt.AlignHCenter + text: qsTr("

To reclaim all space available on the drive, it has to be restored to its factory settings. The live system and all saved data will be deleted.

You don't need to restore the drive if you want to write another live system to it. +

Do you want to restore it to factory settings?

" ) + textFormat: Text.RichText + horizontalAlignment: Text.AlignHCenter + wrapMode: QQC2.Label.Wrap + width: mainWindow.width - (units.gridUnit * 4) + } + + ColumnLayout { + id: progress + visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Restoring + + Column{ + QQC2.Label { Layout.alignment: Qt.AlignHCenter - indeterminate: true + horizontalAlignment: QQC2.Label.AlignHCenter + wrapMode: QQC2.Label.Wrap + width: warningText.width + text: qsTr("

Please wait while Fedora Media Writer restores your portable drive.

") } } - - Label { - id: restoredText - visible: false - Layout.alignment: Qt.AlignHCenter - horizontalAlignment: Text.AlignHCenter - text: qsTr("Your drive was successfully restored!") - wrapMode: Label.Wrap - width: mainColumn.width - } - - Label { - id: errorText - visible: false + + QQC2.ProgressBar { + id: progressIndicator + width: units.gridUnit * 14 Layout.alignment: Qt.AlignHCenter - horizontalAlignment: Text.AlignHCenter - text: qsTr("Unfortunately, an error occurred during the process. Please try restoring the drive using your system tools.") - wrapMode: Label.Wrap - width: mainColumn.width + indeterminate: true } } - } - - Connections { - target: drives - function onLastRestoreableChanged() { - if (!drives.selected) - mainWindow.selectedPage = Units.Page.MainPage + + QQC2.Label { + id: restoredText + visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Restored + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + text: qsTr("Your drive was successfully restored!") + wrapMode: QQC2.Label.Wrap + width: mainWindow.width - (units.gridUnit * 4) + } + + QQC2.Label { + id: errorText + visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Restore_Error + Layout.alignment: Qt.AlignHCenter + horizontalAlignment: Text.AlignHCenter + text: qsTr("Unfortunately, an error occurred during the process. Please try restoring the drive using your system tools.") + wrapMode: QQC2.Label.Wrap + width: mainWindow.width - (units.gridUnit * 4) } } Component.onCompleted: { - mainWindow.lastRestoreable = drives.lastRestoreable + lastRestoreable = drives.lastRestoreable } states: [ - State { - name: "contains_live" - when: mainWindow.lastRestoreable && mainWindow.lastRestoreable.restoreStatus == Units.RestoreStatus.Contains_Live - PropertyChanges { - target: warningText; - visible: true - } - }, - State { - name: "restoring" - when: mainWindow.lastRestoreable && mainWindow.lastRestoreable.restoreStatus == Units.RestoreStatus.Restoring - PropertyChanges { - target: progress; - visible: true - } - PropertyChanges { - target: prevButton; - visible: false - } - PropertyChanges { - target: nextButton; - visible: false - } - }, State { name: "restored" - when: mainWindow.lastRestoreable && mainWindow.lastRestoreable.restoreStatus == Units.RestoreStatus.Restored + when: lastRestoreable.restoreStatus == Units.RestoreStatus.Restored PropertyChanges { target: mainWindow; title: qsTr("Restoring finished") } - PropertyChanges { - target: restoredText; - visible: true - } - PropertyChanges { - target: nextButton; - enabled: true - } - PropertyChanges { - target: prevButton; - visible: false - } StateChangeScript { script: drives.lastRestoreable = null } - }, - State { - name: "restore_error" - when: mainWindow.lastRestoreable && mainWindow.lastRestoreable.restoreStatus == Units.RestoreStatus.Restore_Error - PropertyChanges { - target: errorText; - visible: true - } - PropertyChanges { - target: prevButton; - enabled: true - } - }, - State { - name: "Clean" - when: mainWindow.lastRestoreable && mainWindow.lastRestoreable.restoreStatus == Units.RestoreStatus.Clean - PropertyChanges { - target: prevButton; - enabled: true - } } ] + + previousButtonEnabled: lastRestoreable.restoreStatus != Units.RestoreStatus.Restored && + lastRestoreable.restoreStatus != Units.RestoreStatus.Restoring + previousButtonVisible: previousButtonEnabled + onPreviousButtonClicked: { + selectedPage = Units.Page.MainPage + } + + nextButtonEnabled: lastRestoreable.restoreStatus == Units.RestoreStatus.Restored || + lastRestoreable.restoreStatus == Units.RestoreStatus.Contains_Live + nextButtonVisible: lastRestoreable.restoreStatus != Units.RestoreStatus.Restoring + nextButtonText: lastRestoreable.restoreStatus == Units.RestoreStatus.Restored ? qsTr("Finish") : qsTr("Restore") + onNextButtonClicked: { + if (lastRestoreable.restoreStatus == Units.RestoreStatus.Restored) + selectedPage = Units.Page.MainPage + else + drives.lastRestoreable.restore() + } + } diff --git a/src/app/qml/VersionPage.qml b/src/app/qml/VersionPage.qml index 713d754b..b68b249e 100644 --- a/src/app/qml/VersionPage.qml +++ b/src/app/qml/VersionPage.qml @@ -1,5 +1,6 @@ /* * Fedora Media Writer + * Copyright (C) 2024 Jan Grulich * Copyright (C) 2021-2022 Evžen Gasta * * This program is free software; you can redistribute it and/or @@ -18,73 +19,48 @@ */ import QtQuick 6.6 -import QtQuick.Controls 6.6 +import QtQuick.Controls 6.6 as QQC2 import QtQuick.Layouts 6.6 -import QtQml 6.6 - Page { id: versionPage property int prevSource: 0 - ColumnLayout { - anchors.fill: parent - - Heading { - Layout.alignment: Qt.AlignHCenter - text: qsTr("Select Fedora Release") - level: 5 - } - - ButtonGroup { - id: radioGroup - } - - ColumnLayout { - id: radioColumn - Layout.alignment: Qt.AlignTop - - Label { - text: qsTr("Select from:") - } + text: qsTr("Select Fedora Release") - RadioButton { - checked: true - text: qsTr("Official Editions") - onClicked: changeFilter(Units.Source.Product) - ButtonGroup.group: radioGroup - } + QQC2.Label { + text: qsTr("Select from:") + } - RadioButton { - text: qsTr("Atomic Desktops") - onClicked: changeFilter(Units.Source.Emerging) - ButtonGroup.group: radioGroup - } + QQC2.RadioButton { + checked: true + text: qsTr("Official Editions") + onClicked: changeFilter(Units.Source.Product) + } - RadioButton { - text: qsTr("Spins") - onClicked: changeFilter(Units.Source.Spins) - ButtonGroup.group: radioGroup - } + QQC2.RadioButton { + text: qsTr("Atomic Desktops") + onClicked: changeFilter(Units.Source.Emerging) + } - RadioButton { - text: qsTr("Labs") - onClicked: changeFilter(Units.Source.Labs) - ButtonGroup.group: radioGroup - } + QQC2.RadioButton { + text: qsTr("Spins") + onClicked: changeFilter(Units.Source.Spins) + } - ComboBox { - id: selectFromComboBox - Layout.alignment: Qt.AlignHCenter - Layout.fillWidth: true - Layout.topMargin: units.gridUnit / 2 - textRole: "name" - valueRole: "sourceIndex" - model: releases - onCurrentValueChanged: updateSelectedIndex() + QQC2.RadioButton { + text: qsTr("Labs") + onClicked: changeFilter(Units.Source.Labs) + } - } - } + QQC2.ComboBox { + id: selectFromComboBox + Layout.fillWidth: true + Layout.topMargin: units.gridUnit / 2 + textRole: "name" + valueRole: "sourceIndex" + model: releases + onCurrentValueChanged: updateSelectedIndex() } function changeFilter(filter) { @@ -102,4 +78,7 @@ Page { releases.selectedIndex = parseInt(selectFromComboBox.currentValue) } } + + onPreviousButtonClicked: selectedPage -= 1 + onNextButtonClicked: selectedPage += 1 } diff --git a/src/app/qml/main.qml b/src/app/qml/main.qml index 348504c5..cb53bcb6 100644 --- a/src/app/qml/main.qml +++ b/src/app/qml/main.qml @@ -19,9 +19,6 @@ import QtQuick 6.6 import QtQuick.Controls 6.6 -import QtQuick.Window 6.6 -import QtQuick.Layouts 6.6 -import QtQml 6.6 ApplicationWindow { id: mainWindow @@ -36,74 +33,42 @@ ApplicationWindow { property int selectedOption: Units.MainSelect.Download property QtObject lastRestoreable property bool eraseVariant: false - - ColumnLayout { - id: mainLayout - anchors.fill: parent - - anchors.leftMargin: units.gridUnit * 3 - anchors.rightMargin: units.gridUnit * 3 - anchors.topMargin: units.gridUnit * 2 - anchors.bottomMargin: units.gridUnit * 2 - StackView { - id: stackView - initialItem: "MainPage.qml" - - Layout.fillHeight: true - Layout.fillWidth: true - Layout.leftMargin: parent.width / 8 - Layout.rightMargin: parent.width / 8 - Layout.bottomMargin: units.gridUnit * 2 - - pushEnter: Transition { - XAnimator { - from: mainWindow.width - to: 0 - duration: 250 - } - } - pushExit: Transition { - XAnimator { - from: 0 - to: -mainWindow.width - duration: 250 - } - } - popEnter: Transition { - XAnimator { - from: -mainWindow.width - to: 0 - duration: 250 - } - } - popExit: Transition { - XAnimator { - from: 0 - to: mainWindow.width - duration: 250 - } + StackView { + id: stackView + initialItem: "MainPage.qml" + + anchors { + fill: parent + margins: units.gridUnit * 2 + } + + pushEnter: Transition { + XAnimator { + from: mainWindow.width + to: 0 + duration: 250 } } - - RowLayout { - Layout.alignment: Qt.AlignBottom - - Button { - id: prevButton - visible: true - text: getPrevButtonText() + pushExit: Transition { + XAnimator { + from: 0 + to: -mainWindow.width + duration: 250 } - - Item { - Layout.fillWidth: true + } + popEnter: Transition { + XAnimator { + from: -mainWindow.width + to: 0 + duration: 250 } - - Button { - id: nextButton - visible: mainLayout.state != "downloadPage" - enabled: mainLayout.state != "drivePage" - text: getNextButtonText() + } + popExit: Transition { + XAnimator { + from: 0 + to: mainWindow.width + duration: 250 } } @@ -115,26 +80,7 @@ ApplicationWindow { target: mainWindow title: qsTr("Fedora Media Writer") } - //When comming back from restore page, after successfull restoring a USB drive - PropertyChanges { - target: prevButton - text: getPrevButtonText() - onClicked: aboutDialog.show() - } - 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 - } - } + StateChangeScript { script: { //reset of source on versionPage @@ -152,8 +98,6 @@ 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 } StateChangeScript { script: { //state was pushing same page when returing from drivePage @@ -169,31 +113,6 @@ ApplicationWindow { target: mainWindow title: qsTr("Select Drive") } - 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) - } - } - } - PropertyChanges { - target: prevButton - visible: true - onClicked: { - if (selectedOption == Units.MainSelect.Write) - selectedPage = Units.Page.MainPage - else { - selectedPage -= 1 - stackView.pop() - } - } - } StateChangeScript { script: { stackView.push("DrivePage.qml") @@ -204,73 +123,36 @@ ApplicationWindow { State { name: "downloadPage" when: selectedPage == Units.Page.DownloadPage - PropertyChanges { + PropertyChanges { target: mainWindow title: releases.variant.statusString } StateChangeScript { script: { stackView.push("DownloadPage.qml") } } - 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 - } - } - } - 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) - } - } - } }, State { name: "restorePage" when: selectedPage == Units.Page.RestorePage - PropertyChanges { - target: mainWindow - title: qsTr("Restore") - } - PropertyChanges { - target: nextButton - visible: true - onClicked: { - if (lastRestoreable && lastRestoreable.restoreStatus == Units.RestoreStatus.Restored) - selectedPage = Units.Page.MainPage - else - drives.lastRestoreable.restore() - } - } PropertyChanges { - target: prevButton - visible: true - onClicked: selectedPage = Units.Page.MainPage + target: mainWindow + title: qsTr("Restore") } - StateChangeScript { + StateChangeScript { script: { stackView.push("RestorePage.qml") } } } ] } + Connections { + target: drives + function onLastRestoreableChanged() { + if (!drives.selected) + selectedPage = Units.Page.MainPage + } + } + Units { id: units } @@ -282,38 +164,5 @@ ApplicationWindow { CancelDialog { id: cancelDialog } - - - function getNextButtonText() { - if (mainLayout.state == "restorePage") { - if (lastRestoreable && lastRestoreable.restoreStatus == Units.RestoreStatus.Restored) - return qsTr("Finish") - return qsTr("Restore") - } else if (mainLayout.state == "drivePage") { - if (selectedOption == Units.MainSelect.Write || downloadManager.isDownloaded(releases.selected.version.variant.url)) - return qsTr("Write") - if (Qt.platform.os === "windows" || Qt.platform.os === "osx") - return qsTr("Download && Write") - return qsTr("Download & Write") - } else if (mainLayout.state == "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) - return qsTr("Cancel") - else if (releases.variant.status == Units.DownloadStatus.Ready) - return qsTr("Write") - else if (releases.variant.status === Units.DownloadStatus.Finished) - return qsTr("Finish") - else - return qsTr("Retry") - } - return qsTr("Next") - } - - function getPrevButtonText() { - if (mainLayout.state == "mainPage") - return qsTr("About") - else if (mainLayout.state == "downloadPage") - return qsTr("Cancel") - return qsTr("Previous") - } }