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
SaveItem(const char * name,BMessage * message,uint32 exportMode)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
SavePanel(const char * name,BMessenger * target,entry_ref * startDirectory,uint32 nodeFlavors,bool allowMultipleSelection,BMessage * message,BRefFilter * filter,bool modal,bool hideWhenDone)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
~SavePanel()162 SavePanel::~SavePanel()
163 {
164 }
165
166 // SendMessage
167 void
SendMessage(const BMessenger * messenger,BMessage * message)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
MessageReceived(BMessage * message)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
SetExportMode(bool exportMode)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
SetExportMode(int32 mode)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
ExportMode() const285 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
AdjustExtension()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*
_GetCurrentMenuItem() const350 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
_ExportSettings()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
_BuildMenu()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
_EnableSettings() const465 SavePanel::_EnableSettings() const
466 {
467 // no settings currently necessary
468 fSettingsB->SetEnabled(false);
469 }
470
471