haiku/src/apps/expander/ExpanderWindow.cpp

914 lines
23 KiB
C++

/*
* Copyright 2004-2006, Jérôme DUVAL. All rights reserved.
* Copyright 2010, Karsten Heimrich. All rights reserved.
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "ExpanderWindow.h"
#include <algorithm>
#include <Alert.h>
#include <Box.h>
#include <Button.h>
#include <Catalog.h>
#include <CheckBox.h>
#include <ControlLook.h>
#include <Entry.h>
#include <File.h>
#include <LayoutBuilder.h>
#include <Locale.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <Path.h>
#include <Screen.h>
#include <ScrollView.h>
#include <StringView.h>
#include <TextView.h>
#include "ExpanderApp.h"
#include "ExpanderThread.h"
#include "ExpanderPreferences.h"
#include "PasswordAlert.h"
const uint32 MSG_SOURCE = 'mSOU';
const uint32 MSG_DEST = 'mDES';
const uint32 MSG_EXPAND = 'mEXP';
const uint32 MSG_SHOW = 'mSHO';
const uint32 MSG_STOP = 'mSTO';
const uint32 MSG_PREFERENCES = 'mPRE';
const uint32 MSG_SOURCETEXT = 'mSTX';
const uint32 MSG_DESTTEXT = 'mDTX';
const uint32 MSG_SHOWCONTENTS = 'mSCT';
class StatusView : public BStringView {
public:
StatusView()
:
BStringView(NULL, "")
{
}
virtual ~StatusView()
{
}
void SetStatus(const BString &text)
{
fStatus = text;
Invalidate();
}
void Draw(BRect updateRect)
{
BString truncated = fStatus;
if(fStatus.IsEmpty() == false) {
be_plain_font->TruncateString(&truncated, B_TRUNCATE_END,
Bounds().Width());
}
SetText(truncated);
BStringView::Draw(updateRect);
}
private:
BString fStatus;
};
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "ExpanderWindow"
ExpanderWindow::ExpanderWindow(BRect frame, const entry_ref* ref,
BMessage* settings)
:
BWindow(frame, B_TRANSLATE_SYSTEM_NAME("Expander"), B_TITLED_WINDOW,
B_NORMAL_WINDOW_FEEL),
fSourcePanel(NULL),
fDestPanel(NULL),
fSourceChanged(true),
fListingThread(NULL),
fListingStarted(false),
fExpandingThread(NULL),
fExpandingStarted(false),
fSettings(*settings),
fPreferences(NULL)
{
_CreateMenuBar();
fDestButton = new BButton(B_TRANSLATE("Destination"),
new BMessage(MSG_DEST));
fSourceButton = new BButton(B_TRANSLATE("Source"),
new BMessage(MSG_SOURCE));
fExpandButton = new BButton(B_TRANSLATE("Expand"),
new BMessage(MSG_EXPAND));
BSize size = fDestButton->PreferredSize();
size.width = std::max(size.width, fSourceButton->PreferredSize().width);
size.width = std::max(size.width, fExpandButton->PreferredSize().width);
fDestButton->SetExplicitSize(size);
fSourceButton->SetExplicitSize(size);
fExpandButton->SetExplicitSize(size);
fListingText = new BTextView("listingText");
fListingText->SetText("");
fListingText->MakeEditable(false);
fListingText->SetStylable(false);
fListingText->SetWordWrap(false);
BFont font = be_fixed_font;
fListingText->SetFontAndColor(&font);
fScrollView = new BScrollView("", fListingText, B_INVALIDATE_AFTER_LAYOUT,
true, true);
const float spacing = be_control_look->DefaultItemSpacing();
BGroupLayout* pathLayout;
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
.Add(fBar)
.AddGroup(B_VERTICAL, B_USE_ITEM_SPACING)
.AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING)
.Add(fSourceButton)
.Add(fSourceText = new BTextControl(NULL, NULL,
new BMessage(MSG_SOURCETEXT)))
.End()
.AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING)
.Add(fDestButton)
.Add(fDestText = new BTextControl(NULL, NULL,
new BMessage(MSG_DESTTEXT)))
.End()
.AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING)
.Add(fExpandButton)
.AddGroup(B_HORIZONTAL, B_USE_ITEM_SPACING)
.GetLayout(&pathLayout)
.Add(fShowContents = new BCheckBox(
B_TRANSLATE("Show contents"),
new BMessage(MSG_SHOWCONTENTS)))
.Add(fStatusView = new StatusView())
.End()
.End()
.SetInsets(B_USE_WINDOW_SPACING)
.End()
.Add(fScrollView);
pathLayout->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
size = GetLayout()->View()->PreferredSize();
fSizeLimit = size.Height() - fScrollView->PreferredSize().height - spacing;
fStatusView->SetExplicitMinSize(BSize(50.0f, B_SIZE_UNSET));
fStatusView->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
ResizeTo(Bounds().Width(), fSizeLimit);
SetSizeLimits(size.Width(), 32767.0f, fSizeLimit, fSizeLimit);
SetZoomLimits(Bounds().Width(), fSizeLimit);
fPreviousHeight = -1;
fScrollView->Hide();
Show();
}
ExpanderWindow::~ExpanderWindow()
{
if (fDestPanel && fDestPanel->RefFilter())
delete fDestPanel->RefFilter();
if (fSourcePanel && fSourcePanel->RefFilter())
delete fSourcePanel->RefFilter();
delete fDestPanel;
delete fSourcePanel;
}
bool
ExpanderWindow::ValidateDest()
{
BEntry entry(fDestText->Text(), true);
BVolume volume;
if (!entry.Exists()) {
BAlert* alert = new BAlert("destAlert",
B_TRANSLATE("Destination folder doesn't exist. "
"Would you like to create it?"),
B_TRANSLATE("Create"), B_TRANSLATE("Cancel"), NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() != 0)
return false;
if (create_directory(fDestText->Text(), 0755) != B_OK) {
BAlert* alert = new BAlert("stopAlert",
B_TRANSLATE("Failed to create the destination folder."),
B_TRANSLATE("Cancel"), NULL, NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return false;
}
BEntry newEntry(fDestText->Text(), true);
newEntry.GetRef(&fDestRef);
return true;
}
if (!entry.IsDirectory()) {
BAlert* alert = new BAlert("destAlert",
B_TRANSLATE("The destination is not a folder."),
B_TRANSLATE("Cancel"), NULL, NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return false;
}
if (entry.GetVolume(&volume) != B_OK || volume.IsReadOnly()) {
BAlert* alert = new BAlert("destAlert",
B_TRANSLATE("The destination is read only."),
B_TRANSLATE("Cancel"), NULL, NULL, B_WIDTH_AS_USUAL,
B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return false;
}
entry.GetRef(&fDestRef);
return true;
}
void
ExpanderWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_SOURCE:
{
BEntry entry(fSourceText->Text(), true);
entry_ref srcRef;
if (entry.Exists() && entry.IsDirectory())
entry.GetRef(&srcRef);
if (!fSourcePanel) {
BMessenger messenger(this);
fSourcePanel = new BFilePanel(B_OPEN_PANEL, &messenger, &srcRef,
B_FILE_NODE, false, NULL, new RuleRefFilter(fRules), true);
(fSourcePanel->Window())->SetTitle(
B_TRANSLATE("Expander: Open"));
} else
fSourcePanel->SetPanelDirectory(&srcRef);
fSourcePanel->Show();
break;
}
case MSG_DEST:
{
BEntry entry(fDestText->Text(), true);
entry_ref destRef;
if (entry.Exists() && entry.IsDirectory())
entry.GetRef(&destRef);
if (!fDestPanel) {
BMessenger messenger(this);
fDestPanel = new DirectoryFilePanel(B_OPEN_PANEL, &messenger,
&destRef, B_DIRECTORY_NODE, false, NULL,
new DirectoryRefFilter(), true);
} else
fDestPanel->SetPanelDirectory(&destRef);
fDestPanel->Show();
break;
}
case MSG_DIRECTORY:
{
entry_ref ref;
fDestPanel->GetPanelDirectory(&ref);
fDestRef = ref;
BEntry entry(&ref);
BPath path(&entry);
fDestText->SetText(path.Path());
fDestPanel->Hide();
break;
}
case B_SIMPLE_DATA:
case B_REFS_RECEIVED:
RefsReceived(message);
break;
case MSG_EXPAND:
if (!ValidateDest())
break;
if (!fExpandingStarted) {
StartExpanding();
break;
}
// supposed to fall through
case MSG_STOP:
if (fExpandingStarted) {
fExpandingThread->SuspendExternalExpander();
BAlert* alert = new BAlert("stopAlert",
B_TRANSLATE("Are you sure you want to stop expanding this "
"archive? The expanded items may not be complete."),
B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() == 0) {
fExpandingThread->ResumeExternalExpander();
StopExpanding();
} else
fExpandingThread->ResumeExternalExpander();
}
break;
case MSG_SHOW:
fShowContents->SetValue(fShowContents->Value() == B_CONTROL_OFF
? B_CONTROL_ON : B_CONTROL_OFF);
// supposed to fall through
case MSG_SHOWCONTENTS:
// change menu item label
fShowItem->SetLabel(fShowContents->Value() == B_CONTROL_OFF
? B_TRANSLATE("Show contents") : B_TRANSLATE("Hide contents"));
if (fShowContents->Value() == B_CONTROL_OFF) {
if (fListingStarted)
StopListing();
fScrollView->Hide();
_UpdateWindowSize(false);
} else {
fScrollView->Show();
StartListing();
}
break;
case MSG_SOURCETEXT:
{
BEntry entry(fSourceText->Text(), true);
if (!entry.Exists()) {
BAlert* alert = new BAlert("srcAlert",
B_TRANSLATE("The file doesn't exist"),
B_TRANSLATE("Cancel"), NULL, NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
break;
}
entry_ref ref;
entry.GetRef(&ref);
ExpanderRule* rule = fRules.MatchingRule(&ref);
if (rule) {
fSourceChanged = true;
fSourceRef = ref;
fShowContents->SetEnabled(true);
fExpandButton->SetEnabled(true);
fExpandItem->SetEnabled(true);
fShowItem->SetEnabled(true);
break;
}
BString string = "The file : ";
string += fSourceText->Text();
string += B_TRANSLATE_MARK(" is not supported");
BAlert* alert = new BAlert("srcAlert", string.String(),
B_TRANSLATE("Cancel"),
NULL, NULL, B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_INFO_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
fShowContents->SetEnabled(false);
fExpandButton->SetEnabled(false);
fExpandItem->SetEnabled(false);
fShowItem->SetEnabled(false);
break;
}
case MSG_DESTTEXT:
ValidateDest();
break;
case MSG_PREFERENCES:
if (fPreferences == NULL)
fPreferences = new ExpanderPreferences(&fSettings);
fPreferences->Show();
break;
case 'outp':
if (!fExpandingStarted && fListingStarted) {
// Check if the vertical scroll bar is at the end
float max, pos;
fScrollView->ScrollBar(B_VERTICAL)->GetRange(NULL, &max);
pos = fScrollView->ScrollBar(B_VERTICAL)->Value();
bool atEnd = (pos == max);
BString string;
int32 i = 0;
while (message->FindString("output", i++, &string) == B_OK) {
float length = fListingText->StringWidth(string.String());
if (length > fLongestLine)
fLongestLine = length;
fListingText->Insert(string.String());
}
if (atEnd && fScrollView->ScrollBar(B_VERTICAL)->Value() == pos) {
fScrollView->ScrollBar(B_VERTICAL)->GetRange(NULL, &max);
fScrollView->ScrollBar(B_VERTICAL)->SetValue(max);
}
} else if (fExpandingStarted) {
BString string;
int32 i = 0;
while (message->FindString("output", i++, &string) == B_OK) {
if (strstr(string.String(), "Enter password") != NULL) {
fExpandingThread->SuspendExternalExpander();
BString password;
PasswordAlert* alert =
new PasswordAlert("passwordAlert", string);
alert->Go(password);
fExpandingThread->ResumeExternalExpander();
fExpandingThread->PushInput(password);
}
}
}
break;
case 'errp':
{
BString string;
if (message->FindString("error", &string) == B_OK
&& fExpandingStarted) {
fExpandingThread->SuspendExternalExpander();
if (strstr(string.String(), "password") != NULL) {
BString password;
PasswordAlert* alert = new PasswordAlert("passwordAlert",
string);
alert->Go(password);
fExpandingThread->ResumeExternalExpander();
fExpandingThread->PushInput(password);
} else {
BAlert* alert = new BAlert("stopAlert", string,
B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() == 0) {
fExpandingThread->ResumeExternalExpander();
StopExpanding();
} else
fExpandingThread->ResumeExternalExpander();
}
}
break;
}
case 'exit':
// thread has finished
// (finished, quit, killed, we don't know)
// reset window state
if (fExpandingStarted) {
fStatusView->SetStatus(B_TRANSLATE("File expanded"));
StopExpanding();
OpenDestFolder();
CloseWindowOrKeepOpen();
} else if (fListingStarted) {
fSourceChanged = false;
StopListing();
_ExpandListingText();
} else
fStatusView->SetStatus("");
break;
case 'exrr':
// thread has finished
// reset window state
fStatusView->SetStatus(B_TRANSLATE("Error when expanding archive"));
CloseWindowOrKeepOpen();
break;
default:
BWindow::MessageReceived(message);
}
}
bool
ExpanderWindow::CanQuit()
{
if ((fSourcePanel && fSourcePanel->IsShowing())
|| (fDestPanel && fDestPanel->IsShowing())) {
return false;
}
if (fExpandingStarted) {
fExpandingThread->SuspendExternalExpander();
BAlert* alert = new BAlert("stopAlert",
B_TRANSLATE("Are you sure you want to stop expanding this "
"archive? The expanded items may not be complete."),
B_TRANSLATE("Stop"), B_TRANSLATE("Continue"), NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetShortcut(0, B_ESCAPE);
if (alert->Go() == 0) {
fExpandingThread->ResumeExternalExpander();
StopExpanding();
} else {
fExpandingThread->ResumeExternalExpander();
return false;
}
}
return true;
}
bool
ExpanderWindow::QuitRequested()
{
if (!CanQuit())
return false;
if (fListingStarted)
StopListing();
be_app->PostMessage(B_QUIT_REQUESTED);
fSettings.ReplacePoint("window_position", Frame().LeftTop());
((ExpanderApp*)(be_app))->UpdateSettingsFrom(&fSettings);
return true;
}
void
ExpanderWindow::RefsReceived(BMessage* message)
{
entry_ref ref;
int32 i = 0;
int8 destinationFolder = 0x63;
fSettings.FindInt8("destination_folder", &destinationFolder);
while (message->FindRef("refs", i++, &ref) == B_OK) {
BEntry entry(&ref, true);
BPath path(&entry);
BNode node(&entry);
if (node.IsFile()) {
fSourceChanged = true;
fSourceRef = ref;
fSourceText->SetText(path.Path());
if (destinationFolder == 0x63) {
BPath parent;
path.GetParent(&parent);
fDestText->SetText(parent.Path());
get_ref_for_path(parent.Path(), &fDestRef);
} else if (destinationFolder == 0x65) {
fSettings.FindRef("destination_folder_use", &fDestRef);
BEntry dEntry(&fDestRef, true);
BPath dPath(&dEntry);
fDestText->SetText(dPath.Path());
}
BEntry dEntry(&fDestRef, true);
if (dEntry.Exists()) {
fExpandButton->SetEnabled(true);
fExpandItem->SetEnabled(true);
}
if (fShowContents->Value() == B_CONTROL_ON) {
StopListing();
StartListing();
} else {
fShowContents->SetEnabled(true);
fShowItem->SetEnabled(true);
}
bool fromApp;
if (message->FindBool("fromApp", &fromApp) == B_OK) {
AutoExpand();
} else
AutoListing();
} else if (node.IsDirectory()) {
fDestRef = ref;
fDestText->SetText(path.Path());
}
}
}
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "ExpanderMenu"
void
ExpanderWindow::_CreateMenuBar()
{
fBar = new BMenuBar("menu_bar", B_ITEMS_IN_ROW, B_INVALIDATE_AFTER_LAYOUT);
BMenu* menu = new BMenu(B_TRANSLATE("File"));
menu->AddItem(fSourceItem
= new BMenuItem(B_TRANSLATE("Set source" B_UTF8_ELLIPSIS),
new BMessage(MSG_SOURCE), 'O'));
menu->AddItem(fDestItem
= new BMenuItem(B_TRANSLATE("Set destination" B_UTF8_ELLIPSIS),
new BMessage(MSG_DEST), 'D'));
menu->AddSeparatorItem();
menu->AddItem(fExpandItem = new BMenuItem(B_TRANSLATE("Expand"),
new BMessage(MSG_EXPAND), 'E'));
fExpandItem->SetEnabled(false);
menu->AddItem(fShowItem = new BMenuItem(B_TRANSLATE("Show contents"),
new BMessage(MSG_SHOW), 'L'));
fShowItem->SetEnabled(false);
menu->AddSeparatorItem();
menu->AddItem(fStopItem = new BMenuItem(B_TRANSLATE("Stop"),
new BMessage(MSG_STOP), 'K'));
fStopItem->SetEnabled(false);
menu->AddSeparatorItem();
menu->AddItem(new BMenuItem(B_TRANSLATE("Close"),
new BMessage(B_QUIT_REQUESTED), 'W'));
fBar->AddItem(menu);
menu = new BMenu(B_TRANSLATE("Settings"));
menu->AddItem(fPreferencesItem
= new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
new BMessage(MSG_PREFERENCES), ','));
fBar->AddItem(menu);
}
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "ExpanderWindow"
void
ExpanderWindow::StartExpanding()
{
ExpanderRule* rule = fRules.MatchingRule(&fSourceRef);
if (!rule)
return;
BEntry destEntry(fDestText->Text(), true);
if (!destEntry.Exists()) {
BAlert* alert = new BAlert("destAlert",
B_TRANSLATE("The folder was either moved, renamed or not supported."),
B_TRANSLATE("Cancel"), NULL, NULL,
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_WARNING_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go();
return;
}
BMessage message;
message.AddString("cmd", rule->ExpandCmd());
message.AddRef("srcRef", &fSourceRef);
message.AddRef("destRef", &fDestRef);
fExpandButton->SetLabel(B_TRANSLATE("Stop"));
fSourceButton->SetEnabled(false);
fDestButton->SetEnabled(false);
fShowContents->SetEnabled(false);
fSourceItem->SetEnabled(false);
fDestItem->SetEnabled(false);
fExpandItem->SetEnabled(false);
fShowItem->SetEnabled(false);
fStopItem->SetEnabled(true);
fPreferencesItem->SetEnabled(false);
BEntry entry(&fSourceRef);
BPath path(&entry);
BString text(B_TRANSLATE("Expanding '%s'" B_UTF8_ELLIPSIS));
text.ReplaceFirst("%s", path.Leaf());
fStatusView->SetStatus(text.String());
fExpandingThread = new ExpanderThread(&message, new BMessenger(this));
fExpandingThread->Start();
fExpandingStarted = true;
}
void
ExpanderWindow::StopExpanding(void)
{
if (fExpandingThread) {
fExpandingThread->InterruptExternalExpander();
fExpandingThread = NULL;
}
fExpandingStarted = false;
fExpandButton->SetLabel(B_TRANSLATE("Expand"));
fSourceButton->SetEnabled(true);
fDestButton->SetEnabled(true);
fShowContents->SetEnabled(true);
fSourceItem->SetEnabled(true);
fDestItem->SetEnabled(true);
fExpandItem->SetEnabled(true);
fShowItem->SetEnabled(true);
fStopItem->SetEnabled(false);
fPreferencesItem->SetEnabled(true);
}
void
ExpanderWindow::_ExpandListingText()
{
float delta = fLongestLine - fListingText->Frame().Width();
if (delta > 0) {
BScreen screen;
BRect screenFrame = screen.Frame();
if (Frame().right + delta > screenFrame.right)
delta = screenFrame.right - Frame().right - 4.0f;
ResizeBy(delta, 0.0f);
}
float minWidth, maxWidth, minHeight, maxHeight;
GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
if (minWidth < Frame().Width() + delta) {
// set the Zoom limit as the minimal required size
SetZoomLimits(Frame().Width() + delta,
std::min(fSizeLimit + fListingText->TextRect().Height()
+ fLineHeight + B_H_SCROLL_BAR_HEIGHT + 1.0f,
maxHeight));
} else {
// set the zoom limit based on minimal window size allowed
SetZoomLimits(minWidth,
std::min(fSizeLimit + fListingText->TextRect().Height()
+ fLineHeight + B_H_SCROLL_BAR_HEIGHT + 1.0f,
maxHeight));
}
}
void
ExpanderWindow::_UpdateWindowSize(bool showContents)
{
float minWidth, maxWidth, minHeight, maxHeight;
GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
float bottom = fSizeLimit;
if (showContents) {
if (fPreviousHeight < 0.0) {
BFont font;
font_height fontHeight;
fListingText->GetFont(&font);
font.GetHeight(&fontHeight);
fLineHeight = ceilf(fontHeight.ascent + fontHeight.descent
+ fontHeight.leading);
fPreviousHeight = bottom + 10.0 * fLineHeight;
}
minHeight = bottom + 5.0 * fLineHeight;
maxHeight = 32767.0;
bottom = std::max(fPreviousHeight, minHeight);
} else {
minHeight = fSizeLimit;
maxHeight = fSizeLimit;
fPreviousHeight = Frame().Height();
}
SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight);
ResizeTo(Frame().Width(), bottom);
}
void
ExpanderWindow::StartListing()
{
_UpdateWindowSize(true);
if (!fSourceChanged)
return;
fPreviousHeight = -1.0;
fLongestLine = 0.0f;
ExpanderRule* rule = fRules.MatchingRule(&fSourceRef);
if (!rule)
return;
BMessage message;
message.AddString("cmd", rule->ListingCmd());
message.AddRef("srcRef", &fSourceRef);
fShowContents->SetEnabled(true);
fSourceItem->SetEnabled(false);
fDestItem->SetEnabled(false);
fExpandItem->SetEnabled(false);
fShowItem->SetEnabled(true);
fShowItem->SetLabel(B_TRANSLATE("Hide contents"));
fStopItem->SetEnabled(false);
fPreferencesItem->SetEnabled(false);
fSourceButton->SetEnabled(false);
fDestButton->SetEnabled(false);
fExpandButton->SetEnabled(false);
BEntry entry(&fSourceRef);
BPath path(&entry);
BString text(B_TRANSLATE("Creating listing for '%s'" B_UTF8_ELLIPSIS));
text.ReplaceFirst("%s", path.Leaf());
fStatusView->SetStatus(text.String());
fListingText->SetText("");
fListingText->MakeSelectable(false);
fListingThread = new ExpanderThread(&message, new BMessenger(this));
fListingThread->Start();
fListingStarted = true;
}
void
ExpanderWindow::StopListing(void)
{
if (fListingThread) {
fListingThread->InterruptExternalExpander();
fListingThread = NULL;
}
fListingStarted = false;
fListingText->MakeSelectable(true);
fShowContents->SetEnabled(true);
fSourceItem->SetEnabled(true);
fDestItem->SetEnabled(true);
fExpandItem->SetEnabled(true);
fShowItem->SetEnabled(true);
fStopItem->SetEnabled(false);
fPreferencesItem->SetEnabled(true);
fSourceButton->SetEnabled(true);
fDestButton->SetEnabled(true);
fExpandButton->SetEnabled(true);
fStatusView->SetStatus("");
}
void
ExpanderWindow::CloseWindowOrKeepOpen()
{
bool expandFiles = false;
fSettings.FindBool("automatically_expand_files", &expandFiles);
bool closeWhenDone = false;
fSettings.FindBool("close_when_done", &closeWhenDone);
if (expandFiles || closeWhenDone)
PostMessage(B_QUIT_REQUESTED);
}
void
ExpanderWindow::OpenDestFolder()
{
bool openFolder = true;
fSettings.FindBool("open_destination_folder", &openFolder);
if (!openFolder)
return;
BMessage* message = new BMessage(B_REFS_RECEIVED);
message->AddRef("refs", &fDestRef);
BPath path(&fDestRef);
BMessenger tracker("application/x-vnd.Be-TRAK");
tracker.SendMessage(message);
}
void
ExpanderWindow::AutoListing()
{
bool showContents = false;
fSettings.FindBool("show_contents_listing", &showContents);
if (!showContents)
return;
fShowContents->SetValue(B_CONTROL_ON);
fShowContents->Invoke();
}
void
ExpanderWindow::AutoExpand()
{
bool expandFiles = false;
fSettings.FindBool("automatically_expand_files", &expandFiles);
if (!expandFiles) {
AutoListing();
return;
}
fExpandButton->Invoke();
}