From 83a56a6bd38b92cef8ad3164b7523fde2d9a5490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20G=C3=A2teau?= Date: Thu, 10 Jul 2014 19:55:16 +0200 Subject: [PATCH] Add the ability to (re)create partition tables --- src/modules/partition/CMakeLists.txt | 2 + .../partition/CreatePartitionTableJob.cpp | 96 +++++++++++++++++++ .../partition/CreatePartitionTableJob.h | 46 +++++++++ src/modules/partition/PartitionCoreModule.cpp | 14 +++ src/modules/partition/PartitionCoreModule.h | 2 + src/modules/partition/PartitionPage.cpp | 30 ++++++ src/modules/partition/PartitionPage.h | 1 + src/modules/partition/PartitionPage.ui | 9 +- 8 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/modules/partition/CreatePartitionTableJob.cpp create mode 100644 src/modules/partition/CreatePartitionTableJob.h diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 448179002..7b96fbe31 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -18,6 +18,7 @@ calamares_add_plugin( partition SOURCES CreatePartitionDialog.cpp CreatePartitionJob.cpp + CreatePartitionTableJob.cpp DeletePartitionJob.cpp DeviceModel.cpp PartitionCoreModule.cpp @@ -40,6 +41,7 @@ calamares_add_plugin( partition set( partview_SRCS CreatePartitionDialog.cpp CreatePartitionJob.cpp + CreatePartitionTableJob.cpp DeletePartitionJob.cpp DeviceModel.cpp PartitionCoreModule.cpp diff --git a/src/modules/partition/CreatePartitionTableJob.cpp b/src/modules/partition/CreatePartitionTableJob.cpp new file mode 100644 index 000000000..b3aea3b6c --- /dev/null +++ b/src/modules/partition/CreatePartitionTableJob.cpp @@ -0,0 +1,96 @@ +/* === 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 + +// CalaPM +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qt +#include + +CreatePartitionTableJob::CreatePartitionTableJob( Device* device ) + : m_device( device ) +{ +} + +QString +CreatePartitionTableJob::prettyName() const +{ + return tr( "Create partition table" ); // FIXME +} + +Calamares::JobResult +CreatePartitionTableJob::exec() +{ + Report report( 0 ); + QString message = tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() ); + + CoreBackend* backend = CoreBackendManager::self()->backend(); + QScopedPointer< CoreBackendDevice > backendDevice( backend->openDevice( m_device->deviceNode() ) ); + if ( !backendDevice.data() ) + { + return Calamares::JobResult::error( + message, + tr( "Could not open device %1." ).arg( m_device->deviceNode() ) + ); + } + + QScopedPointer< PartitionTable > table( createTable() ); + bool ok = backendDevice->createPartitionTable( report, *table ); + if ( !ok ) + { + return Calamares::JobResult::error( + message, + report.toText() + ); + } + + return Calamares::JobResult::ok(); +} + +void +CreatePartitionTableJob::updatePreview() +{ + // Device takes ownership of its table, but does not destroy the current + // one when setPartitionTable() is called, so do it ourself + delete m_device->partitionTable(); + m_device->setPartitionTable( createTable() ); + m_device->partitionTable()->updateUnallocated( *m_device ); +} + +PartitionTable* +CreatePartitionTableJob::createTable() +{ + PartitionTable::TableType type = PartitionTable::msdos; + return new PartitionTable(type, + PartitionTable::defaultFirstUsable( *m_device, type ), + PartitionTable::defaultLastUsable( *m_device, type ) + ); +} diff --git a/src/modules/partition/CreatePartitionTableJob.h b/src/modules/partition/CreatePartitionTableJob.h new file mode 100644 index 000000000..50eb9727a --- /dev/null +++ b/src/modules/partition/CreatePartitionTableJob.h @@ -0,0 +1,46 @@ +/* === 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 CREATEPARTITIONTABLEJOB_H +#define CREATEPARTITIONTABLEJOB_H + +#include + +class Device; +class PartitionTable; + +class CreatePartitionTableJob : public Calamares::Job +{ + Q_OBJECT +public: + CreatePartitionTableJob( Device* device ); + QString prettyName() const override; + Calamares::JobResult exec() override; + + void updatePreview(); + Device* device() const + { + return m_device; + } + +private: + Device* m_device; + PartitionTable* createTable(); +}; + +#endif /* CREATEPARTITIONTABLEJOB_H */ diff --git a/src/modules/partition/PartitionCoreModule.cpp b/src/modules/partition/PartitionCoreModule.cpp index 23411c19d..9df844297 100644 --- a/src/modules/partition/PartitionCoreModule.cpp +++ b/src/modules/partition/PartitionCoreModule.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -73,6 +74,19 @@ PartitionCoreModule::partitionModelForDevice( Device* device ) const return m_partitionModelForDeviceHash[ device ]; } +void +PartitionCoreModule::createPartitionTable( Device* device ) +{ + CreatePartitionTableJob* job = new CreatePartitionTableJob( device ); + job->updatePreview(); + refreshPartitionModel( device ); + + // FIXME: Remove all jobs queued for this device, as well as all partition + // info + m_jobs << Calamares::job_ptr( job ); + updateHasRootMountPoint(); +} + void PartitionCoreModule::createPartition( Device* device, PartitionInfo* partitionInfo ) { diff --git a/src/modules/partition/PartitionCoreModule.h b/src/modules/partition/PartitionCoreModule.h index 61b27bd36..42cd68735 100644 --- a/src/modules/partition/PartitionCoreModule.h +++ b/src/modules/partition/PartitionCoreModule.h @@ -50,6 +50,8 @@ public: PartitionModel* partitionModelForDevice( Device* device ) const; + void createPartitionTable( Device* device ); + void createPartition( Device* device, PartitionInfo* partitionInfo ); void deletePartition( Device* device, Partition* partition ); diff --git a/src/modules/partition/PartitionPage.cpp b/src/modules/partition/PartitionPage.cpp index ea6a66efe..ace979f8b 100644 --- a/src/modules/partition/PartitionPage.cpp +++ b/src/modules/partition/PartitionPage.cpp @@ -26,10 +26,14 @@ #include #include +// CalaPM +#include + // Qt #include #include #include +#include #include PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent ) @@ -65,6 +69,7 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent ) connect( model, &QAbstractItemModel::modelReset, this, &PartitionPage::updateButtons ); } ); + connect( m_ui->newPartitionTableButton, &QAbstractButton::clicked, this, &PartitionPage::onNewPartitionTableClicked ); connect( m_ui->createButton, &QAbstractButton::clicked, this, &PartitionPage::onCreateClicked ); connect( m_ui->deleteButton, &QAbstractButton::clicked, this, &PartitionPage::onDeleteClicked ); } @@ -92,6 +97,31 @@ PartitionPage::updateButtons() m_ui->createButton->setEnabled( create ); m_ui->editButton->setEnabled( edit ); m_ui->deleteButton->setEnabled( del ); + + m_ui->newPartitionTableButton->setEnabled( m_ui->deviceListView->currentIndex().isValid() ); +} + +void +PartitionPage::onNewPartitionTableClicked() +{ + QModelIndex index = m_ui->deviceListView->currentIndex(); + Q_ASSERT( index.isValid() ); + Device* device = m_core->deviceModel()->deviceForIndex( index ); + + auto answer = QMessageBox::warning( this, + tr( "New Partition Table" ), + tr( "Are you sure you want to create a new partition table on %1?\n" + "Creating a new partition table will delete all existing data on the disk.") + .arg( device->name() ), + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Cancel + ); + + if (answer != QMessageBox::Ok ) + { + return; + } + m_core->createPartitionTable( device ); } void diff --git a/src/modules/partition/PartitionPage.h b/src/modules/partition/PartitionPage.h index be9643ce1..75d013778 100644 --- a/src/modules/partition/PartitionPage.h +++ b/src/modules/partition/PartitionPage.h @@ -42,6 +42,7 @@ private: QScopedPointer< Ui_PartitionPage > m_ui; PartitionCoreModule* m_core; void updateButtons(); + void onNewPartitionTableClicked(); void onCreateClicked(); void onDeleteClicked(); }; diff --git a/src/modules/partition/PartitionPage.ui b/src/modules/partition/PartitionPage.ui index 2e6f0de41..74e80b477 100644 --- a/src/modules/partition/PartitionPage.ui +++ b/src/modules/partition/PartitionPage.ui @@ -6,7 +6,7 @@ 0 0 - 568 + 655 304 @@ -23,6 +23,13 @@ + + + + New Partition Table + + +