1/*
2 * Copyright 2006, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan A��mus <superstippi@gmx.de>
7 */
8
9#include "SavePanel.h"
10
11#include <stdio.h>
12#include <string.h>
13
14#include <Alert.h>
15#include <Button.h>
16#include <Catalog.h>
17#include <Locale.h>
18#include <MenuBar.h>
19#include <MenuField.h>
20#include <PopUpMenu.h>
21#include <ScrollBar.h>
22#include <TextControl.h>
23#include <TranslationKit.h>
24#include <View.h>
25#include <Window.h>
26
27#include "Exporter.h"
28#include "IconEditorApp.h"
29#include "Panel.h"
30
31
32#undef B_TRANSLATION_CONTEXT
33#define B_TRANSLATION_CONTEXT "Icon-O-Matic-SavePanel"
34
35
36enum {
37	MSG_FORMAT		= 'sfpf',
38	MSG_SETTINGS	= 'sfps',
39};
40
41// SaveItem class
42SaveItem::SaveItem(const char* name,
43				   BMessage* message,
44				   uint32 exportMode)
45	: BMenuItem(name, message),
46	  fExportMode(exportMode)
47{
48}
49
50// #pragma mark -
51
52// SavePanel class
53SavePanel::SavePanel(const char* name,
54					 BMessenger* target,
55					 entry_ref* startDirectory,
56					 uint32 nodeFlavors,
57					 bool allowMultipleSelection,
58					 BMessage* message,
59					 BRefFilter* filter,
60					 bool modal,
61					 bool hideWhenDone)
62	: BFilePanel(B_SAVE_PANEL, target, startDirectory,
63				 nodeFlavors, allowMultipleSelection,
64				 message, filter, modal, hideWhenDone),
65	  BHandler(name),
66	  fConfigWindow(NULL),
67	  fFormatM(NULL),
68	  fExportMode(EXPORT_MODE_ICON_RDEF)
69{
70	BWindow* window = Window();
71	if (!window || !window->Lock())
72		return;
73
74	// add this instance as BHandler to the window's looper
75	window->AddHandler(this);
76
77	// find a couple of important views and mess with their layout
78	BView* background = Window()->ChildAt(0);
79	if (background == NULL) {
80		printf("SavePanel::SavePanel() - couldn't find necessary controls.\n");
81		return;
82	}
83	BButton* cancel = dynamic_cast<BButton*>(
84		background->FindView("cancel button"));
85	BView* textview = background->FindView("text view");
86
87	if (!cancel || !textview) {
88		printf("SavePanel::SavePanel() - couldn't find necessary controls.\n");
89		return;
90	}
91
92	_BuildMenu();
93
94	BRect rect = textview->Frame();
95	rect.top = cancel->Frame().top;
96	font_height fh;
97	be_plain_font->GetHeight(&fh);
98	rect.bottom = rect.top + fh.ascent + fh.descent + 5.0;
99
100	fFormatMF = new BMenuField(rect, "format popup", B_TRANSLATE("Format"),
101								fFormatM, true,
102								B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
103								B_WILL_DRAW | B_NAVIGABLE);
104	fFormatMF->SetDivider(be_plain_font->StringWidth(
105		B_TRANSLATE("Format")) + 7);
106	fFormatMF->MenuBar()->ResizeToPreferred();
107	fFormatMF->ResizeToPreferred();
108
109	float height = fFormatMF->Bounds().Height() + 8.0;
110
111	// find all the views that are in the way and
112	// move up them up the height of the menu field
113	BView *poseview = background->FindView("PoseView");
114	if (poseview) poseview->ResizeBy(0, -height);
115	BView *countvw = (BView *)background->FindView("CountVw");
116	if (countvw) countvw->MoveBy(0, -height);
117	textview->MoveBy(0, -height);
118
119#if HAIKU_TARGET_PLATFORM_DANO
120	fFormatMF->MoveTo(textview->Frame().left, fFormatMF->Frame().top + 2);
121#else
122	fFormatMF->MoveTo(textview->Frame().left, fFormatMF->Frame().top);
123#endif
124
125	background->AddChild(fFormatMF);
126
127	// Build the "Settings" button relative to the format menu
128	rect = cancel->Frame();
129	rect.OffsetTo(fFormatMF->Frame().right + 5.0, rect.top);
130	fSettingsB = new BButton(rect, "settings",
131							 B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
132							 new BMessage(MSG_SETTINGS),
133							 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
134							 B_WILL_DRAW | B_NAVIGABLE);
135	fSettingsB->ResizeToPreferred();
136	background->AddChild(fSettingsB);
137	fSettingsB->SetTarget(this);
138
139	textview->ResizeTo(fSettingsB->Frame().right - fFormatMF->Frame().left,
140					   textview->Frame().Height());
141
142	BButton *insert = (BButton *)background->FindView("default button");
143
144	// Make sure the smallest window won't draw the "Settings" button over
145	// anything else
146	float minWindowWidth = textview->Bounds().Width()
147							+ cancel->Bounds().Width()
148							+ (insert ? insert->Bounds().Width() : 0.0)
149							+ 90;
150	Window()->SetSizeLimits(minWindowWidth, 10000, 250, 10000);
151	if (Window()->Bounds().IntegerWidth() + 1 < minWindowWidth)
152		Window()->ResizeTo(minWindowWidth, Window()->Bounds().Height());
153
154
155	// Init window title
156	SetExportMode(true);
157
158	window->Unlock();
159}
160
161// destructor
162SavePanel::~SavePanel()
163{
164}
165
166// SendMessage
167void
168SavePanel::SendMessage(const BMessenger* messenger, BMessage* message)
169{
170	// add the current format information to the message,
171	// bot only if we are indeed in export mode
172	if (message && fFormatM->IsEnabled())
173		message->AddInt32("export mode", ExportMode());
174	// let the original file panel code handle the rest
175	BFilePanel::SendMessage(messenger, message);
176}
177
178// MessageReceived
179void
180SavePanel::MessageReceived(BMessage* message)
181{
182	// Handle messages from controls we've added
183	switch (message->what) {
184		case MSG_FORMAT:
185			fExportMode = ExportMode();
186			AdjustExtension();
187				// TODO: make this behaviour a setting
188			_EnableSettings();
189			break;
190		case MSG_SETTINGS:
191			_ExportSettings();
192			break;
193		default:
194			BHandler::MessageReceived(message);
195			break;
196	}
197}
198
199// SetExportMode
200void
201SavePanel::SetExportMode(bool exportMode)
202{
203	BWindow* window = Window();
204	if (!window || !window->Lock())
205		return;
206
207	// adjust window title and enable format menu
208	BString title(B_TRANSLATE_SYSTEM_NAME("Icon-O-Matic"));
209	title  << ": ";
210	if (exportMode) {
211		fFormatMF->SetEnabled(true);
212		SetExportMode(fExportMode);
213		_EnableSettings();
214		title << B_TRANSLATE_COMMENT("Export icon", "Dialog title");
215	} else {
216		fExportMode = ExportMode();
217			// does not overwrite fExportMode in case we already were
218			// in native save mode
219		fNativeMI->SetMarked(true);
220
221		fFormatMF->SetEnabled(false);
222		fSettingsB->SetEnabled(false);
223		title << B_TRANSLATE_COMMENT("Save icon", "Dialog title");
224	}
225
226	window->SetTitle(title);
227	window->Unlock();
228}
229
230// SetExportMode
231void
232SavePanel::SetExportMode(int32 mode)
233{
234	BWindow* window = Window();
235	if (!window || !window->Lock())
236		return;
237
238	switch (mode) {
239		case EXPORT_MODE_MESSAGE:
240			fNativeMI->SetMarked(true);
241			break;
242		case EXPORT_MODE_FLAT_ICON:
243			fHVIFMI->SetMarked(true);
244			break;
245		case EXPORT_MODE_SVG:
246			fSVGMI->SetMarked(true);
247			break;
248		case EXPORT_MODE_BITMAP_16:
249			fBitmap16MI->SetMarked(true);
250			break;
251		case EXPORT_MODE_BITMAP_32:
252			fBitmap32MI->SetMarked(true);
253			break;
254		case EXPORT_MODE_BITMAP_64:
255			fBitmap64MI->SetMarked(true);
256			break;
257		case EXPORT_MODE_BITMAP_SET:
258			fBitmapSetMI->SetMarked(true);
259			break;
260		case EXPORT_MODE_ICON_ATTR:
261			fIconAttrMI->SetMarked(true);
262			break;
263		case EXPORT_MODE_ICON_MIME_ATTR:
264			fIconMimeAttrMI->SetMarked(true);
265			break;
266		case EXPORT_MODE_ICON_RDEF:
267			fRDefMI->SetMarked(true);
268			break;
269		case EXPORT_MODE_ICON_SOURCE:
270			fSourceMI->SetMarked(true);
271			break;
272	}
273
274	if (mode != EXPORT_MODE_MESSAGE)
275		fExportMode = mode;
276
277	fFormatMF->SetEnabled(mode != EXPORT_MODE_MESSAGE);
278	_EnableSettings();
279
280	window->Unlock();
281}
282
283// ExportMode
284int32
285SavePanel::ExportMode() const
286{
287	int32 mode = fExportMode;
288	BWindow* window = Window();
289	if (!window || !window->Lock())
290		return mode;
291
292	if (fFormatMF->IsEnabled()) {
293		// means we are actually in export mode
294		SaveItem* item = _GetCurrentMenuItem();
295		mode = item->ExportMode();
296	}
297	window->Unlock();
298
299	return mode;
300}
301
302// AdjustExtension
303void
304SavePanel::AdjustExtension()
305{
306//	if (!Window()->Lock())
307//		return;
308//
309//	BView* background = Window()->ChildAt(0);
310//	BTextControl* textview = dynamic_cast<BTextControl*>(
311//		background->FindView("text view"));
312//
313//	if (textview) {
314//
315//		translator_id id = 0;
316//		uint32 format = 0;
317//		int32 mode = ExportMode();
318//		SaveItem* exportItem = dynamic_cast<SaveItem*>(_GetCurrentMenuItem());
319//		if (mode == EXPORT_TRANSLATOR && exportItem) {
320//			id = exportItem->id;
321//			format = exportItem->format;
322//		}
323//
324//		Exporter* exporter = Exporter::ExporterFor(mode, id, format);
325//
326//		if (exporter) {
327//			BString name(textview->Text());
328//
329//			// adjust the name extension
330//			const char* extension = exporter->Extension();
331//			if (strlen(extension) > 0) {
332//				int32 cutPos = name.FindLast('.');
333//				int32 cutCount = name.Length() - cutPos;
334//				if (cutCount > 0 && cutCount <= 4) {
335//					name.Remove(cutPos, cutCount);
336//				}
337//				name << "." << extension;
338//			}
339//
340//			SetSaveText(name.String());
341//		}
342//
343//		delete exporter;
344//	}
345//	Window()->Unlock();
346}
347
348// _GetCurrentMenuItem
349SaveItem*
350SavePanel::_GetCurrentMenuItem() const
351{
352	SaveItem* item = dynamic_cast<SaveItem*>(fFormatM->FindMarked());
353	if (!item)
354		return fNativeMI;
355	return item;
356}
357
358// _ExportSettings
359void
360SavePanel::_ExportSettings()
361{
362//	SaveItem *item = dynamic_cast<SaveItem*>(_GetCurrentMenuItem());
363//	if (item == NULL)
364//		return;
365//
366//	BTranslatorRoster *roster = BTranslatorRoster::Default();
367//	BView *view;
368//	BRect rect(0, 0, 239, 239);
369//
370//	// Build a window around this translator's configuration view
371//	status_t err = roster->MakeConfigurationView(item->id, NULL, &view, &rect);
372//	if (err < B_OK || view == NULL) {
373//		BAlert *alert = new BAlert(NULL, strerror(err), B_TRANSLATE("OK"));
374//		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
375//		alert->Go();
376//	} else {
377//		if (fConfigWindow != NULL) {
378//			if (fConfigWindow->Lock())
379//				fConfigWindow->Quit();
380//		}
381//		fConfigWindow = new Panel(rect, "Translator Settings",
382//								  B_TITLED_WINDOW_LOOK,
383//								  B_NORMAL_WINDOW_FEEL,
384//								  B_NOT_ZOOMABLE | B_NOT_RESIZABLE);
385//		fConfigWindow->AddChild(view);
386//		// Just to make sure
387//		view->MoveTo(0, 0);
388//		view->ResizeTo(rect.Width(), rect.Height());
389//		view->ResizeToPreferred();
390//		fConfigWindow->MoveTo(100, 100);
391//		fConfigWindow->Show();
392//	}
393}
394
395// _BuildMenu
396void
397SavePanel::_BuildMenu()
398{
399	fFormatM = new BPopUpMenu(B_TRANSLATE("Format"));
400
401	fNativeMI = new SaveItem("Icon-O-Matic",
402		new BMessage(MSG_FORMAT), EXPORT_MODE_MESSAGE);
403	fFormatM->AddItem(fNativeMI);
404	fNativeMI->SetEnabled(false);
405
406	fFormatM->AddSeparatorItem();
407
408	fHVIFMI = new SaveItem("HVIF",
409		new BMessage(MSG_FORMAT), EXPORT_MODE_FLAT_ICON);
410	fFormatM->AddItem(fHVIFMI);
411
412	fRDefMI = new SaveItem("HVIF RDef",
413		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_RDEF);
414	fFormatM->AddItem(fRDefMI);
415
416	fSourceMI = new SaveItem(B_TRANSLATE("HVIF source code"),
417		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_SOURCE);
418	fFormatM->AddItem(fSourceMI);
419
420	fFormatM->AddSeparatorItem();
421
422	fSVGMI = new SaveItem("SVG",
423		new BMessage(MSG_FORMAT), EXPORT_MODE_SVG);
424
425	fFormatM->AddItem(fSVGMI);
426
427	fFormatM->AddSeparatorItem();
428
429	fBitmap16MI = new SaveItem("PNG 16x16",
430		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_16);
431	fFormatM->AddItem(fBitmap16MI);
432
433	fBitmap32MI = new SaveItem("PNG 32x32",
434		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_32);
435	fFormatM->AddItem(fBitmap32MI);
436
437	fBitmap64MI = new SaveItem("PNG 64x64",
438		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_64);
439	fFormatM->AddItem(fBitmap64MI);
440
441	fBitmapSetMI = new SaveItem(B_TRANSLATE("PNG set"),
442		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_SET);
443	fFormatM->AddItem(fBitmapSetMI);
444
445	fFormatM->AddSeparatorItem();
446
447	fIconAttrMI = new SaveItem(B_TRANSLATE("BEOS:ICON attribute"),
448		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_ATTR);
449	fFormatM->AddItem(fIconAttrMI);
450
451	fIconMimeAttrMI = new SaveItem(B_TRANSLATE("META:ICON attribute"),
452		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_MIME_ATTR);
453
454	fFormatM->AddItem(fIconMimeAttrMI);
455
456
457	fFormatM->SetTargetForItems(this);
458
459	// pick the RDef item in the list
460	fRDefMI->SetMarked(true);
461}
462
463// _EnableSettings
464void
465SavePanel::_EnableSettings() const
466{
467	// no settings currently necessary
468	fSettingsB->SetEnabled(false);
469}
470
471