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