Don't assume a device always has a valid partition table. This is the correct

fix for what I initially tried to fix with commit 898001.

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=908045
This commit is contained in:
Volker Lanz 2009-01-09 07:10:59 +00:00
parent edb74962fe
commit 306667e09e
17 changed files with 160 additions and 112 deletions

View File

@ -36,7 +36,7 @@ Device::Device(const QString& name, const QString& devicenode, qint32 heads, qin
QObject(), QObject(),
m_Name(name), m_Name(name),
m_DeviceNode(devicenode), m_DeviceNode(devicenode),
m_PartitionTable(new PartitionTable()), m_PartitionTable(NULL),
m_Heads(heads), m_Heads(heads),
m_SectorsPerTrack(numSectors), m_SectorsPerTrack(numSectors),
m_Cylinders(cylinders), m_Cylinders(cylinders),

View File

@ -27,6 +27,7 @@
class PartitionTable; class PartitionTable;
class CreatePartitionTableOperation; class CreatePartitionTableOperation;
class LibParted;
/** @brief A device. /** @brief A device.
@ -43,6 +44,7 @@ class Device : public QObject
Q_DISABLE_COPY(Device) Q_DISABLE_COPY(Device)
friend class CreatePartitionTableOperation; friend class CreatePartitionTableOperation;
friend class LibParted;
public: public:
Device(const QString& name, const QString& devicenode, qint32 heads, qint32 numSectors, qint32 cylinders, qint64 sectorSize); Device(const QString& name, const QString& devicenode, qint32 heads, qint32 numSectors, qint32 cylinders, qint64 sectorSize);
@ -51,8 +53,8 @@ class Device : public QObject
public: public:
const QString& name() const { return m_Name; } /**< @return the Device's name, usually some manufacturer string */ const QString& name() const { return m_Name; } /**< @return the Device's name, usually some manufacturer string */
const QString& deviceNode() const { return m_DeviceNode; } /**< @return the Device's node, for example "/dev/sda" */ const QString& deviceNode() const { return m_DeviceNode; } /**< @return the Device's node, for example "/dev/sda" */
PartitionTable& partitionTable() { return *m_PartitionTable; } /**< @return the Device's PartitionTable */ PartitionTable* partitionTable() { return m_PartitionTable; } /**< @return the Device's PartitionTable */
const PartitionTable& partitionTable() const { return *m_PartitionTable; } /**< @return the Device's PartitionTable */ const PartitionTable* partitionTable() const { return m_PartitionTable; } /**< @return the Device's PartitionTable */
qint32 heads() const { return m_Heads; } /**< @return the number of heads on the Device in CHS notation */ qint32 heads() const { return m_Heads; } /**< @return the number of heads on the Device in CHS notation */
qint32 cylinders() const { return m_Cylinders; } /**< @return the number of cylinders on the Device in CHS notation */ qint32 cylinders() const { return m_Cylinders; } /**< @return the number of cylinders on the Device in CHS notation */
qint32 sectorsPerTrack() const { return m_SectorsPerTrack; } /**< @return the number of sectors on the Device in CHS notation */ qint32 sectorsPerTrack() const { return m_SectorsPerTrack; } /**< @return the number of sectors on the Device in CHS notation */
@ -63,7 +65,7 @@ class Device : public QObject
protected: protected:
void setPartitionTable(PartitionTable* ptable) { m_PartitionTable = ptable; } void setPartitionTable(PartitionTable* ptable) { m_PartitionTable = ptable; }
private: private:
QString m_Name; QString m_Name;
QString m_DeviceNode; QString m_DeviceNode;

View File

@ -173,6 +173,7 @@ static void scanDevicePartitions(PedDevice* pedDevice, Device& d, PedDisk* pedDi
{ {
Q_ASSERT(pedDevice); Q_ASSERT(pedDevice);
Q_ASSERT(pedDisk); Q_ASSERT(pedDisk);
Q_ASSERT(d.partitionTable());
PedPartition* pedPartition = NULL; PedPartition* pedPartition = NULL;
@ -204,11 +205,11 @@ static void scanDevicePartitions(PedDevice* pedDevice, Device& d, PedDisk* pedDi
} }
// Find an extended partition this partition is in. // Find an extended partition this partition is in.
PartitionNode* parent = d.partitionTable().findPartitionBySector(pedPartition->geom.start, PartitionRole(PartitionRole::Extended)); PartitionNode* parent = d.partitionTable()->findPartitionBySector(pedPartition->geom.start, PartitionRole(PartitionRole::Extended));
// None found, so it's a primary in the device's partition table. // None found, so it's a primary in the device's partition table.
if (parent == NULL) if (parent == NULL)
parent = &d.partitionTable(); parent = d.partitionTable();
const QString node = pedDisk->dev->path + QString::number(pedPartition->num); const QString node = pedDisk->dev->path + QString::number(pedPartition->num);
FileSystem* fs = FileSystemFactory::create(type, pedPartition->geom.start, pedPartition->geom.end); FileSystem* fs = FileSystemFactory::create(type, pedPartition->geom.start, pedPartition->geom.end);
@ -227,7 +228,7 @@ static void scanDevicePartitions(PedDevice* pedDevice, Device& d, PedDisk* pedDi
PartitionTable::isSnapped(d, *part); PartitionTable::isSnapped(d, *part);
} }
d.partitionTable().updateUnallocated(d); d.partitionTable()->updateUnallocated(d);
ped_disk_destroy(pedDisk); ped_disk_destroy(pedDisk);
} }
@ -271,8 +272,9 @@ void LibParted::scanDevices(OperationStack& ostack)
if (pedDisk) if (pedDisk)
{ {
d->partitionTable().setMaxPrimaries(ped_disk_get_max_primary_partition_count(pedDisk)); d->setPartitionTable(new PartitionTable());
d->partitionTable().setTypeName(pedDisk->type->name); d->partitionTable()->setMaxPrimaries(ped_disk_get_max_primary_partition_count(pedDisk));
d->partitionTable()->setTypeName(pedDisk->type->name);
scanDevicePartitions(pedDevice, *d, pedDisk, mountInfo); scanDevicePartitions(pedDevice, *d, pedDisk, mountInfo);
} }

View File

@ -76,7 +76,7 @@ OperationStack::~OperationStack()
<!-- 5 --> <!-- 5 -->
<li>File system is changed for a new Partition: Modify in NewOperation and forget it.</li> <li>File system is changed for a new Partition: Modify in NewOperation and forget it.</li>
</ol> </ol>
@param currentOp the Operation already on the stack to try to merge with @param currentOp the Operation already on the stack to try to merge with
@param pushedOp the newly pushed Operation @param pushedOp the newly pushed Operation
@return true if the OperationStack has been modified in a way that requires merging to stop @return true if the OperationStack has been modified in a way that requires merging to stop
@ -104,7 +104,7 @@ bool OperationStack::mergeNewOperation(Operation*& currentOp, Operation*& pushed
newOp->undo(); newOp->undo();
delete operations().takeAt(operations().indexOf(newOp)); delete operations().takeAt(operations().indexOf(newOp));
return true; return true;
} }
@ -167,9 +167,9 @@ bool OperationStack::mergeNewOperation(Operation*& currentOp, Operation*& pushed
log() << i18nc("@info/plain", "Changing file system for a new partition: No new operation required."); log() << i18nc("@info/plain", "Changing file system for a new partition: No new operation required.");
FileSystem* oldFs = &newOp->newPartition().fileSystem(); FileSystem* oldFs = &newOp->newPartition().fileSystem();
newOp->newPartition().setFileSystem(FileSystemFactory::cloneWithNewType(pushedCreateFileSystemOp->newFileSystem()->type(), *oldFs)); newOp->newPartition().setFileSystem(FileSystemFactory::cloneWithNewType(pushedCreateFileSystemOp->newFileSystem()->type(), *oldFs));
delete oldFs; delete oldFs;
oldFs = NULL; oldFs = NULL;
@ -212,7 +212,7 @@ bool OperationStack::mergeCopyOperation(Operation*& currentOp, Operation*& pushe
DeleteOperation* pushedDeleteOp = dynamic_cast<DeleteOperation*>(pushedOp); DeleteOperation* pushedDeleteOp = dynamic_cast<DeleteOperation*>(pushedOp);
CopyOperation* pushedCopyOp = dynamic_cast<CopyOperation*>(pushedOp); CopyOperation* pushedCopyOp = dynamic_cast<CopyOperation*>(pushedOp);
// -- 1 -- // -- 1 --
if (pushedDeleteOp && &copyOp->copiedPartition() == &pushedDeleteOp->deletedPartition()) if (pushedDeleteOp && &copyOp->copiedPartition() == &pushedDeleteOp->deletedPartition())
{ {
@ -234,7 +234,7 @@ bool OperationStack::mergeCopyOperation(Operation*& currentOp, Operation*& pushe
copyOp->undo(); copyOp->undo();
delete operations().takeAt(operations().indexOf(copyOp)); delete operations().takeAt(operations().indexOf(copyOp));
return true; return true;
} }
@ -262,7 +262,7 @@ bool OperationStack::mergeCopyOperation(Operation*& currentOp, Operation*& pushe
bool OperationStack::mergeRestoreOperation(Operation*& currentOp, Operation*& pushedOp) bool OperationStack::mergeRestoreOperation(Operation*& currentOp, Operation*& pushedOp)
{ {
RestoreOperation* restoreOp = dynamic_cast<RestoreOperation*>(currentOp); RestoreOperation* restoreOp = dynamic_cast<RestoreOperation*>(currentOp);
if (restoreOp == NULL) if (restoreOp == NULL)
return false; return false;
@ -286,7 +286,7 @@ bool OperationStack::mergeRestoreOperation(Operation*& currentOp, Operation*& pu
restoreOp->undo(); restoreOp->undo();
delete operations().takeAt(operations().indexOf(restoreOp)); delete operations().takeAt(operations().indexOf(restoreOp));
return true; return true;
} }
@ -305,7 +305,7 @@ bool OperationStack::mergeRestoreOperation(Operation*& currentOp, Operation*& pu
bool OperationStack::mergePartFlagsOperation(Operation*& currentOp, Operation*& pushedOp) bool OperationStack::mergePartFlagsOperation(Operation*& currentOp, Operation*& pushedOp)
{ {
SetPartFlagsOperation* partFlagsOp = dynamic_cast<SetPartFlagsOperation*>(currentOp); SetPartFlagsOperation* partFlagsOp = dynamic_cast<SetPartFlagsOperation*>(currentOp);
if (partFlagsOp == NULL) if (partFlagsOp == NULL)
return false; return false;
@ -314,7 +314,7 @@ bool OperationStack::mergePartFlagsOperation(Operation*& currentOp, Operation*&
if (pushedFlagsOp && &partFlagsOp->flagPartition() == &pushedFlagsOp->flagPartition()) if (pushedFlagsOp && &partFlagsOp->flagPartition() == &pushedFlagsOp->flagPartition())
{ {
log() << i18nc("@info/plain", "Changing flags again for the same partition: Removing old operation."); log() << i18nc("@info/plain", "Changing flags again for the same partition: Removing old operation.");
pushedFlagsOp->setOldFlags(partFlagsOp->oldFlags()); pushedFlagsOp->setOldFlags(partFlagsOp->oldFlags());
partFlagsOp->undo(); partFlagsOp->undo();
delete operations().takeAt(operations().indexOf(partFlagsOp)); delete operations().takeAt(operations().indexOf(partFlagsOp));
@ -346,14 +346,14 @@ bool OperationStack::mergePartLabelOperation(Operation*& currentOp, Operation*&
if (pushedLabelOp && &partLabelOp->labeledPartition() == &pushedLabelOp->labeledPartition()) if (pushedLabelOp && &partLabelOp->labeledPartition() == &pushedLabelOp->labeledPartition())
{ {
log() << i18nc("@info/plain", "Changing label again for the same partition: Removing old operation."); log() << i18nc("@info/plain", "Changing label again for the same partition: Removing old operation.");
pushedLabelOp->setOldLabel(partLabelOp->oldLabel()); pushedLabelOp->setOldLabel(partLabelOp->oldLabel());
partLabelOp->undo(); partLabelOp->undo();
delete operations().takeAt(operations().indexOf(partLabelOp)); delete operations().takeAt(operations().indexOf(partLabelOp));
return true; return true;
} }
return false; return false;
} }
@ -383,7 +383,7 @@ void OperationStack::push(Operation* o)
if (mergePartFlagsOperation(currentOp, o)) if (mergePartFlagsOperation(currentOp, o))
break; break;
if (mergePartLabelOperation(currentOp, o)) if (mergePartLabelOperation(currentOp, o))
break; break;
} }
@ -431,7 +431,11 @@ void OperationStack::clearDevices()
Device* OperationStack::findDeviceForPartition(const Partition* p) Device* OperationStack::findDeviceForPartition(const Partition* p)
{ {
foreach (Device* d, previewDevices()) foreach (Device* d, previewDevices())
foreach(const Partition* part, d->partitionTable().children()) {
if (d->partitionTable() == NULL)
continue;
foreach(const Partition* part, d->partitionTable()->children())
{ {
if (part == p) if (part == p)
return d; return d;
@ -440,6 +444,7 @@ Device* OperationStack::findDeviceForPartition(const Partition* p)
if (child == p) if (child == p)
return d; return d;
} }
}
return NULL; return NULL;
} }
@ -450,6 +455,6 @@ Device* OperationStack::findDeviceForPartition(const Partition* p)
void OperationStack::addDevice(Device* d) void OperationStack::addDevice(Device* d)
{ {
Q_ASSERT(d); Q_ASSERT(d);
m_PreviewDevices.append(d); m_PreviewDevices.append(d);
} }

View File

@ -271,10 +271,12 @@ bool PartitionTable::isSnapped(const Device& d, const Partition& p)
*/ */
static bool canSnapToSector(const Device& d, const Partition& p, qint64 s, const Partition* originalPartition) static bool canSnapToSector(const Device& d, const Partition& p, qint64 s, const Partition* originalPartition)
{ {
Q_ASSERT(d.partitionTable());
if (s < d.sectorsPerTrack() || s >= d.totalSectors()) if (s < d.sectorsPerTrack() || s >= d.totalSectors())
return false; return false;
const Partition* other = d.partitionTable().findPartitionBySector(s, PartitionRole(PartitionRole::Logical | PartitionRole::Primary | PartitionRole::Extended | PartitionRole::Unallocated)); const Partition* other = d.partitionTable()->findPartitionBySector(s, PartitionRole(PartitionRole::Logical | PartitionRole::Primary | PartitionRole::Extended | PartitionRole::Unallocated));
if (other && other->roles().has(PartitionRole::Unallocated)) if (other && other->roles().has(PartitionRole::Unallocated))
other = NULL; other = NULL;

View File

@ -53,7 +53,7 @@ void InfoPane::clear()
int InfoPane::createHeader(const QString& title) int InfoPane::createHeader(const QString& title)
{ {
int y = 0; int y = 0;
QLabel* label = new QLabel(title, this); QLabel* label = new QLabel(title, this);
QFont font; QFont font;
font.setBold(true); font.setBold(true);
@ -118,9 +118,16 @@ void InfoPane::showDevice(const Device& d)
int y = createHeader(d.name()); int y = createHeader(d.name());
createLabels(i18nc("@label device", "Path:"), d.deviceNode(), y++); createLabels(i18nc("@label device", "Path:"), d.deviceNode(), y++);
const QString type = (d.partitionTable().isReadOnly()) QString type = "---";
? i18nc("@label device", "%1 (read only)", d.partitionTable().typeName()) QString maxPrimaries = "---";
: d.partitionTable().typeName();
if (d.partitionTable() != NULL)
{
type = (d.partitionTable()->isReadOnly())
? i18nc("@label device", "%1 (read only)", d.partitionTable()->typeName())
: d.partitionTable()->typeName();
maxPrimaries = QString("%1/%2").arg(d.partitionTable()->numPrimaries()).arg(d.partitionTable()->maxPrimaries());
}
createLabels(i18nc("@label device", "Type:"), type, y++); createLabels(i18nc("@label device", "Type:"), type, y++);
createLabels(i18nc("@label device", "Capacity:"), Capacity(d).toString(), y++); createLabels(i18nc("@label device", "Capacity:"), Capacity(d).toString(), y++);
@ -130,5 +137,5 @@ void InfoPane::showDevice(const Device& d)
createLabels(i18nc("@label device", "Sectors:"), KGlobal::locale()->formatNumber(d.sectorsPerTrack(), 0), y++); createLabels(i18nc("@label device", "Sectors:"), KGlobal::locale()->formatNumber(d.sectorsPerTrack(), 0), y++);
createLabels(i18nc("@label device", "Sector size:"), Capacity(d.sectorSize()).toString(Capacity::Byte, Capacity::AppendUnit), y++); createLabels(i18nc("@label device", "Sector size:"), Capacity(d.sectorSize()).toString(Capacity::Byte, Capacity::AppendUnit), y++);
createLabels(i18nc("@label device", "Cylinder size:"), i18ncp("@label", "1 Sector", "%1 Sectors", d.cylinderSize()), y++); createLabels(i18nc("@label device", "Cylinder size:"), i18ncp("@label", "1 Sector", "%1 Sectors", d.cylinderSize()), y++);
createLabels(i18nc("@label device", "Primaries/Max:"), QString("%1/%2").arg(d.partitionTable().numPrimaries()).arg(d.partitionTable().maxPrimaries()), y++); createLabels(i18nc("@label device", "Primaries/Max:"), maxPrimaries, y++);
} }

View File

@ -397,7 +397,7 @@ void MainWindow::enableActions()
const Partition* part = selectedPartition(); const Partition* part = selectedPartition();
const bool readOnly = selectedDevice() == NULL || selectedDevice()->partitionTable().isReadOnly(); const bool readOnly = selectedDevice() == NULL || selectedDevice()->partitionTable() == NULL || selectedDevice()->partitionTable()->isReadOnly();
actionCollection()->action("newPartition")->setEnabled(!readOnly && NewOperation::canCreateNew(part)); actionCollection()->action("newPartition")->setEnabled(!readOnly && NewOperation::canCreateNew(part));
const bool canResize = ResizeOperation::canGrow(part) || ResizeOperation::canShrink(part) || ResizeOperation::canMove(part); const bool canResize = ResizeOperation::canGrow(part) || ResizeOperation::canShrink(part) || ResizeOperation::canMove(part);
@ -497,25 +497,28 @@ void MainWindow::updatePartitions()
if (selectedDevice() == NULL) if (selectedDevice() == NULL)
return; return;
partTableWidget().setPartitionTable(&selectedDevice()->partitionTable()); partTableWidget().setPartitionTable(selectedDevice()->partitionTable());
QTreeWidgetItem* deviceItem = new QTreeWidgetItem(); QTreeWidgetItem* deviceItem = new QTreeWidgetItem();
deviceItem->setText(0, selectedDevice()->name()); deviceItem->setText(0, selectedDevice()->name());
deviceItem->setIcon(0, SmallIcon("drive-harddisk")); deviceItem->setIcon(0, SmallIcon("drive-harddisk"));
treePartitions().addTopLevelItem(deviceItem); treePartitions().addTopLevelItem(deviceItem);
foreach(const Partition* p, selectedDevice()->partitionTable().children()) if (selectedDevice()->partitionTable() != NULL)
{ {
QTreeWidgetItem* item = createTreeWidgetItem(*p); foreach(const Partition* p, selectedDevice()->partitionTable()->children())
foreach(const Partition* child, p->children())
{ {
QTreeWidgetItem* childItem = createTreeWidgetItem(*child); QTreeWidgetItem* item = createTreeWidgetItem(*p);
item->addChild(childItem);
}
deviceItem->addChild(item); foreach(const Partition* child, p->children())
item->setExpanded(true); {
QTreeWidgetItem* childItem = createTreeWidgetItem(*child);
item->addChild(childItem);
}
deviceItem->addChild(item);
item->setExpanded(true);
}
} }
treePartitions().setFirstItemColumnSpanned(deviceItem, true); treePartitions().setFirstItemColumnSpanned(deviceItem, true);
@ -549,16 +552,14 @@ void MainWindow::on_m_TreePartitions_itemDoubleClicked(QTreeWidgetItem* item, in
Partition* MainWindow::selectedPartition() Partition* MainWindow::selectedPartition()
{ {
if (selectedDevice() == NULL || partTableWidget().activeWidget() == NULL || partTableWidget().activeWidget()->partition() == NULL) if (selectedDevice() == NULL || selectedDevice()->partitionTable() == NULL || partTableWidget().activeWidget() == NULL || partTableWidget().activeWidget()->partition() == NULL)
return NULL; return NULL;
// The active partition we get from PartTableWidget is const; we need non-const. // The active partition we get from PartTableWidget is const; we need non-const.
// So take the first sector and find the partition in the selected device's // So take the first sector and find the partition in the selected device's
// partition table. // partition table.
const Partition* activePartition = partTableWidget().activeWidget()->partition(); const Partition* activePartition = partTableWidget().activeWidget()->partition();
PartitionTable& ptable = selectedDevice()->partitionTable(); return selectedDevice()->partitionTable()->findPartitionBySector(activePartition->firstSector(), PartitionRole(PartitionRole::Any));
return ptable.findPartitionBySector(activePartition->firstSector(), PartitionRole(PartitionRole::Any));
} }
Device* MainWindow::selectedDevice() Device* MainWindow::selectedDevice()
@ -729,12 +730,14 @@ void MainWindow::onFinished()
static bool checkTooManyPartitions(QWidget* parent, const Device& d, const Partition& p) static bool checkTooManyPartitions(QWidget* parent, const Device& d, const Partition& p)
{ {
if (p.roles().has(PartitionRole::Unallocated) && d.partitionTable().numPrimaries() >= d.partitionTable().maxPrimaries() && !p.roles().has(PartitionRole::Logical)) Q_ASSERT(d.partitionTable());
if (p.roles().has(PartitionRole::Unallocated) && d.partitionTable()->numPrimaries() >= d.partitionTable()->maxPrimaries() && !p.roles().has(PartitionRole::Logical))
{ {
KMessageBox::sorry(parent, i18nc("@info", KMessageBox::sorry(parent, i18nc("@info",
"<para>There are already %1 primary partitions on this device. This is the maximum number its partition table can handle.</para>" "<para>There are already %1 primary partitions on this device. This is the maximum number its partition table can handle.</para>"
"<para>You cannot create, paste or restore a primary partition on it before you delete an existing one.</para>", "<para>You cannot create, paste or restore a primary partition on it before you delete an existing one.</para>",
d.partitionTable().numPrimaries()), i18nc("@title:window", "Too Many Primary Partitions.")); d.partitionTable()->numPrimaries()), i18nc("@title:window", "Too Many Primary Partitions."));
return true; return true;
} }
@ -752,12 +755,20 @@ void MainWindow::onNewPartition()
return; return;
} }
Q_ASSERT(selectedDevice()->partitionTable());
if (selectedDevice()->partitionTable() == NULL)
{
kWarning() << "partition table on selected device is null";
return;
}
if (checkTooManyPartitions(this, *selectedDevice(), *selectedPartition())) if (checkTooManyPartitions(this, *selectedDevice(), *selectedPartition()))
return; return;
Partition* newPartition = NewOperation::createNew(*selectedPartition()); Partition* newPartition = NewOperation::createNew(*selectedPartition());
NewDialog dlg(this, *selectedDevice(), *newPartition, selectedDevice()->partitionTable().childRoles(*selectedPartition())); NewDialog dlg(this, *selectedDevice(), *newPartition, selectedDevice()->partitionTable()->childRoles(*selectedPartition()));
if (dlg.exec() == KDialog::Accepted) if (dlg.exec() == KDialog::Accepted)
{ {
PartitionTable::snap(*selectedDevice(), *newPartition); PartitionTable::snap(*selectedDevice(), *newPartition);
@ -835,8 +846,16 @@ void MainWindow::onResizePartition()
return; return;
} }
const qint64 freeBefore = selectedDevice()->partitionTable().freeSectorsBefore(*selectedPartition()); Q_ASSERT(selectedDevice()->partitionTable());
const qint64 freeAfter = selectedDevice()->partitionTable().freeSectorsAfter(*selectedPartition());
if (selectedDevice()->partitionTable() == NULL)
{
kWarning() << "partition table on selected device is null";
return;
}
const qint64 freeBefore = selectedDevice()->partitionTable()->freeSectorsBefore(*selectedPartition());
const qint64 freeAfter = selectedDevice()->partitionTable()->freeSectorsAfter(*selectedPartition());
Partition resizedPartition(*selectedPartition()); Partition resizedPartition(*selectedPartition());
ResizeDialog dlg(this, *selectedDevice(), resizedPartition, freeBefore, freeAfter); ResizeDialog dlg(this, *selectedDevice(), resizedPartition, freeBefore, freeAfter);

View File

@ -45,7 +45,7 @@ PartPropsDialog::PartPropsDialog(QWidget* parent, Device& d, Partition& p) :
m_Partition(p), m_Partition(p),
m_WarnFileSystemChange(false), m_WarnFileSystemChange(false),
m_DialogWidget(new PartPropsWidget(this)), m_DialogWidget(new PartPropsWidget(this)),
m_ReadOnly(partition().isMounted() || partition().state() == Partition::StateCopy || partition().state() == Partition::StateRestore || d.partitionTable().isReadOnly()), m_ReadOnly(partition().isMounted() || partition().state() == Partition::StateCopy || partition().state() == Partition::StateRestore || d.partitionTable()->isReadOnly()),
m_ForceRecreate(false) m_ForceRecreate(false)
{ {
setMainWidget(&dialogWidget()); setMainWidget(&dialogWidget());

View File

@ -345,8 +345,10 @@ void PartResizerWidget::resizeLogicals()
if (!partition().roles().has(PartitionRole::Extended) || partition().children().size() == 0) if (!partition().roles().has(PartitionRole::Extended) || partition().children().size() == 0)
return; return;
device().partitionTable().removeUnallocated(&partition()); Q_ASSERT(device().partitionTable());
device().partitionTable().insertUnallocated(device(), &partition(), partition().firstSector());
device().partitionTable()->removeUnallocated(&partition());
device().partitionTable()->insertUnallocated(device(), &partition(), partition().firstSector());
partWidget().updateChildren(); partWidget().updateChildren();
} }

View File

@ -45,22 +45,17 @@ PartTableWidget::PartTableWidget(QWidget* parent) :
*/ */
void PartTableWidget::setPartitionTable(const PartitionTable* ptable) void PartTableWidget::setPartitionTable(const PartitionTable* ptable)
{ {
Q_ASSERT(ptable);
clear(); clear();
if (ptable == NULL)
{
kWarning() << "ptable is null.";
return;
}
m_PartitionTable = ptable; m_PartitionTable = ptable;
foreach(const Partition* p, partitionTable()->children()) if (partitionTable() != NULL)
{ {
widgets().append(new PartWidget(this, this, p)); foreach(const Partition* p, partitionTable()->children())
widgets().last()->show(); {
widgets().append(new PartWidget(this, this, p));
widgets().last()->show();
}
} }
if (widgets().isEmpty()) if (widgets().isEmpty())
@ -149,7 +144,7 @@ void PartTableWidget::mouseDoubleClickEvent(QMouseEvent* event)
{ {
if (event->button() != Qt::LeftButton) if (event->button() != Qt::LeftButton)
return; return;
event->accept(); event->accept();
const PartWidget* child = static_cast<PartWidget*>(childAt(event->pos())); const PartWidget* child = static_cast<PartWidget*>(childAt(event->pos()));

View File

@ -181,5 +181,7 @@ void SizeDialogBase::onFreeSpaceAfterChanged(int newAfter)
const PartitionTable& SizeDialogBase::partitionTable() const const PartitionTable& SizeDialogBase::partitionTable() const
{ {
return device().partitionTable(); Q_ASSERT(device().partitionTable());
return *device().partitionTable();
} }

View File

@ -45,7 +45,9 @@ bool CreatePartitionTableJob::run(Report& parent)
if (openPed(device().deviceNode(), true)) if (openPed(device().deviceNode(), true))
{ {
PedDiskType* pedDiskType = ped_disk_type_get(device().partitionTable().typeName().toAscii()); Q_ASSERT(device().partitionTable());
PedDiskType* pedDiskType = ped_disk_type_get(device().partitionTable()->typeName().toAscii());
if (pedDiskType) if (pedDiskType)
{ {
@ -54,7 +56,7 @@ bool CreatePartitionTableJob::run(Report& parent)
ped_disk_destroy(pedDisk); ped_disk_destroy(pedDisk);
} }
else else
report->line() << i18nc("@info/plain", "Creating partition table failed: Could not retrieve partition table type \"%1\" for <filename>%2</filename>.", device().partitionTable().typeName(), device().deviceNode()); report->line() << i18nc("@info/plain", "Creating partition table failed: Could not retrieve partition table type \"%1\" for <filename>%2</filename>.", device().partitionTable()->typeName(), device().deviceNode());
closePed(); closePed();
} }

View File

@ -58,13 +58,15 @@ CopyOperation::CopyOperation(Device& targetdevice, Partition* copiedpartition, D
m_CheckTargetJob(NULL), m_CheckTargetJob(NULL),
m_MaximizeJob(NULL) m_MaximizeJob(NULL)
{ {
Partition* dest = targetDevice().partitionTable().findPartitionBySector(copiedPartition().firstSector(), PartitionRole(PartitionRole::Primary | PartitionRole::Logical | PartitionRole::Unallocated)); Q_ASSERT(targetDevice().partitionTable());
Partition* dest = targetDevice().partitionTable()->findPartitionBySector(copiedPartition().firstSector(), PartitionRole(PartitionRole::Primary | PartitionRole::Logical | PartitionRole::Unallocated));
Q_ASSERT(dest); Q_ASSERT(dest);
if (dest == NULL) if (dest == NULL)
kWarning() << "destination partition not found at sector " << copiedPartition().firstSector(); kWarning() << "destination partition not found at sector " << copiedPartition().firstSector();
if (dest && !dest->roles().has(PartitionRole::Unallocated)) if (dest && !dest->roles().has(PartitionRole::Unallocated))
{ {
copiedPartition().setLastSector(dest->lastSector()); copiedPartition().setLastSector(dest->lastSector());
@ -72,10 +74,10 @@ CopyOperation::CopyOperation(Device& targetdevice, Partition* copiedpartition, D
} }
addJob(m_CheckSourceJob = new CheckFileSystemJob(sourcePartition())); addJob(m_CheckSourceJob = new CheckFileSystemJob(sourcePartition()));
if (overwrittenPartition() == NULL) if (overwrittenPartition() == NULL)
addJob(m_CreatePartitionJob = new CreatePartitionJob(targetDevice(), copiedPartition())); addJob(m_CreatePartitionJob = new CreatePartitionJob(targetDevice(), copiedPartition()));
addJob(m_CopyFSJob = new CopyFileSystemJob(targetDevice(), copiedPartition(), sourceDevice(), sourcePartition())); addJob(m_CopyFSJob = new CopyFileSystemJob(targetDevice(), copiedPartition(), sourceDevice(), sourcePartition()));
addJob(m_CheckTargetJob = new CheckFileSystemJob(copiedPartition())); addJob(m_CheckTargetJob = new CheckFileSystemJob(copiedPartition()));
addJob(m_MaximizeJob = new ResizeFileSystemJob(targetDevice(), copiedPartition())); addJob(m_MaximizeJob = new ResizeFileSystemJob(targetDevice(), copiedPartition()));
@ -94,7 +96,7 @@ void CopyOperation::preview()
{ {
if (overwrittenPartition()) if (overwrittenPartition())
removePreviewPartition(targetDevice(), *overwrittenPartition()); removePreviewPartition(targetDevice(), *overwrittenPartition());
insertPreviewPartition(targetDevice(), copiedPartition()); insertPreviewPartition(targetDevice(), copiedPartition());
} }
@ -110,7 +112,7 @@ bool CopyOperation::execute(Report& parent)
{ {
bool rval = false; bool rval = false;
bool warning = false; bool warning = false;
Report* report = parent.newChild(description()); Report* report = parent.newChild(description());
// check the source first // check the source first
@ -136,7 +138,7 @@ bool CopyOperation::execute(Report& parent)
copiedPartition().setDevicePath(overwrittenPartition()->devicePath()); copiedPartition().setDevicePath(overwrittenPartition()->devicePath());
copiedPartition().setNumber(overwrittenPartition()->number()); copiedPartition().setNumber(overwrittenPartition()->number());
} }
// now run the copy job itself // now run the copy job itself
if ((rval = copyFSJob()->run(*report))) if ((rval = copyFSJob()->run(*report)))
{ {
@ -179,7 +181,7 @@ bool CopyOperation::execute(Report& parent)
setStatus(StatusError); setStatus(StatusError);
report->setStatus(i18nc("@info/plain status (success, error, warning...) of operation", "%1: %2", description(), statusText())); report->setStatus(i18nc("@info/plain status (success, error, warning...) of operation", "%1: %2", description(), statusText()));
return rval; return rval;
} }
@ -269,7 +271,7 @@ Partition* CopyOperation::createCopy(const Partition& target, const Partition& s
p->fileSystem().setFirstSector(p->firstSector()); p->fileSystem().setFirstSector(p->firstSector());
p->fileSystem().setLastSector(p->lastSector()); p->fileSystem().setLastSector(p->lastSector());
return p; return p;
} }
@ -281,7 +283,7 @@ bool CopyOperation::canCopy(const Partition* p)
{ {
if (p == NULL) if (p == NULL)
return false; return false;
if (p->isMounted()) if (p->isMounted())
return false; return false;
@ -301,10 +303,10 @@ bool CopyOperation::canPaste(const Partition* p, const Partition* source)
{ {
if (p == NULL || source == NULL) if (p == NULL || source == NULL)
return false; return false;
if (p->isMounted()) if (p->isMounted())
return false; return false;
if (p->roles().has(PartitionRole::Extended)) if (p->roles().has(PartitionRole::Extended))
return false; return false;

View File

@ -36,12 +36,12 @@
CreatePartitionTableOperation::CreatePartitionTableOperation(Device& d) : CreatePartitionTableOperation::CreatePartitionTableOperation(Device& d) :
Operation(), Operation(),
m_TargetDevice(d), m_TargetDevice(d),
m_OldPartitionTable(&targetDevice().partitionTable()), m_OldPartitionTable(targetDevice().partitionTable()),
m_PartitionTable(new PartitionTable()), m_PartitionTable(new PartitionTable()),
m_CreatePartitionTableJob(new CreatePartitionTableJob(targetDevice())) m_CreatePartitionTableJob(new CreatePartitionTableJob(targetDevice()))
{ {
addJob(createPartitionTableJob()); addJob(createPartitionTableJob());
partitionTable().insertUnallocated(targetDevice(), &partitionTable(), targetDevice().sectorsPerTrack()); partitionTable()->insertUnallocated(targetDevice(), partitionTable(), targetDevice().sectorsPerTrack());
} }
CreatePartitionTableOperation::~CreatePartitionTableOperation() CreatePartitionTableOperation::~CreatePartitionTableOperation()
@ -52,19 +52,21 @@ CreatePartitionTableOperation::~CreatePartitionTableOperation()
void CreatePartitionTableOperation::preview() void CreatePartitionTableOperation::preview()
{ {
targetDevice().setPartitionTable(&partitionTable()); targetDevice().setPartitionTable(partitionTable());
targetDevice().partitionTable().updateUnallocated(targetDevice()); targetDevice().partitionTable()->updateUnallocated(targetDevice());
} }
void CreatePartitionTableOperation::undo() void CreatePartitionTableOperation::undo()
{ {
targetDevice().setPartitionTable(&oldPartitionTable()); targetDevice().setPartitionTable(oldPartitionTable());
targetDevice().partitionTable().updateUnallocated(targetDevice());
if (targetDevice().partitionTable())
targetDevice().partitionTable()->updateUnallocated(targetDevice());
} }
bool CreatePartitionTableOperation::execute(Report& parent) bool CreatePartitionTableOperation::execute(Report& parent)
{ {
targetDevice().setPartitionTable(&partitionTable()); targetDevice().setPartitionTable(partitionTable());
return Operation::execute(parent); return Operation::execute(parent);
} }
@ -74,7 +76,7 @@ bool CreatePartitionTableOperation::execute(Report& parent)
*/ */
bool CreatePartitionTableOperation::canCreate(const Device* device) bool CreatePartitionTableOperation::canCreate(const Device* device)
{ {
return device != NULL && !device->partitionTable().isChildMounted(); return device != NULL && (device->partitionTable() == NULL || !device->partitionTable()->isChildMounted());
} }
QString CreatePartitionTableOperation::description() const QString CreatePartitionTableOperation::description() const

View File

@ -53,11 +53,11 @@ class CreatePartitionTableOperation : public Operation
Device& targetDevice() { return m_TargetDevice; } Device& targetDevice() { return m_TargetDevice; }
const Device& targetDevice() const { return m_TargetDevice; } const Device& targetDevice() const { return m_TargetDevice; }
PartitionTable& partitionTable() { return *m_PartitionTable; } PartitionTable* partitionTable() { return m_PartitionTable; }
PartitionTable& oldPartitionTable() { return *m_OldPartitionTable; } PartitionTable* oldPartitionTable() { return m_OldPartitionTable; }
CreatePartitionTableJob* createPartitionTableJob() { return m_CreatePartitionTableJob; } CreatePartitionTableJob* createPartitionTableJob() { return m_CreatePartitionTableJob; }
private: private:
Device& m_TargetDevice; Device& m_TargetDevice;
PartitionTable* m_OldPartitionTable; PartitionTable* m_OldPartitionTable;

View File

@ -47,17 +47,21 @@ Operation::~Operation()
void Operation::insertPreviewPartition(Device& device, Partition& p) void Operation::insertPreviewPartition(Device& device, Partition& p)
{ {
device.partitionTable().removeUnallocated(); Q_ASSERT(device.partitionTable());
device.partitionTable()->removeUnallocated();
p.parent()->insert(&p); p.parent()->insert(&p);
device.partitionTable().updateUnallocated(device); device.partitionTable()->updateUnallocated(device);
} }
void Operation::removePreviewPartition(Device& device, Partition& p) void Operation::removePreviewPartition(Device& device, Partition& p)
{ {
Q_ASSERT(device.partitionTable());
if (p.parent()->remove(&p)) if (p.parent()->remove(&p))
device.partitionTable().updateUnallocated(device); device.partitionTable()->updateUnallocated(device);
else else
kWarning() << "failed to remove partition " << p.deviceNode() << " at " << &p << " from preview."; kWarning() << "failed to remove partition " << p.deviceNode() << " at " << &p << " from preview.";
} }
@ -76,7 +80,7 @@ QString Operation::statusText() const
}; };
Q_ASSERT(status() >= 0 && static_cast<quint32>(status()) < sizeof(s) / sizeof(s[0])); Q_ASSERT(status() >= 0 && static_cast<quint32>(status()) < sizeof(s) / sizeof(s[0]));
if (status() < 0 || static_cast<quint32>(status()) >= sizeof(s) / sizeof(s[0])) if (status() < 0 || static_cast<quint32>(status()) >= sizeof(s) / sizeof(s[0]))
{ {
kWarning() << "invalid status " << status(); kWarning() << "invalid status " << status();
@ -98,15 +102,15 @@ QIcon Operation::statusIcon() const
"dialog-warning", "dialog-warning",
"dialog-error" "dialog-error"
}; };
Q_ASSERT(status() >= 0 && static_cast<quint32>(status()) < sizeof(icons) / sizeof(icons[0])); Q_ASSERT(status() >= 0 && static_cast<quint32>(status()) < sizeof(icons) / sizeof(icons[0]));
if (status() < 0 || static_cast<quint32>(status()) >= sizeof(icons) / sizeof(icons[0])) if (status() < 0 || static_cast<quint32>(status()) >= sizeof(icons) / sizeof(icons[0]))
{ {
kWarning() << "invalid status " << status(); kWarning() << "invalid status " << status();
return QIcon(); return QIcon();
} }
if (status() == StatusNone) if (status() == StatusNone)
return QIcon(); return QIcon();
@ -163,7 +167,7 @@ bool Operation::execute(Report& parent)
bool rval = false; bool rval = false;
Report* report = parent.newChild(description()); Report* report = parent.newChild(description());
foreach (Job* job, jobs()) foreach (Job* job, jobs())
if (!(rval = job->run(*report))) if (!(rval = job->run(*report)))
break; break;
@ -171,6 +175,6 @@ bool Operation::execute(Report& parent)
setStatus(rval ? StatusFinishedSuccess : StatusError); setStatus(rval ? StatusFinishedSuccess : StatusError);
report->setStatus(i18nc("@info/plain status (success, error, warning...) of operation", "%1: %2", description(), statusText())); report->setStatus(i18nc("@info/plain status (success, error, warning...) of operation", "%1: %2", description(), statusText()));
return rval; return rval;
} }

View File

@ -62,13 +62,15 @@ RestoreOperation::RestoreOperation(Device& d, Partition* p, const QString& filen
{ {
restorePartition().setState(Partition::StateRestore); restorePartition().setState(Partition::StateRestore);
Partition* dest = targetDevice().partitionTable().findPartitionBySector(restorePartition().firstSector(), PartitionRole(PartitionRole::Primary | PartitionRole::Logical | PartitionRole::Unallocated)); Q_ASSERT(targetDevice().partitionTable());
Partition* dest = targetDevice().partitionTable()->findPartitionBySector(restorePartition().firstSector(), PartitionRole(PartitionRole::Primary | PartitionRole::Logical | PartitionRole::Unallocated));
Q_ASSERT(dest); Q_ASSERT(dest);
if (dest == NULL) if (dest == NULL)
kWarning() << "destination partition not found at sector " << restorePartition().firstSector(); kWarning() << "destination partition not found at sector " << restorePartition().firstSector();
if (dest && !dest->roles().has(PartitionRole::Unallocated)) if (dest && !dest->roles().has(PartitionRole::Unallocated))
{ {
restorePartition().setLastSector(dest->lastSector()); restorePartition().setLastSector(dest->lastSector());
@ -78,7 +80,7 @@ RestoreOperation::RestoreOperation(Device& d, Partition* p, const QString& filen
if (!overwrittenPartition()) if (!overwrittenPartition())
addJob(m_CreatePartitionJob = new CreatePartitionJob(targetDevice(), restorePartition())); addJob(m_CreatePartitionJob = new CreatePartitionJob(targetDevice(), restorePartition()));
addJob(m_RestoreJob = new RestoreFileSystemJob(targetDevice(), restorePartition(), fileName())); addJob(m_RestoreJob = new RestoreFileSystemJob(targetDevice(), restorePartition(), fileName()));
addJob(m_CheckTargetJob = new CheckFileSystemJob(restorePartition())); addJob(m_CheckTargetJob = new CheckFileSystemJob(restorePartition()));
addJob(m_MaximizeJob = new ResizeFileSystemJob(targetDevice(), restorePartition())); addJob(m_MaximizeJob = new ResizeFileSystemJob(targetDevice(), restorePartition()));
@ -110,12 +112,12 @@ bool RestoreOperation::execute(Report& parent)
{ {
bool rval = false; bool rval = false;
bool warning = false; bool warning = false;
Report* report = parent.newChild(description()); Report* report = parent.newChild(description());
if (overwrittenPartition()) if (overwrittenPartition())
restorePartition().setNumber(overwrittenPartition()->number()); restorePartition().setNumber(overwrittenPartition()->number());
if (overwrittenPartition() || (rval = createPartitionJob()->run(*report))) if (overwrittenPartition() || (rval = createPartitionJob()->run(*report)))
{ {
restorePartition().setState(Partition::StateNone); restorePartition().setState(Partition::StateNone);
@ -144,7 +146,7 @@ bool RestoreOperation::execute(Report& parent)
} }
else else
report->line() << i18nc("@info/plain", "Creating the destination partition to restore to failed."); report->line() << i18nc("@info/plain", "Creating the destination partition to restore to failed.");
if (rval) if (rval)
setStatus(warning ? StatusFinishedWarning : StatusFinishedSuccess); setStatus(warning ? StatusFinishedWarning : StatusFinishedSuccess);
else else
@ -159,14 +161,14 @@ QString RestoreOperation::description() const
{ {
if (overwrittenPartition()) if (overwrittenPartition())
return QString(i18nc("@info/plain", "Restore partition from <filename>%1</filename> to <filename>%2</filename>", fileName(), overwrittenPartition()->deviceNode())); return QString(i18nc("@info/plain", "Restore partition from <filename>%1</filename> to <filename>%2</filename>", fileName(), overwrittenPartition()->deviceNode()));
return QString(i18nc("@info/plain", "Restore partition on <filename>%1</filename> at %2 from <filename>%3</filename>", targetDevice().deviceNode(), Capacity(restorePartition().firstSector() * restorePartition().sectorSize()).toString(), fileName())); return QString(i18nc("@info/plain", "Restore partition on <filename>%1</filename> at %2 from <filename>%3</filename>", targetDevice().deviceNode(), Capacity(restorePartition().firstSector() * restorePartition().sectorSize()).toString(), fileName()));
} }
void RestoreOperation::setOverwrittenPartition(Partition* p) void RestoreOperation::setOverwrittenPartition(Partition* p)
{ {
// This is copied from CopyOperation. One day we might create a common base class ;-) // This is copied from CopyOperation. One day we might create a common base class ;-)
cleanupOverwrittenPartition(); cleanupOverwrittenPartition();
m_OverwrittenPartition = p; m_OverwrittenPartition = p;
m_MustDeleteOverwritten = (p && p->state() == Partition::StateNone); m_MustDeleteOverwritten = (p && p->state() == Partition::StateNone);
@ -192,10 +194,10 @@ bool RestoreOperation::canRestore(const Partition* p)
if (p->isMounted()) if (p->isMounted())
return false; return false;
if (p->roles().has(PartitionRole::Extended)) if (p->roles().has(PartitionRole::Extended))
return false; return false;
return true; return true;
} }
/** Creates a new Partition to restore to. /** Creates a new Partition to restore to.