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