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_TRANSLATE_CONTEXT 24 #define B_TRANSLATE_CONTEXT "FileSelectionPage" 25 26 27 const uint32 kMsgOpenFilePanel = 'open'; 28 29 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 42 FileSelectionPage::~FileSelectionPage() 43 { 44 } 45 46 47 void 48 FileSelectionPage::FrameResized(float width, float height) 49 { 50 WizardPageView::FrameResized(width, height); 51 _Layout(); 52 } 53 54 55 void 56 FileSelectionPage::AttachedToWindow() 57 { 58 fSelect->SetTarget(this); 59 } 60 61 62 void 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 83 FileSelectionPage::PageCompleted() 84 { 85 fSettings->ReplaceString("file", fFile->Text()); 86 } 87 88 89 const float kFileButtonDistance = 10; 90 91 void 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 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 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 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 205 FileSelectionPage::_FilePanelCanceled() 206 { 207 delete fFilePanel; 208 fFilePanel = NULL; 209 } 210