From c8dbeb534136b569470cb76d1536122f0d8b3627 Mon Sep 17 00:00:00 2001 From: shainer Date: Sun, 20 Nov 2016 22:05:55 +0000 Subject: [PATCH 1/5] Avoid creating a new partition with a used mountpoint. We get the mountpoints already used by other partitions, and disable the Ok button in the "Create new partition" dialog if the user selects/writes a mountpoint which is already used. We are going to do the same in the Edit partition dialog after testing. --- .../partition/gui/CreatePartitionDialog.cpp | 20 ++++++++++++-- .../partition/gui/CreatePartitionDialog.h | 4 ++- .../partition/gui/CreatePartitionDialog.ui | 26 ++++++++++++++----- src/modules/partition/gui/PartitionPage.cpp | 23 ++++++++++++++-- src/modules/partition/gui/PartitionPage.h | 2 ++ 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 994e60010..788aa0355 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -40,8 +40,9 @@ // Qt #include #include -#include #include +#include +#include static QSet< FileSystem::Type > s_unmountableFS( { @@ -52,12 +53,13 @@ static QSet< FileSystem::Type > s_unmountableFS( FileSystem::Lvm2_PV } ); -CreatePartitionDialog::CreatePartitionDialog( Device* device, PartitionNode* parentPartition, QWidget* parentWidget ) +CreatePartitionDialog::CreatePartitionDialog( Device* device, PartitionNode* parentPartition, const QStringList& usedMountPoints, QWidget* parentWidget ) : QDialog( parentWidget ) , m_ui( new Ui_CreatePartitionDialog ) , m_partitionSizeController( new PartitionSizeController( this ) ) , m_device( device ) , m_parent( parentPartition ) + , m_usedMountPoints( usedMountPoints ) { m_ui->setupUi( this ); m_ui->encryptWidget->setText( tr( "En&crypt" ) ); @@ -101,6 +103,8 @@ CreatePartitionDialog::CreatePartitionDialog( Device* device, PartitionNode* par connect( m_ui->fsComboBox, SIGNAL( activated( int ) ), SLOT( updateMountPointUi() ) ); connect( m_ui->extendedRadioButton, SIGNAL( toggled( bool ) ), SLOT( updateMountPointUi() ) ); + connect( m_ui->mountPointComboBox, &QComboBox::currentTextChanged, this, &CreatePartitionDialog::checkMountPointSelection ); + // Select a default m_ui->fsComboBox->setCurrentIndex( defaultFsIndex ); updateMountPointUi(); @@ -252,6 +256,18 @@ CreatePartitionDialog::updateMountPointUi() m_ui->mountPointComboBox->setCurrentText( QString() ); } +void +CreatePartitionDialog::checkMountPointSelection(const QString& selection) +{ + if (m_usedMountPoints.contains(selection)) { + m_ui->labelMountPoint->setText("Mountpoint already used. Please select another one."); + m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + } else { + m_ui->labelMountPoint->setText( QString() ); + m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + } +} + void CreatePartitionDialog::initPartResizerWidget( Partition* partition ) { diff --git a/src/modules/partition/gui/CreatePartitionDialog.h b/src/modules/partition/gui/CreatePartitionDialog.h index aca7ed6a0..7773d5f8b 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.h +++ b/src/modules/partition/gui/CreatePartitionDialog.h @@ -42,7 +42,7 @@ class CreatePartitionDialog : public QDialog { Q_OBJECT public: - CreatePartitionDialog( Device* device, PartitionNode* parentPartition, QWidget* parentWidget = nullptr ); + CreatePartitionDialog( Device* device, PartitionNode* parentPartition, const QStringList& usedMountPoints, QWidget* parentWidget = nullptr ); ~CreatePartitionDialog(); /** @@ -61,6 +61,7 @@ public: private Q_SLOTS: void updateMountPointUi(); + void checkMountPointSelection(const QString &); private: void setupFlagsList(); @@ -69,6 +70,7 @@ private: Device* m_device; PartitionNode* m_parent; PartitionRole m_role = PartitionRole( PartitionRole::None ); + QStringList m_usedMountPoints; void initGptPartitionTypeUi(); void initMbrPartitionTypeUi(); diff --git a/src/modules/partition/gui/CreatePartitionDialog.ui b/src/modules/partition/gui/CreatePartitionDialog.ui index 28961c543..bad15a4cf 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.ui +++ b/src/modules/partition/gui/CreatePartitionDialog.ui @@ -108,7 +108,7 @@ 20 - 12 + 13 @@ -126,6 +126,9 @@ + + + @@ -162,14 +165,26 @@ - + + + + + true + + + + + + + + Flags: - + true @@ -182,7 +197,7 @@ - + Qt::Vertical @@ -195,9 +210,6 @@ - - - diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 2ba07606d..99dd1679b 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -176,7 +176,7 @@ PartitionPage::onCreateClicked() Partition* partition = model->partitionForIndex( index ); Q_ASSERT( partition ); - QPointer dlg = new CreatePartitionDialog( model->device(), partition->parent(), this ); + QPointer dlg = new CreatePartitionDialog( model->device(), partition->parent(), getCurrentUsedMountpoints(), this ); dlg->initFromFreeSpace( partition ); if ( dlg->exec() == QDialog::Accepted ) { @@ -265,7 +265,7 @@ PartitionPage::onPartitionViewActivated() void PartitionPage::updatePartitionToCreate( Device* device, Partition* partition ) { - QPointer dlg = new CreatePartitionDialog( device, partition->parent(), this ); + QPointer dlg = new CreatePartitionDialog( device, partition->parent(), getCurrentUsedMountpoints(), this ); dlg->initFromPartitionToCreate( partition ); if ( dlg->exec() == QDialog::Accepted ) { @@ -375,3 +375,22 @@ PartitionPage::updateBootLoaderIndex() m_ui->bootLoaderComboBox->setCurrentIndex( m_lastSelectedBootLoaderIndex ); } } + +QStringList +PartitionPage::getCurrentUsedMountpoints() +{ + QModelIndex index = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); + if ( !index.isValid() ) + return QStringList(); + + Device* device = m_core->deviceModel()->deviceForIndex( index ); + QStringList mountPoints; + + for (Partition* partition : device->partitionTable()->children()) { + if (!partition->mountPoint().isEmpty()) { + mountPoints << partition->mountPoint(); + } + } + + return mountPoints; +} diff --git a/src/modules/partition/gui/PartitionPage.h b/src/modules/partition/gui/PartitionPage.h index 2dc02159d..59453ce18 100644 --- a/src/modules/partition/gui/PartitionPage.h +++ b/src/modules/partition/gui/PartitionPage.h @@ -62,6 +62,8 @@ private: void updateFromCurrentDevice(); void updateBootLoaderIndex(); + QStringList getCurrentUsedMountpoints(); + QMutex m_revertMutex; int m_lastSelectedBootLoaderIndex; }; From f51b05e8aa64cee3666224f758018fa1f0513faf Mon Sep 17 00:00:00 2001 From: shainer Date: Sun, 20 Nov 2016 22:46:28 +0000 Subject: [PATCH 2/5] Get the mountpoint from PartitionInfo. The Partition object includes the root mountpoint in the partition mountpoint, which is not what we want. --- src/modules/partition/gui/PartitionPage.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 99dd1679b..438d89b3d 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -23,6 +23,7 @@ #include "core/BootLoaderModel.h" #include "core/DeviceModel.h" #include "core/PartitionCoreModule.h" +#include "core/PartitionInfo.h" #include "core/PartitionModel.h" #include "core/KPMHelpers.h" #include "gui/CreatePartitionDialog.h" @@ -387,8 +388,10 @@ PartitionPage::getCurrentUsedMountpoints() QStringList mountPoints; for (Partition* partition : device->partitionTable()->children()) { - if (!partition->mountPoint().isEmpty()) { - mountPoints << partition->mountPoint(); + const QString& mountPoint = PartitionInfo::mountPoint( partition ); + + if (!mountPoint.isEmpty()) { + mountPoints << mountPoint; } } From 8c1199df2ddbcfdd1a9e3bc7bcd45cb6bab2df0b Mon Sep 17 00:00:00 2001 From: shainer Date: Sun, 20 Nov 2016 23:05:44 +0000 Subject: [PATCH 3/5] Check first selection of mountpoint too. When opening the dialog. --- src/modules/partition/gui/CreatePartitionDialog.cpp | 8 ++++++-- src/modules/partition/gui/CreatePartitionDialog.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 788aa0355..90545fe80 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -110,6 +110,8 @@ CreatePartitionDialog::CreatePartitionDialog( Device* device, PartitionNode* par updateMountPointUi(); setupFlagsList(); + // Checks the initial selection. + checkMountPointSelection(); } CreatePartitionDialog::~CreatePartitionDialog() @@ -257,10 +259,12 @@ CreatePartitionDialog::updateMountPointUi() } void -CreatePartitionDialog::checkMountPointSelection(const QString& selection) +CreatePartitionDialog::checkMountPointSelection() { + const QString& selection = m_ui->mountPointComboBox->currentText(); + if (m_usedMountPoints.contains(selection)) { - m_ui->labelMountPoint->setText("Mountpoint already used. Please select another one."); + m_ui->labelMountPoint->setText("Mountpoint already in use. Please select another one."); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } else { m_ui->labelMountPoint->setText( QString() ); diff --git a/src/modules/partition/gui/CreatePartitionDialog.h b/src/modules/partition/gui/CreatePartitionDialog.h index 7773d5f8b..641616e3f 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.h +++ b/src/modules/partition/gui/CreatePartitionDialog.h @@ -61,7 +61,7 @@ public: private Q_SLOTS: void updateMountPointUi(); - void checkMountPointSelection(const QString &); + void checkMountPointSelection(); private: void setupFlagsList(); From 349470ae714cea563a1806a8f5a1730e4cf49135 Mon Sep 17 00:00:00 2001 From: shainer Date: Sun, 20 Nov 2016 23:06:03 +0000 Subject: [PATCH 4/5] Check mountpoints when editing a partition too. --- .../gui/EditExistingPartitionDialog.cpp | 21 ++++++++++++++++++- .../gui/EditExistingPartitionDialog.h | 6 +++++- .../gui/EditExistingPartitionDialog.ui | 16 ++++++++++++-- src/modules/partition/gui/PartitionPage.cpp | 2 +- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index 2652567d2..a11aec48b 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -43,13 +43,15 @@ // Qt #include #include +#include -EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, Partition* partition, QWidget* parentWidget ) +EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, Partition* partition, const QStringList& usedMountPoints, QWidget* parentWidget ) : QDialog( parentWidget ) , m_ui( new Ui_EditExistingPartitionDialog ) , m_device( device ) , m_partition( partition ) , m_partitionSizeController( new PartitionSizeController( this ) ) + , m_usedMountPoints( usedMountPoints ) { m_ui->setupUi( this ); @@ -60,11 +62,14 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, Partit mountPoints.sort(); m_ui->mountPointComboBox->addItems( mountPoints ); + m_usedMountPoints.removeOne( PartitionInfo::mountPoint( partition ) ); + QColor color = ColorUtils::colorForPartition( m_partition ); m_partitionSizeController->init( m_device, m_partition, color ); m_partitionSizeController->setSpinBox( m_ui->sizeSpinBox ); m_ui->mountPointComboBox->setCurrentText( PartitionInfo::mountPoint( partition ) ); + connect( m_ui->mountPointComboBox, &QComboBox::currentTextChanged, this, &EditExistingPartitionDialog::checkMountPointSelection ); replacePartResizerWidget(); @@ -291,3 +296,17 @@ EditExistingPartitionDialog::updateMountPointPicker() if ( !canMount ) m_ui->mountPointComboBox->setCurrentText( QString() ); } + +void +EditExistingPartitionDialog::checkMountPointSelection() +{ + const QString& selection = m_ui->mountPointComboBox->currentText(); + + if (m_usedMountPoints.contains(selection)) { + m_ui->labelMountPoint->setText("Mountpoint already in use. Please select another one."); + m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + } else { + m_ui->labelMountPoint->setText( QString() ); + m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); + } +} diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.h b/src/modules/partition/gui/EditExistingPartitionDialog.h index 0aa89bb98..83552fe55 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.h +++ b/src/modules/partition/gui/EditExistingPartitionDialog.h @@ -40,16 +40,20 @@ class EditExistingPartitionDialog : public QDialog { Q_OBJECT public: - EditExistingPartitionDialog( Device* device, Partition* partition, QWidget* parentWidget = nullptr ); + EditExistingPartitionDialog( Device* device, Partition* partition, const QStringList& usedMountPoints, QWidget* parentWidget = nullptr ); ~EditExistingPartitionDialog(); void applyChanges( PartitionCoreModule* module ); +private slots: + void checkMountPointSelection(); + private: QScopedPointer< Ui_EditExistingPartitionDialog > m_ui; Device* m_device; Partition* m_partition; PartitionSizeController* m_partitionSizeController; + QStringList m_usedMountPoints; PartitionTable::Flags newFlags() const; void setupFlagsList(); diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.ui b/src/modules/partition/gui/EditExistingPartitionDialog.ui index 9ed7e1bb4..27e930fda 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.ui +++ b/src/modules/partition/gui/EditExistingPartitionDialog.ui @@ -139,14 +139,14 @@ - + Flags: - + true @@ -159,6 +159,18 @@ + + + + + true + + + + + + + diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 438d89b3d..6fa64fda8 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -280,7 +280,7 @@ PartitionPage::updatePartitionToCreate( Device* device, Partition* partition ) void PartitionPage::editExistingPartition( Device* device, Partition* partition ) { - QPointer dlg = new EditExistingPartitionDialog( device, partition, this ); + QPointer dlg = new EditExistingPartitionDialog( device, partition, getCurrentUsedMountpoints(), this ); if ( dlg->exec() == QDialog::Accepted ) dlg->applyChanges( m_core ); delete dlg; From 2759529841d91129a57296abbed5fc2e0e0610f9 Mon Sep 17 00:00:00 2001 From: shainer Date: Sun, 20 Nov 2016 23:19:33 +0000 Subject: [PATCH 5/5] Remove current partition's mountpoint from used list. This means that when we edit a partition, we don't consider its current mountpoint invalid because it is already in-use. We need to do this for both "edit existing partition" and "edit a partition that we are still creating". --- .../partition/gui/EditExistingPartitionDialog.cpp | 2 -- src/modules/partition/gui/PartitionPage.cpp | 10 ++++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index a11aec48b..5aa1e21f6 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -62,8 +62,6 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, Partit mountPoints.sort(); m_ui->mountPointComboBox->addItems( mountPoints ); - m_usedMountPoints.removeOne( PartitionInfo::mountPoint( partition ) ); - QColor color = ColorUtils::colorForPartition( m_partition ); m_partitionSizeController->init( m_device, m_partition, color ); m_partitionSizeController->setSpinBox( m_ui->sizeSpinBox ); diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 6fa64fda8..5e3239050 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -266,7 +266,10 @@ PartitionPage::onPartitionViewActivated() void PartitionPage::updatePartitionToCreate( Device* device, Partition* partition ) { - QPointer dlg = new CreatePartitionDialog( device, partition->parent(), getCurrentUsedMountpoints(), this ); + QStringList mountPoints = getCurrentUsedMountpoints(); + mountPoints.removeOne( PartitionInfo::mountPoint( partition ) ); + + QPointer dlg = new CreatePartitionDialog( device, partition->parent(), mountPoints, this ); dlg->initFromPartitionToCreate( partition ); if ( dlg->exec() == QDialog::Accepted ) { @@ -280,7 +283,10 @@ PartitionPage::updatePartitionToCreate( Device* device, Partition* partition ) void PartitionPage::editExistingPartition( Device* device, Partition* partition ) { - QPointer dlg = new EditExistingPartitionDialog( device, partition, getCurrentUsedMountpoints(), this ); + QStringList mountPoints = getCurrentUsedMountpoints(); + mountPoints.removeOne( PartitionInfo::mountPoint( partition ) ); + + QPointer dlg = new EditExistingPartitionDialog( device, partition, mountPoints, this ); if ( dlg->exec() == QDialog::Accepted ) dlg->applyChanges( m_core ); delete dlg;