vfs: check userland buffers before reading them.
[haiku.git] / src / apps / expander / DirectoryFilePanel.cpp
blob5c07404f07aa1bcef7eacc223511e16f41bdba97
1 /*
2 * Copyright 2004-2009 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Jérôme Duval
7 */
10 #include "DirectoryFilePanel.h"
12 #include <Catalog.h>
13 #include <Locale.h>
14 #include <Window.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
20 #include <compat/sys/stat.h>
23 DirectoryRefFilter::DirectoryRefFilter()
28 bool
29 DirectoryRefFilter::Filter(const entry_ref* ref, BNode* node,
30 struct stat_beos* stat, const char* mimeType)
32 if (S_ISDIR(stat->st_mode))
33 return true;
35 if (S_ISLNK(stat->st_mode)) {
36 // Traverse symlinks
37 BEntry entry(ref, true);
38 return entry.IsDirectory();
41 return false;
45 // #pragma mark - DirectoryFilePanel
48 #undef B_TRANSLATION_CONTEXT
49 #define B_TRANSLATION_CONTEXT "DirectoryFilePanel"
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)
57 BFilePanel(mode, target, startDirectory, nodeFlavors,
58 allowMultipleSelection, message, filter, modal, hideWhenDone),
59 fCurrentButton(NULL)
64 void
65 DirectoryFilePanel::Show()
67 if (fCurrentButton == NULL && Window()->Lock()) {
68 BView* background = Window()->ChildAt(0);
69 BView* cancel = background->FindView("cancel button");
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;
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);
89 background->AddChild(fCurrentButton);
90 fCurrentButton->SetTarget(Messenger());
92 SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select"));
93 Window()->SetTitle(B_TRANSLATE("Expander: Choose destination"));
95 Window()->Unlock();
97 SelectionChanged();
100 BFilePanel::Show();
104 void
105 DirectoryFilePanel::SelectionChanged()
107 // Resize button so that the label fits
108 // maximum width is dictated by the window's size limits
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;
117 BRect oldBounds = fCurrentButton->Bounds();
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);
128 float width;
129 float height;
130 fCurrentButton->GetPreferredSize(&width, &height);
131 if (width > maxWidth)
132 width = maxWidth;
134 fCurrentButton->ResizeTo(width, oldBounds.Height());
135 fCurrentButton->MoveBy(oldBounds.Width() - width, 0);
137 Window()->Unlock();
140 BFilePanel::SelectionChanged();