2020-08-25 16:05:56 +02:00
|
|
|
/* === This file is part of Calamares - <https://calamares.io> ===
|
2014-07-17 09:49:15 +02:00
|
|
|
*
|
2020-08-22 01:19:58 +02:00
|
|
|
* SPDX-FileCopyrightText: 2008-2009 Volker Lanz <vl@fidra.de>
|
|
|
|
* SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org>
|
|
|
|
* SPDX-FileCopyrightText: 2016 Andrius Štikonas <andrius@stikonas.eu>
|
|
|
|
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
|
|
|
* SPDX-FileCopyrightText: 2018 2020, Adriaan de Groot <groot@kde.org>
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
2016-03-04 19:13:49 +01:00
|
|
|
*
|
2020-08-22 01:19:58 +02:00
|
|
|
* Flags handling originally from KDE Partition Manager.
|
2014-07-17 09:49:15 +02:00
|
|
|
*
|
2020-08-25 16:05:56 +02:00
|
|
|
* Calamares is Free Software: see the License-Identifier above.
|
2014-07-17 09:49:15 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-02-13 13:24:53 +01:00
|
|
|
#include "EditExistingPartitionDialog.h"
|
2020-02-13 13:54:04 +01:00
|
|
|
#include "ui_EditExistingPartitionDialog.h"
|
2014-08-08 13:25:56 +02:00
|
|
|
|
2020-02-13 13:24:53 +01:00
|
|
|
#include "core/ColorUtils.h"
|
2020-08-22 01:19:58 +02:00
|
|
|
#include "core/PartUtils.h"
|
2020-02-13 13:24:53 +01:00
|
|
|
#include "core/PartitionCoreModule.h"
|
|
|
|
#include "core/PartitionInfo.h"
|
2018-05-16 14:34:33 +02:00
|
|
|
#include "gui/PartitionDialogHelpers.h"
|
2020-02-13 13:24:53 +01:00
|
|
|
#include "gui/PartitionSizeController.h"
|
2014-07-17 09:49:15 +02:00
|
|
|
|
2015-03-16 10:50:34 +01:00
|
|
|
#include "GlobalStorage.h"
|
|
|
|
#include "JobQueue.h"
|
2020-02-13 13:48:12 +01:00
|
|
|
#include "partition/FileSystem.h"
|
2020-02-13 13:24:53 +01:00
|
|
|
#include "utils/Logger.h"
|
2014-07-17 09:49:15 +02:00
|
|
|
|
2015-07-08 18:21:19 +02:00
|
|
|
#include <kpmcore/core/device.h>
|
|
|
|
#include <kpmcore/core/partition.h>
|
|
|
|
#include <kpmcore/fs/filesystemfactory.h>
|
2014-07-17 09:49:15 +02:00
|
|
|
|
|
|
|
#include <QComboBox>
|
2015-03-16 10:50:34 +01:00
|
|
|
#include <QDir>
|
2016-11-21 00:06:03 +01:00
|
|
|
#include <QPushButton>
|
2014-07-17 09:49:15 +02:00
|
|
|
|
2020-02-13 13:48:12 +01:00
|
|
|
using CalamaresUtils::Partition::untranslatedFS;
|
|
|
|
using CalamaresUtils::Partition::userVisibleFS;
|
|
|
|
|
2020-08-22 01:19:58 +02:00
|
|
|
EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device,
|
|
|
|
Partition* partition,
|
|
|
|
const QStringList& usedMountPoints,
|
|
|
|
QWidget* parentWidget )
|
2014-07-17 09:49:15 +02:00
|
|
|
: QDialog( parentWidget )
|
|
|
|
, m_ui( new Ui_EditExistingPartitionDialog )
|
|
|
|
, m_device( device )
|
|
|
|
, m_partition( partition )
|
2014-08-06 18:31:46 +02:00
|
|
|
, m_partitionSizeController( new PartitionSizeController( this ) )
|
2016-11-21 00:06:03 +01:00
|
|
|
, m_usedMountPoints( usedMountPoints )
|
2014-07-17 09:49:15 +02:00
|
|
|
{
|
|
|
|
m_ui->setupUi( this );
|
2020-08-22 01:19:58 +02:00
|
|
|
standardMountPoints( *( m_ui->mountPointComboBox ), PartitionInfo::mountPoint( partition ) );
|
2015-03-16 10:50:34 +01:00
|
|
|
|
2014-08-07 17:26:26 +02:00
|
|
|
QColor color = ColorUtils::colorForPartition( m_partition );
|
2014-08-09 11:31:00 +02:00
|
|
|
m_partitionSizeController->init( m_device, m_partition, color );
|
2014-08-06 18:31:46 +02:00
|
|
|
m_partitionSizeController->setSpinBox( m_ui->sizeSpinBox );
|
|
|
|
|
2020-08-22 01:19:58 +02:00
|
|
|
connect( m_ui->mountPointComboBox,
|
|
|
|
&QComboBox::currentTextChanged,
|
|
|
|
this,
|
|
|
|
&EditExistingPartitionDialog::checkMountPointSelection );
|
2014-08-06 18:31:46 +02:00
|
|
|
|
2016-07-23 20:04:23 +02:00
|
|
|
// The filesystem label dialog is always enabled, because we may want to change
|
|
|
|
// the label on the current filesystem without formatting.
|
|
|
|
m_ui->fileSystemLabelEdit->setText( m_partition->fileSystem().label() );
|
|
|
|
|
2014-08-06 18:31:46 +02:00
|
|
|
replacePartResizerWidget();
|
|
|
|
|
2020-10-12 14:27:01 +02:00
|
|
|
connect( m_ui->formatRadioButton, &QAbstractButton::toggled, [this]( bool doFormat ) {
|
2014-08-06 18:31:46 +02:00
|
|
|
replacePartResizerWidget();
|
2015-07-15 12:51:35 +02:00
|
|
|
|
|
|
|
m_ui->fileSystemLabel->setEnabled( doFormat );
|
|
|
|
m_ui->fileSystemComboBox->setEnabled( doFormat );
|
2015-07-15 13:25:52 +02:00
|
|
|
|
2015-07-15 13:35:07 +02:00
|
|
|
if ( !doFormat )
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
2020-02-13 13:48:12 +01:00
|
|
|
m_ui->fileSystemComboBox->setCurrentText( userVisibleFS( m_partition->fileSystem() ) );
|
2020-08-22 01:19:58 +02:00
|
|
|
}
|
2015-07-15 13:35:07 +02:00
|
|
|
|
2015-07-15 13:25:52 +02:00
|
|
|
updateMountPointPicker();
|
|
|
|
} );
|
|
|
|
|
2020-08-22 01:19:58 +02:00
|
|
|
connect(
|
2020-10-12 14:27:01 +02:00
|
|
|
m_ui->fileSystemComboBox, &QComboBox::currentTextChanged, [this]( QString ) { updateMountPointPicker(); } );
|
2015-07-15 12:51:35 +02:00
|
|
|
|
|
|
|
// File system
|
|
|
|
QStringList fsNames;
|
|
|
|
for ( auto fs : FileSystemFactory::map() )
|
|
|
|
{
|
|
|
|
if ( fs->supportCreate() != FileSystem::cmdSupportNone && fs->type() != FileSystem::Extended )
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
|
|
|
fsNames << userVisibleFS( fs ); // For the combo box
|
|
|
|
}
|
2015-07-15 12:51:35 +02:00
|
|
|
}
|
|
|
|
m_ui->fileSystemComboBox->addItems( fsNames );
|
|
|
|
|
2020-02-13 13:24:53 +01:00
|
|
|
FileSystem::Type defaultFSType;
|
2021-06-18 11:06:02 +02:00
|
|
|
QString untranslatedFSName = PartUtils::canonicalFilesystemName(
|
2020-08-22 01:19:58 +02:00
|
|
|
Calamares::JobQueue::instance()->globalStorage()->value( "defaultFileSystemType" ).toString(), &defaultFSType );
|
2020-02-13 13:24:53 +01:00
|
|
|
if ( defaultFSType == FileSystem::Type::Unknown )
|
|
|
|
{
|
|
|
|
defaultFSType = FileSystem::Type::Ext4;
|
|
|
|
}
|
|
|
|
|
2020-02-13 13:48:12 +01:00
|
|
|
QString thisFSNameForUser = userVisibleFS( m_partition->fileSystem() );
|
2020-02-13 13:24:53 +01:00
|
|
|
if ( fsNames.contains( thisFSNameForUser ) )
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
2020-02-13 13:24:53 +01:00
|
|
|
m_ui->fileSystemComboBox->setCurrentText( thisFSNameForUser );
|
2020-08-22 01:19:58 +02:00
|
|
|
}
|
2015-07-15 12:51:35 +02:00
|
|
|
else
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
2020-02-13 13:24:53 +01:00
|
|
|
m_ui->fileSystemComboBox->setCurrentText( FileSystem::nameForType( defaultFSType ) );
|
2020-08-22 01:19:58 +02:00
|
|
|
}
|
2015-07-15 12:51:35 +02:00
|
|
|
|
|
|
|
m_ui->fileSystemLabel->setEnabled( m_ui->formatRadioButton->isChecked() );
|
|
|
|
m_ui->fileSystemComboBox->setEnabled( m_ui->formatRadioButton->isChecked() );
|
2016-03-04 19:13:49 +01:00
|
|
|
|
2020-08-22 01:19:58 +02:00
|
|
|
setFlagList( *( m_ui->m_listFlags ), m_partition->availableFlags(), PartitionInfo::flags( m_partition ) );
|
2014-07-17 09:49:15 +02:00
|
|
|
}
|
|
|
|
|
2016-03-04 19:13:49 +01:00
|
|
|
|
2020-08-22 01:19:58 +02:00
|
|
|
EditExistingPartitionDialog::~EditExistingPartitionDialog() {}
|
2014-07-17 09:49:15 +02:00
|
|
|
|
2016-03-04 19:13:49 +01:00
|
|
|
|
|
|
|
PartitionTable::Flags
|
|
|
|
EditExistingPartitionDialog::newFlags() const
|
|
|
|
{
|
2020-08-22 01:19:58 +02:00
|
|
|
return flagsFromList( *( m_ui->m_listFlags ) );
|
2016-03-04 19:13:49 +01:00
|
|
|
}
|
|
|
|
|
2014-07-17 09:49:15 +02:00
|
|
|
void
|
2014-07-17 14:59:59 +02:00
|
|
|
EditExistingPartitionDialog::applyChanges( PartitionCoreModule* core )
|
2014-07-17 09:49:15 +02:00
|
|
|
{
|
2020-08-22 01:19:58 +02:00
|
|
|
PartitionInfo::setMountPoint( m_partition, selectedMountPoint( m_ui->mountPointComboBox ) );
|
2014-08-04 18:16:05 +02:00
|
|
|
|
2014-08-09 11:31:00 +02:00
|
|
|
qint64 newFirstSector = m_partitionSizeController->firstSector();
|
2020-08-22 01:19:58 +02:00
|
|
|
qint64 newLastSector = m_partitionSizeController->lastSector();
|
|
|
|
bool partResizedMoved = newFirstSector != m_partition->firstSector() || newLastSector != m_partition->lastSector();
|
2014-08-06 18:31:46 +02:00
|
|
|
|
2020-08-22 01:19:58 +02:00
|
|
|
cDebug() << "old boundaries:" << m_partition->firstSector() << m_partition->lastSector() << m_partition->length();
|
2020-11-03 23:46:07 +01:00
|
|
|
cDebug() << Logger::SubEntry << "new boundaries:" << newFirstSector << newLastSector;
|
|
|
|
cDebug() << Logger::SubEntry << "dirty status:" << m_partitionSizeController->isDirty();
|
2016-06-24 17:15:26 +02:00
|
|
|
|
2015-07-15 12:51:35 +02:00
|
|
|
FileSystem::Type fsType = FileSystem::Unknown;
|
|
|
|
if ( m_ui->formatRadioButton->isChecked() )
|
|
|
|
{
|
|
|
|
fsType = m_partition->roles().has( PartitionRole::Extended )
|
2020-08-22 01:19:58 +02:00
|
|
|
? FileSystem::Extended
|
|
|
|
: FileSystem::typeForName( m_ui->fileSystemComboBox->currentText() );
|
2015-07-15 12:51:35 +02:00
|
|
|
}
|
2016-07-21 14:33:35 +02:00
|
|
|
const QString fsLabel = m_ui->fileSystemLabelEdit->text();
|
2015-07-15 12:51:35 +02:00
|
|
|
|
2020-11-04 00:58:11 +01:00
|
|
|
const auto resultFlags = newFlags();
|
|
|
|
const auto currentFlags = PartitionInfo::flags( m_partition );
|
|
|
|
|
2016-03-04 19:13:49 +01:00
|
|
|
if ( partResizedMoved )
|
2014-08-04 18:16:05 +02:00
|
|
|
{
|
|
|
|
if ( m_ui->formatRadioButton->isChecked() )
|
|
|
|
{
|
2020-08-22 01:19:58 +02:00
|
|
|
Partition* newPartition = KPMHelpers::createNewPartition( m_partition->parent(),
|
|
|
|
*m_device,
|
|
|
|
m_partition->roles(),
|
|
|
|
fsType,
|
2016-07-21 14:33:35 +02:00
|
|
|
fsLabel,
|
2020-08-22 01:19:58 +02:00
|
|
|
newFirstSector,
|
|
|
|
newLastSector,
|
2020-11-04 00:58:11 +01:00
|
|
|
resultFlags );
|
2014-08-04 18:16:05 +02:00
|
|
|
PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) );
|
|
|
|
PartitionInfo::setFormat( newPartition, true );
|
|
|
|
|
|
|
|
core->deletePartition( m_device, m_partition );
|
|
|
|
core->createPartition( m_device, newPartition );
|
2020-11-04 00:58:11 +01:00
|
|
|
core->setPartitionFlags( m_device, newPartition, resultFlags );
|
2014-08-04 18:16:05 +02:00
|
|
|
}
|
|
|
|
else
|
2015-07-15 12:51:35 +02:00
|
|
|
{
|
2020-08-22 01:19:58 +02:00
|
|
|
core->resizePartition( m_device, m_partition, newFirstSector, newLastSector );
|
2020-11-04 00:58:11 +01:00
|
|
|
if ( currentFlags != resultFlags )
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
2020-11-04 00:58:11 +01:00
|
|
|
core->setPartitionFlags( m_device, m_partition, resultFlags );
|
2020-08-22 01:19:58 +02:00
|
|
|
}
|
2015-07-15 12:51:35 +02:00
|
|
|
}
|
2014-08-04 18:16:05 +02:00
|
|
|
}
|
2014-08-04 19:26:16 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// No size changes
|
|
|
|
if ( m_ui->formatRadioButton->isChecked() )
|
2015-07-15 12:51:35 +02:00
|
|
|
{
|
|
|
|
// if the FS type is unchanged, we just format
|
|
|
|
if ( m_partition->fileSystem().type() == fsType )
|
|
|
|
{
|
|
|
|
core->formatPartition( m_device, m_partition );
|
2020-11-04 00:58:11 +01:00
|
|
|
if ( currentFlags != resultFlags )
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
2020-11-04 00:58:11 +01:00
|
|
|
core->setPartitionFlags( m_device, m_partition, resultFlags );
|
2020-08-22 01:19:58 +02:00
|
|
|
}
|
2016-07-23 20:04:23 +02:00
|
|
|
core->setFilesystemLabel( m_device, m_partition, fsLabel );
|
2015-07-15 12:51:35 +02:00
|
|
|
}
|
2020-08-22 01:19:58 +02:00
|
|
|
else // otherwise, we delete and recreate the partition with new fs type
|
2015-07-15 12:51:35 +02:00
|
|
|
{
|
2020-08-22 01:19:58 +02:00
|
|
|
Partition* newPartition = KPMHelpers::createNewPartition( m_partition->parent(),
|
|
|
|
*m_device,
|
|
|
|
m_partition->roles(),
|
|
|
|
fsType,
|
2016-07-21 14:33:35 +02:00
|
|
|
fsLabel,
|
2020-08-22 01:19:58 +02:00
|
|
|
m_partition->firstSector(),
|
|
|
|
m_partition->lastSector(),
|
2020-11-04 00:58:11 +01:00
|
|
|
resultFlags );
|
2015-07-15 12:51:35 +02:00
|
|
|
PartitionInfo::setMountPoint( newPartition, PartitionInfo::mountPoint( m_partition ) );
|
|
|
|
PartitionInfo::setFormat( newPartition, true );
|
|
|
|
|
|
|
|
core->deletePartition( m_device, m_partition );
|
|
|
|
core->createPartition( m_device, newPartition );
|
2020-11-04 00:58:11 +01:00
|
|
|
core->setPartitionFlags( m_device, newPartition, resultFlags );
|
2015-07-15 12:51:35 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-04 19:26:16 +02:00
|
|
|
else
|
2015-07-15 12:51:35 +02:00
|
|
|
{
|
2020-11-04 00:58:11 +01:00
|
|
|
if ( currentFlags != resultFlags )
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
2020-11-04 00:58:11 +01:00
|
|
|
core->setPartitionFlags( m_device, m_partition, resultFlags );
|
2020-08-22 01:19:58 +02:00
|
|
|
}
|
2016-07-23 20:04:23 +02:00
|
|
|
// In this case, we are not formatting the partition, but we are setting the
|
|
|
|
// label on the current filesystem, if any. We only create the job if the
|
|
|
|
// label actually changed.
|
2021-03-27 15:43:32 +01:00
|
|
|
if ( m_partition->fileSystem().type() != FileSystem::Type::Unformatted
|
|
|
|
&& fsLabel != m_partition->fileSystem().label() )
|
|
|
|
{
|
2016-07-23 20:04:23 +02:00
|
|
|
core->setFilesystemLabel( m_device, m_partition, fsLabel );
|
|
|
|
}
|
2020-11-04 00:58:11 +01:00
|
|
|
core->refreshPartition( m_device, m_partition );
|
2015-07-15 12:51:35 +02:00
|
|
|
}
|
2014-08-04 19:26:16 +02:00
|
|
|
}
|
2014-07-17 09:49:15 +02:00
|
|
|
}
|
2014-08-06 18:31:46 +02:00
|
|
|
|
2016-03-04 19:13:49 +01:00
|
|
|
|
2014-08-06 18:31:46 +02:00
|
|
|
void
|
|
|
|
EditExistingPartitionDialog::replacePartResizerWidget()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* There is no way to reliably update the partition used by
|
|
|
|
* PartResizerWidget, which is necessary when we switch between "format" and
|
|
|
|
* "keep". This is a hack which replaces the existing PartResizerWidget
|
|
|
|
* with a new one.
|
|
|
|
*/
|
|
|
|
PartResizerWidget* widget = new PartResizerWidget( this );
|
|
|
|
|
|
|
|
layout()->replaceWidget( m_ui->partResizerWidget, widget );
|
|
|
|
delete m_ui->partResizerWidget;
|
|
|
|
m_ui->partResizerWidget = widget;
|
|
|
|
|
2014-08-09 11:31:00 +02:00
|
|
|
m_partitionSizeController->setPartResizerWidget( widget, m_ui->formatRadioButton->isChecked() );
|
2014-08-06 18:31:46 +02:00
|
|
|
}
|
2015-07-15 13:25:52 +02:00
|
|
|
|
2016-03-04 19:13:49 +01:00
|
|
|
|
2015-07-15 13:25:52 +02:00
|
|
|
void
|
|
|
|
EditExistingPartitionDialog::updateMountPointPicker()
|
|
|
|
{
|
|
|
|
bool doFormat = m_ui->formatRadioButton->isChecked();
|
|
|
|
FileSystem::Type fsType = FileSystem::Unknown;
|
|
|
|
if ( doFormat )
|
|
|
|
{
|
|
|
|
fsType = FileSystem::typeForName( m_ui->fileSystemComboBox->currentText() );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fsType = m_partition->fileSystem().type();
|
|
|
|
}
|
|
|
|
bool canMount = true;
|
2020-08-22 01:19:58 +02:00
|
|
|
if ( fsType == FileSystem::Extended || fsType == FileSystem::LinuxSwap || fsType == FileSystem::Unformatted
|
|
|
|
|| fsType == FileSystem::Unknown || fsType == FileSystem::Lvm2_PV )
|
2015-07-15 13:25:52 +02:00
|
|
|
{
|
|
|
|
canMount = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ui->mountPointLabel->setEnabled( canMount );
|
|
|
|
m_ui->mountPointComboBox->setEnabled( canMount );
|
|
|
|
if ( !canMount )
|
2020-08-22 01:19:58 +02:00
|
|
|
{
|
2018-05-15 14:26:01 +02:00
|
|
|
setSelectedMountPoint( m_ui->mountPointComboBox, QString() );
|
2020-08-22 01:19:58 +02:00
|
|
|
}
|
2015-07-15 13:25:52 +02:00
|
|
|
}
|
2016-11-21 00:06:03 +01:00
|
|
|
|
|
|
|
void
|
|
|
|
EditExistingPartitionDialog::checkMountPointSelection()
|
|
|
|
{
|
2018-05-15 12:30:18 +02:00
|
|
|
if ( m_usedMountPoints.contains( selectedMountPoint( m_ui->mountPointComboBox ) ) )
|
2017-01-04 15:27:48 +01:00
|
|
|
{
|
|
|
|
m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) );
|
|
|
|
m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-11-21 00:06:03 +01:00
|
|
|
m_ui->labelMountPoint->setText( QString() );
|
2017-01-04 15:27:48 +01:00
|
|
|
m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
|
2016-11-21 00:06:03 +01:00
|
|
|
}
|
|
|
|
}
|