xref: /haiku/src/apps/icon-o-matic/gui/SavePanel.cpp (revision d06cbe081b7ea043aea2012359744091de6d604d)
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 	BButton* cancel = dynamic_cast<BButton*>(
80 		background->FindView("cancel button"));
81 	BView* textview = background->FindView("text view");
82 	BScrollBar* hscrollbar = dynamic_cast<BScrollBar*>(
83 		background->FindView("HScrollBar"));
84 
85 	if (!background || !cancel || !textview || !hscrollbar) {
86 		printf("SavePanel::SavePanel() - couldn't find necessary controls.\n");
87 		return;
88 	}
89 
90 	_BuildMenu();
91 
92 	BRect rect = textview->Frame();
93 	rect.top = cancel->Frame().top;
94 	font_height fh;
95 	be_plain_font->GetHeight(&fh);
96 	rect.bottom = rect.top + fh.ascent + fh.descent + 5.0;
97 
98 	fFormatMF = new BMenuField(rect, "format popup", B_TRANSLATE("Format"),
99 								fFormatM, true,
100 								B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
101 								B_WILL_DRAW | B_NAVIGABLE);
102 	fFormatMF->SetDivider(be_plain_font->StringWidth(
103 		B_TRANSLATE("Format")) + 7);
104 	fFormatMF->MenuBar()->ResizeToPreferred();
105 	fFormatMF->ResizeToPreferred();
106 
107 	float height = fFormatMF->Bounds().Height() + 8.0;
108 
109 	// find all the views that are in the way and
110 	// move up them up the height of the menu field
111 	BView *poseview = background->FindView("PoseView");
112 	if (poseview) poseview->ResizeBy(0, -height);
113 	BButton *insert = (BButton *)background->FindView("default button");
114 	if (hscrollbar) hscrollbar->MoveBy(0, -height);
115 	BScrollBar *vscrollbar = (BScrollBar *)background->FindView("VScrollBar");
116 	if (vscrollbar) vscrollbar->ResizeBy(0, -height);
117 	BView *countvw = (BView *)background->FindView("CountVw");
118 	if (countvw) countvw->MoveBy(0, -height);
119 	textview->MoveBy(0, -height);
120 
121 #if HAIKU_TARGET_PLATFORM_DANO
122 	fFormatMF->MoveTo(textview->Frame().left, fFormatMF->Frame().top + 2);
123 #else
124 	fFormatMF->MoveTo(textview->Frame().left, fFormatMF->Frame().top);
125 #endif
126 
127 	background->AddChild(fFormatMF);
128 
129 	// Build the "Settings" button relative to the format menu
130 	rect = cancel->Frame();
131 	rect.OffsetTo(fFormatMF->Frame().right + 5.0, rect.top);
132 	fSettingsB = new BButton(rect, "settings",
133 							 B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
134 							 new BMessage(MSG_SETTINGS),
135 							 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
136 							 B_WILL_DRAW | B_NAVIGABLE);
137 	fSettingsB->ResizeToPreferred();
138 	background->AddChild(fSettingsB);
139 	fSettingsB->SetTarget(this);
140 
141 	textview->ResizeTo(fSettingsB->Frame().right - fFormatMF->Frame().left,
142 					   textview->Frame().Height());
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("Icon-O-Matic: ");
209 	if (exportMode) {
210 		fFormatMF->SetEnabled(true);
211 		SetExportMode(fExportMode);
212 		_EnableSettings();
213 		title << B_TRANSLATE_CONTEXT("Export icon", "Dialog title");
214 	} else {
215 		fExportMode = ExportMode();
216 			// does not overwrite fExportMode in case we already were
217 			// in native save mode
218 		fNativeMI->SetMarked(true);
219 
220 		fFormatMF->SetEnabled(false);
221 		fSettingsB->SetEnabled(false);
222 		title << B_TRANSLATE_CONTEXT("Save icon", "Dialog title");
223 	}
224 
225 	window->SetTitle(title);
226 	window->Unlock();
227 }
228 
229 // SetExportMode
230 void
231 SavePanel::SetExportMode(int32 mode)
232 {
233 	BWindow* window = Window();
234 	if (!window || !window->Lock())
235 		return;
236 
237 	switch (mode) {
238 		case EXPORT_MODE_MESSAGE:
239 			fNativeMI->SetMarked(true);
240 			break;
241 		case EXPORT_MODE_FLAT_ICON:
242 			fHVIFMI->SetMarked(true);
243 			break;
244 		case EXPORT_MODE_SVG:
245 			fSVGMI->SetMarked(true);
246 			break;
247 		case EXPORT_MODE_BITMAP_16:
248 			fBitmap16MI->SetMarked(true);
249 			break;
250 		case EXPORT_MODE_BITMAP_32:
251 			fBitmap32MI->SetMarked(true);
252 			break;
253 		case EXPORT_MODE_BITMAP_64:
254 			fBitmap64MI->SetMarked(true);
255 			break;
256 		case EXPORT_MODE_BITMAP_SET:
257 			fBitmapSetMI->SetMarked(true);
258 			break;
259 		case EXPORT_MODE_ICON_ATTR:
260 			fIconAttrMI->SetMarked(true);
261 			break;
262 		case EXPORT_MODE_ICON_MIME_ATTR:
263 			fIconMimeAttrMI->SetMarked(true);
264 			break;
265 		case EXPORT_MODE_ICON_RDEF:
266 			fRDefMI->SetMarked(true);
267 			break;
268 		case EXPORT_MODE_ICON_SOURCE:
269 			fSourceMI->SetMarked(true);
270 			break;
271 	}
272 
273 	if (mode != EXPORT_MODE_MESSAGE)
274 		fExportMode = mode;
275 
276 	fFormatMF->SetEnabled(mode != EXPORT_MODE_MESSAGE);
277 	_EnableSettings();
278 
279 	window->Unlock();
280 }
281 
282 // ExportMode
283 int32
284 SavePanel::ExportMode() const
285 {
286 	int32 mode = fExportMode;
287 	BWindow* window = Window();
288 	if (!window || !window->Lock())
289 		return mode;
290 
291 	if (fFormatMF->IsEnabled()) {
292 		// means we are actually in export mode
293 		SaveItem* item = _GetCurrentMenuItem();
294 		mode = item->ExportMode();
295 	}
296 	window->Unlock();
297 
298 	return mode;
299 }
300 
301 // AdjustExtension
302 void
303 SavePanel::AdjustExtension()
304 {
305 //	if (!Window()->Lock())
306 //		return;
307 //
308 //	BView* background = Window()->ChildAt(0);
309 //	BTextControl* textview = dynamic_cast<BTextControl*>(
310 //		background->FindView("text view"));
311 //
312 //	if (textview) {
313 //
314 //		translator_id id = 0;
315 //		uint32 format = 0;
316 //		int32 mode = ExportMode();
317 //		SaveItem* exportItem = dynamic_cast<SaveItem*>(_GetCurrentMenuItem());
318 //		if (mode == EXPORT_TRANSLATOR && exportItem) {
319 //			id = exportItem->id;
320 //			format = exportItem->format;
321 //		}
322 //
323 //		Exporter* exporter = Exporter::ExporterFor(mode, id, format);
324 //
325 //		if (exporter) {
326 //			BString name(textview->Text());
327 //
328 //			// adjust the name extension
329 //			const char* extension = exporter->Extension();
330 //			if (strlen(extension) > 0) {
331 //				int32 cutPos = name.FindLast('.');
332 //				int32 cutCount = name.Length() - cutPos;
333 //				if (cutCount > 0 && cutCount <= 4) {
334 //					name.Remove(cutPos, cutCount);
335 //				}
336 //				name << "." << extension;
337 //			}
338 //
339 //			SetSaveText(name.String());
340 //		}
341 //
342 //		delete exporter;
343 //	}
344 //	Window()->Unlock();
345 }
346 
347 // _GetCurrentMenuItem
348 SaveItem*
349 SavePanel::_GetCurrentMenuItem() const
350 {
351 	SaveItem* item = dynamic_cast<SaveItem*>(fFormatM->FindMarked());
352 	if (!item)
353 		return fNativeMI;
354 	return item;
355 }
356 
357 // _ExportSettings
358 void
359 SavePanel::_ExportSettings()
360 {
361 //	SaveItem *item = dynamic_cast<SaveItem*>(_GetCurrentMenuItem());
362 //	if (item == NULL)
363 //		return;
364 //
365 //	BTranslatorRoster *roster = BTranslatorRoster::Default();
366 //	BView *view;
367 //	BRect rect(0, 0, 239, 239);
368 //
369 //	// Build a window around this translator's configuration view
370 //	status_t err = roster->MakeConfigurationView(item->id, NULL, &view, &rect);
371 //	if (err < B_OK || view == NULL) {
372 //		BAlert *alert = new BAlert(NULL, strerror(err), "OK");
373 //		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
374 //		alert->Go();
375 //	} else {
376 //		if (fConfigWindow != NULL) {
377 //			if (fConfigWindow->Lock())
378 //				fConfigWindow->Quit();
379 //		}
380 //		fConfigWindow = new Panel(rect, "Translator Settings",
381 //								  B_TITLED_WINDOW_LOOK,
382 //								  B_NORMAL_WINDOW_FEEL,
383 //								  B_NOT_ZOOMABLE | B_NOT_RESIZABLE);
384 //		fConfigWindow->AddChild(view);
385 //		// Just to make sure
386 //		view->MoveTo(0, 0);
387 //		view->ResizeTo(rect.Width(), rect.Height());
388 //		view->ResizeToPreferred();
389 //		fConfigWindow->MoveTo(100, 100);
390 //		fConfigWindow->Show();
391 //	}
392 }
393 
394 // _BuildMenu
395 void
396 SavePanel::_BuildMenu()
397 {
398 	fFormatM = new BPopUpMenu(B_TRANSLATE("Format"));
399 
400 	fNativeMI = new SaveItem("Icon-O-Matic",
401 		new BMessage(MSG_FORMAT), EXPORT_MODE_MESSAGE);
402 	fFormatM->AddItem(fNativeMI);
403 	fNativeMI->SetEnabled(false);
404 
405 	fFormatM->AddSeparatorItem();
406 
407 	fHVIFMI = new SaveItem("HVIF",
408 		new BMessage(MSG_FORMAT), EXPORT_MODE_FLAT_ICON);
409 	fFormatM->AddItem(fHVIFMI);
410 
411 	fRDefMI = new SaveItem("HVIF RDef",
412 		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_RDEF);
413 	fFormatM->AddItem(fRDefMI);
414 
415 	fSourceMI = new SaveItem(B_TRANSLATE("HVIF Source Code"),
416 		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_SOURCE);
417 	fFormatM->AddItem(fSourceMI);
418 
419 	fFormatM->AddSeparatorItem();
420 
421 	fSVGMI = new SaveItem("SVG",
422 		new BMessage(MSG_FORMAT), EXPORT_MODE_SVG);
423 
424 	fFormatM->AddItem(fSVGMI);
425 
426 	fFormatM->AddSeparatorItem();
427 
428 	fBitmap16MI = new SaveItem("PNG 16x16",
429 		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_16);
430 	fFormatM->AddItem(fBitmap16MI);
431 
432 	fBitmap32MI = new SaveItem("PNG 32x32",
433 		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_32);
434 	fFormatM->AddItem(fBitmap32MI);
435 
436 	fBitmap64MI = new SaveItem("PNG 64x64",
437 		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_64);
438 	fFormatM->AddItem(fBitmap64MI);
439 
440 	fBitmapSetMI = new SaveItem(B_TRANSLATE("PNG Set"),
441 		new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_SET);
442 	fFormatM->AddItem(fBitmapSetMI);
443 
444 	fFormatM->AddSeparatorItem();
445 
446 	fIconAttrMI = new SaveItem(B_TRANSLATE("BEOS:ICON Attribute"),
447 		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_ATTR);
448 	fFormatM->AddItem(fIconAttrMI);
449 
450 	fIconMimeAttrMI = new SaveItem(B_TRANSLATE("META:ICON Attribute"),
451 		new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_MIME_ATTR);
452 
453 	fFormatM->AddItem(fIconMimeAttrMI);
454 
455 
456 	fFormatM->SetTargetForItems(this);
457 
458 	// pick the RDef item in the list
459 	fRDefMI->SetMarked(true);
460 }
461 
462 // _EnableSettings
463 void
464 SavePanel::_EnableSettings() const
465 {
466 	// no settings currently necessary
467 	fSettingsB->SetEnabled(false);
468 }
469 
470