227 lines
6.3 KiB
C++
227 lines
6.3 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2008-2010 Volker Lanz <vl@fidra.de>
|
|
SPDX-FileCopyrightText: 2012-2019 Andrius Štikonas <andrius@stikonas.eu>
|
|
SPDX-FileCopyrightText: 2015 Teo Mrnjavac <teo@kde.org>
|
|
SPDX-FileCopyrightText: 2020 Gaël PORTAY <gael.portay@collabora.com>
|
|
|
|
SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
#include "ops/newoperation.h"
|
|
|
|
#include "core/partition.h"
|
|
#include "core/device.h"
|
|
#include "core/partitionnode.h"
|
|
|
|
#include "jobs/createpartitionjob.h"
|
|
#include "jobs/createfilesystemjob.h"
|
|
#include "jobs/setpartitionlabeljob.h"
|
|
#include "jobs/setpartitionuuidjob.h"
|
|
#include "jobs/setpartitionattributesjob.h"
|
|
#include "jobs/setfilesystemlabeljob.h"
|
|
#include "jobs/setpartflagsjob.h"
|
|
#include "jobs/checkfilesystemjob.h"
|
|
|
|
#include "fs/filesystem.h"
|
|
#include "fs/filesystemfactory.h"
|
|
|
|
#include "util/capacity.h"
|
|
|
|
#include <QString>
|
|
|
|
#include <KLocalizedString>
|
|
|
|
struct NewOperationPrivate
|
|
{
|
|
NewOperationPrivate(Device& d, Partition* p) :
|
|
m_TargetDevice(d),
|
|
m_NewPartition(p),
|
|
m_CreatePartitionJob(new CreatePartitionJob(d, *p)),
|
|
m_SetPartitionLabelJob(nullptr),
|
|
m_SetPartitionUUIDJob(nullptr),
|
|
m_SetPartitionAttributesJob(nullptr),
|
|
m_CreateFileSystemJob(nullptr),
|
|
m_SetPartFlagsJob(nullptr),
|
|
m_SetFileSystemLabelJob(nullptr),
|
|
m_CheckFileSystemJob(nullptr)
|
|
{
|
|
}
|
|
|
|
Device& m_TargetDevice;
|
|
Partition* m_NewPartition;
|
|
CreatePartitionJob* m_CreatePartitionJob;
|
|
SetPartitionLabelJob* m_SetPartitionLabelJob;
|
|
SetPartitionUUIDJob* m_SetPartitionUUIDJob;
|
|
SetPartitionAttributesJob* m_SetPartitionAttributesJob;
|
|
CreateFileSystemJob* m_CreateFileSystemJob;
|
|
SetPartFlagsJob* m_SetPartFlagsJob;
|
|
SetFileSystemLabelJob* m_SetFileSystemLabelJob;
|
|
CheckFileSystemJob* m_CheckFileSystemJob;
|
|
};
|
|
|
|
/** Creates a new NewOperation.
|
|
@param d the Device to create a new Partition on
|
|
@param p pointer to the new Partition to create. May not be nullptr.
|
|
*/
|
|
NewOperation::NewOperation(Device& d, Partition* p) :
|
|
Operation(),
|
|
d_ptr(std::make_unique<NewOperationPrivate>(d, p))
|
|
{
|
|
addJob(createPartitionJob());
|
|
|
|
if (!p->label().isEmpty()) {
|
|
d_ptr->m_SetPartitionLabelJob = new SetPartitionLabelJob(targetDevice(), newPartition(), p->label());
|
|
addJob(setPartitionLabelJob());
|
|
}
|
|
|
|
if (!p->uuid().isEmpty()) {
|
|
d_ptr->m_SetPartitionUUIDJob = new SetPartitionUUIDJob(targetDevice(), newPartition(), p->uuid());
|
|
addJob(setPartitionUUIDJob());
|
|
}
|
|
|
|
if (p->attributes()) {
|
|
d_ptr->m_SetPartitionAttributesJob = new SetPartitionAttributesJob(targetDevice(), newPartition(), p->attributes());
|
|
addJob(setPartitionAttributesJob());
|
|
}
|
|
|
|
const FileSystem& fs = newPartition().fileSystem();
|
|
|
|
if (fs.type() != FileSystem::Type::Extended) {
|
|
// It would seem tempting to skip the CreateFileSystemJob or the
|
|
// SetFileSystemLabelJob if either has nothing to do (unformatted FS or
|
|
// empty label). However, the user might later on decide to change FS or
|
|
// label. The operation stack will merge these operations with this one here
|
|
// and if the jobs don't exist things will break.
|
|
|
|
d_ptr->m_CreateFileSystemJob = new CreateFileSystemJob(targetDevice(), newPartition(), fs.label());
|
|
addJob(createFileSystemJob());
|
|
|
|
if (fs.type() == FileSystem::Type::Lvm2_PV) {
|
|
d_ptr->m_SetPartFlagsJob = new SetPartFlagsJob(targetDevice(), newPartition(), PartitionTable::Flag::Lvm);
|
|
addJob(setPartFlagsJob());
|
|
}
|
|
|
|
d_ptr->m_SetFileSystemLabelJob = new SetFileSystemLabelJob(newPartition(), fs.label());
|
|
addJob(setLabelJob());
|
|
|
|
d_ptr->m_CheckFileSystemJob = new CheckFileSystemJob(newPartition());
|
|
addJob(checkJob());
|
|
}
|
|
}
|
|
|
|
NewOperation::~NewOperation()
|
|
{
|
|
if (status() == StatusPending)
|
|
delete d_ptr->m_NewPartition;
|
|
}
|
|
|
|
Partition& NewOperation::newPartition()
|
|
{
|
|
return *d_ptr->m_NewPartition;
|
|
}
|
|
|
|
const Partition& NewOperation::newPartition() const
|
|
{
|
|
return *d_ptr->m_NewPartition;
|
|
}
|
|
|
|
Device& NewOperation::targetDevice()
|
|
{
|
|
return d_ptr->m_TargetDevice;
|
|
}
|
|
|
|
const Device& NewOperation::targetDevice() const
|
|
{
|
|
return d_ptr->m_TargetDevice;
|
|
}
|
|
|
|
CreatePartitionJob* NewOperation::createPartitionJob()
|
|
{
|
|
return d_ptr->m_CreatePartitionJob;
|
|
}
|
|
|
|
SetPartitionLabelJob* NewOperation::setPartitionLabelJob()
|
|
{
|
|
return d_ptr->m_SetPartitionLabelJob;
|
|
}
|
|
|
|
SetPartitionUUIDJob* NewOperation::setPartitionUUIDJob()
|
|
{
|
|
return d_ptr->m_SetPartitionUUIDJob;
|
|
}
|
|
|
|
SetPartitionAttributesJob* NewOperation::setPartitionAttributesJob()
|
|
{
|
|
return d_ptr->m_SetPartitionAttributesJob;
|
|
}
|
|
|
|
CreateFileSystemJob* NewOperation::createFileSystemJob()
|
|
{
|
|
return d_ptr->m_CreateFileSystemJob;
|
|
}
|
|
|
|
SetPartFlagsJob* NewOperation::setPartFlagsJob()
|
|
{
|
|
return d_ptr->m_SetPartFlagsJob;
|
|
}
|
|
|
|
SetFileSystemLabelJob* NewOperation::setLabelJob()
|
|
{
|
|
return d_ptr->m_SetFileSystemLabelJob;
|
|
}
|
|
|
|
CheckFileSystemJob* NewOperation::checkJob()
|
|
{
|
|
return d_ptr->m_CheckFileSystemJob;
|
|
}
|
|
|
|
bool NewOperation::targets(const Device& d) const
|
|
{
|
|
return d == targetDevice();
|
|
}
|
|
|
|
bool NewOperation::targets(const Partition& p) const
|
|
{
|
|
return p == newPartition();
|
|
}
|
|
|
|
void NewOperation::preview()
|
|
{
|
|
insertPreviewPartition(targetDevice(), newPartition());
|
|
}
|
|
|
|
void NewOperation::undo()
|
|
{
|
|
removePreviewPartition(targetDevice(), newPartition());
|
|
}
|
|
|
|
QString NewOperation::description() const
|
|
{
|
|
return xi18nc("@info:status", "Create a new partition (%1, %2) on <filename>%3</filename>", Capacity::formatByteSize(newPartition().capacity()), newPartition().fileSystem().name(), targetDevice().deviceNode());
|
|
}
|
|
|
|
/** Can a Partition be created somewhere?
|
|
@param p the Partition where a new Partition is to be created, may be nullptr
|
|
@return true if a new Partition can be created in @p p
|
|
*/
|
|
bool NewOperation::canCreateNew(const Partition* p)
|
|
{
|
|
return p != nullptr && p->roles().has(PartitionRole::Unallocated);
|
|
}
|
|
|
|
Partition* NewOperation::createNew(const Partition& cloneFrom,
|
|
FileSystem::Type type)
|
|
{
|
|
Partition* p = new Partition(cloneFrom);
|
|
|
|
p->deleteFileSystem();
|
|
p->setFileSystem(FileSystemFactory::create(type,
|
|
p->firstSector(),
|
|
p->lastSector(),
|
|
p->sectorSize()));
|
|
p->setState(Partition::State::New);
|
|
p->setPartitionPath(QString());
|
|
|
|
return p;
|
|
}
|