1/*
2 * Copyright 2004-2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Jérôme Duval
7 *		Humdinger <humdingerb@gmail.com>
8 */
9
10
11#include "ExpanderPreferences.h"
12
13#include <Box.h>
14#include <Button.h>
15#include <CheckBox.h>
16#include <Catalog.h>
17#include <ControlLook.h>
18#include <LayoutBuilder.h>
19#include <Locale.h>
20#include <Message.h>
21#include <Path.h>
22#include <RadioButton.h>
23#include <Screen.h>
24#include <SeparatorView.h>
25#include <StringView.h>
26#include <TextControl.h>
27
28#include "DirectoryFilePanel.h"
29
30
31static const uint32 MSG_OK			= 'mgOK';
32static const uint32 MSG_CANCEL		= 'mCan';
33static const uint32 MSG_LEAVEDEST	= 'mLed';
34static const uint32 MSG_SAMEDIR		= 'mSad';
35static const uint32 MSG_DESTUSE		= 'mDeu';
36static const uint32 MSG_DESTTEXT	= 'mDet';
37static const uint32 MSG_DESTSELECT	= 'mDes';
38
39
40#undef B_TRANSLATION_CONTEXT
41#define B_TRANSLATION_CONTEXT "ExpanderPreferences"
42
43
44ExpanderPreferences::ExpanderPreferences(BMessage* settings)
45	:
46	BWindow(BRect(0, 0, 325, 305), B_TRANSLATE("Expander settings"),
47		B_FLOATING_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL,
48		B_NOT_RESIZABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE
49			| B_AUTO_UPDATE_SIZE_LIMITS),
50	fSettings(settings),
51	fUsePanel(NULL)
52{
53	const float kSpacing = be_control_look->DefaultItemSpacing();
54
55	BStringView* expansionLabel = new BStringView("stringViewExpansion",
56		B_TRANSLATE("Expansion"));
57	expansionLabel->SetFont(be_bold_font);
58	BStringView* destinationLabel = new BStringView("stringViewDestination",
59		B_TRANSLATE("Destination folder"));
60	destinationLabel->SetFont(be_bold_font);
61	BStringView* otherLabel = new BStringView("stringViewOther",
62		B_TRANSLATE("Other"));
63	otherLabel->SetFont(be_bold_font);
64
65	fAutoExpand = new BCheckBox("autoExpand",
66		B_TRANSLATE("Automatically expand files"), NULL);
67	fCloseWindow = new BCheckBox("closeWindowWhenDone",
68		B_TRANSLATE("Close window when done expanding"), NULL);
69
70	fLeaveDest = new BRadioButton("leaveDest",
71		B_TRANSLATE("Leave destination folder path empty"),
72		new BMessage(MSG_LEAVEDEST));
73	fSameDest = new BRadioButton("sameDir",
74		B_TRANSLATE("Same directory as source (archive) file"),
75		new BMessage(MSG_SAMEDIR));
76	fDestUse = new BRadioButton("destUse",
77		B_TRANSLATE("Use:"), new BMessage(MSG_DESTUSE));
78	fDestText = new BTextControl("destText", "", "",
79		new BMessage(MSG_DESTTEXT));
80	fDestText->SetDivider(0);
81	fDestText->TextView()->MakeEditable(false);
82	fDestText->SetEnabled(false);
83	fSelect = new BButton("selectButton", B_TRANSLATE("Select"),
84		new BMessage(MSG_DESTSELECT));
85	fSelect->SetEnabled(false);
86
87	fOpenDest = new BCheckBox("openDestination",
88		B_TRANSLATE("Open destination folder after extraction"), NULL);
89	fAutoShow = new BCheckBox("autoShow",
90		B_TRANSLATE("Automatically show contents listing"), NULL);
91
92	BButton* okbutton = new BButton("OKButton", B_TRANSLATE("OK"),
93		new BMessage(MSG_OK));
94	okbutton->MakeDefault(true);
95	BButton* cancel = new BButton("CancelButton", B_TRANSLATE("Cancel"),
96		new BMessage(MSG_CANCEL));
97
98	// Build the layout
99	BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
100		.AddGroup(B_VERTICAL, 0)
101			.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
102				B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
103			.Add(expansionLabel)
104			.AddGroup(B_VERTICAL, 0)
105				.Add(fAutoExpand)
106				.Add(fCloseWindow)
107				.AddGlue()
108				.SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, 0,
109					B_USE_ITEM_SPACING)
110				.End()
111			.Add(destinationLabel)
112			.AddGroup(B_VERTICAL, 0)
113				.Add(fLeaveDest)
114				.Add(fSameDest)
115				.Add(fDestUse)
116				.AddGroup(B_HORIZONTAL, 0)
117					.Add(fDestText, 0.8)
118					.AddStrut(B_USE_ITEM_SPACING)
119					.Add(fSelect, 0.2)
120					.SetInsets(kSpacing * 2, 0, 0, 0)
121					.End()
122				.AddGlue()
123				.SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, 0,
124					B_USE_ITEM_SPACING)
125				.End()
126			.Add(otherLabel)
127			.AddGroup(B_VERTICAL, 0)
128				.Add(fOpenDest)
129				.Add(fAutoShow)
130				.AddGlue()
131				.SetInsets(B_USE_SMALL_SPACING, B_USE_SMALL_SPACING, 0, 0)
132				.End()
133			.End()
134		.Add(new BSeparatorView(B_HORIZONTAL))
135		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
136			.SetInsets(0, B_USE_DEFAULT_SPACING,
137				B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING)
138			.AddGlue()
139			.Add(cancel)
140			.Add(okbutton)
141		.End();
142
143
144	fDestText->SetExplicitAlignment(
145		BAlignment(B_ALIGN_HORIZONTAL_UNSET, B_ALIGN_VERTICAL_CENTER));
146
147	CenterOnScreen();
148
149	_ReadSettings();
150}
151
152
153ExpanderPreferences::~ExpanderPreferences()
154{
155	if (fUsePanel && fUsePanel->RefFilter())
156		delete fUsePanel->RefFilter();
157
158	delete fUsePanel;
159}
160
161
162void
163ExpanderPreferences::_ReadSettings()
164{
165	bool automatically_expand_files;
166	bool close_when_done;
167	int8 destination_folder;
168	entry_ref ref;
169	bool open_destination_folder;
170	bool show_contents_listing;
171	if ((fSettings->FindBool("automatically_expand_files",
172			&automatically_expand_files) == B_OK)
173		&& automatically_expand_files) {
174		fAutoExpand->SetValue(B_CONTROL_ON);
175	}
176
177	if (fSettings->FindBool("close_when_done", &close_when_done) == B_OK
178		&& close_when_done) {
179		fCloseWindow->SetValue(B_CONTROL_ON);
180	}
181
182	if (fSettings->FindInt8("destination_folder", &destination_folder)
183			== B_OK) {
184		switch (destination_folder) {
185			case 0x63:
186				fSameDest->SetValue(B_CONTROL_ON);
187				break;
188
189			case 0x65:
190				fDestUse->SetValue(B_CONTROL_ON);
191				fDestText->SetEnabled(true);
192				fSelect->SetEnabled(true);
193				break;
194
195			case 0x66:
196				fLeaveDest->SetValue(B_CONTROL_ON);
197				break;
198		}
199	}
200
201	if (fSettings->FindRef("destination_folder_use", &fRef) == B_OK) {
202		BEntry entry(&fRef);
203		if (entry.Exists()) {
204			BPath path(&entry);
205			fDestText->SetText(path.Path());
206		}
207	}
208
209	if (fSettings->FindBool("open_destination_folder",
210			&open_destination_folder) == B_OK
211		&& open_destination_folder) {
212		fOpenDest->SetValue(B_CONTROL_ON);
213	}
214
215	if (fSettings->FindBool("show_contents_listing",
216			&show_contents_listing) == B_OK
217		&& show_contents_listing) {
218		fAutoShow->SetValue(B_CONTROL_ON);
219	}
220}
221
222
223void
224ExpanderPreferences::_WriteSettings()
225{
226	fSettings->ReplaceBool("automatically_expand_files",
227		fAutoExpand->Value() == B_CONTROL_ON);
228	fSettings->ReplaceBool("close_when_done",
229		fCloseWindow->Value() == B_CONTROL_ON);
230	fSettings->ReplaceInt8("destination_folder",
231		(fSameDest->Value() == B_CONTROL_ON) ? 0x63
232		: ((fLeaveDest->Value() == B_CONTROL_ON) ? 0x66 : 0x65));
233	fSettings->ReplaceRef("destination_folder_use", &fRef);
234	fSettings->ReplaceBool("open_destination_folder",
235		fOpenDest->Value() == B_CONTROL_ON);
236	fSettings->ReplaceBool("show_contents_listing",
237		fAutoShow->Value() == B_CONTROL_ON);
238}
239
240
241void
242ExpanderPreferences::MessageReceived(BMessage* message)
243{
244	switch (message->what) {
245		case MSG_DESTSELECT:
246		{
247			if (!fUsePanel) {
248				BMessenger messenger(this);
249				fUsePanel = new DirectoryFilePanel(B_OPEN_PANEL, &messenger,
250					NULL, B_DIRECTORY_NODE, false, NULL,
251					new DirectoryRefFilter(), true);
252			}
253			fUsePanel->Show();
254			break;
255		}
256
257		case MSG_DIRECTORY:
258		{
259			entry_ref ref;
260			fUsePanel->GetPanelDirectory(&ref);
261			fRef = ref;
262			BEntry entry(&ref);
263			BPath path(&entry);
264			fDestText->SetText(path.Path());
265			fUsePanel->Hide();
266			break;
267		}
268
269		case B_REFS_RECEIVED:
270		{
271			if (message->FindRef("refs", 0, &fRef) == B_OK) {
272				BEntry entry(&fRef, true);
273				BPath path(&entry);
274				fDestText->SetText(path.Path());
275			}
276			break;
277		}
278
279		case MSG_LEAVEDEST:
280		case MSG_SAMEDIR:
281		{
282			fDestText->SetEnabled(false);
283			fSelect->SetEnabled(false);
284			break;
285		}
286
287		case MSG_DESTUSE:
288		{
289			fDestText->SetEnabled(true);
290			fSelect->SetEnabled(true);
291			fDestText->TextView()->MakeEditable(false);
292			break;
293		}
294
295		case B_KEY_DOWN:
296		{
297			int32 index;
298			if (message->FindInt32("key", &index) == B_OK && index != 1)
299				break;
300		}
301		// fall-through on ESC
302		case MSG_CANCEL:
303		{
304			_ReadSettings();
305			Hide();
306			break;
307		}
308
309		case MSG_OK:
310		{
311			_WriteSettings();
312			Hide();
313			break;
314		}
315	}
316}
317