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 23DirectoryRefFilter::DirectoryRefFilter() 24{ 25} 26 27 28bool 29DirectoryRefFilter::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 52DirectoryFilePanel::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 64void 65DirectoryFilePanel::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 104void 105DirectoryFilePanel::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