From 8632b7cf0d8ca4c8815b84020663cfd8dee3069d Mon Sep 17 00:00:00 2001 From: Volker Lanz Date: Thu, 15 Apr 2010 15:30:08 +0000 Subject: [PATCH] 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 --- src/core/partition.h | 2 ++ src/gui/partitionmanagerwidget.cpp | 36 +++++++++++---------------- src/gui/resizedialog.cpp | 39 +++++++++++++++++++++++++++++- src/gui/resizedialog.h | 11 +++++++++ 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/core/partition.h b/src/core/partition.h index 35b5a86..db1bd82 100644 --- a/src/core/partition.h +++ b/src/core/partition.h @@ -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; diff --git a/src/gui/partitionmanagerwidget.cpp b/src/gui/partitionmanagerwidget.cpp index 0d2dff5..1e0d58a 100644 --- a/src/gui/partitionmanagerwidget.cpp +++ b/src/gui/partitionmanagerwidget.cpp @@ -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 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 %1 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; diff --git a/src/gui/resizedialog.cpp b/src/gui/resizedialog.cpp index fa35e0f..06c50ea 100644 --- a/src/gui/resizedialog.cpp +++ b/src/gui/resizedialog.cpp @@ -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 + /** 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: %1", 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(); diff --git a/src/gui/resizedialog.h b/src/gui/resizedialog.h index 1730659..cb979a2 100644 --- a/src/gui/resizedialog.h +++ b/src/gui/resizedialog.h @@ -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