xref: /haiku/src/apps/icon-o-matic/gui/SavePanel.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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 
36 enum {
37 	MSG_FORMAT		= 'sfpf',
38 	MSG_SETTINGS	= 'sfps',
39 };
40 
41 // SaveItem class
42 SaveItem::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
53 SavePanel::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
162 SavePanel::~SavePanel()
163 {
164 }
165 
166 // SendMessage
167 void
168 SavePanel::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
179 void
180 SavePanel::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
200 void
201 SavePanel::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
231 void
232 SavePanel::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
284 int32
285 SavePanel::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
303 void
304 SavePanel::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
349 SaveItem*
350 SavePanel::_GetCurrentMenuItem() const
351 {
352 	SaveItem* item = dynamic_cast<SaveItem*>(fFormatM->FindMarked());
353 	if (!item)
354 		return fNativeMI;
355 	return item;
356 }
357 
358 // _ExportSettings
359 void
360 SavePanel::_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
396 void
397 SavePanel::_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
464 void
465 SavePanel::_EnableSettings() const
466 {
467 	// no settings currently necessary
468 	fSettingsB->SetEnabled(false);
469 }
470 
471