* 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
This commit is contained in:
Stephan Aßmus 2008-02-03 20:24:05 +00:00
parent fb3fcd8754
commit 967d72041f
9 changed files with 172 additions and 64 deletions

View File

@ -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("<empty>", 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);
}

View File

@ -9,12 +9,15 @@
#include <DiskDevice.h>
#include <View.h>
#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;

View File

@ -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 ) {

View File

@ -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<PartitionListRow*>(_topLevelRow);
PartitionListRow* selectedRow
= dynamic_cast<PartitionListRow*>(_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());

View File

@ -13,6 +13,8 @@
#include <DiskDeviceRoster.h>
#include <Window.h>
#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;

View File

@ -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);

View File

@ -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,

View File

@ -10,6 +10,7 @@
#include "Support.h"
#include <Partition.h>
#include <String.h>
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<HashString, partition_id>()
, 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;
}

View File

@ -6,7 +6,9 @@
#define SUPPORT_H
#include <SupportDefs.h>
#include <DiskDeviceDefs.h>
#include <HashMap.h>
#include <HashString.h>
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<HashString, partition_id> {
public:
SpaceIDMap();
virtual ~SpaceIDMap();
partition_id SpaceIDFor(partition_id parentID,
off_t spaceOffset);
private:
partition_id fNextSpaceID;
};
#endif // SUPPORT_H