* disable sorting in the partitions list
* sort the partitions by id (TODO: should be disk offset, but works as intended now) * expand the partition tree entries by default * renamed DriveVisitor to ListPopulatorVisitor, moved implementation into class definition * added MountAllVisitor and used it to implement according menu item * added menu item members to MainWindow, so it keeps the pointers * added MainWindow::_EnabledDisableMenuItems() which looks for the current disk and partition and their properties to en-/disable the items * moved BDiskDevice member from DiskView to MainWindow, renamed to fCurrentDisk * implemented mounting and unmounting the currently selected partition, mounting works, unmounting does not work as in Tracker, but the error description is not as helpful, or just as helpful, since Force Unmount does not work in Tracker at the moment * implemented initializing the selected partition, not tested to the end, but likely works, so beware! (TODO: finish the parameter window and use it, partitions are hardcoded to "BFS Init Test" and 2048 blocksize). The process displays a warning at the beginning and another one at the end before writing anything to disk, but please do take it seriously... :-) * store and restore the listview column settings (width of columns mostly) * more appropriate usage of the BDiskDeviceRoster API * improved DiskView display a little with frames and more contrast in the colors * implemented FrameResized() to adapt the box layout * no longer pass disk pointer to BDiskDeviceRoster::VisitEachPartition(), since it will overwrite it! * no longer use BDiskDeviceRoster at all, BPartition::VisitEachDescendant() is what we need * added a WIP InitParamsPanel, does not compile, but is not added to the Jamfile yet, it will be a blocking panel like a BAlert and will later be refactored into the parameter editor add-on for BFS git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23545 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
#include "DiskView.h"
|
||||
|
||||
#include <DiskDeviceRoster.h>
|
||||
#include <DiskDeviceVisitor.h>
|
||||
#include <HashMap.h>
|
||||
|
||||
@@ -122,6 +121,11 @@ public:
|
||||
frame.InsetBy(1, 1);
|
||||
fView->StrokeRect(frame);
|
||||
frame.InsetBy(1, 1);
|
||||
} else {
|
||||
fView->SetHighColor(tint_color(box.color, B_DARKEN_2_TINT));
|
||||
frame.InsetBy(-1, -1);
|
||||
fView->StrokeRect(frame);
|
||||
frame.InsetBy(1, 1);
|
||||
}
|
||||
|
||||
fView->SetHighColor(box.color);
|
||||
@@ -129,6 +133,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void Unset()
|
||||
{
|
||||
fColorIndex = 0;
|
||||
fBoxMap.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
rgb_color _NextColor()
|
||||
@@ -153,14 +163,15 @@ public:
|
||||
|
||||
|
||||
DiskView::DiskView(const BRect& frame, uint32 resizeMode)
|
||||
: Inherited(frame, "diskview", resizeMode, B_WILL_DRAW)
|
||||
: Inherited(frame, "diskview", resizeMode,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS)
|
||||
, fDisk(NULL)
|
||||
, fPartitionDrawer(new PartitionDrawer(this))
|
||||
{
|
||||
for (int32 i = 0; i < kMaxPartitionColors; i++) {
|
||||
kPartitionColors[i].red = 120 + ((i * 1675) & 120);
|
||||
kPartitionColors[i].green = 120 + ((i * 318) & 120);
|
||||
kPartitionColors[i].blue = 120 + ((i * 9328) & 120);
|
||||
kPartitionColors[i].red = 90 + ((i * 1675) & 160);
|
||||
kPartitionColors[i].green = 90 + ((i * 318) & 160);
|
||||
kPartitionColors[i].blue = 90 + ((i * 9328) & 160);
|
||||
kPartitionColors[i].alpha = 255;
|
||||
}
|
||||
}
|
||||
@@ -189,15 +200,33 @@ DiskView::Draw(BRect updateRect)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DiskView::FrameResized(float width, float height)
|
||||
{
|
||||
_UpdateLayout();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DiskView::SetDisk(BDiskDevice* disk, partition_id selectedPartition)
|
||||
{
|
||||
delete fDisk;
|
||||
fDisk = disk;
|
||||
fPartitionDrawer->SetSelectedPartition(selectedPartition);
|
||||
_UpdateLayout();
|
||||
}
|
||||
|
||||
BDiskDeviceRoster roster;
|
||||
roster.VisitEachPartition(fPartitionDrawer, fDisk);
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
DiskView::_UpdateLayout()
|
||||
{
|
||||
fPartitionDrawer->Unset();
|
||||
|
||||
if (fDisk)
|
||||
fDisk->VisitEachDescendant(fPartitionDrawer);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,13 @@ public:
|
||||
|
||||
// BView interface
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void FrameResized(float width, float height);
|
||||
|
||||
void SetDisk(BDiskDevice* disk,
|
||||
partition_id selectedPartition);
|
||||
private:
|
||||
void _UpdateLayout();
|
||||
|
||||
BDiskDevice* fDisk;
|
||||
|
||||
class PartitionDrawer;
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
#include "InitParamsPanel.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <TextControl.h>
|
||||
|
||||
|
||||
|
||||
class InitParamsPanel::EscapeFilter : public BMessageFilter {
|
||||
public:
|
||||
EscapeFilter(InitParamsPanel* target)
|
||||
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
|
||||
fPanel(target)
|
||||
{
|
||||
}
|
||||
virtual ~EscapeFilter()
|
||||
{
|
||||
}
|
||||
virtual filter_result Filter(BMessage* message, BHandler** target)
|
||||
{
|
||||
filter_result result = B_DISPATCH_MESSAGE;
|
||||
switch (message->what) {
|
||||
case B_KEY_DOWN:
|
||||
case B_UNMAPPED_KEY_DOWN: {
|
||||
uint32 key;
|
||||
if (message->FindInt32("raw_char", (int32*)&key) >= B_OK) {
|
||||
if (key == B_ESCAPE) {
|
||||
result = B_SKIP_MESSAGE;
|
||||
fPanel->Cancel();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
InitParamsPanel* fPanel;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
enum {
|
||||
MSG_OK = 'okok',
|
||||
MSG_CANCEL = 'cncl'
|
||||
};
|
||||
|
||||
|
||||
|
||||
InitParamsPanel::InitParamsPanel(BWindow *window)
|
||||
: Panel(BRect(300.0, 200.0, 600.0, 400.0), 0, B_MODAL_WINDOW_LOOK,
|
||||
B_MODAL_SUBSET_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS),
|
||||
, fEscapeFilter(new EscapeFilter(this))
|
||||
, fExitSemaphore(create_sem(0, "InitParamsPanel exit")
|
||||
, fWindow(window)
|
||||
, fReturnValue(GO_CANCELED)
|
||||
{
|
||||
AddCommonFilter(fEscapeFilter);
|
||||
|
||||
...
|
||||
|
||||
AddChild(topView);
|
||||
SetDefaultButton(okButton);
|
||||
|
||||
AddToSubset(fWindow);
|
||||
}
|
||||
|
||||
|
||||
InitParamsPanel::~InitParamsPanel()
|
||||
{
|
||||
RemoveCommonFilter(fEscapeFilter);
|
||||
delete fEscapeFilter;
|
||||
|
||||
delete_sem(fExitSemaphore);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
InitParamsPanel::QuitRequested()
|
||||
{
|
||||
release_sem(fExitSemaphore);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InitParamsPanel::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case MSG_CANCEL:
|
||||
Cancel();
|
||||
break;
|
||||
|
||||
case MSG_OK:
|
||||
fReturnValue = GO_SUCCESS;
|
||||
release_sem(fExitSemaphore);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
InitParamsPanel::Answer(BString& name, BString& parameters)
|
||||
{
|
||||
// run the window thread, to get an initial layout of the controls
|
||||
Hide();
|
||||
Show();
|
||||
if (!Lock())
|
||||
return false;
|
||||
|
||||
// center the panel above the parent window
|
||||
BRect frame = Frame();
|
||||
BRect parentFrame = fWindow->Frame();
|
||||
MoveTo((parentFrame.left + parentFrame.right - frame.Width()) / 2.0,
|
||||
(parentFrame.top + parentFrame.bottom - frame.Height()) / 2.0);
|
||||
|
||||
fNameTC->SetText(name.String());
|
||||
fNameTC->MakeFocus(true);
|
||||
|
||||
Show();
|
||||
Unlock();
|
||||
|
||||
// block this thread now
|
||||
acquire_sem(fExitSemaphore);
|
||||
|
||||
if (fMode == GO_SUCCESS) {
|
||||
name = fNameTC->Text();
|
||||
parameters ...
|
||||
}
|
||||
|
||||
Lock();
|
||||
Quit();
|
||||
return fReturnValue;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InitParamsPanel::Cancel()
|
||||
{
|
||||
fReturnValue = GO_CANCELED;
|
||||
release_sem(fExitSemaphore);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef INIT_PARAMS_PANEL_H
|
||||
#define INIT_PARAMS_PANEL_H
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
class BMenuField;
|
||||
class BTextControl;
|
||||
|
||||
enum {
|
||||
GO_CANCELED = 0,
|
||||
GO_SUCCESS
|
||||
};
|
||||
|
||||
class InitParamsPanel : public BWindow {
|
||||
public:
|
||||
InitParamsPanel(BWindow* window);
|
||||
virtual ~InitParamsPanel();
|
||||
|
||||
virtual bool QuitRequested();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
int32 Go(BString& name, BString& parameters);
|
||||
void Cancel();
|
||||
|
||||
private:
|
||||
class EscapeFilter;
|
||||
EscapeFilter* fEscapeFilter;
|
||||
sem_id fExitSemaphore;
|
||||
BWindow* fWindow;
|
||||
int32 fReturnValue;
|
||||
|
||||
BTextControl* fNameTC;
|
||||
BMenuField* fBlockSizeMF;
|
||||
};
|
||||
|
||||
#endif // INIT_PARAMS_PANEL_H
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "PartitionList.h"
|
||||
#include "Support.h"
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
|
||||
#include <DiskDeviceVisitor.h>
|
||||
@@ -28,12 +29,53 @@
|
||||
#include <Screen.h>
|
||||
|
||||
|
||||
class DriveVisitor : public BDiskDeviceVisitor {
|
||||
class ListPopulatorVisitor : public BDiskDeviceVisitor {
|
||||
public:
|
||||
DriveVisitor(PartitionListView* list);
|
||||
ListPopulatorVisitor(PartitionListView* list)
|
||||
: fPartitionList(list)
|
||||
{
|
||||
// start with an empty list
|
||||
int32 rows = fPartitionList->CountRows();
|
||||
for (int32 i = rows - 1; i >= 0; i--) {
|
||||
BRow* row = fPartitionList->RowAt(i);
|
||||
fPartitionList->RemoveRow(row);
|
||||
delete row;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool Visit(BDiskDevice* device);
|
||||
virtual bool Visit(BPartition* partition, int32 level);
|
||||
virtual bool Visit(BDiskDevice* device)
|
||||
{
|
||||
fPartitionList->AddPartition(device);
|
||||
return false; // Don't stop yet!
|
||||
}
|
||||
|
||||
virtual bool Visit(BPartition* partition, int32 level)
|
||||
{
|
||||
fPartitionList->AddPartition(partition);
|
||||
return false; // Don't stop yet!
|
||||
}
|
||||
|
||||
private:
|
||||
PartitionListView* fPartitionList;
|
||||
};
|
||||
|
||||
|
||||
class MountAllVisitor : public BDiskDeviceVisitor {
|
||||
public:
|
||||
MountAllVisitor()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Visit(BDiskDevice* device)
|
||||
{
|
||||
return false; // Don't stop yet!
|
||||
}
|
||||
|
||||
virtual bool Visit(BPartition* partition, int32 level)
|
||||
{
|
||||
partition->Mount();
|
||||
return false; // Don't stop yet!
|
||||
}
|
||||
|
||||
private:
|
||||
PartitionListView* fPartitionList;
|
||||
@@ -60,45 +102,67 @@ enum {
|
||||
MainWindow::MainWindow(BRect frame)
|
||||
: BWindow(frame, "DriveSetup", B_DOCUMENT_WINDOW,
|
||||
B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE)
|
||||
, fCurrentDisk(NULL)
|
||||
{
|
||||
BMenuBar* rootMenu = new BMenuBar(Bounds(), "root menu");
|
||||
BMenuBar* menuBar = new BMenuBar(Bounds(), "root menu");
|
||||
|
||||
// create all the menu items
|
||||
fFormatMI = new BMenuItem("Format", new BMessage(MSG_FORMAT));
|
||||
fEjectMI = new BMenuItem("Eject", new BMessage(MSG_EJECT), 'E');
|
||||
fSurfaceTestMI = new BMenuItem("Surface Test",
|
||||
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));
|
||||
|
||||
fMountMI = new BMenuItem("Mount", new BMessage(MSG_MOUNT), 'M');
|
||||
fUnmountMI = new BMenuItem("Unmount", new BMessage(MSG_UNMOUNT), 'U');
|
||||
fMountAllMI = new BMenuItem("Mount All",
|
||||
new BMessage(MSG_MOUNT_ALL), 'M', B_SHIFT_KEY);
|
||||
|
||||
// Disk menu
|
||||
BMenu* menu = new BMenu("Disk");
|
||||
menu->AddItem(new BMenuItem("Format", new BMessage(MSG_FORMAT), 'F'));
|
||||
menu->AddItem(new BMenuItem("Eject", new BMessage(MSG_EJECT), 'E'));
|
||||
menu->AddItem(new BMenuItem("Surface Test",
|
||||
new BMessage(MSG_SURFACE_TEST), 'T'));
|
||||
menu->AddSeparatorItem();
|
||||
menu->AddItem(new BMenuItem("Rescan", new BMessage(MSG_RESCAN)));
|
||||
rootMenu->AddItem(menu);
|
||||
fDiskMenu = new BMenu("Disk");
|
||||
fDiskMenu->AddItem(fFormatMI);
|
||||
fDiskMenu->AddItem(fEjectMI);
|
||||
fDiskMenu->AddItem(fSurfaceTestMI);
|
||||
|
||||
fDiskMenu->AddSeparatorItem();
|
||||
|
||||
fDiskMenu->AddItem(fRescanMI);
|
||||
menuBar->AddItem(fDiskMenu);
|
||||
|
||||
// Parition menu
|
||||
menu = new BMenu("Partition");
|
||||
BMenu* createMenu = new BMenu("Create");
|
||||
menu->AddItem(createMenu);
|
||||
fPartitionMenu = new BMenu("Partition");
|
||||
fCreateMenu = new BMenu("Create");
|
||||
fCreateMenu->AddItem(fCreatePrimaryMI);
|
||||
fCreateMenu->AddItem(fCreateExtendedMI);
|
||||
fCreateMenu->AddItem(fCreateLogicalMI);
|
||||
fPartitionMenu->AddItem(fCreateMenu);
|
||||
|
||||
fInitMenu = new BMenu("Initialize");
|
||||
menu->AddItem(fInitMenu);
|
||||
menu->AddSeparatorItem();
|
||||
menu->AddItem(new BMenuItem("Mount", new BMessage(MSG_MOUNT), 'M'));
|
||||
menu->AddItem(new BMenuItem("Unmount", new BMessage(MSG_UNMOUNT), 'U'));
|
||||
menu->AddSeparatorItem();
|
||||
menu->AddItem(new BMenuItem("Mount All",
|
||||
new BMessage(MSG_MOUNT_ALL), 'M', B_SHIFT_KEY));
|
||||
rootMenu->AddItem(menu);
|
||||
fPartitionMenu->AddItem(fInitMenu);
|
||||
|
||||
AddChild(rootMenu);
|
||||
fPartitionMenu->AddSeparatorItem();
|
||||
|
||||
fPartitionMenu->AddItem(fMountMI);
|
||||
fPartitionMenu->AddItem(fUnmountMI);
|
||||
|
||||
fPartitionMenu->AddSeparatorItem();
|
||||
|
||||
fPartitionMenu->AddItem(fMountAllMI);
|
||||
menuBar->AddItem(fPartitionMenu);
|
||||
|
||||
AddChild(menuBar);
|
||||
|
||||
createMenu->AddItem(new BMenuItem("Primary",
|
||||
new BMessage(MSG_CREATE_PRIMARY)));
|
||||
createMenu->AddItem(new BMenuItem("Extended",
|
||||
new BMessage(MSG_CREATE_EXTENDED)));
|
||||
createMenu->AddItem(new BMenuItem("Logical",
|
||||
new BMessage(MSG_CREATE_LOGICAL)));
|
||||
|
||||
// add DiskView
|
||||
BRect r(Bounds());
|
||||
r.top = rootMenu->Frame().bottom + 1;
|
||||
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);
|
||||
AddChild(fDiskView);
|
||||
@@ -114,11 +178,19 @@ MainWindow::MainWindow(BRect frame)
|
||||
fListView->SetSelectionMessage(new BMessage(MSG_PARTITION_ROW_SELECTED));
|
||||
fListView->SetTarget(this);
|
||||
|
||||
// Populate the Initialiaze menu with the available file systems
|
||||
// populate the Initialiaze menu with the available file systems
|
||||
_ScanFileSystems();
|
||||
|
||||
// Visit all disks in the system and show their contents
|
||||
// visit all disks in the system and show their contents
|
||||
_ScanDrives();
|
||||
|
||||
_EnabledDisableMenuItems(NULL, -1);
|
||||
}
|
||||
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete fCurrentDisk;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,13 +199,13 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_MOUNT_ALL:
|
||||
printf("MSG_MOUNT_ALL\n");
|
||||
_MountAll();
|
||||
break;
|
||||
case MSG_MOUNT:
|
||||
printf("MSG_MOUNT\n");
|
||||
_Mount(fCurrentDisk, fCurrentPartitionID);
|
||||
break;
|
||||
case MSG_UNMOUNT:
|
||||
printf("MSG_UNMOUNT\n");
|
||||
_Unmount(fCurrentDisk, fCurrentPartitionID);
|
||||
break;
|
||||
|
||||
case MSG_FORMAT:
|
||||
@@ -150,12 +222,22 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
printf("MSG_CREATE_LOGICAL\n");
|
||||
break;
|
||||
|
||||
case MSG_INITIALIZE:
|
||||
printf("MSG_INITIALIZE\n");
|
||||
case MSG_INITIALIZE: {
|
||||
BString diskSystemName;
|
||||
if (message->FindString("format", &diskSystemName) != B_OK)
|
||||
break;
|
||||
_Initialize(fCurrentDisk, fCurrentPartitionID, diskSystemName);
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_EJECT:
|
||||
printf("MSG_EJECT\n");
|
||||
// TODO: completely untested, especially interesting
|
||||
// if partition list behaves when partitions disappear
|
||||
if (fCurrentDisk) {
|
||||
// TODO: only if no partitions are mounted anymore?
|
||||
fCurrentDisk->Eject(true);
|
||||
_ScanDrives();
|
||||
}
|
||||
break;
|
||||
case MSG_SURFACE_TEST:
|
||||
printf("MSG_SURFACE_TEST\n");
|
||||
@@ -193,7 +275,12 @@ MainWindow::StoreSettings(BMessage* archive) const
|
||||
{
|
||||
if (archive->ReplaceRect("window frame", Frame()) < B_OK)
|
||||
archive->AddRect("window frame", Frame());
|
||||
// TODO: store column list settings
|
||||
|
||||
BMessage columnSettings;
|
||||
fListView->SaveState(&columnSettings);
|
||||
if (archive->ReplaceMessage("column settings", &columnSettings) < B_OK)
|
||||
archive->AddMessage("column settings", &columnSettings);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -209,7 +296,11 @@ MainWindow::RestoreSettings(BMessage* archive)
|
||||
ResizeTo(frame.Width(), frame.Height());
|
||||
}
|
||||
}
|
||||
// TODO: restore column list settings
|
||||
|
||||
BMessage columnSettings;
|
||||
if (archive->FindMessage("column settings", &columnSettings) == B_OK)
|
||||
fListView->LoadState(&columnSettings);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -220,10 +311,8 @@ MainWindow::RestoreSettings(BMessage* archive)
|
||||
void
|
||||
MainWindow::_ScanDrives()
|
||||
{
|
||||
DriveVisitor driveVisitor(fListView);
|
||||
BPartition* partition = NULL;
|
||||
BDiskDevice device;
|
||||
fDDRoster.VisitEachPartition(&driveVisitor, &device, &partition);
|
||||
ListPopulatorVisitor driveVisitor(fListView);
|
||||
fDDRoster.VisitEachPartition(&driveVisitor);
|
||||
}
|
||||
|
||||
|
||||
@@ -235,10 +324,10 @@ MainWindow::_ScanFileSystems()
|
||||
|
||||
BDiskSystem diskSystem;
|
||||
fDDRoster.RewindDiskSystems();
|
||||
while(fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
|
||||
while (fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
|
||||
if (diskSystem.IsFileSystem() && diskSystem.SupportsInitializing()) {
|
||||
BMessage* message = new BMessage(MSG_INITIALIZE);
|
||||
message->AddString("format", diskSystem.Name());
|
||||
message->AddString("format", diskSystem.PrettyName());
|
||||
BString label = diskSystem.PrettyName();
|
||||
label << B_UTF8_ELLIPSIS;
|
||||
fInitMenu->AddItem(new BMenuItem(label.String(), message));
|
||||
@@ -247,12 +336,20 @@ MainWindow::_ScanFileSystems()
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_AdaptToSelectedPartition()
|
||||
{
|
||||
delete fCurrentDisk;
|
||||
fCurrentDisk = NULL;
|
||||
fCurrentPartitionID = -1;
|
||||
|
||||
BRow* _selectedRow = fListView->CurrentSelection();
|
||||
if (!_selectedRow) {
|
||||
fDiskView->SetDisk(NULL, -1);
|
||||
_EnabledDisableMenuItems(NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -270,47 +367,278 @@ MainWindow::_AdaptToSelectedPartition()
|
||||
if (!topLevelRow || !selectedRow)
|
||||
return;
|
||||
|
||||
BDiskDevice* disk = new BDiskDevice();
|
||||
disk->SetTo(topLevelRow->ID());
|
||||
fDiskView->SetDisk(disk, selectedRow->ID());
|
||||
fCurrentDisk = new BDiskDevice();
|
||||
status_t ret = fCurrentDisk->SetTo(topLevelRow->ID());
|
||||
if (ret < B_OK) {
|
||||
printf("error switching disks: %s\n", strerror(ret));
|
||||
delete fCurrentDisk;
|
||||
fCurrentDisk = NULL;
|
||||
return;
|
||||
}
|
||||
fCurrentPartitionID = selectedRow->ID();
|
||||
|
||||
fDiskView->SetDisk(fCurrentDisk, fCurrentPartitionID);
|
||||
_EnabledDisableMenuItems(fCurrentDisk, fCurrentPartitionID);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - DriveVisitor
|
||||
|
||||
|
||||
DriveVisitor::DriveVisitor(PartitionListView* list)
|
||||
: fPartitionList(list)
|
||||
void
|
||||
MainWindow::_EnabledDisableMenuItems(BDiskDevice* disk,
|
||||
partition_id selectedPartition)
|
||||
{
|
||||
// start with an empty list
|
||||
int32 rows = fPartitionList->CountRows();
|
||||
for (int32 i = rows - 1; i >= 0; i--) {
|
||||
BRow* row = fPartitionList->RowAt(i);
|
||||
fPartitionList->RemoveRow(row);
|
||||
delete row;
|
||||
if (!disk) {
|
||||
fFormatMI->SetEnabled(false);
|
||||
fEjectMI->SetEnabled(false);
|
||||
fSurfaceTestMI->SetEnabled(false);
|
||||
|
||||
fPartitionMenu->SetEnabled(false);
|
||||
} else {
|
||||
// fFormatMI->SetEnabled(true);
|
||||
fEjectMI->SetEnabled(disk->IsRemovableMedia());
|
||||
// fSurfaceTestMI->SetEnabled(true);
|
||||
|
||||
fPartitionMenu->SetEnabled(true);
|
||||
fCreatePrimaryMI->SetEnabled(false);
|
||||
fCreateExtendedMI->SetEnabled(false);
|
||||
fCreateLogicalMI->SetEnabled(false);
|
||||
|
||||
BPartition* partition = disk->FindDescendant(selectedPartition);
|
||||
if (partition) {
|
||||
fInitMenu->SetEnabled(!partition->IsMounted());
|
||||
fMountMI->SetEnabled(!partition->IsMounted());
|
||||
fUnmountMI->SetEnabled(partition->IsMounted());
|
||||
} else {
|
||||
fInitMenu->SetEnabled(false);
|
||||
fMountMI->SetEnabled(false);
|
||||
fUnmountMI->SetEnabled(false);
|
||||
}
|
||||
fMountAllMI->SetEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DriveVisitor::Visit(BDiskDevice* device)
|
||||
void
|
||||
MainWindow::_DisplayPartitionError(BString _message,
|
||||
const BPartition* partition, status_t error) const
|
||||
{
|
||||
fPartitionList->AddPartition(device);
|
||||
char message[1024];
|
||||
|
||||
if (partition && _message.FindFirst("%s") >= 0) {
|
||||
BString name;
|
||||
name << " \"" << partition->ContentName() << "\"";
|
||||
sprintf(message, _message.String(), name.String());
|
||||
} else {
|
||||
_message.ReplaceAll("%s", "");
|
||||
sprintf(message, _message.String());
|
||||
}
|
||||
|
||||
// printf("Visit(%p)\n", device);
|
||||
// dump_partition_info(device);
|
||||
if (error < B_OK) {
|
||||
BString helper = message;
|
||||
sprintf(message, "%s\n\nError: %s", helper.String(), strerror(error));
|
||||
}
|
||||
|
||||
return false; // Don't stop yet!
|
||||
BAlert* alert = new BAlert("error", message, "Ok", NULL, NULL,
|
||||
B_WIDTH_FROM_WIDEST, error < B_OK ? B_STOP_ALERT : B_INFO_ALERT);
|
||||
alert->Go(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DriveVisitor::Visit(BPartition* partition, int32 level)
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_Mount(BDiskDevice* disk, partition_id selectedPartition)
|
||||
{
|
||||
fPartitionList->AddPartition(partition);
|
||||
if (!disk || selectedPartition < 0) {
|
||||
_DisplayPartitionError("You need to select a partition "
|
||||
"entry from the list.");
|
||||
return;
|
||||
}
|
||||
|
||||
// printf("Visit(%p, %ld)\n", partition, level);
|
||||
// dump_partition_info(partition);
|
||||
BPartition* partition = disk->FindDescendant(selectedPartition);
|
||||
if (!partition) {
|
||||
_DisplayPartitionError("Unable to find the selected partition by id.");
|
||||
return;
|
||||
}
|
||||
|
||||
return false; // Don't stop yet!
|
||||
if (!partition->IsMounted()) {
|
||||
status_t ret = partition->Mount();
|
||||
if (ret < B_OK) {
|
||||
_DisplayPartitionError("Could not mount partition %s.",
|
||||
partition, ret);
|
||||
} else {
|
||||
// successful mount, adapt to the changes
|
||||
_ScanDrives();
|
||||
}
|
||||
} else {
|
||||
_DisplayPartitionError("The partition %s is already mounted.",
|
||||
partition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_Unmount(BDiskDevice* disk, partition_id selectedPartition)
|
||||
{
|
||||
if (!disk || selectedPartition < 0) {
|
||||
_DisplayPartitionError("You need to select a partition "
|
||||
"entry from the list.");
|
||||
return;
|
||||
}
|
||||
|
||||
BPartition* partition = disk->FindDescendant(selectedPartition);
|
||||
if (!partition) {
|
||||
_DisplayPartitionError("Unable to find the selected partition by id.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (partition->IsMounted()) {
|
||||
status_t ret = partition->Unmount();
|
||||
if (ret < B_OK) {
|
||||
_DisplayPartitionError("Could not unmount partition %s.",
|
||||
partition, ret);
|
||||
} else {
|
||||
// successful unmount, adapt to the changes
|
||||
_ScanDrives();
|
||||
}
|
||||
} else {
|
||||
_DisplayPartitionError("The partition %s is already unmounted.",
|
||||
partition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_MountAll()
|
||||
{
|
||||
MountAllVisitor visitor;
|
||||
fDDRoster.VisitEachPartition(&visitor);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_Initialize(BDiskDevice* disk, partition_id selectedPartition,
|
||||
const BString& diskSystemName)
|
||||
{
|
||||
if (!disk || selectedPartition < 0) {
|
||||
_DisplayPartitionError("You need to select a partition "
|
||||
"entry from the list.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (disk->IsReadOnly()) {
|
||||
_DisplayPartitionError("The selected disk is read-only.");
|
||||
return;
|
||||
}
|
||||
|
||||
BPartition* partition = disk->FindDescendant(selectedPartition);
|
||||
if (!partition) {
|
||||
_DisplayPartitionError("Unable to find the selected partition by id.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (partition->IsMounted()) {
|
||||
_DisplayPartitionError("The partition %s is currently mounted.");
|
||||
// TODO: option to unmount and continue on success to unmount
|
||||
return;
|
||||
}
|
||||
|
||||
BString message("Are you sure you want to initialize the partition ");
|
||||
message << "\"" << partition->ContentName();
|
||||
message << "\"? After entering the initialization parameters, ";
|
||||
message << "you can abort this operation right before writing ";
|
||||
message << "changes back to the disk.";
|
||||
BAlert* alert = new BAlert("first notice", message.String(),
|
||||
"Continue", "Cancel", NULL, B_WIDTH_FROM_WIDEST, B_WARNING_ALERT);
|
||||
int32 choice = alert->Go();
|
||||
|
||||
if (choice == 1)
|
||||
return;
|
||||
|
||||
BDiskSystem diskSystem;
|
||||
fDDRoster.RewindDiskSystems();
|
||||
bool found = false;
|
||||
while (fDDRoster.GetNextDiskSystem(&diskSystem) == B_OK) {
|
||||
if (diskSystem.IsFileSystem() && diskSystem.SupportsInitializing()) {
|
||||
if (diskSystemName == diskSystem.PrettyName()) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
BString message("Disk system \"");
|
||||
message << diskSystemName << "\" not found!";
|
||||
_DisplayPartitionError(message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO: check and allow BFS only, since our parameter string
|
||||
// construction only handles BFS at the moment
|
||||
// if (BString("") != diskSystem) {
|
||||
// }
|
||||
|
||||
status_t ret = disk->PrepareModifications();
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("There was an error preparing the "
|
||||
"disk for modifications.", NULL, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: use partition initialization editor
|
||||
// (partition->GetInitializationParameterEditor())
|
||||
|
||||
BString name = "BFS Init Test";
|
||||
BString parameters;
|
||||
parameters << "block_size " << 2048 << "\n";
|
||||
|
||||
bool supportsName = diskSystem.SupportsContentName();
|
||||
BString validatedName(name);
|
||||
ret = partition->ValidateInitialize(diskSystem.PrettyName(),
|
||||
supportsName ? &validatedName : NULL, parameters.String());
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("Validation of the given initialization "
|
||||
"parameters failed.", partition, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
BString previousName = partition->ContentName();
|
||||
|
||||
ret = partition->Initialize(diskSystem.PrettyName(),
|
||||
supportsName ? name.String() : NULL, parameters.String());
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("Initialization of the partition %s "
|
||||
"failed. (Nothing has been written to disk.)", partition, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// everything looks fine, we are ready to actually write the changes
|
||||
// to disk
|
||||
|
||||
message = "Are you sure you want to write the changes back to "
|
||||
"disk now?\n\n";
|
||||
message << "All data on the partition \"" << previousName;
|
||||
message << "\" will be irrevertably lost if you do so!";
|
||||
alert = new BAlert("final notice", message.String(),
|
||||
"Write Changes", "Cancel", NULL, B_WIDTH_FROM_WIDEST, B_WARNING_ALERT);
|
||||
choice = alert->Go();
|
||||
|
||||
if (choice == 1)
|
||||
return;
|
||||
|
||||
// commit
|
||||
ret = disk->CommitModifications();
|
||||
if (ret == B_OK) {
|
||||
_DisplayPartitionError("The partition %s has been successfully "
|
||||
"initialized.\n", partition);
|
||||
} else {
|
||||
_DisplayPartitionError("Failed to initialize the partition "
|
||||
"%s!\n", partition, ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
class BDiskDevice;
|
||||
class BPartition;
|
||||
class BMenu;
|
||||
class BMenuItem;
|
||||
class DiskView;
|
||||
class PartitionListView;
|
||||
|
||||
@@ -20,6 +21,7 @@ class PartitionListView;
|
||||
class MainWindow : public BWindow {
|
||||
public:
|
||||
MainWindow(BRect frame);
|
||||
virtual ~MainWindow();
|
||||
|
||||
// BWindow interface
|
||||
virtual bool QuitRequested();
|
||||
@@ -32,14 +34,49 @@ public:
|
||||
private:
|
||||
void _ScanDrives();
|
||||
void _ScanFileSystems();
|
||||
|
||||
void _AdaptToSelectedPartition();
|
||||
void _EnabledDisableMenuItems(BDiskDevice* disk,
|
||||
partition_id selectedPartition);
|
||||
|
||||
void _DisplayPartitionError(BString message,
|
||||
const BPartition* partition = NULL,
|
||||
status_t error = B_OK) const;
|
||||
|
||||
void _Mount(BDiskDevice* disk,
|
||||
partition_id selectedPartition);
|
||||
void _Unmount(BDiskDevice* disk,
|
||||
partition_id selectedPartition);
|
||||
void _MountAll();
|
||||
|
||||
void _Initialize(BDiskDevice* disk,
|
||||
partition_id selectedPartition,
|
||||
const BString& diskSystemName);
|
||||
|
||||
|
||||
BDiskDeviceRoster fDDRoster;
|
||||
BDiskDevice* fCurrentDisk;
|
||||
partition_id fCurrentPartitionID;
|
||||
|
||||
PartitionListView* fListView;
|
||||
DiskView* fDiskView;
|
||||
|
||||
BMenu* fDiskMenu;
|
||||
BMenu* fPartitionMenu;
|
||||
BMenu* fInitMenu;
|
||||
BMenu* fCreateMenu;
|
||||
|
||||
BMenuItem* fFormatMI;
|
||||
BMenuItem* fEjectMI;
|
||||
BMenuItem* fSurfaceTestMI;
|
||||
BMenuItem* fRescanMI;
|
||||
|
||||
BMenuItem* fCreatePrimaryMI;
|
||||
BMenuItem* fCreateExtendedMI;
|
||||
BMenuItem* fCreateLogicalMI;
|
||||
BMenuItem* fMountMI;
|
||||
BMenuItem* fUnmountMI;
|
||||
BMenuItem* fMountAllMI;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@ PartitionListView::PartitionListView(const BRect& frame, uint32 resizeMode)
|
||||
AddColumn(new BStringColumn("Volume Name", 130, 50, 500, B_TRUNCATE_MIDDLE), kVolumeNameColumn);
|
||||
AddColumn(new BStringColumn("Mounted At", 100, 50, 500, B_TRUNCATE_MIDDLE), kMountedAtColumn);
|
||||
AddColumn(new BStringColumn("Size", 100, 50, 500, B_TRUNCATE_END, B_ALIGN_RIGHT), kSizeColumn);
|
||||
|
||||
SetSortingEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +77,8 @@ PartitionListRow*
|
||||
PartitionListView::FindRow(partition_id id, PartitionListRow* parent)
|
||||
{
|
||||
for (int32 i = 0; i < CountRows(parent); i++) {
|
||||
PartitionListRow* item = dynamic_cast<PartitionListRow*>(RowAt(i, parent));
|
||||
PartitionListRow* item
|
||||
= dynamic_cast<PartitionListRow*>(RowAt(i, parent));
|
||||
if (item != NULL && item->ID() == id)
|
||||
return item;
|
||||
if (CountRows(item) > 0) {
|
||||
@@ -95,29 +98,42 @@ PartitionListView::AddPartition(BPartition* partition)
|
||||
{
|
||||
PartitionListRow* partitionrow = FindRow(partition->ID());
|
||||
|
||||
// Forget about it if this partition is already in the listview
|
||||
// forget about it if this partition is already in the listview
|
||||
if (partitionrow != NULL) {
|
||||
return partitionrow;
|
||||
}
|
||||
|
||||
// Create the row for this partition
|
||||
// create the row for this partition
|
||||
partitionrow = new PartitionListRow(partition);
|
||||
PartitionListRow* parent = NULL;
|
||||
|
||||
// If this partition has a parent...
|
||||
// see if this partition has a parent, or should have
|
||||
// a parent (add it in this case)
|
||||
if (partition->Parent() != NULL) {
|
||||
// check if it is in the listview
|
||||
PartitionListRow* parent = FindRow(partition->Parent()->ID());
|
||||
parent = FindRow(partition->Parent()->ID());
|
||||
// If parent of this partition is not yet in the list
|
||||
if (parent == NULL) {
|
||||
// add it
|
||||
parent = AddPartition(partition->Parent());
|
||||
}
|
||||
// Now it is ok to add this partition under its parent
|
||||
AddRow(partitionrow, parent);
|
||||
} else {
|
||||
// If this partition has no parent, add it in the 'root'
|
||||
AddRow(partitionrow);
|
||||
}
|
||||
|
||||
// find a proper insertion index based on the id
|
||||
int32 index = 0;
|
||||
int32 count = CountRows(parent);
|
||||
for (; index < count; index++) {
|
||||
PartitionListRow* item
|
||||
= dynamic_cast<PartitionListRow*>(RowAt(index, parent));
|
||||
if (item && item->ID() > partition->ID())
|
||||
break;
|
||||
}
|
||||
|
||||
// add the row, parent may be NULL (add at top level)
|
||||
AddRow(partitionrow, index, parent);
|
||||
|
||||
// make sure the row is initially expanded
|
||||
ExpandOrCollapse(partitionrow, true);
|
||||
|
||||
return partitionrow;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user