xref: /haiku/src/apps/bootmanager/FileSelectionPage.cpp (revision 25a7b01d15612846f332751841da3579db313082)
1 /*
2  * Copyright 2008-2010, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Michael Pfeiffer <laplace@users.sourceforge.net>
7  */
8 
9 
10 #include "FileSelectionPage.h"
11 
12 #include <string.h>
13 
14 #include <Button.h>
15 #include <Catalog.h>
16 #include <ControlLook.h>
17 #include <Path.h>
18 #include <RadioButton.h>
19 #include <TextControl.h>
20 #include <TextView.h>
21 
22 
23 #undef B_TRANSLATION_CONTEXT
24 #define B_TRANSLATION_CONTEXT "FileSelectionPage"
25 
26 
27 const uint32 kMsgOpenFilePanel = 'open';
28 
29 
FileSelectionPage(BMessage * settings,BRect frame,const char * name,const char * description,file_panel_mode mode)30 FileSelectionPage::FileSelectionPage(BMessage* settings, BRect frame,
31 	const char* name, const char* description, file_panel_mode mode)
32 	:
33 	WizardPageView(settings, frame, name, B_FOLLOW_ALL,
34 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE),
35 	fMode(mode),
36 	fFilePanel(NULL)
37 {
38 	_BuildUI(description);
39 }
40 
41 
~FileSelectionPage()42 FileSelectionPage::~FileSelectionPage()
43 {
44 }
45 
46 
47 void
FrameResized(float width,float height)48 FileSelectionPage::FrameResized(float width, float height)
49 {
50 	WizardPageView::FrameResized(width, height);
51 	_Layout();
52 }
53 
54 
55 void
AttachedToWindow()56 FileSelectionPage::AttachedToWindow()
57 {
58 	fSelect->SetTarget(this);
59 }
60 
61 
62 void
MessageReceived(BMessage * message)63 FileSelectionPage::MessageReceived(BMessage* message)
64 {
65 	switch (message->what) {
66 		case kMsgOpenFilePanel:
67 			_OpenFilePanel();
68 			break;
69 		case B_REFS_RECEIVED:
70 		case B_SAVE_REQUESTED:
71 			_SetFileFromFilePanelMessage(message);
72 			break;
73 		case B_CANCEL:
74 			_FilePanelCanceled();
75 			break;
76 		default:
77 			WizardPageView::MessageReceived(message);
78 	}
79 }
80 
81 
82 void
PageCompleted()83 FileSelectionPage::PageCompleted()
84 {
85 	fSettings->ReplaceString("file", fFile->Text());
86 }
87 
88 
89 const float kFileButtonDistance = 10;
90 
91 void
_BuildUI(const char * description)92 FileSelectionPage::_BuildUI(const char* description)
93 {
94 	const float kSpacing = be_control_look->DefaultItemSpacing();
95 	BRect rect(Bounds());
96 
97 	fDescription = CreateDescription(rect, "description", description);
98 
99 	MakeHeading(fDescription);
100 	AddChild(fDescription);
101 
102 	BString file;
103 	fSettings->FindString("file", &file);
104 
105 	fSelect = new BButton(rect, "select",
106 		B_TRANSLATE_COMMENT("Select", "Button"),
107 		new BMessage(kMsgOpenFilePanel),
108 		B_FOLLOW_RIGHT);
109 	fSelect->ResizeToPreferred();
110 
111 	float selectLeft = rect.right - fSelect->Bounds().Width();
112 	rect.right = selectLeft - kSpacing;
113 	fFile = new BTextControl(rect, "file",
114 		B_TRANSLATE_COMMENT("File:", "Text control label"),
115 		file.String(), new BMessage());
116 	fFile->SetDivider(be_plain_font->StringWidth(fFile->Label()) + 5);
117 	AddChild(fFile);
118 
119 	fSelect->MoveTo(selectLeft, 0);
120 	AddChild(fSelect);
121 
122 	_Layout();
123 }
124 
125 
126 void
_Layout()127 FileSelectionPage::_Layout()
128 {
129 	const float kSpacing = be_control_look->DefaultItemSpacing();
130 	LayoutDescriptionVertically(fDescription);
131 
132 	float left = fFile->Frame().left;
133 	float top = fDescription->Frame().bottom + kSpacing;
134 
135 	// center "file" text field and "select" button vertically
136 	float selectTop = top;
137 	float fileTop = top;
138 	float fileHeight = fFile->Bounds().Height();
139 	float selectHeight = fSelect->Bounds().Height();
140 	if (fileHeight < selectHeight) {
141 		int delta = (int)((selectHeight - fileHeight + 1) / 2);
142 		fileTop += delta;
143 	} else {
144 		int delta = (int)((fileHeight - selectHeight + 1) / 2);
145 		selectTop += delta;
146 	}
147 
148 	fFile->MoveTo(left, fileTop);
149 
150 	float width = fSelect->Frame().left - kSpacing - left;
151 	fFile->ResizeTo(width, fileHeight);
152 
153 	left = fSelect->Frame().left;
154 	fSelect->MoveTo(left, selectTop);
155 }
156 
157 
158 void
_OpenFilePanel()159 FileSelectionPage::_OpenFilePanel()
160 {
161 	if (fFilePanel != NULL)
162 		return;
163 
164 	const entry_ref* directory = NULL;
165 	entry_ref base;
166 	BPath file(fFile->Text());
167 	BPath parent;
168 
169 	if (file.GetParent(&parent) == B_OK &&
170 		get_ref_for_path(parent.Path(), &base) == B_OK)
171 		directory = &base;
172 
173 	BMessenger messenger(this);
174 	fFilePanel = new BFilePanel(fMode, &messenger, directory,
175 		B_FILE_NODE, false, NULL, NULL, true);
176 	if (fMode == B_SAVE_PANEL && file.Leaf() != NULL)
177 		fFilePanel->SetSaveText(file.Leaf());
178 	fFilePanel->Show();
179 }
180 
181 
182 void
_SetFileFromFilePanelMessage(BMessage * message)183 FileSelectionPage::_SetFileFromFilePanelMessage(BMessage* message)
184 {
185 	if (message->what == B_SAVE_REQUESTED) {
186 		entry_ref directory;
187 		BString name;
188 		message->FindRef("directory", &directory);
189 		message->FindString("name", &name);
190 		BPath path(&directory);
191 		if (path.Append(name.String()) == B_OK)
192 			fFile->SetText(path.Path());
193 	} else {
194 		entry_ref entryRef;
195 		message->FindRef("refs", &entryRef);
196 		BEntry entry(&entryRef);
197 		BPath path;
198 		if (entry.GetPath(&path) == B_OK)
199 			fFile->SetText(path.Path());
200 	}
201 }
202 
203 
204 void
_FilePanelCanceled()205 FileSelectionPage::_FilePanelCanceled()
206 {
207 	delete fFilePanel;
208 	fFilePanel = NULL;
209 }
210