1 /* 2 * Copyright 2004-2009 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jérôme Duval 7 */ 8 9 10 #include "DirectoryFilePanel.h" 11 12 #include <Catalog.h> 13 #include <Locale.h> 14 #include <Window.h> 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 20 #include <compat/sys/stat.h> 21 22 23 DirectoryRefFilter::DirectoryRefFilter() 24 { 25 } 26 27 28 bool 29 DirectoryRefFilter::Filter(const entry_ref* ref, BNode* node, 30 struct stat_beos* stat, const char* mimeType) 31 { 32 if (S_ISDIR(stat->st_mode)) 33 return true; 34 35 if (S_ISLNK(stat->st_mode)) { 36 // Traverse symlinks 37 BEntry entry(ref, true); 38 return entry.IsDirectory(); 39 } 40 41 return false; 42 } 43 44 45 // #pragma mark - DirectoryFilePanel 46 47 48 #undef B_TRANSLATION_CONTEXT 49 #define B_TRANSLATION_CONTEXT "DirectoryFilePanel" 50 51 52 DirectoryFilePanel::DirectoryFilePanel(file_panel_mode mode, 53 BMessenger* target, const entry_ref* startDirectory, uint32 nodeFlavors, 54 bool allowMultipleSelection, BMessage* message, BRefFilter* filter, 55 bool modal, bool hideWhenDone) 56 : 57 BFilePanel(mode, target, startDirectory, nodeFlavors, 58 allowMultipleSelection, message, filter, modal, hideWhenDone), 59 fCurrentButton(NULL) 60 { 61 } 62 63 64 void 65 DirectoryFilePanel::Show() 66 { 67 if (fCurrentButton == NULL && Window()->Lock()) { 68 BView* background = Window()->ChildAt(0); 69 BView* cancel = background->FindView("cancel button"); 70 71 BRect rect; 72 if (cancel != NULL) 73 rect = cancel->Frame(); 74 else { 75 rect = background->Bounds(); 76 rect.left = rect.right; 77 rect.top = rect.bottom - 35; 78 rect.bottom -= 10; 79 } 80 81 rect.right = rect.left -= 30; 82 float width = be_plain_font->StringWidth( 83 B_TRANSLATE("Select current")) + 20; 84 rect.left = width > 75 ? rect.right - width : rect.right - 75; 85 fCurrentButton = new BButton(rect, "directoryButton", 86 B_TRANSLATE("Select current"), new BMessage(MSG_DIRECTORY), 87 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 88 89 background->AddChild(fCurrentButton); 90 fCurrentButton->SetTarget(Messenger()); 91 92 SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select")); 93 Window()->SetTitle(B_TRANSLATE("Expander: Choose destination")); 94 95 Window()->Unlock(); 96 97 SelectionChanged(); 98 } 99 100 BFilePanel::Show(); 101 } 102 103 104 void 105 DirectoryFilePanel::SelectionChanged() 106 { 107 // Resize button so that the label fits 108 // maximum width is dictated by the window's size limits 109 110 if (Window()->Lock()) { 111 float dummy; 112 float maxWidth; 113 Window()->GetSizeLimits(&maxWidth, &dummy, &dummy, &dummy); 114 maxWidth -= Window()->Bounds().Width() + 8 115 - fCurrentButton->Frame().right; 116 117 BRect oldBounds = fCurrentButton->Bounds(); 118 119 char* label; 120 entry_ref ref; 121 GetPanelDirectory(&ref); 122 if (asprintf(&label, B_TRANSLATE("Select '%s'" B_UTF8_ELLIPSIS), 123 ref.name) != -1) { 124 fCurrentButton->SetLabel(label); 125 free(label); 126 } 127 128 float width; 129 float height; 130 fCurrentButton->GetPreferredSize(&width, &height); 131 if (width > maxWidth) 132 width = maxWidth; 133 134 fCurrentButton->ResizeTo(width, oldBounds.Height()); 135 fCurrentButton->MoveBy(oldBounds.Width() - width, 0); 136 137 Window()->Unlock(); 138 } 139 140 BFilePanel::SelectionChanged(); 141 } 142