Patch by Bryce Groff with small changes by myself: Implemented partition
creation (ATM BFS only) and deletion. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31237 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright 2008-2009 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
* Bryce Groff <[email protected]>
|
||||
*/
|
||||
|
||||
#include "CreateParamsPanel.h"
|
||||
#include "Support.h"
|
||||
|
||||
#include <Button.h>
|
||||
#include <GridLayoutBuilder.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <GroupView.h>
|
||||
#include <MenuField.h>
|
||||
#include <MenuItem.h>
|
||||
#include <Message.h>
|
||||
#include <MessageFilter.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Slider.h>
|
||||
#include <SpaceLayoutItem.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class CreateParamsPanel::EscapeFilter : public BMessageFilter {
|
||||
public:
|
||||
EscapeFilter(CreateParamsPanel* 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:
|
||||
CreateParamsPanel* fPanel;
|
||||
};
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
enum {
|
||||
MSG_OK = 'okok',
|
||||
MSG_CANCEL = 'cncl',
|
||||
MSG_PARTITION_TYPE = 'prty'
|
||||
};
|
||||
|
||||
|
||||
CreateParamsPanel::CreateParamsPanel(BWindow* window, off_t offset, off_t size)
|
||||
: BWindow(BRect(300.0, 200.0, 600.0, 300.0), 0, B_MODAL_WINDOW_LOOK,
|
||||
B_MODAL_SUBSET_WINDOW_FEEL,
|
||||
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fEscapeFilter(new EscapeFilter(this)),
|
||||
fExitSemaphore(create_sem(0, "CreateParamsPanel exit")),
|
||||
fWindow(window),
|
||||
fReturnValue(GO_CANCELED)
|
||||
{
|
||||
AddCommonFilter(fEscapeFilter);
|
||||
_CreateViewControls(offset, size);
|
||||
}
|
||||
|
||||
|
||||
CreateParamsPanel::~CreateParamsPanel()
|
||||
{
|
||||
RemoveCommonFilter(fEscapeFilter);
|
||||
delete fEscapeFilter;
|
||||
|
||||
delete_sem(fExitSemaphore);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CreateParamsPanel::QuitRequested()
|
||||
{
|
||||
release_sem(fExitSemaphore);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CreateParamsPanel::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_CANCEL:
|
||||
Cancel();
|
||||
break;
|
||||
|
||||
case MSG_OK:
|
||||
fReturnValue = GO_SUCCESS;
|
||||
release_sem(fExitSemaphore);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
CreateParamsPanel::Go(off_t& offset, off_t& size, BString& type)
|
||||
{
|
||||
// run the window thread, to get an initial layout of the controls
|
||||
Hide();
|
||||
Show();
|
||||
if (!Lock())
|
||||
return GO_CANCELED;
|
||||
|
||||
// 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);
|
||||
|
||||
Show();
|
||||
Unlock();
|
||||
|
||||
// block this thread now, but keep the window repainting
|
||||
while (true) {
|
||||
status_t err = acquire_sem_etc(fExitSemaphore, 1,
|
||||
B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT, 50000);
|
||||
if (err != B_TIMED_OUT && err != B_INTERRUPTED)
|
||||
break;
|
||||
fWindow->UpdateIfNeeded();
|
||||
}
|
||||
|
||||
if (!Lock())
|
||||
return GO_CANCELED;
|
||||
|
||||
if (fReturnValue == GO_SUCCESS) {
|
||||
if (BMenuItem* item = fTypeMenuField->Menu()->FindMarked()) {
|
||||
const char* _type;
|
||||
BMessage* message = item->Message();
|
||||
if (!message || message->FindString("type", &_type) < B_OK)
|
||||
_type = "BFS Filesystem";
|
||||
type << _type;
|
||||
}
|
||||
size = fSizeSlider->Value();
|
||||
}
|
||||
|
||||
int32 value = fReturnValue;
|
||||
|
||||
Quit();
|
||||
// NOTE: this object is toast now!
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CreateParamsPanel::Cancel()
|
||||
{
|
||||
fReturnValue = GO_CANCELED;
|
||||
release_sem(fExitSemaphore);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CreateParamsPanel::_CreateViewControls(off_t offset, off_t size)
|
||||
{
|
||||
// Setup the controls
|
||||
//TODO Add all the partition types that we want/can use
|
||||
fTypePopUpMenu = new BPopUpMenu("Partition Type");
|
||||
BMessage* message = new BMessage(MSG_PARTITION_TYPE);
|
||||
message->AddString("type", "BFS Filesystem");
|
||||
BMenuItem *item = new BMenuItem("BFS Filesystem", message);
|
||||
fTypePopUpMenu->AddItem(item);
|
||||
item->SetMarked(true);
|
||||
fTypeMenuField = new BMenuField("Partition Type", fTypePopUpMenu, NULL);
|
||||
|
||||
fSizeSlider = new SizeSlider("Slider", "Partition Size", NULL, offset,
|
||||
size);
|
||||
fSizeSlider->SetPosition(1.0);
|
||||
|
||||
fOKButton = new BButton("Create", new BMessage(MSG_OK));
|
||||
fCancelButton = new BButton("Cancel", new BMessage(MSG_CANCEL));
|
||||
|
||||
BView* rootView = BGroupLayoutBuilder(B_VERTICAL, 4)
|
||||
|
||||
.Add(BSpaceLayoutItem::CreateVerticalStrut(10))
|
||||
|
||||
// test views
|
||||
.Add(BGridLayoutBuilder(10, 10)
|
||||
// row 1
|
||||
.Add(BSpaceLayoutItem::CreateHorizontalStrut(5), 0, 0)
|
||||
|
||||
.Add(fSizeSlider, 1, 0)
|
||||
.Add(BSpaceLayoutItem::CreateVerticalStrut(5), 1, 0)
|
||||
.Add(fTypeMenuField, 1, 1)
|
||||
)
|
||||
|
||||
// controls
|
||||
.AddGroup(B_HORIZONTAL, 10)
|
||||
.Add(BSpaceLayoutItem::CreateHorizontalStrut(5))
|
||||
.AddGlue()
|
||||
.Add(fCancelButton)
|
||||
.Add(fOKButton)
|
||||
.Add(BSpaceLayoutItem::CreateHorizontalStrut(5))
|
||||
.End()
|
||||
|
||||
.Add(BSpaceLayoutItem::CreateVerticalStrut(5))
|
||||
;
|
||||
|
||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
AddChild(rootView);
|
||||
SetDefaultButton(fOKButton);
|
||||
|
||||
AddToSubset(fWindow);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2008 Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <[email protected]>
|
||||
* Bryce Groff <[email protected]>
|
||||
*/
|
||||
#ifndef CREATE_PARAMS_PANEL_H
|
||||
#define CREATE_PARAMS_PANEL_H
|
||||
|
||||
#include "Support.h"
|
||||
|
||||
#include <Window.h>
|
||||
#include <InterfaceKit.h>
|
||||
#include <Partition.h>
|
||||
|
||||
class BMenuField;
|
||||
class BTextControl;
|
||||
class SizeSlider;
|
||||
|
||||
class CreateParamsPanel : public BWindow {
|
||||
public:
|
||||
CreateParamsPanel(BWindow* window,
|
||||
off_t offset, off_t size);
|
||||
virtual ~CreateParamsPanel();
|
||||
|
||||
virtual bool QuitRequested();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
int32 Go(off_t& offset, off_t& size,
|
||||
BString& parameters);
|
||||
void Cancel();
|
||||
|
||||
|
||||
private:
|
||||
void _CreateViewControls(off_t offset, off_t size);
|
||||
|
||||
class EscapeFilter;
|
||||
EscapeFilter* fEscapeFilter;
|
||||
sem_id fExitSemaphore;
|
||||
BWindow* fWindow;
|
||||
int32 fReturnValue;
|
||||
|
||||
BPopUpMenu* fTypePopUpMenu;
|
||||
BMenuField* fTypeMenuField;
|
||||
SizeSlider* fSizeSlider;
|
||||
BButton* fOKButton;
|
||||
BButton* fCancelButton;
|
||||
};
|
||||
|
||||
#endif // CREATE_PARAMS_PANEL_H
|
||||
@@ -13,7 +13,7 @@ resource app_version {
|
||||
internal = 0,
|
||||
|
||||
short_info = "DriveSetup",
|
||||
long_info = "DriveSetup ©2002-2008 Haiku"
|
||||
long_info = "DriveSetup ©2002-2009 Haiku"
|
||||
};
|
||||
|
||||
resource app_flags B_SINGLE_LAUNCH;
|
||||
|
||||
@@ -8,15 +8,13 @@
|
||||
#ifndef INIT_PARAMS_PANEL_H
|
||||
#define INIT_PARAMS_PANEL_H
|
||||
|
||||
#include "Support.h"
|
||||
|
||||
#include <Window.h>
|
||||
|
||||
class BMenuField;
|
||||
class BTextControl;
|
||||
|
||||
enum {
|
||||
GO_CANCELED = 0,
|
||||
GO_SUCCESS
|
||||
};
|
||||
|
||||
class InitParamsPanel : public BWindow {
|
||||
public:
|
||||
|
||||
@@ -5,6 +5,7 @@ AddSubDirSupportedPlatforms libbe_test ;
|
||||
UsePrivateHeaders interface shared storage tracker ;
|
||||
|
||||
Preference DriveSetup :
|
||||
CreateParamsPanel.cpp
|
||||
DiskView.cpp
|
||||
DriveSetup.cpp
|
||||
InitParamsPanel.cpp
|
||||
|
||||
+129
-217
@@ -12,6 +12,7 @@
|
||||
#include "MainWindow.h"
|
||||
#include "DiskView.h"
|
||||
#include "InitParamsPanel.h"
|
||||
#include "CreateParamsPanel.h"
|
||||
#include "PartitionList.h"
|
||||
#include "Support.h"
|
||||
#include "tracker_private.h"
|
||||
@@ -23,8 +24,10 @@
|
||||
#include <Application.h>
|
||||
#include <ColumnListView.h>
|
||||
#include <ColumnTypes.h>
|
||||
#include <Debug.h>
|
||||
#include <DiskDevice.h>
|
||||
#include <DiskDeviceVisitor.h>
|
||||
#include <DiskDeviceTypes.h>
|
||||
#include <DiskSystem.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MenuBar.h>
|
||||
@@ -37,33 +40,6 @@
|
||||
#include <Volume.h>
|
||||
#include <VolumeRoster.h>
|
||||
|
||||
|
||||
//static void
|
||||
//print_partition_table_header()
|
||||
//{
|
||||
//printf(" Index Start Size Content Type "
|
||||
//"Content Name\n");
|
||||
//printf("--------------------------------------------------------------"
|
||||
//"------------\n");
|
||||
//}
|
||||
|
||||
|
||||
//static void
|
||||
//print_partition(BPartition* partition, int level, int index)
|
||||
//{
|
||||
//BString offset, size;
|
||||
//get_size_string(partition->Offset(), offset);
|
||||
//get_size_string(partition->Size(), size);
|
||||
|
||||
//printf("%*s%02d%*s %8s %8s %26.26s %16.16s\n", 2 * level, "",
|
||||
//index,
|
||||
//2 * max_c(3 - level, 0), "",
|
||||
//offset.String(), size.String(),
|
||||
//(partition->ContentType() ? partition->ContentType() : "-"),
|
||||
//(partition->ContentName() ? partition->ContentName() : ""));
|
||||
//}
|
||||
|
||||
|
||||
class ListPopulatorVisitor : public BDiskDeviceVisitor {
|
||||
public:
|
||||
ListPopulatorVisitor(PartitionListView* list, int32& diskCount,
|
||||
@@ -192,9 +168,7 @@ MainWindow::MainWindow(BRect frame)
|
||||
new BMessage(MSG_SURFACE_TEST));
|
||||
fRescanMI = new BMenuItem("Rescan", new BMessage(MSG_RESCAN));
|
||||
|
||||
fDeleteMI = new BMenuItem("Delete (not implemented)",
|
||||
new BMessage(MSG_DELETE));
|
||||
fDeleteMI->SetEnabled(false);
|
||||
fDeleteMI = new BMenuItem("Delete", new BMessage(MSG_DELETE), 'D');
|
||||
|
||||
fMountMI = new BMenuItem("Mount", new BMessage(MSG_MOUNT), 'M');
|
||||
fUnmountMI = new BMenuItem("Unmount", new BMessage(MSG_UNMOUNT), 'U');
|
||||
@@ -214,7 +188,7 @@ MainWindow::MainWindow(BRect frame)
|
||||
|
||||
// Parition menu
|
||||
fPartitionMenu = new BMenu("Partition");
|
||||
fCreateMenu = new BMenu("Create (not implemented)");
|
||||
fCreateMenu = new BMenu("Create");
|
||||
fPartitionMenu->AddItem(fCreateMenu);
|
||||
|
||||
fInitMenu = new BMenu("Initialize");
|
||||
@@ -288,9 +262,13 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
printf("MSG_FORMAT\n");
|
||||
break;
|
||||
|
||||
case MSG_CREATE:
|
||||
printf("MSG_CREATE\n");
|
||||
case MSG_CREATE: {
|
||||
BString diskSystemName;
|
||||
//if (message->FindString("disk system", &diskSystemName) != B_OK)
|
||||
// break;
|
||||
_Create(fCurrentDisk, fCurrentPartitionID, diskSystemName);
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_INITIALIZE: {
|
||||
BString diskSystemName;
|
||||
@@ -301,7 +279,7 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
case MSG_DELETE:
|
||||
printf("MSG_DELETE\n");
|
||||
_Delete(fCurrentDisk, fCurrentPartitionID);
|
||||
break;
|
||||
|
||||
case MSG_EJECT:
|
||||
@@ -462,6 +440,7 @@ MainWindow::_SetToDiskAndPartition(partition_id disk, partition_id partition,
|
||||
{
|
||||
printf("MainWindow::_SetToDiskAndPartition(disk: %ld, partition: %ld, "
|
||||
"parent: %ld)\n", disk, partition, parent);
|
||||
|
||||
BDiskDevice* oldDisk = NULL;
|
||||
if (!fCurrentDisk || fCurrentDisk->ID() != disk) {
|
||||
oldDisk = fCurrentDisk;
|
||||
@@ -490,10 +469,6 @@ void
|
||||
MainWindow::_UpdateMenus(BDiskDevice* disk,
|
||||
partition_id selectedPartition, partition_id parentID)
|
||||
{
|
||||
printf("MainWindow::_UpdateMenus(disk: %p, "
|
||||
"selectedPartition: %ld, parentID: %ld)\n", disk, selectedPartition,
|
||||
parentID);
|
||||
|
||||
// clean out Create and Init menu
|
||||
while (BMenuItem* item = fCreateMenu->RemoveItem(0L))
|
||||
delete item;
|
||||
@@ -526,11 +501,10 @@ printf("MainWindow::_UpdateMenus(disk: %p, "
|
||||
partition = disk;
|
||||
|
||||
bool prepared = disk->PrepareModifications() == B_OK;
|
||||
printf(" prepared: %d\n", prepared);
|
||||
// fCreateMenu->SetEnabled(prepared);
|
||||
// TODO: Enable once _Create() is implemented...
|
||||
fCreateMenu->SetEnabled(false);
|
||||
fCreateMenu->SetEnabled(prepared);
|
||||
fInitMenu->SetEnabled(prepared);
|
||||
fDeleteMI->SetEnabled(prepared);
|
||||
|
||||
|
||||
BDiskSystem diskSystem;
|
||||
fDDRoster.RewindDiskSystems();
|
||||
@@ -559,7 +533,6 @@ fCreateMenu->SetEnabled(false);
|
||||
}
|
||||
|
||||
if (parentPartition != NULL) {
|
||||
printf(" parent partition: %p\n", parentPartition);
|
||||
BString supportedChildType;
|
||||
int32 cookie = 0;
|
||||
status_t ret;
|
||||
@@ -577,7 +550,6 @@ printf(" parent partition: %p\n", parentPartition);
|
||||
fprintf(stderr, "Failed to get supported child types: %s\n",
|
||||
strerror(ret));
|
||||
} else {
|
||||
printf(" no parent partition\n");
|
||||
fCreateMenu->SetEnabled(false);
|
||||
}
|
||||
|
||||
@@ -587,8 +559,7 @@ printf(" no parent partition\n");
|
||||
// Mount items
|
||||
if (partition) {
|
||||
fInitMenu->SetEnabled(!partition->IsMounted());
|
||||
// fDeleteMI->SetEnabled(!partition->IsMounted());
|
||||
fDeleteMI->SetEnabled(false);
|
||||
fDeleteMI->SetEnabled(!partition->IsMounted());
|
||||
fMountMI->SetEnabled(!partition->IsMounted());
|
||||
|
||||
bool unMountable = false;
|
||||
@@ -742,6 +713,7 @@ public:
|
||||
status_t ret = fDisk->CommitModifications();
|
||||
if (ret == B_OK)
|
||||
fModificationStatus = B_ERROR;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -907,210 +879,150 @@ void
|
||||
MainWindow::_Create(BDiskDevice* disk, partition_id selectedPartition,
|
||||
const BString& partitionType)
|
||||
{
|
||||
printf("_Create(disk: %p, selectedPartition: %ld)\n", disk,
|
||||
selectedPartition);
|
||||
|
||||
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 0
|
||||
// get the parent partition
|
||||
BPartition* partition = NULL;
|
||||
int32 partitionIndex;
|
||||
if (!_SelectPartition("parent partition index [-1 to abort]: ",
|
||||
partition, partitionIndex)) {
|
||||
BPartition* partition = disk->FindDescendant(selectedPartition);
|
||||
if (partition) {
|
||||
_DisplayPartitionError("The selected partition contains a file "
|
||||
"system");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\nselected partition:\n\n");
|
||||
print_partition_table_header();
|
||||
print_partition(partition, 0, partitionIndex);
|
||||
|
||||
if (!partition->ContainsPartitioningSystem()) {
|
||||
printf("The selected partition does not contain a partitioning "
|
||||
"system.\n");
|
||||
if (!disk->ContainsPartitioningSystem()) {
|
||||
_DisplayPartitionError("The selected partition does not contain "
|
||||
"a partitioning system.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// get supported types
|
||||
BObjectList<BString> supportedTypes(20, true);
|
||||
BString typeBuffer;
|
||||
int32 cookie = 0;
|
||||
while (partition->GetNextSupportedChildType(&cookie, &typeBuffer)
|
||||
== B_OK) {
|
||||
supportedTypes.AddItem(new BString(typeBuffer));
|
||||
}
|
||||
|
||||
if (supportedTypes.IsEmpty()) {
|
||||
printf("The partitioning system is not able to create any "
|
||||
"child partition (no supported types).\n");
|
||||
ModificationPreparer modificationPreparer(disk);
|
||||
status_t ret = modificationPreparer.ModificationStatus();
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("There was an error preparing the "
|
||||
"disk for modifications.", NULL, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
// get partitioning info
|
||||
BPartitioningInfo partitioningInfo;
|
||||
status_t error = partition->GetPartitioningInfo(&partitioningInfo);
|
||||
status_t error = disk->GetPartitioningInfo(&partitioningInfo);
|
||||
if (error != B_OK) {
|
||||
printf("Failed to get partitioning info for partition: %s\n",
|
||||
strerror(error));
|
||||
_DisplayPartitionError("Could not aquire partitioning information.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Find out which partition is the currently selected partition and get
|
||||
// the information about the offset and how large of a partition we can create.
|
||||
int32 spacesCount = partitioningInfo.CountPartitionableSpaces();
|
||||
if (spacesCount == 0) {
|
||||
printf("There's no space on the partition where a child partition "
|
||||
"could be created\n");
|
||||
_DisplayPartitionError("There's no space on the partition where a "
|
||||
"child partition could be created\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// let the user select the partition type, if there's more than one
|
||||
int64 typeIndex = 0;
|
||||
int32 supportedTypesCount = supportedTypes.CountItems();
|
||||
if (supportedTypesCount > 1) {
|
||||
// list them
|
||||
printf("Possible partition types:\n");
|
||||
for (int32 i = 0; i < supportedTypesCount; i++)
|
||||
printf("%2ld %s\n", i, supportedTypes.ItemAt(i)->String());
|
||||
BString name, type, parameters;
|
||||
off_t offset, size;
|
||||
partitioningInfo.GetPartitionableSpaceAt(0, &offset, &size);
|
||||
|
||||
if (!_ReadNumber("supported type index [-1 to abort]: ", 0,
|
||||
supportedTypesCount - 1, -1, "invalid index", typeIndex)) {
|
||||
return;
|
||||
}
|
||||
CreateParamsPanel* panel = new CreateParamsPanel(this, offset, size);
|
||||
if (panel->Go(offset, size, type) == GO_CANCELED)
|
||||
return;
|
||||
|
||||
ret = disk->ValidateCreateChild(&offset, &size, type.String(),
|
||||
NULL, NULL);
|
||||
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("Validation of the given creation "
|
||||
"parameters failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
const char* type = supportedTypes.ItemAt(typeIndex)->String();
|
||||
// Warn the user one more time...
|
||||
BString message = "Are you sure you want to write the changes back to "
|
||||
"disk now?\n\n";
|
||||
message << "All data on the partition";
|
||||
message << " will be irrevertably lost if you do so!";
|
||||
BAlert* alert = new BAlert("final notice", message.String(),
|
||||
"Write Changes", "Cancel", NULL, B_WIDTH_FROM_WIDEST, B_WARNING_ALERT);
|
||||
int32 choice = alert->Go();
|
||||
|
||||
// list partitionable spaces
|
||||
printf("Unused regions where the new partition could be created:\n");
|
||||
for (int32 i = 0; i < spacesCount; i++) {
|
||||
off_t _offset;
|
||||
off_t _size;
|
||||
partitioningInfo.GetPartitionableSpaceAt(i, &_offset, &_size);
|
||||
BString offset, size;
|
||||
get_size_string(_offset, offset);
|
||||
get_size_string(_size, size);
|
||||
printf("%2ld start: %8s, size: %8s\n", i, offset.String(),
|
||||
size.String());
|
||||
if (choice == 1)
|
||||
return;
|
||||
|
||||
ret = disk->CreateChild(offset, size, type.String(),
|
||||
NULL, parameters.String());
|
||||
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("Creation of the partition has failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// let the user select the partitionable space, if there's more than one
|
||||
int64 spaceIndex = 0;
|
||||
if (spacesCount > 1) {
|
||||
if (!_ReadNumber("unused region index [-1 to abort]: ", 0,
|
||||
spacesCount - 1, -1, "invalid index", spaceIndex)) {
|
||||
return;
|
||||
}
|
||||
// commit
|
||||
ret = modificationPreparer.CommitModifications();
|
||||
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("Failed to initialize the partition. "
|
||||
"This operation is exiting.\nNo changes have been made!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
off_t spaceOffset;
|
||||
off_t spaceSize;
|
||||
partitioningInfo.GetPartitionableSpaceAt(spaceIndex, &spaceOffset,
|
||||
&spaceSize);
|
||||
|
||||
off_t start;
|
||||
off_t size;
|
||||
BString parameters;
|
||||
while (true) {
|
||||
// let the user enter start, size, and parameters
|
||||
|
||||
// start
|
||||
while (true) {
|
||||
BString spaceOffsetString;
|
||||
get_size_string(spaceOffset, spaceOffsetString);
|
||||
BString prompt("partition start [default: ");
|
||||
prompt << spaceOffsetString << "]: ";
|
||||
if (!_ReadSize(prompt.String(), spaceOffset, start))
|
||||
return;
|
||||
|
||||
if (start >= spaceOffset && start <= spaceOffset + spaceSize)
|
||||
break;
|
||||
|
||||
printf("invalid partition start\n");
|
||||
}
|
||||
|
||||
// size
|
||||
off_t maxSize = spaceOffset + spaceSize - start;
|
||||
while (true) {
|
||||
BString maxSizeString;
|
||||
get_size_string(maxSize, maxSizeString);
|
||||
BString prompt("partition size [default: ");
|
||||
prompt << maxSizeString << "]: ";
|
||||
if (!_ReadSize(prompt.String(), maxSize, size))
|
||||
return;
|
||||
|
||||
if (size >= 0 && start + size <= spaceOffset + spaceSize)
|
||||
break;
|
||||
|
||||
printf("invalid partition size\n");
|
||||
}
|
||||
|
||||
// parameters
|
||||
if (!_ReadLine("partition parameters: ", parameters))
|
||||
return;
|
||||
|
||||
// validate parameters
|
||||
off_t validatedStart = start;
|
||||
off_t validatedSize = size;
|
||||
// TODO: Support the name parameter!
|
||||
if (partition->ValidateCreateChild(&start, &size, type, NULL,
|
||||
parameters.String()) != B_OK) {
|
||||
printf("Validation of the given values failed. Sorry, can't "
|
||||
"continue.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// did the disk system change offset or size?
|
||||
if (validatedStart == start && validatedSize == size) {
|
||||
printf("Everything looks dandy.\n");
|
||||
} else {
|
||||
BString startString, sizeString;
|
||||
get_size_string(validatedStart, startString);
|
||||
get_size_string(validatedSize, sizeString);
|
||||
printf("The disk system adjusted the partition start and "
|
||||
"size to %lld (%s) and %lld (%s).\n",
|
||||
validatedStart, startString.String(), validatedSize,
|
||||
sizeString.String());
|
||||
start = validatedStart;
|
||||
size = validatedSize;
|
||||
}
|
||||
|
||||
// let the user decide whether to continue, change parameters, or
|
||||
// abort
|
||||
bool changeParameters = false;
|
||||
while (true) {
|
||||
BString line;
|
||||
_ReadLine("[c]ontinue, change [p]arameters, or [a]bort? ", line);
|
||||
if (line == "a")
|
||||
return;
|
||||
if (line == "p") {
|
||||
changeParameters = true;
|
||||
break;
|
||||
}
|
||||
if (line == "c")
|
||||
break;
|
||||
|
||||
printf("invalid input\n");
|
||||
}
|
||||
|
||||
if (!changeParameters)
|
||||
break;
|
||||
}
|
||||
|
||||
// create child
|
||||
error = partition->CreateChild(start, size, type, NULL,
|
||||
parameters.String());
|
||||
if (error != B_OK)
|
||||
printf("Creating the partition failed: %s\n", strerror(error));
|
||||
#endif // 0
|
||||
// The disk layout has changed, update disk information
|
||||
bool updated;
|
||||
ret = disk->Update(&updated);
|
||||
|
||||
_ScanDrives();
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::_Delete(BDiskDevice* disk, partition_id selectedPartition)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
ModificationPreparer modificationPreparer(disk);
|
||||
status_t ret = modificationPreparer.ModificationStatus();
|
||||
if (ret != B_OK) {
|
||||
_DisplayPartitionError("There was an error preparing the "
|
||||
"disk for modifications.", NULL, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!disk->CanDeleteChild(partition->Index())) {
|
||||
_DisplayPartitionError("Cannot delete the selected partition");
|
||||
return;
|
||||
}
|
||||
|
||||
// Warn the user one more time...
|
||||
BString message = "Are you sure you want to delete the selected ";
|
||||
message << "partition?\n\nAll data on the partition";
|
||||
message << " will be irrevertably lost if you do so!";
|
||||
BAlert* alert = new BAlert("final notice", message.String(),
|
||||
"Delete Partition", "Cancel", NULL, B_WIDTH_FROM_WIDEST,
|
||||
B_WARNING_ALERT);
|
||||
int32 choice = alert->Go();
|
||||
|
||||
if (choice == 1)
|
||||
return;
|
||||
|
||||
ret = disk->DeleteChild(partition->Index());
|
||||
if (ret != B_OK) {
|
||||
PRINT(("MainWindow::_Delete(): DeleteChild() failed: %s\n",
|
||||
strerror(ret)));
|
||||
_DisplayPartitionError("Could not delete the selected partition");
|
||||
return;
|
||||
}
|
||||
|
||||
modificationPreparer.CommitModifications();
|
||||
|
||||
_ScanDrives();
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ private:
|
||||
void _Create(BDiskDevice* disk,
|
||||
partition_id selectedPartition,
|
||||
const BString& partitionType);
|
||||
void _Delete(BDiskDevice* disk,
|
||||
partition_id selectedPartition);
|
||||
|
||||
|
||||
BDiskDeviceRoster fDDRoster;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#include <String.h>
|
||||
|
||||
|
||||
uint32 kMegaByte = 1048576;
|
||||
|
||||
|
||||
const char*
|
||||
string_for_size(off_t size, char *string)
|
||||
{
|
||||
@@ -111,3 +114,33 @@ SpaceIDMap::SpaceIDFor(partition_id parentID, off_t spaceOffset)
|
||||
return newID;
|
||||
}
|
||||
|
||||
|
||||
SizeSlider::SizeSlider(const char* name, const char* label,
|
||||
BMessage* message, int32 minValue, int32 maxValue)
|
||||
: BSlider(name, label, message, minValue, maxValue, B_HORIZONTAL,
|
||||
B_TRIANGLE_THUMB),
|
||||
fOffset(minValue),
|
||||
fSize(maxValue)
|
||||
{
|
||||
SetBarColor((rgb_color){ 0, 80, 255, 255 });
|
||||
BString offset, size;
|
||||
offset << fOffset / kMegaByte; offset << " MB";
|
||||
size << fSize / kMegaByte; size << " MB";
|
||||
SetLimitLabels(offset.String(), size.String());
|
||||
}
|
||||
|
||||
|
||||
SizeSlider::~SizeSlider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
SizeSlider::UpdateText() const
|
||||
{
|
||||
fStatusLabel.Truncate(0);
|
||||
fStatusLabel << (Value() / kMegaByte);
|
||||
fStatusLabel << " MB";
|
||||
|
||||
return fStatusLabel.String();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <DiskDeviceDefs.h>
|
||||
#include <HashMap.h>
|
||||
#include <HashString.h>
|
||||
#include <Slider.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class BPartition;
|
||||
@@ -20,6 +22,10 @@ void dump_partition_info(const BPartition* partition);
|
||||
|
||||
bool is_valid_partitionable_space(size_t size);
|
||||
|
||||
enum {
|
||||
GO_CANCELED = 0,
|
||||
GO_SUCCESS
|
||||
};
|
||||
|
||||
class SpaceIDMap : public HashMap<HashString, partition_id> {
|
||||
public:
|
||||
@@ -33,5 +39,19 @@ private:
|
||||
partition_id fNextSpaceID;
|
||||
};
|
||||
|
||||
class SizeSlider : public BSlider {
|
||||
public:
|
||||
SizeSlider(const char* name, const char* label,
|
||||
BMessage* message, int32 minValue,
|
||||
int32 maxValue);
|
||||
virtual ~SizeSlider();
|
||||
|
||||
virtual const char* UpdateText() const;
|
||||
|
||||
private:
|
||||
off_t fOffset;
|
||||
off_t fSize;
|
||||
mutable BString fStatusLabel;
|
||||
};
|
||||
|
||||
#endif // SUPPORT_H
|
||||
|
||||
Reference in New Issue
Block a user