From 56d794d68eaf9562d60cb397db1a030561960c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 1 Feb 2008 14:50:06 +0000 Subject: [PATCH] * implemented detecting and displaying available space on devices and partitions - I couldn't test it yet, but what is definitely missing is being able to select these spaces to create new partitions on them * fixed the bug that if you select a partition on another disk, the disk view does not switch to the new disk. (I was comparing disk pointers, but since I deleted the old BDiskDevice instance first, the new one got assigned the same pointer... at least it appears I am not leaking memory anywhere... :-)) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23811 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/drivesetup/DiskView.cpp | 83 +++++++++++++++++++++------ src/apps/drivesetup/DiskView.h | 1 - src/apps/drivesetup/MainWindow.cpp | 28 ++++++++- src/apps/drivesetup/PartitionList.cpp | 19 +++--- src/apps/drivesetup/PartitionList.h | 5 +- 5 files changed, 101 insertions(+), 35 deletions(-) diff --git a/src/apps/drivesetup/DiskView.cpp b/src/apps/drivesetup/DiskView.cpp index d026578bae..4a63ca3b8a 100644 --- a/src/apps/drivesetup/DiskView.cpp +++ b/src/apps/drivesetup/DiskView.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include using BPrivate::HashMap; @@ -24,10 +25,13 @@ static const float kLayoutInset = 6; class PartitionView : public BView { public: - PartitionView(const char* name, float weight, int32 level, partition_id id) + PartitionView(const char* name, float weight, off_t offset, + int32 level, partition_id id) : BView(name, B_WILL_DRAW | B_SUPPORTS_LAYOUT | B_FULL_UPDATE_ON_RESIZE) , fID(id) , fWeight(weight) + , fOffset(offset) + , fLevel(level) , fSelected(false) , fMouseOver(false) , fGroupLayout(new BGroupLayout(B_HORIZONTAL, kLayoutInset)) @@ -37,7 +41,7 @@ public: SetViewColor(B_TRANSPARENT_COLOR); rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); base = tint_color(base, B_LIGHTEN_2_TINT); - base = tint_color(base, 1 + 0.13 * level); + base = tint_color(base, 1 + 0.13 * (level - 1)); SetLowColor(base); SetHighColor(tint_color(base, B_DARKEN_1_TINT)); @@ -84,11 +88,16 @@ public: SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); StrokeRect(b, B_SOLID_HIGH); b.InsetBy(1, 1); + StrokeRect(b, B_SOLID_HIGH); + b.InsetBy(1, 1); + } else if (fLevel > 0) { + StrokeRect(b, B_SOLID_HIGH); + b.InsetBy(1, 1); } - StrokeRect(b, B_SOLID_HIGH); - b.InsetBy(1, 1); FillRect(b, B_SOLID_LOW); + + // prevent the text from moving when border width changes if (!fSelected) b.InsetBy(1, 1); @@ -127,6 +136,16 @@ public: return fWeight; } + off_t Offset() const + { + return fOffset; + } + + int32 Level() const + { + return fLevel; + } + BGroupLayout* GroupLayout() const { return fGroupLayout; @@ -153,6 +172,8 @@ private: private: partition_id fID; float fWeight; + off_t fOffset; + int32 fLevel; bool fSelected; bool fMouseOver; BGroupLayout* fGroupLayout; @@ -170,20 +191,22 @@ public: virtual bool Visit(BDiskDevice* device) { - PartitionView* view = new PartitionView("Device", 1.0, 0, device->ID()); + PartitionView* view = new PartitionView("Device", 1.0, + device->Offset(), 0, device->ID()); fViewMap.Put(device->ID(), view); fView->GetLayout()->AddView(view); + _AddSpaces(device, view); return false; } virtual bool Visit(BPartition* partition, int32 level) { - if (!partition->Parent() || !fViewMap.ContainsKey(partition->Parent()->ID())) + if (!partition->Parent() + || !fViewMap.ContainsKey(partition->Parent()->ID())) return false; // calculate size factor within parent frame -// TODO: support gaps view these offsets: -// off_t offset = partition->Offset(); + off_t offset = partition->Offset(); // off_t parentOffset = partition->Parent()->Offset(); off_t size = partition->Size(); off_t parentSize = partition->Parent()->Size(); @@ -197,13 +220,15 @@ public: name << "Partition " << partition->ID(); } partition_id id = partition->ID(); - PartitionView* view = new PartitionView(name.String(), scale, level, id); + PartitionView* view = new PartitionView(name.String(), scale, offset, + level, id); view->SetSelected(id == fSelectedPartition); PartitionView* parent = fViewMap.Get(partition->Parent()->ID()); BGroupLayout* layout = parent->GroupLayout(); layout->AddView(view, scale); fViewMap.Put(partition->ID(), view); + _AddSpaces(partition, view); return false; } @@ -232,6 +257,35 @@ public: } private: + void _AddSpaces(BPartition* partition, PartitionView* parentView) const + { + // add any available space on the partition + BPartitioningInfo info; + if (partition->GetPartitioningInfo(&info) >= B_OK) { + off_t parentSize = partition->Size(); + off_t offset; + off_t size; + for (int32 i = 0; + info.GetPartitionableSpaceAt(i, &offset, &size) >= B_OK; + i++) { + double scale = (double)size / parentSize; + PartitionView* view = new PartitionView("Empty", scale, + offset, parentView->Level() + 1, -2); + + BGroupLayout* layout = parentView->GroupLayout(); + int32 count = parentView->CountChildren(); + int32 insertIndex = 0; + for (int32 j = 0; j < count; j++) { + PartitionView* sibling = dynamic_cast( + parentView->ChildAt(j)); + if (sibling && sibling->Offset() > offset) + break; + insertIndex++; + } + layout->AddView(view, scale); + } + } + } typedef HashKey32 PartitionKey; typedef HashMap PartitionViewMap; @@ -247,15 +301,15 @@ public: DiskView::DiskView(const BRect& frame, uint32 resizeMode) : Inherited(frame, "diskview", resizeMode, - B_WILL_DRAW | B_FRAME_EVENTS) + B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) , fDiskCount(0) , fDisk(NULL) , fPartitionLayout(new PartitionLayout(this)) { BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL, kLayoutInset); - layout->SetInsets(2, 2, 2, 2); SetLayout(layout); + SetViewColor(B_TRANSPARENT_COLOR); rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); SetHighColor(tint_color(base, B_DARKEN_2_TINT)); SetLowColor(tint_color(base, (B_DARKEN_2_TINT + B_DARKEN_1_TINT) / 2)); @@ -336,13 +390,6 @@ DiskView::Draw(BRect updateRect) } -void -DiskView::FrameResized(float width, float height) -{ -// DoLayout(); -} - - void DiskView::SetDiskCount(int32 count) { diff --git a/src/apps/drivesetup/DiskView.h b/src/apps/drivesetup/DiskView.h index bc3d87d442..ff1d596853 100644 --- a/src/apps/drivesetup/DiskView.h +++ b/src/apps/drivesetup/DiskView.h @@ -19,7 +19,6 @@ public: // BView interface virtual void Draw(BRect updateRect); - virtual void FrameResized(float width, float height); void SetDiskCount(int32 count); void SetDisk(BDiskDevice* disk, diff --git a/src/apps/drivesetup/MainWindow.cpp b/src/apps/drivesetup/MainWindow.cpp index 7a70200b0e..11666bb182 100644 --- a/src/apps/drivesetup/MainWindow.cpp +++ b/src/apps/drivesetup/MainWindow.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -49,17 +50,35 @@ public: virtual bool Visit(BDiskDevice* device) { fDiskCount++; - fPartitionList->AddPartition(device); + _AddPartition(device); return false; // Don't stop yet! } virtual bool Visit(BPartition* partition, int32 level) { - fPartitionList->AddPartition(partition); + _AddPartition(partition); return false; // Don't stop yet! } private: + void _AddPartition(BPartition* partition) const + { + // add the partition itself + fPartitionList->AddPartition(partition); + + // add any available space on it + BPartitioningInfo info; + if (partition->GetPartitioningInfo(&info) >= B_OK) { + off_t offset; + off_t size; + for (int32 i = 0; + info.GetPartitionableSpaceAt(i, &offset, &size) >= B_OK; + i++) { + fPartitionList->AddSpace(partition->ID(), offset, size); + } + } + } + PartitionListView* fPartitionList; int32& fDiskCount; }; @@ -402,8 +421,9 @@ MainWindow::_AdaptToSelectedPartition() void MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition) { + BDiskDevice* oldDisk = NULL; if (!fCurrentDisk || fCurrentDisk->ID() != disk) { - delete fCurrentDisk; + oldDisk = fCurrentDisk; fCurrentDisk = NULL; if (disk >= 0) { BDiskDevice* newDisk = new BDiskDevice(); @@ -420,6 +440,8 @@ MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition) fDiskView->SetDisk(fCurrentDisk, fCurrentPartitionID); _EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID); + + delete oldDisk; } diff --git a/src/apps/drivesetup/PartitionList.cpp b/src/apps/drivesetup/PartitionList.cpp index cb22a72d9a..0d9b4fcd3c 100644 --- a/src/apps/drivesetup/PartitionList.cpp +++ b/src/apps/drivesetup/PartitionList.cpp @@ -28,6 +28,7 @@ enum { PartitionListRow::PartitionListRow(BPartition* partition) : Inherited() , fPartitionID(partition->ID()) + , fParentID(partition->Parent() ? partition->Parent()->ID() : -1) , fOffset(partition->Offset()) , fSize(partition->Size()) { @@ -57,9 +58,11 @@ PartitionListRow::PartitionListRow(BPartition* partition) } -PartitionListRow::PartitionListRow(partition_id id, off_t offset, off_t size) +PartitionListRow::PartitionListRow(partition_id parentID, off_t offset, + off_t size) : Inherited() - , fPartitionID(id) + , fPartitionID(-2) + , fParentID(parentID) , fOffset(offset) , fSize(size) { @@ -156,22 +159,16 @@ PartitionListView::AddPartition(BPartition* partition) PartitionListRow* -PartitionListView::AddSpace(partition_id parentID, partition_id id, - off_t offset, off_t size) +PartitionListView::AddSpace(partition_id parentID, off_t offset, off_t size) { - PartitionListRow* partitionrow = FindRow(id); - - // forget about it if this item is already in the listview - if (partitionrow != NULL) - return partitionrow; - // the parent should already be in the listview PartitionListRow* parent = FindRow(parentID); if (!parent) return NULL; // create the row for this partition - partitionrow = new PartitionListRow(id, offset, size); + PartitionListRow* partitionrow = new PartitionListRow(parentID, + offset, size); // find a proper insertion index based on the on-disk offset int32 index = _InsertIndexForOffset(parent, offset); diff --git a/src/apps/drivesetup/PartitionList.h b/src/apps/drivesetup/PartitionList.h index 9b4e02848f..f5f7135206 100644 --- a/src/apps/drivesetup/PartitionList.h +++ b/src/apps/drivesetup/PartitionList.h @@ -25,7 +25,7 @@ class PartitionListRow : public BRow { typedef BRow Inherited; public: PartitionListRow(BPartition* partition); - PartitionListRow(partition_id id, + PartitionListRow(partition_id parentID, off_t offset, off_t size); partition_id ID() const @@ -36,6 +36,7 @@ public: { return fSize; } private: partition_id fPartitionID; + partition_id fParentID; off_t fOffset; off_t fSize; }; @@ -51,7 +52,7 @@ public: PartitionListRow* parent = NULL); PartitionListRow* AddPartition(BPartition* partition); PartitionListRow* AddSpace(partition_id parent, - partition_id id, off_t offset, off_t size); + off_t offset, off_t size); private: int32 _InsertIndexForOffset(PartitionListRow* parent,