1290026d3SAxel Dörfler/*
2e326cef6SJohn Scipione * Copyright 2004-2009 Haiku, Inc. All rights reserved.
3290026d3SAxel Dörfler * Distributed under the terms of the MIT License.
4290026d3SAxel Dörfler *
5290026d3SAxel Dörfler * Authors:
6290026d3SAxel Dörfler *		J��r��me Duval
7290026d3SAxel Dörfler */
8290026d3SAxel Dörfler
955a5a6bdSJérôme Duval
1055a5a6bdSJérôme Duval#include "DirectoryFilePanel.h"
11290026d3SAxel Dörfler
12ab7b6568SAdrien Destugues#include <Catalog.h>
13ab7b6568SAdrien Destugues#include <Locale.h>
1455a5a6bdSJérôme Duval#include <Window.h>
15290026d3SAxel Dörfler
1655a5a6bdSJérôme Duval#include <stdio.h>
171e35cfaeSJohn Scipione#include <stdlib.h>
18b0bc48fbSAxel Dörfler#include <string.h>
1955a5a6bdSJérôme Duval
20bcfe344cSIngo Weinhold#include <compat/sys/stat.h>
21bcfe344cSIngo Weinhold
22290026d3SAxel Dörfler
2355a5a6bdSJérôme DuvalDirectoryRefFilter::DirectoryRefFilter()
2455a5a6bdSJérôme Duval{
2555a5a6bdSJérôme Duval}
2655a5a6bdSJérôme Duval
2755a5a6bdSJérôme Duval
2855a5a6bdSJérôme Duvalbool
29e326cef6SJohn ScipioneDirectoryRefFilter::Filter(const entry_ref* ref, BNode* node,
30e326cef6SJohn Scipione	struct stat_beos* stat, const char* mimeType)
3155a5a6bdSJérôme Duval{
32e326cef6SJohn Scipione	if (S_ISDIR(stat->st_mode))
332c5ecffaSAxel Dörfler		return true;
342c5ecffaSAxel Dörfler
35e326cef6SJohn Scipione	if (S_ISLNK(stat->st_mode)) {
362c5ecffaSAxel Dörfler		// Traverse symlinks
372c5ecffaSAxel Dörfler		BEntry entry(ref, true);
382c5ecffaSAxel Dörfler		return entry.IsDirectory();
392c5ecffaSAxel Dörfler	}
402c5ecffaSAxel Dörfler
412c5ecffaSAxel Dörfler	return false;
4255a5a6bdSJérôme Duval}
4355a5a6bdSJérôme Duval
4455a5a6bdSJérôme Duval
45e326cef6SJohn Scipione//	#pragma mark - DirectoryFilePanel
46e326cef6SJohn Scipione
47290026d3SAxel Dörfler
48546208a5SOliver Tappe#undef B_TRANSLATION_CONTEXT
49546208a5SOliver Tappe#define B_TRANSLATION_CONTEXT "DirectoryFilePanel"
50290026d3SAxel Dörfler
51ab7b6568SAdrien Destugues
52e326cef6SJohn ScipioneDirectoryFilePanel::DirectoryFilePanel(file_panel_mode mode,
53e326cef6SJohn Scipione	BMessenger* target, const entry_ref* startDirectory, uint32 nodeFlavors,
54e326cef6SJohn Scipione	bool allowMultipleSelection, BMessage* message, BRefFilter* filter,
55e326cef6SJohn Scipione	bool modal, bool hideWhenDone)
56e326cef6SJohn Scipione	:
57e326cef6SJohn Scipione	BFilePanel(mode, target, startDirectory, nodeFlavors,
58290026d3SAxel Dörfler		allowMultipleSelection, message, filter, modal, hideWhenDone),
5996303159SJérôme Duval	fCurrentButton(NULL)
6055a5a6bdSJérôme Duval{
6155a5a6bdSJérôme Duval}
6255a5a6bdSJérôme Duval
6355a5a6bdSJérôme Duval
6455a5a6bdSJérôme Duvalvoid
6555a5a6bdSJérôme DuvalDirectoryFilePanel::Show()
6655a5a6bdSJérôme Duval{
67122abe43SJohn Scipione	if (fCurrentButton == NULL && Window()->Lock()) {
6896303159SJérôme Duval		BView* background = Window()->ChildAt(0);
69290026d3SAxel Dörfler		BView* cancel = background->FindView("cancel button");
70290026d3SAxel Dörfler
71290026d3SAxel Dörfler		BRect rect;
72290026d3SAxel Dörfler		if (cancel != NULL)
73290026d3SAxel Dörfler			rect = cancel->Frame();
74290026d3SAxel Dörfler		else {
75290026d3SAxel Dörfler			rect = background->Bounds();
76290026d3SAxel Dörfler			rect.left = rect.right;
77290026d3SAxel Dörfler			rect.top = rect.bottom - 35;
78290026d3SAxel Dörfler			rect.bottom -= 10;
79290026d3SAxel Dörfler		}
80c1dac92aSAxel Dörfler
8199a76eaeSJérôme Duval		rect.right = rect.left -= 30;
82e07f1f2fSMatt Madia		float width = be_plain_font->StringWidth(
83e07f1f2fSMatt Madia			B_TRANSLATE("Select current")) + 20;
84c1dac92aSAxel Dörfler		rect.left = width > 75 ? rect.right - width : rect.right - 75;
85e07f1f2fSMatt Madia		fCurrentButton = new BButton(rect, "directoryButton",
86e07f1f2fSMatt Madia			B_TRANSLATE("Select current"), new BMessage(MSG_DIRECTORY),
87e07f1f2fSMatt Madia			B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
88c1dac92aSAxel Dörfler
8955a5a6bdSJérôme Duval		background->AddChild(fCurrentButton);
9055a5a6bdSJérôme Duval		fCurrentButton->SetTarget(Messenger());
91290026d3SAxel Dörfler
92e07f1f2fSMatt Madia		SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select"));
93e07f1f2fSMatt Madia		Window()->SetTitle(B_TRANSLATE("Expander: Choose destination"));
94fc17c9d2SKarsten Heimrich
9555a5a6bdSJérôme Duval		Window()->Unlock();
96290026d3SAxel Dörfler
97290026d3SAxel Dörfler		SelectionChanged();
9855a5a6bdSJérôme Duval	}
99290026d3SAxel Dörfler
10055a5a6bdSJérôme Duval	BFilePanel::Show();
10155a5a6bdSJérôme Duval}
10255a5a6bdSJérôme Duval
103290026d3SAxel Dörfler
10455a5a6bdSJérôme Duvalvoid
105c1dac92aSAxel DörflerDirectoryFilePanel::SelectionChanged()
10655a5a6bdSJérôme Duval{
107290026d3SAxel Dörfler	// Resize button so that the label fits
108290026d3SAxel Dörfler	// maximum width is dictated by the window's size limits
109290026d3SAxel Dörfler
110122abe43SJohn Scipione	if (Window()->Lock()) {
111122abe43SJohn Scipione		float dummy;
112122abe43SJohn Scipione		float maxWidth;
113122abe43SJohn Scipione		Window()->GetSizeLimits(&maxWidth, &dummy, &dummy, &dummy);
114122abe43SJohn Scipione		maxWidth -= Window()->Bounds().Width() + 8
115122abe43SJohn Scipione			- fCurrentButton->Frame().right;
116290026d3SAxel Dörfler
117122abe43SJohn Scipione		BRect oldBounds = fCurrentButton->Bounds();
1181e35cfaeSJohn Scipione
119122abe43SJohn Scipione		char* label;
120122abe43SJohn Scipione		entry_ref ref;
121122abe43SJohn Scipione		GetPanelDirectory(&ref);
122be931d07SJohn Scipione		if (asprintf(&label, B_TRANSLATE("Select '%s'" B_UTF8_ELLIPSIS),
123be931d07SJohn Scipione				ref.name) != -1) {
124be931d07SJohn Scipione			fCurrentButton->SetLabel(label);
125be931d07SJohn Scipione			free(label);
126be931d07SJohn Scipione		}
1271e35cfaeSJohn Scipione
128122abe43SJohn Scipione		float width;
129122abe43SJohn Scipione		float height;
130122abe43SJohn Scipione		fCurrentButton->GetPreferredSize(&width, &height);
131122abe43SJohn Scipione		if (width > maxWidth)
132122abe43SJohn Scipione			width = maxWidth;
133e326cef6SJohn Scipione
134122abe43SJohn Scipione		fCurrentButton->ResizeTo(width, oldBounds.Height());
135122abe43SJohn Scipione		fCurrentButton->MoveBy(oldBounds.Width() - width, 0);
136290026d3SAxel Dörfler
137122abe43SJohn Scipione		Window()->Unlock();
138122abe43SJohn Scipione	}
139290026d3SAxel Dörfler
14055a5a6bdSJérôme Duval	BFilePanel::SelectionChanged();
14155a5a6bdSJérôme Duval}
142