Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 47 additions & 21 deletions src/app/drivemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,27 @@ int DriveManager::length() const
return m_drives.count();
}

Drive *DriveManager::lastRestoreable()
int DriveManager::restoreableCount() const
{
return m_lastRestoreable;
return m_restoreableDrives.count();
}

QVariantList DriveManager::restoreableDrives() const
{
QVariantList list;
for (auto d : m_restoreableDrives) {
list.append(QVariant::fromValue(d));
}
return list;
}

Drive *DriveManager::restoreableDriveAt(int index) const
{
if (index >= 0 && index < m_restoreableDrives.count())
return m_restoreableDrives[index];
return nullptr;
}

bool DriveManager::isBackendBroken()
{
return !m_errorString.isEmpty();
Expand All @@ -136,14 +153,6 @@ QString DriveManager::errorString()
return m_errorString;
}

void DriveManager::setLastRestoreable(Drive *d)
{
if (m_lastRestoreable != d) {
m_lastRestoreable = d;
emit restoreableDriveChanged();
}
}

void DriveManager::onDriveConnected(Drive *d)
{
int position = 0;
Expand All @@ -165,13 +174,11 @@ void DriveManager::onDriveConnected(Drive *d)
emit selectedChanged();
}

if (d->restoreStatus() == Drive::CONTAINS_LIVE) {
setLastRestoreable(d);
connect(d, &Drive::restoreStatusChanged, [=]() {
if (d && d == m_lastRestoreable && d->restoreStatus() != Drive::CONTAINS_LIVE)
setLastRestoreable(nullptr);
});
}
// Connect to restoreStatus changes for updating the restorable list
connect(d, &Drive::restoreStatusChanged, this, &DriveManager::onDriveRestoreStatusChanged);

// Update restorable drives list
updateRestoreableDrives();
}

void DriveManager::onDriveRemoved(Drive *d)
Expand All @@ -186,11 +193,10 @@ void DriveManager::onDriveRemoved(Drive *d)
m_selectedIndex = 0;
}
emit selectedChanged();

if (d == m_lastRestoreable) {
setLastRestoreable(nullptr);
}
}

// Update restorable drives list
updateRestoreableDrives();
}

void DriveManager::onBackendBroken(const QString &message)
Expand All @@ -199,6 +205,26 @@ void DriveManager::onBackendBroken(const QString &message)
emit isBackendBrokenChanged();
}

void DriveManager::onDriveRestoreStatusChanged()
{
updateRestoreableDrives();
}

void DriveManager::updateRestoreableDrives()
{
QList<Drive *> newList;
for (auto d : m_drives) {
if (d->restoreStatus() == Drive::CONTAINS_LIVE) {
newList.append(d);
}
}

if (newList != m_restoreableDrives) {
m_restoreableDrives = newList;
emit restoreableDrivesChanged();
}
}

DriveProvider *DriveProvider::create(DriveManager *parent)
{
if (options.testing)
Expand Down
18 changes: 11 additions & 7 deletions src/app/drivemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <QAbstractListModel>
#include <QDebug>
#include <QVariantList>

#include "releasemanager.h"

Expand All @@ -40,7 +41,7 @@ class UdisksDrive;
* @property length count of the drives
* @property selected the selected drive
* @property selectedIndex the index of the selected drive
* @property lastRestoreable the most recently connected restoreable drive
* @property restoreableCount count of drives containing live USB
*/
class DriveManager : public QAbstractListModel
{
Expand All @@ -51,7 +52,8 @@ class DriveManager : public QAbstractListModel
Q_PROPERTY(bool isBroken READ isBackendBroken NOTIFY isBackendBrokenChanged)
Q_PROPERTY(QString errorString READ errorString NOTIFY isBackendBrokenChanged)

Q_PROPERTY(Drive *lastRestoreable READ lastRestoreable WRITE setLastRestoreable NOTIFY restoreableDriveChanged)
Q_PROPERTY(int restoreableCount READ restoreableCount NOTIFY restoreableDrivesChanged)
Q_PROPERTY(QVariantList restoreableDrives READ restoreableDrives NOTIFY restoreableDrivesChanged)
public:
static DriveManager *instance();

Expand All @@ -66,31 +68,33 @@ class DriveManager : public QAbstractListModel

int length() const;

Drive *lastRestoreable();
int restoreableCount() const;
QVariantList restoreableDrives() const;
Q_INVOKABLE Drive *restoreableDriveAt(int index) const;

bool isBackendBroken();
QString errorString();

void setLastRestoreable(Drive *d);

private slots:
void onDriveConnected(Drive *d);
void onDriveRemoved(Drive *d);
void onBackendBroken(const QString &message);
void onDriveRestoreStatusChanged();

signals:
void drivesChanged();
void selectedChanged();
void restoreableDriveChanged();
void restoreableDrivesChanged();
void isBackendBrokenChanged();

private:
explicit DriveManager(QObject *parent = 0);
void updateRestoreableDrives();

static DriveManager *_self;
QList<Drive *> m_drives{};
QList<Drive *> m_restoreableDrives{};
int m_selectedIndex{0};
Drive *m_lastRestoreable{nullptr};
DriveProvider *m_provider{nullptr};
QString m_errorString{};
};
Expand Down
15 changes: 10 additions & 5 deletions src/app/qml/MainPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,23 @@ Page {

QQC2.RadioButton {
id: restoreRadio
visible: drives.lastRestoreable
text: drives.lastRestoreable ? qsTr("Restore <b>%1</b>").arg(drives.lastRestoreable.name) : ""
visible: drives.restoreableCount
text: {
if (drives.restoreableCount === 1)
return qsTr("Restore <b>%1</b>").arg(drives.restoreableDriveAt(0).name)
else
return qsTr("Restore a USB drive (%1 available)").arg(drives.restoreableCount)
}
onClicked: {
selectedOption = Units.MainSelect.Restore
}

Connections {
target: drives
function onLastRestoreableChanged() {
if (drives.lastRestoreable != null && !restoreRadio.visible)
function onRestoreableDrivesChanged() {
if (drives.restoreableCount && !restoreRadio.visible)
restoreRadio.visible = true
if (!drives.lastRestoreable)
if (!drives.restoreableCount)
restoreRadio.visible = false
}
}
Expand Down
72 changes: 48 additions & 24 deletions src/app/qml/RestorePage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,36 @@ import QtQuick.Layouts 6.6
Page {
id: restorePage

text: qsTr("Restore Drive <b>%1</b>").arg(lastRestoreable.name)
property var selectedDrive: drives.restoreableCount > 0 ? drives.restoreableDriveAt(driveCombo.currentIndex) : null
property var restoringDrive: null

text: qsTr("Restore Drive <b>%1</b>").arg(restoringDrive ? restoringDrive.name : (selectedDrive ? selectedDrive.name : ""))
textLevel: 1

ColumnLayout {
id: driveSelectionColumn
visible: drives.restoreableCount > 0 && !restoringDrive
Layout.fillWidth: true

QQC2.Label {
text: qsTr("Select USB Drive to Restore:")
font.bold: true
}

QQC2.ComboBox {
id: driveCombo
Layout.fillWidth: true
model: drives.restoreableDrives
enabled: drives.restoreableCount > 0
visible: drives.restoreableCount > 0
currentIndex: 0
textRole: "name"
}
}

QQC2.Label {
id: warningText
visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Contains_Live
visible: selectedDrive && selectedDrive.restoreStatus == Units.RestoreStatus.Contains_Live && !restoringDrive
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("<p align=\"justify\"> 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.</p> <p align=\"justify\"> You don't need to restore the drive if you want to write another live system to it.</p> <p align=\"justify\"> Do you want to restore it to factory settings? </p>" )
Expand All @@ -40,7 +64,7 @@ Page {

ColumnLayout {
id: progress
visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Restoring
visible: restoringDrive && restoringDrive.restoreStatus == Units.RestoreStatus.Restoring

Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Expand All @@ -63,7 +87,7 @@ Page {

QQC2.Label {
id: restoredText
visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Restored
visible: restoringDrive && restoringDrive.restoreStatus == Units.RestoreStatus.Restored
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("Your drive was successfully restored!")
Expand All @@ -72,47 +96,47 @@ Page {

QQC2.Label {
id: errorText
visible: lastRestoreable.restoreStatus == Units.RestoreStatus.Restore_Error
visible: restoringDrive && restoringDrive.restoreStatus == Units.RestoreStatus.Restore_Error
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("Unfortunately, an error occurred during the process. Please try restoring the drive using your system tools.")
wrapMode: QQC2.Label.Wrap
}

Component.onCompleted: {
lastRestoreable = drives.lastRestoreable
}


states: [
State {
name: "restored"
when: lastRestoreable.restoreStatus == Units.RestoreStatus.Restored
when: restoringDrive && restoringDrive.restoreStatus == Units.RestoreStatus.Restored
PropertyChanges {
target: mainWindow;
title: qsTr("Restoring finished")
}
StateChangeScript {
script: drives.lastRestoreable = null
}
}
]

previousButtonEnabled: lastRestoreable.restoreStatus != Units.RestoreStatus.Restored &&
lastRestoreable.restoreStatus != Units.RestoreStatus.Restoring
previousButtonEnabled: !restoringDrive || (restoringDrive.restoreStatus != Units.RestoreStatus.Restoring && restoringDrive.restoreStatus != Units.RestoreStatus.Restored)
previousButtonVisible: previousButtonEnabled
onPreviousButtonClicked: {
restoringDrive = null
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")
nextButtonEnabled: {
if (restoringDrive) {
return restoringDrive.restoreStatus == Units.RestoreStatus.Restored ||
restoringDrive.restoreStatus == Units.RestoreStatus.Restore_Error
}
return selectedDrive && selectedDrive.restoreStatus == Units.RestoreStatus.Contains_Live
}
nextButtonVisible: !restoringDrive || restoringDrive.restoreStatus != Units.RestoreStatus.Restoring
nextButtonText: restoringDrive && (restoringDrive.restoreStatus == Units.RestoreStatus.Restored || restoringDrive.restoreStatus == Units.RestoreStatus.Restore_Error) ? qsTr("Finish") : qsTr("Restore")
onNextButtonClicked: {
if (lastRestoreable.restoreStatus == Units.RestoreStatus.Restored)
if (restoringDrive && (restoringDrive.restoreStatus == Units.RestoreStatus.Restored || restoringDrive.restoreStatus == Units.RestoreStatus.Restore_Error)) {
restoringDrive = null
selectedPage = Units.Page.MainPage
else
drives.lastRestoreable.restore()
} else if (selectedDrive) {
restoringDrive = selectedDrive
restoringDrive.restore()
}
}

}
9 changes: 0 additions & 9 deletions src/app/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ ApplicationWindow {
property int selectedPage: Units.Page.MainPage
property int selectedVersion: Units.Source.Product
property int selectedOption: Units.MainSelect.Download
property QtObject lastRestoreable
property bool eraseVariant: false

StackView {
Expand Down Expand Up @@ -144,14 +143,6 @@ ApplicationWindow {
}
]
}

Connections {
target: drives
function onLastRestoreableChanged() {
if (!drives.selected)
selectedPage = Units.Page.MainPage
}
}

Units {
id: units
Expand Down