From ab4604258c33f59a1665e7175d2c2500342d7825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20G=C3=A2teau?= Date: Wed, 23 Jul 2014 18:14:27 +0200 Subject: [PATCH] Rework boot loader combo box List MBR of all devices Does not loose its selection when updated --- src/modules/partition/BootLoaderModel.cpp | 104 ++++++++++++++++++ src/modules/partition/BootLoaderModel.h | 56 ++++++++++ src/modules/partition/CMakeLists.txt | 1 + src/modules/partition/PMUtils.cpp | 13 +++ src/modules/partition/PMUtils.h | 6 + src/modules/partition/PartitionCoreModule.cpp | 44 +------- src/modules/partition/PartitionCoreModule.h | 8 +- src/modules/partition/tests/CMakeLists.txt | 2 + 8 files changed, 188 insertions(+), 46 deletions(-) create mode 100644 src/modules/partition/BootLoaderModel.cpp create mode 100644 src/modules/partition/BootLoaderModel.h diff --git a/src/modules/partition/BootLoaderModel.cpp b/src/modules/partition/BootLoaderModel.cpp new file mode 100644 index 000000000..479e1751f --- /dev/null +++ b/src/modules/partition/BootLoaderModel.cpp @@ -0,0 +1,104 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Aurélien Gâteau + * + * Calamares 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 3 of the License, or + * (at your option) any later version. + * + * Calamares 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 Calamares. If not, see . + */ +#include + +#include +#include + +// CalaPM +#include + +static QStandardItem* +createBootLoaderItem( const QString& description, const QString& path, bool isPartition ) +{ + QStandardItem* item = new QStandardItem( description ); + item->setData( path, BootLoaderModel::BootLoaderPathRole ); + item->setData( isPartition, BootLoaderModel::IsPartitionRole ); + return item; +} + +BootLoaderModel::BootLoaderModel( QObject* parent ) + : QStandardItemModel( parent ) +{ +} + +BootLoaderModel::~BootLoaderModel() +{ +} + +void +BootLoaderModel::init( const QList< Device* >& devices ) +{ + m_devices = devices; + clear(); + createMbrItems(); +} + +void +BootLoaderModel::createMbrItems() +{ + for( auto device : m_devices ) + { + QString text = tr( "Master Boot Record of %1" ) + .arg( device->name() ); + appendRow( + createBootLoaderItem( text, device->deviceNode(), false ) + ); + } +} + +void +BootLoaderModel::update() +{ + QString partitionText; + Partition* partition = PMUtils::findPartitionByMountPoint( m_devices, "/boot" ); + if ( partition ) + partitionText = tr( "Boot Partition" ); + else + { + partition = PMUtils::findPartitionByMountPoint( m_devices, "/" ); + if ( partition ) + partitionText = tr( "System Partition" ); + } + + Q_ASSERT( rowCount() > 0 ); + QStandardItem* last = item( rowCount() - 1 ); + Q_ASSERT( last ); + bool lastIsPartition = last->data( IsPartitionRole ).toBool(); + + if ( !partition ) + { + if ( lastIsPartition ) + takeRow( rowCount() - 1 ); + return; + } + + QString mountPoint = PartitionInfo::mountPoint( partition ); + if ( lastIsPartition ) + { + last->setText( partitionText ); + last->setData( mountPoint, BootLoaderPathRole ); + } + else + { + appendRow( + createBootLoaderItem( partitionText, PartitionInfo::mountPoint( partition ), true ) + ); + } +} + diff --git a/src/modules/partition/BootLoaderModel.h b/src/modules/partition/BootLoaderModel.h new file mode 100644 index 000000000..7142c9e5b --- /dev/null +++ b/src/modules/partition/BootLoaderModel.h @@ -0,0 +1,56 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Aurélien Gâteau + * + * Calamares 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 3 of the License, or + * (at your option) any later version. + * + * Calamares 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 Calamares. If not, see . + */ +#ifndef BOOTLOADERMODEL_H +#define BOOTLOADERMODEL_H + +#include +#include + +class Device; + +/** + * This model contains one entry for each device MBR plus one entry for the + * /boot or / partition + */ +class BootLoaderModel : public QStandardItemModel +{ +public: + enum + { + BootLoaderPathRole = Qt::UserRole + 1, + IsPartitionRole + }; + + BootLoaderModel( QObject* parent = 0 ); + ~BootLoaderModel(); + + /** + * Init the model with the list of devices. Does *not* take ownership of the + * devices. + */ + void init( const QList< Device* >& devices ); + + void update(); + +private: + QList< Device* > m_devices; + + void createMbrItems(); +}; + +#endif /* BOOTLOADERMODEL_H */ diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 6ebe64cc8..984e23ce3 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -22,6 +22,7 @@ calamares_add_plugin( partition EXPORT_MACRO PLUGINDLLEXPORT_PRO CONFIG_FILE module.conf SOURCES + BootLoaderModel.cpp CreatePartitionDialog.cpp CreatePartitionJob.cpp CreatePartitionTableJob.cpp diff --git a/src/modules/partition/PMUtils.cpp b/src/modules/partition/PMUtils.cpp index 49433a9f0..1f0997f14 100644 --- a/src/modules/partition/PMUtils.cpp +++ b/src/modules/partition/PMUtils.cpp @@ -18,6 +18,9 @@ #include +#include +#include + // CalaPM #include #include @@ -35,4 +38,14 @@ bool isPartitionNew( Partition* partition ) return partition->state() == Partition::StateNew; } +Partition* +findPartitionByMountPoint( const QList< Device* >& devices, const QString& mountPoint ) +{ + for ( auto device : devices ) + for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it ) + if ( PartitionInfo::mountPoint( *it ) == mountPoint ) + return *it; + return nullptr; +} + } // namespace diff --git a/src/modules/partition/PMUtils.h b/src/modules/partition/PMUtils.h index 2b0f42237..09112363d 100644 --- a/src/modules/partition/PMUtils.h +++ b/src/modules/partition/PMUtils.h @@ -18,6 +18,10 @@ #ifndef PMUTILS_H #define PMUTILS_H +// Qt +#include + +class Device; class Partition; namespace PMUtils @@ -27,6 +31,8 @@ bool isPartitionFreeSpace( Partition* ); bool isPartitionNew( Partition* ); +Partition* findPartitionByMountPoint( const QList< Device* >& devices, const QString& mountPoint ); + } #endif /* PMUTILS_H */ diff --git a/src/modules/partition/PartitionCoreModule.cpp b/src/modules/partition/PartitionCoreModule.cpp index 9b01b6b0b..151b2fbd6 100644 --- a/src/modules/partition/PartitionCoreModule.cpp +++ b/src/modules/partition/PartitionCoreModule.cpp @@ -18,6 +18,7 @@ #include +#include #include #include #include @@ -63,7 +64,7 @@ PartitionCoreModule::DeviceInfo::forgetChanges() PartitionCoreModule::PartitionCoreModule( QObject* parent ) : QObject( parent ) , m_deviceModel( new DeviceModel( this ) ) - , m_bootLoaderModel( new QStandardItemModel( this ) ) + , m_bootLoaderModel( new BootLoaderModel( this ) ) { // FIXME: Should be done at startup if ( !CalaPM::init() ) @@ -80,6 +81,7 @@ PartitionCoreModule::PartitionCoreModule( QObject* parent ) } m_deviceModel->init( devices ); + m_bootLoaderModel->init( devices ); } PartitionCoreModule::~PartitionCoreModule() @@ -246,7 +248,7 @@ PartitionCoreModule::refresh( Device* device ) Q_ASSERT( model ); model->reload(); updateHasRootMountPoint(); - updateBootLoaderModel(); + m_bootLoaderModel->update(); } void PartitionCoreModule::updateHasRootMountPoint() @@ -269,44 +271,6 @@ PartitionCoreModule::infoForDevice( Device* device ) const return nullptr; } -static QStandardItem* -createBootLoaderItem( const QString& description, const QString& path ) -{ - QString text = PartitionCoreModule::tr( "%1 (%2)" ) - .arg( description ) - .arg( path ); - QStandardItem* item = new QStandardItem( text ); - item->setData( path, PartitionCoreModule::BootLoaderPathRole ); - return item; -} - -void -PartitionCoreModule::updateBootLoaderModel() -{ - m_bootLoaderModel->clear(); - // Can contain up to 2 entries: - // - MBR of disk which contains /boot or / - // - /boot or / partition - QString partitionText; - Partition* partition = findPartitionByMountPoint( "/boot" ); - if ( partition ) - partitionText = tr( "Boot Partition" ); - else - { - partition = findPartitionByMountPoint( "/" ); - if ( partition ) - partitionText = tr( "System Partition" ); - else - return; - } - m_bootLoaderModel->appendRow( - createBootLoaderItem( tr( "Master Boot Record" ), partition->devicePath() ) - ); - m_bootLoaderModel->appendRow( - createBootLoaderItem( partitionText, partition->partitionPath() ) - ); -} - Partition* PartitionCoreModule::findPartitionByMountPoint( const QString& mountPoint ) const { diff --git a/src/modules/partition/PartitionCoreModule.h b/src/modules/partition/PartitionCoreModule.h index 8e1a891a1..51d6160ba 100644 --- a/src/modules/partition/PartitionCoreModule.h +++ b/src/modules/partition/PartitionCoreModule.h @@ -29,6 +29,7 @@ #include #include +class BootLoaderModel; class CreatePartitionJob; class Device; class DeviceModel; @@ -44,11 +45,6 @@ class PartitionCoreModule : public QObject { Q_OBJECT public: - enum - { - BootLoaderPathRole = Qt::UserRole + 1 - }; - PartitionCoreModule( QObject* parent = nullptr ); ~PartitionCoreModule(); @@ -95,7 +91,7 @@ private: QList< DeviceInfo* > m_deviceInfos; DeviceModel* m_deviceModel; - QStandardItemModel* m_bootLoaderModel; + BootLoaderModel* m_bootLoaderModel; bool m_hasRootMountPoint = false; void listDevices(); diff --git a/src/modules/partition/tests/CMakeLists.txt b/src/modules/partition/tests/CMakeLists.txt index c533a6095..9b0c54767 100644 --- a/src/modules/partition/tests/CMakeLists.txt +++ b/src/modules/partition/tests/CMakeLists.txt @@ -5,6 +5,8 @@ set( jobtests_SRCS ${PartitionModule_SOURCE_DIR}/CreatePartitionJob.cpp ${PartitionModule_SOURCE_DIR}/CreatePartitionTableJob.cpp ${PartitionModule_SOURCE_DIR}/DeletePartitionJob.cpp + ${PartitionModule_SOURCE_DIR}/PartitionInfo.cpp + ${PartitionModule_SOURCE_DIR}/PartitionIterator.cpp ${PartitionModule_SOURCE_DIR}/PartitionJob.cpp ${PartitionModule_SOURCE_DIR}/PMUtils.cpp JobTests.cpp