Move the workaround-code that replaced making a temp copy of a partition for

the ResizeDialog to said dialog instead of cluttering the
PartitionManagetWidget's call with that.

Call updatePartitions() after exec'ing ResizeDialog() even if the dialog was
not accepted as it might have deleted and re-created unallocated children of
extended partitions anyway -- and that would crash us later.

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=1115191
This commit is contained in:
Volker Lanz 2010-04-15 15:30:08 +00:00
parent 0bebc1a2d0
commit 8632b7cf0d
4 changed files with 65 additions and 23 deletions

View File

@ -36,6 +36,7 @@ class CoreBackendPartitionTable;
class PartitionAlignment;
class PartResizerWidget;
class ResizeDialog;
class InsertDialog;
class NewDialog;
class EditMountPointDialog;
@ -81,6 +82,7 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Partition : public PartitionNode
friend class PartitionAlignment;
friend class PartResizerWidget;
friend class ResizeDialog;
friend class InsertDialog;
friend class NewDialog;
friend class EditMountPointDialog;

View File

@ -559,33 +559,25 @@ void PartitionManagerWidget::onResizePartition()
const qint64 freeBefore = selectedDevice()->partitionTable()->freeSectorsBefore(p);
const qint64 freeAfter = selectedDevice()->partitionTable()->freeSectorsAfter(p);
// in 1.0.x we used to copy the selected partition to a temporary Partition object and
// pass that to the ResizeDialog. This leads to problems with PartitionAlignment
// having to find out if a sector is occupied by another partition or by the original
// partition we did copy from here. Thus we don't do that anymore but modify the original
// partition and revert the modifications again before setting upt the ResizeOperation.
const qint64 originalFirst = p.firstSector();
const qint64 originalLast = p.lastSector();
QPointer<ResizeDialog> dlg = new ResizeDialog(this, *selectedDevice(), p, p.firstSector() - freeBefore, freeAfter + p.lastSector());
int status = dlg->exec();
const qint64 resizedFirst = p.firstSector();
const qint64 resizedLast = p.lastSector();
p.setFirstSector(originalFirst);
p.fileSystem().setFirstSector(originalFirst);
p.setLastSector(originalLast);
p.fileSystem().setLastSector(originalLast);
if (status == KDialog::Accepted)
if (dlg->exec() == KDialog::Accepted)
{
if (resizedFirst == originalFirst && resizedLast == originalLast)
if (dlg->resizedFirstSector() == p.firstSector() && dlg->resizedLastSector() == p.lastSector())
Log(Log::information) << i18nc("@info/plain", "Partition <filename>%1</filename> has the same position and size after resize/move. Ignoring operation.", p.deviceNode());
else
operationStack().push(new ResizeOperation(*selectedDevice(), p, resizedFirst, resizedLast));
operationStack().push(new ResizeOperation(*selectedDevice(), p, dlg->resizedFirstSector(), dlg->resizedLastSector()));
}
if (p.roles().has(PartitionRole::Extended))
{
// Even if the user dismissed the resize dialog we must update the partitions
// if it's an extended partition:
// The dialog has to remove and create unallocated children if the user resizes
// an extended partition. We can't know if that has happened, so to avoid
// any problems (like, the user resized an extended and then canceled, which would
// lead to the unallocated children having the wrong size) do this now.
updatePartitions();
}
delete dlg;

View File

@ -21,11 +21,16 @@
#include "gui/sizedialogwidget.h"
#include "core/partition.h"
#include "core/device.h"
#include "fs/filesystem.h"
#include "ops/resizeoperation.h"
#include "util/capacity.h"
#include <kdebug.h>
/** Creates a new ResizeDialog
@param parent pointer to the parent widget
@param device the Device the Partition to resize is on
@ -36,7 +41,9 @@
ResizeDialog::ResizeDialog(QWidget* parent, Device& d, Partition& p, qint64 minFirst, qint64 maxLast) :
SizeDialogBase(parent, d, p, minFirst, maxLast),
m_OriginalFirstSector(p.firstSector()),
m_OriginalLastSector(p.lastSector())
m_OriginalLastSector(p.lastSector()),
m_ResizedFirstSector(p.firstSector()),
m_ResizedLastSector(p.lastSector())
{
setCaption(i18nc("@title:window", "Resize/move partition: <filename>%1</filename>", partition().deviceNode()));
@ -58,6 +65,36 @@ ResizeDialog::~ResizeDialog()
saveDialogSize(kcg);
}
void ResizeDialog::rollback()
{
partition().setFirstSector(originalFirstSector());
partition().fileSystem().setFirstSector(originalFirstSector());
partition().setLastSector(originalLastSector());
partition().fileSystem().setLastSector(originalLastSector());
if (partition().roles().has(PartitionRole::Extended))
{
device().partitionTable()->removeUnallocated(&partition());
device().partitionTable()->insertUnallocated(device(), &partition(), partition().firstSector());
}
}
void ResizeDialog::accept()
{
setResizedFirstSector(partition().firstSector());
setResizedLastSector(partition().lastSector());
rollback();
KDialog::accept();
}
void ResizeDialog::reject()
{
rollback();
KDialog::reject();
}
void ResizeDialog::setupDialog()
{
SizeDialogBase::setupDialog();

View File

@ -46,6 +46,12 @@ class ResizeDialog : public SizeDialogBase
public:
bool isModified() const;
qint64 resizedFirstSector() const { return m_ResizedFirstSector; }
qint64 resizedLastSector() const { return m_ResizedLastSector; }
public slots:
virtual void accept();
virtual void reject();
protected:
virtual bool canGrow() const;
@ -53,6 +59,9 @@ class ResizeDialog : public SizeDialogBase
virtual bool canMove() const;
virtual void setupDialog();
virtual void setDirty();
void rollback();
void setResizedFirstSector(qint64 s) { m_ResizedFirstSector = s; }
void setResizedLastSector(qint64 s) { m_ResizedLastSector = s; }
protected:
qint64 originalFirstSector() const { return m_OriginalFirstSector; }
@ -61,6 +70,8 @@ class ResizeDialog : public SizeDialogBase
private:
qint64 m_OriginalFirstSector;
qint64 m_OriginalLastSector;
qint64 m_ResizedFirstSector;
qint64 m_ResizedLastSector;
};
#endif