diff --git a/src/modules/partition/CreatePartitionDialog.cpp b/src/modules/partition/CreatePartitionDialog.cpp index 6ffb5b8c7..a4abfbcfe 100644 --- a/src/modules/partition/CreatePartitionDialog.cpp +++ b/src/modules/partition/CreatePartitionDialog.cpp @@ -88,8 +88,8 @@ CreatePartitionDialog::CreatePartitionDialog( Device* device, PartitionNode* par CreatePartitionDialog::~CreatePartitionDialog() {} -PartitionInfo* -CreatePartitionDialog::createPartitionInfo() +Partition* +CreatePartitionDialog::createPartition() { if ( m_role.roles() == PartitionRole::None ) { @@ -138,10 +138,9 @@ CreatePartitionDialog::createPartitionInfo() Partition::StateNew ); - auto info = new PartitionInfo( partition ); PartitionInfo::setMountPoint( partition, m_ui->mountPointComboBox->currentText() ); PartitionInfo::setFormat( partition, true ); - return info; + return partition; } void @@ -175,10 +174,9 @@ CreatePartitionDialog::initFromFreeSpace( Partition* freeSpacePartition ) } void -CreatePartitionDialog::initFromPartitionInfo( PartitionInfo* partitionInfo ) +CreatePartitionDialog::initFromPartitionToCreate( Partition* partition ) { - Q_ASSERT( partitionInfo ); - Partition* partition = partitionInfo->partition; + Q_ASSERT( partition ); bool isExtended = partition->roles().has( PartitionRole::Extended ); Q_ASSERT( !isExtended ); diff --git a/src/modules/partition/CreatePartitionDialog.h b/src/modules/partition/CreatePartitionDialog.h index dd700f558..4ed8740ac 100644 --- a/src/modules/partition/CreatePartitionDialog.h +++ b/src/modules/partition/CreatePartitionDialog.h @@ -28,7 +28,6 @@ class Device; class Partition; class PartitionNode; -class PartitionInfo; class Ui_CreatePartitionDialog; class CreatePartitionDialog : public QDialog @@ -39,8 +38,8 @@ public: ~CreatePartitionDialog(); void initFromFreeSpace( Partition* partition ); - void initFromPartitionInfo( PartitionInfo* partitionInfo ); - PartitionInfo* createPartitionInfo(); + void initFromPartitionToCreate( Partition* partition ); + Partition* createPartition(); private Q_SLOTS: void updateMountPointUi(); diff --git a/src/modules/partition/PartitionCoreModule.cpp b/src/modules/partition/PartitionCoreModule.cpp index 8f12b8a91..48dfd4e44 100644 --- a/src/modules/partition/PartitionCoreModule.cpp +++ b/src/modules/partition/PartitionCoreModule.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,80 @@ #include #include +class PartitionIterator +{ +public: + Partition* operator*() const + { + return m_current; + } + + void operator++() + { + if ( !m_current ) + return; + if ( m_current->hasChildren() ) + { + // Go to the first child + m_current = static_cast< Partition* >( m_current->children().first() ); + return; + } + PartitionNode* parent = m_current->parent(); + Partition* successor = parent->successor( *m_current ); + if ( successor ) + { + // Go to the next sibling + m_current = successor; + return; + } + if ( parent->isRoot() ) + { + // We reached the end + m_current = nullptr; + return; + } + // Try to go to the next sibling of our parent + + PartitionNode* grandParent = parent->parent(); + Q_ASSERT( grandParent ); + // If parent is not root, then it's not a PartitionTable but a + // Partition, we can static_cast it. + m_current = grandParent->successor( *static_cast< Partition* >( parent ) ); + } + + bool operator==( const PartitionIterator& other ) const + { + return m_device == other.m_device && m_current == other.m_current; + } + + bool operator!=( const PartitionIterator& other ) const + { + return ! ( *this == other ); + } + + static PartitionIterator begin( Device* device ) + { + auto it = PartitionIterator( device ); + PartitionTable* table = device->partitionTable(); + if ( !table ) + return it; + it.m_current = table->children().first(); + return it; + } + + static PartitionIterator end( Device* device ) + { + return PartitionIterator( device ); + } + +private: + PartitionIterator( Device* device ) + : m_device( device ) + {} + + Device* m_device; + Partition* m_current = nullptr; +}; //- DeviceInfo --------------------------------------------- PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device ) @@ -43,37 +118,14 @@ PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device ) PartitionCoreModule::DeviceInfo::~DeviceInfo() { - qDeleteAll( m_partitionInfoHash ); -} - -PartitionInfo* -PartitionCoreModule::DeviceInfo::infoForPartition( Partition* partition ) const -{ - return m_partitionInfoHash.value( partition ); -} - -bool -PartitionCoreModule::DeviceInfo::addInfoForPartition( PartitionInfo* partitionInfo ) -{ - Q_ASSERT( partitionInfo ); - if ( infoForPartition( partitionInfo->partition ) ) - return false; - m_partitionInfoHash.insert( partitionInfo->partition, partitionInfo ); - return true; -} - -void -PartitionCoreModule::DeviceInfo::removeInfoForPartition( Partition* partition ) -{ - m_partitionInfoHash.remove( partition ); } bool PartitionCoreModule::DeviceInfo::hasRootMountPoint() const { - for ( auto info : m_partitionInfoHash ) + for ( auto it = PartitionIterator::begin( device.data() ); it != PartitionIterator::end( device.data() ); ++it) { - if ( PartitionInfo::mountPoint( info->partition ) == "/" ) + if ( PartitionInfo::mountPoint( *it ) == "/" ) return true; } return false; @@ -83,8 +135,10 @@ void PartitionCoreModule::DeviceInfo::forgetChanges() { jobs.clear(); - qDeleteAll( m_partitionInfoHash ); - m_partitionInfoHash.clear(); + for ( auto it = PartitionIterator::begin( device.data() ); it != PartitionIterator::end( device.data() ); ++it) + { + PartitionInfo::reset( *it ); + } } //- PartitionCoreModule ------------------------------------ @@ -103,7 +157,7 @@ PartitionCoreModule::PartitionCoreModule( QObject* parent ) auto deviceInfo = new DeviceInfo( device ); m_deviceInfos << deviceInfo; - deviceInfo->partitionModel->init( device, deviceInfo ); + deviceInfo->partitionModel->init( device ); } m_deviceModel->init( devices ); @@ -145,17 +199,11 @@ PartitionCoreModule::createPartitionTable( Device* device, PartitionTable::Table } void -PartitionCoreModule::createPartition( Device* device, PartitionInfo* partitionInfo ) +PartitionCoreModule::createPartition( Device* device, Partition* partition ) { auto deviceInfo = infoForDevice( device ); Q_ASSERT( deviceInfo ); - if ( !deviceInfo->addInfoForPartition( partitionInfo ) ) - { - cDebug() << "Adding partition failed, there is already a PartitionInfo instance for it"; - return; - } - auto partition = partitionInfo->partition; CreatePartitionJob* job = new CreatePartitionJob( device, partition ); job->updatePreview(); @@ -171,7 +219,6 @@ PartitionCoreModule::deletePartition( Device* device, Partition* partition ) { auto deviceInfo = infoForDevice( device ); Q_ASSERT( deviceInfo ); - deviceInfo->removeInfoForPartition( partition ); QList< Calamares::job_ptr >& jobs = deviceInfo->jobs; diff --git a/src/modules/partition/PartitionCoreModule.h b/src/modules/partition/PartitionCoreModule.h index 4f07e4cd4..bbdf6d536 100644 --- a/src/modules/partition/PartitionCoreModule.h +++ b/src/modules/partition/PartitionCoreModule.h @@ -19,7 +19,6 @@ #ifndef PARTITIONCOREMODULE_H #define PARTITIONCOREMODULE_H -#include #include #include @@ -55,7 +54,7 @@ public: /** * Takes ownership of partitionInfo */ - void createPartition( Device* device, PartitionInfo* partitionInfo ); + void createPartition( Device* device, Partition* partition ); void deletePartition( Device* device, Partition* partition ); @@ -71,10 +70,9 @@ Q_SIGNALS: private: /** - * Owns the Device, PartitionModel and all attached PartitionInfo instances. - * Implements the PartitionInfoProvider interface. + * Owns the Device, PartitionModel and the jobs */ - struct DeviceInfo : public PartitionInfoProvider + struct DeviceInfo { DeviceInfo( Device* ); ~DeviceInfo(); @@ -82,20 +80,9 @@ private: QScopedPointer< PartitionModel > partitionModel; QList< Calamares::job_ptr > jobs; - PartitionInfo* infoForPartition( Partition* partition ) const override; - - /** - * Returns false if there was already a PartitionInfo for this partition - */ - bool addInfoForPartition( PartitionInfo* partitionInfo ); - - void removeInfoForPartition( Partition* partition ); - bool hasRootMountPoint() const; void forgetChanges(); - private: - QHash< Partition*, PartitionInfo* > m_partitionInfoHash; }; QList< DeviceInfo* > m_deviceInfos; diff --git a/src/modules/partition/PartitionInfo.cpp b/src/modules/partition/PartitionInfo.cpp index 99f5d3281..f38c0457f 100644 --- a/src/modules/partition/PartitionInfo.cpp +++ b/src/modules/partition/PartitionInfo.cpp @@ -23,33 +23,41 @@ // Qt #include +namespace PartitionInfo +{ + static const char* MOUNT_POINT_PROPERTY = "_calamares_mountPoint"; static const char* FORMAT_PROPERTY = "_calamares_format"; -PartitionInfo::PartitionInfo( Partition* p ) - : partition( p ) -{} - QString -PartitionInfo::mountPoint( Partition* partition ) +mountPoint( Partition* partition ) { return partition->property( MOUNT_POINT_PROPERTY ).toString(); } void -PartitionInfo::setMountPoint( Partition* partition, const QString& value ) +setMountPoint( Partition* partition, const QString& value ) { partition->setProperty( MOUNT_POINT_PROPERTY, value ); } bool -PartitionInfo::format( Partition* partition ) +format( Partition* partition ) { return partition->property( FORMAT_PROPERTY ).toBool(); } void -PartitionInfo::setFormat( Partition* partition, bool value ) +setFormat( Partition* partition, bool value ) { partition->setProperty( FORMAT_PROPERTY, value ); } + +void +reset( Partition* partition ) +{ + partition->setProperty( MOUNT_POINT_PROPERTY, QVariant() ); + partition->setProperty( FORMAT_PROPERTY, QVariant() ); +} + +} // namespace diff --git a/src/modules/partition/PartitionInfo.h b/src/modules/partition/PartitionInfo.h index 1f747dd30..6b2da192a 100644 --- a/src/modules/partition/PartitionInfo.h +++ b/src/modules/partition/PartitionInfo.h @@ -24,19 +24,20 @@ class Partition; /** - * Stores Calamares-specific info about a partition. - * Does not own anything. + * Functions to store Calamares-specific info in the Qt properties of a + * Partition object. */ -struct PartitionInfo +namespace PartitionInfo { - explicit PartitionInfo( Partition* ); - Partition* partition; - static QString mountPoint( Partition* partition ); - static void setMountPoint( Partition* partition, const QString& value ); +QString mountPoint( Partition* partition ); +void setMountPoint( Partition* partition, const QString& value ); + +bool format( Partition* partition ); +void setFormat( Partition* partition, bool value ); + +void reset( Partition* partition ); - static bool format( Partition* partition ); - static void setFormat( Partition* partition, bool value ); }; #endif /* PARTITIONINFO_H */ diff --git a/src/modules/partition/PartitionModel.cpp b/src/modules/partition/PartitionModel.cpp index f8b5cc0eb..972bb72a9 100644 --- a/src/modules/partition/PartitionModel.cpp +++ b/src/modules/partition/PartitionModel.cpp @@ -30,19 +30,15 @@ // KF5 #include -PartitionInfoProvider::~PartitionInfoProvider() -{} - PartitionModel::PartitionModel( QObject* parent ) : QAbstractListModel( parent ) { } void -PartitionModel::init( Device* device, PartitionInfoProvider* infoProvider ) +PartitionModel::init( Device* device ) { m_device = device; - m_infoProvider = infoProvider; reload(); } @@ -134,12 +130,3 @@ PartitionModel::partitionForIndex( const QModelIndex& index ) const return nullptr; return m_partitionList.at( row ); } - -PartitionInfo* -PartitionModel::partitionInfoForIndex( const QModelIndex& index ) const -{ - Partition* partition = partitionForIndex( index ); - if ( !partition ) - return nullptr; - return m_infoProvider->infoForPartition( partition ); -} diff --git a/src/modules/partition/PartitionModel.h b/src/modules/partition/PartitionModel.h index 6abccae72..d46ac1c82 100644 --- a/src/modules/partition/PartitionModel.h +++ b/src/modules/partition/PartitionModel.h @@ -18,23 +18,13 @@ #ifndef PARTITIONMODEL_H #define PARTITIONMODEL_H -#include - // Qt #include class Device; class Partition; -class PartitionInfo; class PartitionNode; -class PartitionInfoProvider -{ -public: - virtual ~PartitionInfoProvider(); - virtual PartitionInfo* infoForPartition( Partition* partition ) const = 0; -}; - class PartitionModel : public QAbstractListModel { public: @@ -49,17 +39,15 @@ public: PartitionModel( QObject* parent = 0 ); /** - * device and infoForPartitions must remain alive for the life of - * PartitionModel + * device must remain alive for the life of PartitionModel */ - void init( Device* device, PartitionInfoProvider* infoProvider ); + void init( Device* device ); int columnCount( const QModelIndex& parent = QModelIndex() ) const override; int rowCount( const QModelIndex& parent = QModelIndex() ) const override; QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; Partition* partitionForIndex( const QModelIndex& index ) const; - PartitionInfo* partitionInfoForIndex( const QModelIndex& index ) const; Device* device() const { @@ -73,7 +61,6 @@ public: private: Device* m_device; - PartitionInfoProvider* m_infoProvider; QList< Partition* > m_partitionList; void fillPartitionList( PartitionNode* parent ); diff --git a/src/modules/partition/PartitionPage.cpp b/src/modules/partition/PartitionPage.cpp index 3b74fc947..c4f71474b 100644 --- a/src/modules/partition/PartitionPage.cpp +++ b/src/modules/partition/PartitionPage.cpp @@ -146,7 +146,7 @@ PartitionPage::onCreateClicked() QPointer dlg = new CreatePartitionDialog( model->device(), partition->parent(), this ); dlg->initFromFreeSpace( partition ); if ( dlg->exec() == QDialog::Accepted ) - m_core->createPartition( model->device(), dlg->createPartitionInfo() ); + m_core->createPartition( model->device(), dlg->createPartition() ); delete dlg; } @@ -158,11 +158,10 @@ PartitionPage::onEditClicked() const PartitionModel* model = static_cast< const PartitionModel* >( index.model() ); Partition* partition = model->partitionForIndex( index ); - PartitionInfo* partitionInfo = model->partitionInfoForIndex( index ); Q_ASSERT( partition ); - if ( PMUtils::isPartitionNew( partitionInfo->partition ) ) - updatePartitionToCreate( model->device(), partitionInfo ); + if ( PMUtils::isPartitionNew( partition ) ) + updatePartitionToCreate( model->device(), partition ); else editExistingPartition( partition ); } @@ -181,15 +180,14 @@ PartitionPage::onDeleteClicked() } void -PartitionPage::updatePartitionToCreate( Device* device, PartitionInfo* partitionInfo ) +PartitionPage::updatePartitionToCreate( Device* device, Partition* partition ) { - Partition* partition = partitionInfo->partition; QPointer dlg = new CreatePartitionDialog( device, partition->parent(), this ); - dlg->initFromPartitionInfo( partitionInfo ); + dlg->initFromPartitionToCreate( partition ); if ( dlg->exec() == QDialog::Accepted ) { m_core->deletePartition( device, partition ); - m_core->createPartition( device, dlg->createPartitionInfo() ); + m_core->createPartition( device, dlg->createPartition() ); } delete dlg; } diff --git a/src/modules/partition/PartitionPage.h b/src/modules/partition/PartitionPage.h index ac9634694..d4741a5ea 100644 --- a/src/modules/partition/PartitionPage.h +++ b/src/modules/partition/PartitionPage.h @@ -28,7 +28,6 @@ class Ui_PartitionPage; class Device; class DeviceModel; class Partition; -class PartitionInfo; class PartitionPage : public QWidget { @@ -50,7 +49,7 @@ private: void onEditClicked(); void onDeleteClicked(); - void updatePartitionToCreate( Device*, PartitionInfo* ); + void updatePartitionToCreate( Device*, Partition* ); void editExistingPartition( Partition* ); };