haiku/src/apps/expander/DirectoryFilePanel.cpp

142 lines
3.0 KiB
C++

/*
* Copyright 2004-2009 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Jérôme Duval
*/
#include "DirectoryFilePanel.h"
#include <Catalog.h>
#include <Locale.h>
#include <Window.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <compat/sys/stat.h>
DirectoryRefFilter::DirectoryRefFilter()
{
}
bool
DirectoryRefFilter::Filter(const entry_ref* ref, BNode* node,
struct stat_beos* stat, const char* mimeType)
{
if (S_ISDIR(stat->st_mode))
return true;
if (S_ISLNK(stat->st_mode)) {
// Traverse symlinks
BEntry entry(ref, true);
return entry.IsDirectory();
}
return false;
}
// #pragma mark - DirectoryFilePanel
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "DirectoryFilePanel"
DirectoryFilePanel::DirectoryFilePanel(file_panel_mode mode,
BMessenger* target, const entry_ref* startDirectory, uint32 nodeFlavors,
bool allowMultipleSelection, BMessage* message, BRefFilter* filter,
bool modal, bool hideWhenDone)
:
BFilePanel(mode, target, startDirectory, nodeFlavors,
allowMultipleSelection, message, filter, modal, hideWhenDone),
fCurrentButton(NULL)
{
}
void
DirectoryFilePanel::Show()
{
if (fCurrentButton == NULL && Window()->Lock()) {
BView* background = Window()->ChildAt(0);
BView* cancel = background->FindView("cancel button");
BRect rect;
if (cancel != NULL)
rect = cancel->Frame();
else {
rect = background->Bounds();
rect.left = rect.right;
rect.top = rect.bottom - 35;
rect.bottom -= 10;
}
rect.right = rect.left -= 30;
float width = be_plain_font->StringWidth(
B_TRANSLATE("Select current")) + 20;
rect.left = width > 75 ? rect.right - width : rect.right - 75;
fCurrentButton = new BButton(rect, "directoryButton",
B_TRANSLATE("Select current"), new BMessage(MSG_DIRECTORY),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
background->AddChild(fCurrentButton);
fCurrentButton->SetTarget(Messenger());
SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select"));
Window()->SetTitle(B_TRANSLATE("Expander: Choose destination"));
Window()->Unlock();
SelectionChanged();
}
BFilePanel::Show();
}
void
DirectoryFilePanel::SelectionChanged()
{
// Resize button so that the label fits
// maximum width is dictated by the window's size limits
if (Window()->Lock()) {
float dummy;
float maxWidth;
Window()->GetSizeLimits(&maxWidth, &dummy, &dummy, &dummy);
maxWidth -= Window()->Bounds().Width() + 8
- fCurrentButton->Frame().right;
BRect oldBounds = fCurrentButton->Bounds();
char* label;
entry_ref ref;
GetPanelDirectory(&ref);
if (asprintf(&label, B_TRANSLATE("Select '%s'" B_UTF8_ELLIPSIS),
ref.name) != -1) {
fCurrentButton->SetLabel(label);
free(label);
}
float width;
float height;
fCurrentButton->GetPreferredSize(&width, &height);
if (width > maxWidth)
width = maxWidth;
fCurrentButton->ResizeTo(width, oldBounds.Height());
fCurrentButton->MoveBy(oldBounds.Width() - width, 0);
Window()->Unlock();
}
BFilePanel::SelectionChanged();
}