1/*
2 * Copyright 2008-2011, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * 		Axel Dörfler, <axeld@pinc-software.de>
7 *		Michael Pfeiffer, laplace@users.sourceforge.net
8 *		Ingo Weinhold <bonefish@cs.tu-berlin.de>
9 */
10
11
12#include "PartitionsPage.h"
13
14#include <stdio.h>
15#include <string.h>
16
17#include <Catalog.h>
18#include <CheckBox.h>
19#include <ControlLook.h>
20#include <LayoutBuilder.h>
21#include <RadioButton.h>
22#include <ScrollView.h>
23#include <SeparatorView.h>
24#include <StringView.h>
25#include <TextControl.h>
26#include <TextView.h>
27#include <ViewPort.h>
28
29#include <StringForSize.h>
30
31
32#undef B_TRANSLATION_CONTEXT
33#define B_TRANSLATION_CONTEXT "PartitionsPage"
34
35
36const uint32 kMessageShow = 'show';
37const uint32 kMessageName = 'name';
38
39
40PartitionsPage::PartitionsPage(BMessage* settings, const char* name)
41	:
42	WizardPageView(settings, name)
43{
44	_BuildUI();
45}
46
47
48PartitionsPage::~PartitionsPage()
49{
50}
51
52
53void
54PartitionsPage::PageCompleted()
55{
56	BGridLayout* layout = (BGridLayout*)fPartitions->GetLayout();
57	int32 index = 0;
58
59	for (int32 row = 0; row < layout->CountRows(); row += 3, index++) {
60		BCheckBox* showBox
61			= dynamic_cast<BCheckBox*>(layout->ItemAt(0, row)->View());
62		BTextControl* nameControl
63			= dynamic_cast<BTextControl*>(layout->ItemAt(1, row)->View());
64		if (nameControl == NULL || showBox == NULL)
65			debugger("partitions page is broken");
66
67		BMessage partition;
68		if (fSettings->FindMessage("partition", index, &partition) != B_OK)
69			continue;
70
71		partition.ReplaceBool("show", showBox->Value() != 0);
72		partition.ReplaceString("name", nameControl->Text());
73
74		fSettings->ReplaceMessage("partition", index, &partition);
75	}
76}
77
78
79void
80PartitionsPage::_BuildUI()
81{
82	BString text;
83	text << B_TRANSLATE_COMMENT("Partitions", "Title") << "\n"
84		<< B_TRANSLATE("The following partitions were detected. Please "
85			"check the box next to the partitions to be included "
86			"in the boot menu. You can also set the names of the "
87			"partitions as you would like them to appear in the "
88			"boot menu.");
89	fDescription = CreateDescription("description", text);
90	MakeHeading(fDescription);
91
92	fPartitions = new BGridView("partitions", 0,
93		be_control_look->DefaultItemSpacing() / 3);
94
95	BLayoutBuilder::Grid<>(fPartitions)
96		.SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
97			B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING)
98		.SetColumnWeight(0, 0)
99		.SetColumnWeight(1, 1)
100		.SetColumnWeight(2, 0.5)
101		.SetColumnWeight(3, 0.5);
102	_FillPartitionsView(fPartitions);
103
104	BViewPort* viewPort = new BViewPort(fPartitions);
105
106	BScrollView* scrollView = new BScrollView("scrollView", viewPort, 0,
107		false, true);
108
109	SetLayout(new BGroupLayout(B_VERTICAL));
110
111	BLayoutBuilder::Group<>((BGroupLayout*)GetLayout())
112		.Add(fDescription)
113		.Add(scrollView);
114}
115
116
117void
118PartitionsPage::_FillPartitionsView(BView* view)
119{
120	// show | name | type | size | path
121
122	int32 rowNumber = 0;
123
124	BMessage message;
125	for (int32 i = 0; fSettings->FindMessage("partition", i, &message) == B_OK;
126			i++, rowNumber++) {
127		// get partition data
128		bool show;
129		BString name;
130		BString type;
131		BString path;
132		int64 size;
133		message.FindBool("show", &show);
134		message.FindString("name", &name);
135		message.FindString("type", &type);
136		message.FindString("path", &path);
137		message.FindInt64("size", &size);
138
139		// check box
140		BCheckBox* checkBox = new BCheckBox("show", "",
141			_CreateControlMessage(kMessageShow, i));
142		if (show)
143			checkBox->SetValue(1);
144
145		// name
146		BTextControl* nameControl = new BTextControl("name", "",
147			name.String(), _CreateControlMessage(kMessageName, i));
148		nameControl->SetExplicitMinSize(BSize(StringWidth("WWWWWWWWWWWWWW"),
149			B_SIZE_UNSET));
150
151		// size
152		BString sizeText;
153		_CreateSizeText(size, &sizeText);
154		sizeText << ", " << type.String();
155		BStringView* typeView = new BStringView("type", sizeText.String());
156		typeView->SetExplicitAlignment(
157			BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_UNSET));
158
159		// path
160		BStringView* pathView = new BStringView("path", path.String());
161		pathView->SetExplicitAlignment(
162			BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_UNSET));
163
164		if (rowNumber > 0) {
165			BLayoutBuilder::Grid<>((BGridLayout*)view->GetLayout())
166				.Add(new BSeparatorView(B_HORIZONTAL), 0, rowNumber, 4, 1)
167				.SetRowWeight(rowNumber, 0);
168			rowNumber++;
169		}
170
171		BLayoutBuilder::Grid<>((BGridLayout*)view->GetLayout())
172			.Add(checkBox, 0, rowNumber, 1, 2)
173			.Add(nameControl, 1, rowNumber, 1, 2)
174			.Add(BSpaceLayoutItem::CreateHorizontalStrut(10), 2, rowNumber)
175			.Add(typeView, 3, rowNumber)
176			.Add(pathView, 3, rowNumber + 1)
177			.SetRowWeight(rowNumber + 1, 1);
178		rowNumber++;
179	}
180}
181
182
183void
184PartitionsPage::_CreateSizeText(int64 size, BString* text)
185{
186	char buffer[256];
187	*text = string_for_size(size, buffer, sizeof(buffer));
188}
189
190
191BMessage*
192PartitionsPage::_CreateControlMessage(uint32 what, int32 index)
193{
194	BMessage* message = new BMessage(what);
195	message->AddInt32("index", index);
196	return message;
197}
198