From 967d72041f81ab74e2cd286cf91ed2b594ba91f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 3 Feb 2008 20:24:05 +0000 Subject: [PATCH] * Implemented support for generating global partition_ids for partitionable spaces. This way we can use all the existing logic to select them in either list view or the disk layout view. IAW, selecting empty spaces now works. * Changed the way the Create menu works. It is now only enabled if a space item is selected and then the sub items are filled with the types that the parent partition says it supports for child creation. (Does not yet seem to work.) * PartitionViews for spaces were not put into the partition_id -> view map. * Fixed focus indication when switching the disk for the disk layout view, previously, the correct view was only selected when the disk did not change. * Added a temporary work around to avoid showing bogus space items at all (those smaller than a "cylinder size"). Currently hard coded to 8 MB size. But I already have an idea how we could fix this in the Disk Device API implementation. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23854 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/drivesetup/DiskView.cpp | 25 ++++-- src/apps/drivesetup/DiskView.h | 6 +- src/apps/drivesetup/Jamfile | 5 +- src/apps/drivesetup/MainWindow.cpp | 110 +++++++++++++++++--------- src/apps/drivesetup/MainWindow.h | 15 ++-- src/apps/drivesetup/PartitionList.cpp | 11 +-- src/apps/drivesetup/PartitionList.h | 4 +- src/apps/drivesetup/Support.cpp | 41 ++++++++++ src/apps/drivesetup/Support.h | 19 ++++- 9 files changed, 172 insertions(+), 64 deletions(-) diff --git a/src/apps/drivesetup/DiskView.cpp b/src/apps/drivesetup/DiskView.cpp index f9807bcf6e..4d38a4b3d6 100644 --- a/src/apps/drivesetup/DiskView.cpp +++ b/src/apps/drivesetup/DiskView.cpp @@ -183,10 +183,11 @@ private: class DiskView::PartitionLayout : public BDiskDeviceVisitor { public: - PartitionLayout(BView* view) + PartitionLayout(BView* view, SpaceIDMap& spaceIDMap) : fView(view) , fViewMap() , fSelectedPartition(-1) + , fSpaceIDMap(spaceIDMap) { } @@ -258,7 +259,7 @@ public: } private: - void _AddSpaces(BPartition* partition, PartitionView* parentView) const + void _AddSpaces(BPartition* partition, PartitionView* parentView) { // add any available space on the partition BPartitioningInfo info; @@ -269,10 +270,17 @@ public: for (int32 i = 0; info.GetPartitionableSpaceAt(i, &offset, &size) >= B_OK; i++) { + // TODO: remove again once Disk Device API is fixed + if (!is_valid_partitionable_space(size)) + continue; + // double scale = (double)size / parentSize; + partition_id id + = fSpaceIDMap.SpaceIDFor(partition->ID(), offset); PartitionView* view = new PartitionView("", scale, - offset, parentView->Level() + 1, -2); + offset, parentView->Level() + 1, id); + fViewMap.Put(id, view); BGroupLayout* layout = parentView->GroupLayout(); layout->AddView(_FindInsertIndex(view, layout), view, scale); } @@ -301,18 +309,21 @@ public: BView* fView; PartitionViewMap fViewMap; partition_id fSelectedPartition; + SpaceIDMap& fSpaceIDMap; }; // #pragma mark - -DiskView::DiskView(const BRect& frame, uint32 resizeMode) +DiskView::DiskView(const BRect& frame, uint32 resizeMode, + SpaceIDMap& spaceIDMap) : Inherited(frame, "diskview", resizeMode, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE) , fDiskCount(0) , fDisk(NULL) - , fPartitionLayout(new PartitionLayout(this)) + , fSpaceIDMap(spaceIDMap) + , fPartitionLayout(new PartitionLayout(this, fSpaceIDMap)) { BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL, kLayoutInset); SetLayout(layout); @@ -407,12 +418,12 @@ DiskView::SetDiskCount(int32 count) void DiskView::SetDisk(BDiskDevice* disk, partition_id selectedPartition) { - fPartitionLayout->SetSelectedPartition(selectedPartition); - if (fDisk != disk) { fDisk = disk; _UpdateLayout(); } + + fPartitionLayout->SetSelectedPartition(selectedPartition); } diff --git a/src/apps/drivesetup/DiskView.h b/src/apps/drivesetup/DiskView.h index ff1d596853..1670ee58e1 100644 --- a/src/apps/drivesetup/DiskView.h +++ b/src/apps/drivesetup/DiskView.h @@ -9,12 +9,15 @@ #include #include +#include "Support.h" + class DiskView : public BView { typedef BView Inherited; public: DiskView(const BRect& frame, - uint32 resizeMode); + uint32 resizeMode, + SpaceIDMap& spaceIDMap); virtual ~DiskView(); // BView interface @@ -28,6 +31,7 @@ private: int32 fDiskCount; BDiskDevice* fDisk; + SpaceIDMap& fSpaceIDMap; class PartitionLayout; PartitionLayout* fPartitionLayout; diff --git a/src/apps/drivesetup/Jamfile b/src/apps/drivesetup/Jamfile index 3927ad613f..bd85b21ee7 100644 --- a/src/apps/drivesetup/Jamfile +++ b/src/apps/drivesetup/Jamfile @@ -12,9 +12,8 @@ Preference DriveSetup : PartitionList.cpp Support.cpp - : be libcolumnlistview.a - : - DriveSetup.rdef + : be libcolumnlistview.a libshared.a + : DriveSetup.rdef ; if ( $(TARGET_PLATFORM) = libbe_test ) { diff --git a/src/apps/drivesetup/MainWindow.cpp b/src/apps/drivesetup/MainWindow.cpp index 38b0995b14..acd72c6daa 100644 --- a/src/apps/drivesetup/MainWindow.cpp +++ b/src/apps/drivesetup/MainWindow.cpp @@ -35,11 +35,14 @@ class ListPopulatorVisitor : public BDiskDeviceVisitor { public: - ListPopulatorVisitor(PartitionListView* list, int32& diskCount) + ListPopulatorVisitor(PartitionListView* list, int32& diskCount, + SpaceIDMap& spaceIDMap) : fPartitionList(list) , fDiskCount(diskCount) + , fSpaceIDMap(spaceIDMap) { fDiskCount = 0; + fSpaceIDMap.Clear(); // start with an empty list int32 rows = fPartitionList->CountRows(); for (int32 i = rows - 1; i >= 0; i--) { @@ -76,18 +79,25 @@ private: BPartitioningInfo info; status_t ret = partition->GetPartitioningInfo(&info); if (ret >= B_OK) { + partition_id parentID = partition->ID(); off_t offset; off_t size; for (int32 i = 0; info.GetPartitionableSpaceAt(i, &offset, &size) >= B_OK; i++) { - fPartitionList->AddSpace(partition->ID(), offset, size); + // TODO: remove again once Disk Device API is fixed + if (!is_valid_partitionable_space(size)) + continue; + // + partition_id id = fSpaceIDMap.SpaceIDFor(parentID, offset); + fPartitionList->AddSpace(parentID, id, offset, size); } } } PartitionListView* fPartitionList; int32& fDiskCount; + SpaceIDMap& fSpaceIDMap; }; @@ -118,9 +128,7 @@ enum { MSG_MOUNT = 'mnts', MSG_UNMOUNT = 'unmt', MSG_FORMAT = 'frmt', - MSG_CREATE_PRIMARY = 'crpr', - MSG_CREATE_EXTENDED = 'crex', - MSG_CREATE_LOGICAL = 'crlg', + MSG_CREATE = 'crtp', MSG_INITIALIZE = 'init', MSG_DELETE = 'delt', MSG_EJECT = 'ejct', @@ -131,10 +139,14 @@ enum { }; +// #pragma mark - + + MainWindow::MainWindow(BRect frame) : BWindow(frame, "DriveSetup", B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE) , fCurrentDisk(NULL) + , fSpaceIDMap() { BMenuBar* menuBar = new BMenuBar(Bounds(), "root menu"); @@ -145,13 +157,6 @@ MainWindow::MainWindow(BRect frame) new BMessage(MSG_SURFACE_TEST)); fRescanMI = new BMenuItem("Rescan", new BMessage(MSG_RESCAN)); - fCreatePrimaryMI = new BMenuItem("Primary", - new BMessage(MSG_CREATE_PRIMARY)); - fCreateExtendedMI = new BMenuItem("Extended", - new BMessage(MSG_CREATE_EXTENDED)); - fCreateLogicalMI = new BMenuItem("Logical", - new BMessage(MSG_CREATE_LOGICAL)); - fDeleteMI = new BMenuItem("Delete (not implemented)", new BMessage(MSG_DELETE)); fDeleteMI->SetEnabled(false); @@ -174,10 +179,7 @@ fDeleteMI->SetEnabled(false); // Parition menu fPartitionMenu = new BMenu("Partition"); - fCreateMenu = new BMenu("Create (not implemented)"); - fCreateMenu->AddItem(fCreatePrimaryMI); - fCreateMenu->AddItem(fCreateExtendedMI); - fCreateMenu->AddItem(fCreateLogicalMI); + fCreateMenu = new BMenu("Create"); fPartitionMenu->AddItem(fCreateMenu); fInitMenu = new BMenu("Initialize"); @@ -202,7 +204,8 @@ fDeleteMI->SetEnabled(false); BRect r(Bounds()); r.top = menuBar->Frame().bottom + 1; r.bottom = floorf(r.top + r.Height() * 0.33); - fDiskView = new DiskView(r, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); + fDiskView = new DiskView(r, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, + fSpaceIDMap); AddChild(fDiskView); // add PartitionListView @@ -222,7 +225,7 @@ fDeleteMI->SetEnabled(false); // visit all disks in the system and show their contents _ScanDrives(); - _EnabledDisableMenuItems(NULL, -1); + _EnabledDisableMenuItems(NULL, -1, -1); } @@ -250,14 +253,8 @@ MainWindow::MessageReceived(BMessage* message) printf("MSG_FORMAT\n"); break; - case MSG_CREATE_PRIMARY: - printf("MSG_CREATE_PRIMARY\n"); - break; - case MSG_CREATE_EXTENDED: - printf("MSG_CREATE_EXTENDED\n"); - break; - case MSG_CREATE_LOGICAL: - printf("MSG_CREATE_LOGICAL\n"); + case MSG_CREATE: + printf("MSG_CREATE\n"); break; case MSG_INITIALIZE: { @@ -366,8 +363,9 @@ MainWindow::RestoreSettings(BMessage* archive) void MainWindow::_ScanDrives() { + fSpaceIDMap.Clear(); int32 diskCount = 0; - ListPopulatorVisitor driveVisitor(fListView, diskCount); + ListPopulatorVisitor driveVisitor(fListView, diskCount, fSpaceIDMap); fDDRoster.VisitEachPartition(&driveVisitor); fDiskView->SetDiskCount(diskCount); } @@ -399,8 +397,9 @@ MainWindow::_ScanFileSystems() void MainWindow::_AdaptToSelectedPartition() { - partition_id disk = -1; - partition_id partition = -1; + partition_id diskID = -1; + partition_id partitionID = -1; + partition_id parentID = -1; BRow* _selectedRow = fListView->CurrentSelection(); if (_selectedRow) { @@ -409,24 +408,27 @@ MainWindow::_AdaptToSelectedPartition() BRow* parent = NULL; while (fListView->FindParent(_topLevelRow, &parent, NULL)) _topLevelRow = parent; - + PartitionListRow* topLevelRow = dynamic_cast(_topLevelRow); PartitionListRow* selectedRow = dynamic_cast(_selectedRow); if (topLevelRow) - disk = topLevelRow->ID(); - if (selectedRow) - partition = selectedRow->ID(); + diskID = topLevelRow->ID(); + if (selectedRow) { + partitionID = selectedRow->ID(); + parentID = selectedRow->ParentID(); + } } - _SetToDiskAndPartition(disk, partition); + _SetToDiskAndPartition(diskID, partitionID, parentID); } void -MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition) +MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition, + partition_id parent) { BDiskDevice* oldDisk = NULL; if (!fCurrentDisk || fCurrentDisk->ID() != disk) { @@ -446,7 +448,7 @@ MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition) fCurrentPartitionID = partition; fDiskView->SetDisk(fCurrentDisk, fCurrentPartitionID); - _EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID); + _EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID, parent); delete oldDisk; } @@ -454,8 +456,12 @@ MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition) void MainWindow::_EnabledDisableMenuItems(BDiskDevice* disk, - partition_id selectedPartition) + partition_id selectedPartition, partition_id parentID) { + // clean out Create menu + while (BMenuItem* item = fCreateMenu->RemoveItem(0L)) + delete item; + if (!disk) { fFormatMI->SetEnabled(false); fEjectMI->SetEnabled(false); @@ -469,10 +475,36 @@ fFormatMI->SetEnabled(false); // fSurfaceTestMI->SetEnabled(true); fSurfaceTestMI->SetEnabled(false); + // Create menu and items fPartitionMenu->SetEnabled(true); - // fCreateMenu->SetEnabled(/*empty space selected*/); -fCreateMenu->SetEnabled(false); + BPartition* parentPartition = NULL; + if (selectedPartition <= -2) + parentPartition = disk->FindDescendant(parentID); + + if (parentPartition) { + fCreateMenu->SetEnabled(true); + BString supportedChildType; + int32 cookie = 0; + status_t ret; + while ((ret = parentPartition->GetNextSupportedChildType(&cookie, + &supportedChildType)) == B_OK) { + BMessage* message = new BMessage(MSG_CREATE); + message->AddInt32("parent id", parentID); + message->AddInt32("space id", selectedPartition); + message->AddString("type", supportedChildType); + BMenuItem* item = new BMenuItem(supportedChildType.String(), + message); + fCreateMenu->AddItem(item); + } + if (fCreateMenu->CountItems() == 0) + fprintf(stderr, "Failed to get supported child types: %s\n", + strerror(ret)); + } else { + fCreateMenu->SetEnabled(false); + } + + // Mount items BPartition* partition = disk->FindDescendant(selectedPartition); if (partition) { fInitMenu->SetEnabled(!partition->IsMounted()); diff --git a/src/apps/drivesetup/MainWindow.h b/src/apps/drivesetup/MainWindow.h index 910f189e19..691dd63fc5 100644 --- a/src/apps/drivesetup/MainWindow.h +++ b/src/apps/drivesetup/MainWindow.h @@ -13,6 +13,8 @@ #include #include +#include "Support.h" + class BDiskDevice; class BPartition; @@ -45,10 +47,12 @@ private: void _ScanFileSystems(); void _AdaptToSelectedPartition(); - void _SetToDiskAndPartition(partition_id disk, - partition_id partition); + void _SetToDiskAndPartition(partition_id diskID, + partition_id partitionID, + partition_id parentID); void _EnabledDisableMenuItems(BDiskDevice* disk, - partition_id selectedPartition); + partition_id selectedPartition, + partition_id parentID); void _DisplayPartitionError(BString message, const BPartition* partition = NULL, @@ -72,6 +76,8 @@ private: PartitionListView* fListView; DiskView* fDiskView; + SpaceIDMap fSpaceIDMap; + BMenu* fDiskMenu; BMenu* fPartitionMenu; BMenu* fInitMenu; @@ -82,9 +88,6 @@ private: BMenuItem* fSurfaceTestMI; BMenuItem* fRescanMI; - BMenuItem* fCreatePrimaryMI; - BMenuItem* fCreateExtendedMI; - BMenuItem* fCreateLogicalMI; BMenuItem* fDeleteMI; BMenuItem* fMountMI; BMenuItem* fUnmountMI; diff --git a/src/apps/drivesetup/PartitionList.cpp b/src/apps/drivesetup/PartitionList.cpp index 36335f5027..b0699d06d5 100644 --- a/src/apps/drivesetup/PartitionList.cpp +++ b/src/apps/drivesetup/PartitionList.cpp @@ -190,10 +190,10 @@ PartitionListRow::PartitionListRow(BPartition* partition) } -PartitionListRow::PartitionListRow(partition_id parentID, off_t offset, - off_t size) +PartitionListRow::PartitionListRow(partition_id parentID, partition_id id, + off_t offset, off_t size) : Inherited() - , fPartitionID(-2) + , fPartitionID(id) , fParentID(parentID) , fOffset(offset) , fSize(size) @@ -288,7 +288,8 @@ PartitionListView::AddPartition(BPartition* partition) PartitionListRow* -PartitionListView::AddSpace(partition_id parentID, off_t offset, off_t size) +PartitionListView::AddSpace(partition_id parentID, partition_id id, + off_t offset, off_t size) { // the parent should already be in the listview PartitionListRow* parent = FindRow(parentID); @@ -297,7 +298,7 @@ PartitionListView::AddSpace(partition_id parentID, off_t offset, off_t size) // create the row for this partition PartitionListRow* partitionrow = new PartitionListRow(parentID, - offset, size); + id, 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 9e53296252..c180b042ae 100644 --- a/src/apps/drivesetup/PartitionList.h +++ b/src/apps/drivesetup/PartitionList.h @@ -64,7 +64,7 @@ class PartitionListRow : public BRow { public: PartitionListRow(BPartition* partition); PartitionListRow(partition_id parentID, - off_t offset, off_t size); + partition_id id, off_t offset, off_t size); partition_id ID() const { return fPartitionID; } @@ -92,7 +92,7 @@ public: PartitionListRow* parent = NULL); PartitionListRow* AddPartition(BPartition* partition); PartitionListRow* AddSpace(partition_id parent, - off_t offset, off_t size); + partition_id id, off_t offset, off_t size); private: int32 _InsertIndexForOffset(PartitionListRow* parent, diff --git a/src/apps/drivesetup/Support.cpp b/src/apps/drivesetup/Support.cpp index 597c895d2f..3702d6efdd 100644 --- a/src/apps/drivesetup/Support.cpp +++ b/src/apps/drivesetup/Support.cpp @@ -10,6 +10,7 @@ #include "Support.h" #include +#include const char* @@ -67,3 +68,43 @@ dump_partition_info(const BPartition* partition) printf("\tID(): %lx\n\n", partition->ID()); } + +bool +is_valid_partitionable_space(size_t size) +{ + // TODO: remove this again, the DiskDeviceAPI should + // not even show these spaces to begin with + return size >= 8 * 1024 * 1024; +} + + +// #pragma mark -SpaceIDMap + +SpaceIDMap::SpaceIDMap() + : HashMap() + , fNextSpaceID(-2) +{ +} + + +SpaceIDMap::~SpaceIDMap() +{ +} + + +partition_id +SpaceIDMap::SpaceIDFor(partition_id parentID, off_t spaceOffset) +{ + BString key; + key << parentID << ':' << (uint64)spaceOffset; + + if (ContainsKey(key.String())) + return Get(key.String()); + + partition_id newID = fNextSpaceID--; + Put(key.String(), newID); + + return newID; +} + + diff --git a/src/apps/drivesetup/Support.h b/src/apps/drivesetup/Support.h index 82d0f37624..42a118b316 100644 --- a/src/apps/drivesetup/Support.h +++ b/src/apps/drivesetup/Support.h @@ -6,7 +6,9 @@ #define SUPPORT_H -#include +#include +#include +#include class BPartition; @@ -16,5 +18,20 @@ const char* string_for_size(off_t size, char *string); void dump_partition_info(const BPartition* partition); +bool is_valid_partitionable_space(size_t size); + + +class SpaceIDMap : public HashMap { +public: + SpaceIDMap(); + virtual ~SpaceIDMap(); + + partition_id SpaceIDFor(partition_id parentID, + off_t spaceOffset); + +private: + partition_id fNextSpaceID; +}; + #endif // SUPPORT_H