Files
haiku-beta6/src/apps/bootman/PartitionsPage.cpp
T
Matt Madia 4eb0cbb044 Updated TR_CONTEXT to be B_TRANSLATE_CONTEXT, relating to #5408.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36733 a95241bf-73f2-0310-859d-f6bbb57e9c96
2010-05-07 20:19:06 +00:00

357 lines
9.0 KiB
C++

/*
* Copyright 2008, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Pfeiffer, [email protected]
* Ingo Weinhold <[email protected]>
*/
#include "PartitionsPage.h"
#include <Catalog.h>
#include <CheckBox.h>
#include <RadioButton.h>
#include <ScrollView.h>
#include <StringView.h>
#include <TextControl.h>
#include <TextView.h>
#include <stdio.h>
#include <string.h>
#include <String.h>
#undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "PartitionsPage"
const uint32 kMessageShow = 'show';
const uint32 kMessageName = 'name';
PartitionsPage::PartitionsPage(BMessage* settings, BRect frame, const char* name)
: WizardPageView(settings, frame, name, B_FOLLOW_ALL,
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE)
{
_BuildUI();
}
PartitionsPage::~PartitionsPage()
{
}
void
PartitionsPage::PageCompleted()
{
int32 i;
const int32 n = fPartitions->CountChildren();
for (i = 0; i < n; i ++) {
BView* row = fPartitions->ChildAt(i);
int32 j;
const int32 m = row->CountChildren();
for (j = 0; j < m; j ++) {
BView* child = row->ChildAt(j);
BControl* control = dynamic_cast<BControl*>(child);
if (control == NULL)
continue;
int32 index;
BMessage* message = control->Message();
if (message == NULL || message->FindInt32("index", &index) != B_OK)
continue;
BMessage partition;
if (fSettings->FindMessage("partition", index, &partition) != B_OK)
continue;
if (kMessageShow == message->what) {
partition.ReplaceBool("show", control->Value() == 1);
} else if (kMessageName == message->what &&
dynamic_cast<BTextControl*>(control) != NULL) {
partition.ReplaceString("name", ((BTextControl*)control)->Text());
}
fSettings->ReplaceMessage("partition", index, &partition);
}
}
}
void
PartitionsPage::FrameResized(float width, float height)
{
WizardPageView::FrameResized(width, height);
_Layout();
}
static const float kTextDistance = 10;
void
PartitionsPage::_BuildUI()
{
BRect rect(Bounds());
BString text;
text <<
B_TRANSLATE_COMMENT("Partitions", "Title") << "\n\n" <<
B_TRANSLATE("The following partitions were detected. Please "
"check the box next to the partitions to be included "
"in the boot menu. You can also set the names of the "
"partitions as you would like them to appear in the "
"boot menu.");
fDescription = CreateDescription(rect, "description", text);
MakeHeading(fDescription);
AddChild(fDescription);
LayoutDescriptionVertically(fDescription);
rect.left = fDescription->Frame().left + 1;
rect.top = fDescription->Frame().bottom + kTextDistance;
rect.right -= B_V_SCROLL_BAR_WIDTH;
rect.bottom -= B_H_SCROLL_BAR_HEIGHT + 3;
fPartitions = new BView(rect, "partitions", B_FOLLOW_ALL,
B_WILL_DRAW);
fPartitionsScrollView = new BScrollView("scrollView", fPartitions,
B_FOLLOW_ALL,
0,
true, true);
fPartitionsScrollView->SetViewColor(ViewColor());
AddChild(fPartitionsScrollView);
_FillPartitionsView(fPartitions);
_Layout();
}
void
PartitionsPage::_Layout()
{
LayoutDescriptionVertically(fDescription);
float left = fPartitionsScrollView->Frame().left;
float top = fDescription->Frame().bottom + kTextDistance;
fPartitionsScrollView->MoveTo(left, top);
float width = fPartitionsScrollView->Frame().Width();
float height = Bounds().bottom - top;
fPartitionsScrollView->ResizeTo(width, height);
// update scroll bar range and proportion
BScrollBar* scrollbar = fPartitionsScrollView->ScrollBar(B_HORIZONTAL);
float viewWidth = fPartitions->Bounds().IntegerWidth();
float max = fPartitionsWidth - viewWidth;
if (max < 0)
max = 0;
scrollbar->SetRange(0, max);
float proportion;
if (fPartitionsWidth <= viewWidth)
proportion = 1.0;
else
proportion = viewWidth / fPartitionsWidth;
scrollbar->SetProportion(proportion);
scrollbar = fPartitionsScrollView->ScrollBar(B_VERTICAL);
float viewHeight = fPartitions->Bounds().IntegerHeight();
max = fPartitionsHeight - viewHeight;
if (max < 0)
max = 0;
scrollbar->SetRange(0, max);
if (fPartitionsHeight <= viewHeight)
proportion = 1.0;
else
proportion = viewHeight / fPartitionsHeight;
scrollbar->SetProportion(proportion);
}
const rgb_color kOddRowColor = {224, 255, 224};
const rgb_color kEvenRowColor = {224, 224, 255};
void
PartitionsPage::_FillPartitionsView(BView* view)
{
const int32 inset = 1;
font_height fontHeight;
be_plain_font->GetHeight(&fontHeight);
int32 textControlHeight;
{
BTextControl control(BRect(0, 0, 100, 100), "", "", "", NULL);
control.ResizeToPreferred();
textControlHeight = control.Bounds().IntegerHeight();
}
const int32 textHeight = (int32)(fontHeight.ascent + fontHeight.descent);
const int32 height = (int32)(2*inset
+ max_c(textControlHeight, textHeight));
const int32 kDistance = (int32)(ceil(be_plain_font->StringWidth("x")));
// show | name | type | size | path
int32 showWidth = 0;
int32 nameWidth = 0;
int32 typeWidth = 0;
int32 sizeWidth = 0;
int32 pathWidth = 0;
_ComputeColumnWidths(showWidth, nameWidth, typeWidth, sizeWidth, pathWidth);
int32 totalWidth = showWidth + nameWidth + typeWidth + sizeWidth
+ pathWidth + 2 * inset + 4 * kDistance;
int32 rowNumber = 0;
BRect frame(view->Bounds());
frame.bottom = frame.top + height;
frame.right = frame.left + 65000;
BMessage message;
for (int32 i = 0; fSettings->FindMessage("partition", i, &message) == B_OK; i ++, rowNumber ++) {
// get partition data
bool show;
BString name;
BString type;
BString path;
int64 size;
message.FindBool("show", &show);
message.FindString("name", &name);
message.FindString("type", &type);
message.FindString("path", &path);
message.FindInt64("size", &size);
// create row for partition data
BView* row = new BView(frame, "row", B_FOLLOW_TOP | B_FOLLOW_LEFT, 0);
row->SetViewColor(((rowNumber % 2) == 0) ? kEvenRowColor : kOddRowColor);
view->AddChild(row);
frame.OffsetBy(0, height + 1);
// check box
BRect rect(row->Bounds());
rect.InsetBy(inset, inset);
rect.right = rect.left + showWidth;
BCheckBox* checkBox = new BCheckBox(rect, "show", "",
_CreateControlMessage(kMessageShow, i));
if (show)
checkBox->SetValue(1);
// center vertically
checkBox->ResizeToPreferred();
const int32 showHeight = checkBox->Bounds().IntegerHeight();
if (showHeight < height)
checkBox->MoveTo(inset, (int)((height - showHeight + 1) / 2));
row->AddChild(checkBox);
rect.OffsetBy(showWidth + kDistance, 0);
// name
rect.right = rect.left + nameWidth;
BTextControl* nameControl = new BTextControl(rect, "name", "", name.String(),
_CreateControlMessage(kMessageName, i));
nameControl->SetDivider(0);
row->AddChild(nameControl);
rect.OffsetBy(nameWidth + kDistance, 0);
// type
rect.right = rect.left + typeWidth;
BStringView* typeView = new BStringView(rect, "type", type.String());
row->AddChild(typeView);
rect.OffsetBy(typeWidth + kDistance, 0);
// size
BString sizeText;
_CreateSizeText(size, &sizeText);
rect.right = rect.left + sizeWidth;
BStringView* sizeView = new BStringView(rect, "type", sizeText.String());
sizeView->SetAlignment(B_ALIGN_RIGHT);
row->AddChild(sizeView);
rect.OffsetBy(sizeWidth + kDistance, 0);
// path
rect.right = rect.left + pathWidth;
BStringView* pathView = new BStringView(rect, "path", path.String());
row->AddChild(pathView);
}
fPartitionsWidth = totalWidth;
fPartitionsHeight = frame.top;
}
void
PartitionsPage::_ComputeColumnWidths(int32& showWidth, int32& nameWidth,
int32& typeWidth, int32& sizeWidth, int32& pathWidth)
{
BCheckBox checkBox(BRect(0, 0, 100, 100), "show", "", new BMessage());
checkBox.ResizeToPreferred();
showWidth = checkBox.Bounds().IntegerWidth();
// reserve space for about 16 characters
nameWidth = (int32)ceil(be_plain_font->StringWidth("oooooooooooooooo"));
const int32 kStringViewInsets = 2;
BMessage message;
for (int32 i = 0; fSettings->FindMessage("partition", i, &message) == B_OK; i ++) {
// get partition data
BString type;
BString path;
int64 size;
message.FindString("type", &type);
message.FindString("path", &path);
message.FindInt64("size", &size);
BString sizeText;
_CreateSizeText(size, &sizeText);
int32 width = (int32)ceil(be_plain_font->StringWidth(type.String())) +
kStringViewInsets;
if (typeWidth < width)
typeWidth = width;
width = (int32)ceil(be_plain_font->StringWidth(path.String())) +
kStringViewInsets;
if (pathWidth < width)
pathWidth = width;
width = (int32)ceil(be_plain_font->StringWidth(sizeText.String())) +
kStringViewInsets;
if (sizeWidth < width)
sizeWidth = width;
}
}
void
PartitionsPage::_CreateSizeText(int64 _size, BString* text)
{
const char* suffixes[] = {
"", "K", "M", "G", "T", NULL
};
double size = _size;
int index = 0;
while (size > 1024 && suffixes[index + 1]) {
size /= 1024;
index++;
}
char buffer[128];
snprintf(buffer, sizeof(buffer), "%.2f%s", size, suffixes[index]);
*text = buffer;
}
BMessage*
PartitionsPage::_CreateControlMessage(uint32 what, int32 index)
{
BMessage* message = new BMessage(what);
message->AddInt32("index", index);
return message;
}