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