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