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 TR_CONTEXT 47 #define TR_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(TR("Select current")) + 20; 81 rect.left = width > 75 ? rect.right - width : rect.right - 75; 82 fCurrentButton = new BButton(rect, "directoryButton", TR("Select current"), 83 new BMessage(MSG_DIRECTORY), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 84 85 background->AddChild(fCurrentButton); 86 fCurrentButton->SetTarget(Messenger()); 87 88 SetButtonLabel(B_DEFAULT_BUTTON, TR("Select")); 89 Window()->SetTitle(TR("Expander: Choose destination")); 90 91 Window()->Unlock(); 92 93 SelectionChanged(); 94 } 95 96 BFilePanel::Show(); 97 } 98 99 100 void 101 DirectoryFilePanel::SelectionChanged() 102 { 103 Window()->Lock(); 104 105 char label[64]; 106 entry_ref ref; 107 GetPanelDirectory(&ref); 108 if (snprintf(label, sizeof(label), 109 TR("Select '%s'"), ref.name) >= (int)sizeof(label)) 110 strcpy(label + sizeof(label) - 5, B_UTF8_ELLIPSIS "'"); 111 112 // Resize button so that the label fits 113 // maximum width is dictated by the window's size limits 114 115 float dummy, maxWidth; 116 Window()->GetSizeLimits(&maxWidth, &dummy, &dummy, &dummy); 117 maxWidth -= Window()->Bounds().Width() + 8 - fCurrentButton->Frame().right; 118 119 BRect oldBounds = fCurrentButton->Bounds(); 120 fCurrentButton->SetLabel(label); 121 float width, height; 122 fCurrentButton->GetPreferredSize(&width, &height); 123 if (width > maxWidth) 124 width = maxWidth; 125 fCurrentButton->ResizeTo(width, oldBounds.Height()); 126 fCurrentButton->MoveBy(oldBounds.Width() - width, 0); 127 128 Window()->Unlock(); 129 130 BFilePanel::SelectionChanged(); 131 } 132