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 window->SetTitle(B_TRANSLATE("Save image")); 75 76 // add this instance as BHandler to the window's looper 77 window->AddHandler(this); 78 79 // find a couple of important views and mess with their layout 80 BView* background = Window()->ChildAt(0); 81 BButton* cancel = dynamic_cast<BButton*>(background->FindView("cancel button")); 82 BView* textview = background->FindView("text view"); 83 BScrollBar* hscrollbar = dynamic_cast<BScrollBar*>(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 anything else 145 float minWindowWidth = textview->Bounds().Width() 146 + cancel->Bounds().Width() 147 + (insert ? insert->Bounds().Width() : 0.0) 148 + 90; 149 Window()->SetSizeLimits(minWindowWidth, 10000, 250, 10000); 150 if (Window()->Bounds().IntegerWidth() + 1 < minWindowWidth) 151 Window()->ResizeTo(minWindowWidth, Window()->Bounds().Height()); 152 153 154 window->Unlock(); 155 } 156 157 // destructor 158 SavePanel::~SavePanel() 159 { 160 } 161 162 // SendMessage 163 void 164 SavePanel::SendMessage(const BMessenger* messenger, BMessage* message) 165 { 166 // add the current format information to the message, 167 // bot only if we are indeed in export mode 168 if (message && fFormatM->IsEnabled()) 169 message->AddInt32("export mode", ExportMode()); 170 // let the original file panel code handle the rest 171 BFilePanel::SendMessage(messenger, message); 172 } 173 174 // MessageReceived 175 void 176 SavePanel::MessageReceived(BMessage* message) 177 { 178 // Handle messages from controls we've added 179 switch (message->what) { 180 case MSG_FORMAT: 181 fExportMode = ExportMode(); 182 AdjustExtension(); 183 // TODO: make this behaviour a setting 184 _EnableSettings(); 185 break; 186 case MSG_SETTINGS: 187 _ExportSettings(); 188 break; 189 default: 190 BHandler::MessageReceived(message); 191 break; 192 } 193 } 194 195 // SetExportMode 196 void 197 SavePanel::SetExportMode(bool exportMode) 198 { 199 BWindow* window = Window(); 200 if (!window || !window->Lock()) 201 return; 202 203 // adjust window title and enable format menu 204 BString helper("Icon-O-Matic: "); 205 if (exportMode) { 206 fFormatMF->SetEnabled(true); 207 SetExportMode(fExportMode); 208 _EnableSettings(); 209 helper << B_TRANSLATE_CONTEXT("Export Icon", "Dialog title"); 210 } else { 211 fExportMode = ExportMode(); 212 // does not overwrite fExportMode in case we already were 213 // in native save mode 214 fNativeMI->SetMarked(true); 215 216 fFormatMF->SetEnabled(false); 217 fSettingsB->SetEnabled(false); 218 helper << B_TRANSLATE_CONTEXT("Save Icon", "Dialog title"); 219 } 220 221 window->Unlock(); 222 } 223 224 // SetExportMode 225 void 226 SavePanel::SetExportMode(int32 mode) 227 { 228 BWindow* window = Window(); 229 if (!window || !window->Lock()) 230 return; 231 232 switch (mode) { 233 case EXPORT_MODE_MESSAGE: 234 fNativeMI->SetMarked(true); 235 break; 236 case EXPORT_MODE_FLAT_ICON: 237 fHVIFMI->SetMarked(true); 238 break; 239 case EXPORT_MODE_SVG: 240 fSVGMI->SetMarked(true); 241 break; 242 case EXPORT_MODE_BITMAP_16: 243 fBitmap16MI->SetMarked(true); 244 break; 245 case EXPORT_MODE_BITMAP_32: 246 fBitmap32MI->SetMarked(true); 247 break; 248 case EXPORT_MODE_BITMAP_64: 249 fBitmap64MI->SetMarked(true); 250 break; 251 case EXPORT_MODE_BITMAP_SET: 252 fBitmapSetMI->SetMarked(true); 253 break; 254 case EXPORT_MODE_ICON_ATTR: 255 fIconAttrMI->SetMarked(true); 256 break; 257 case EXPORT_MODE_ICON_MIME_ATTR: 258 fIconMimeAttrMI->SetMarked(true); 259 break; 260 case EXPORT_MODE_ICON_RDEF: 261 fRDefMI->SetMarked(true); 262 break; 263 case EXPORT_MODE_ICON_SOURCE: 264 fSourceMI->SetMarked(true); 265 break; 266 } 267 268 if (mode != EXPORT_MODE_MESSAGE) 269 fExportMode = mode; 270 271 fFormatMF->SetEnabled(mode != EXPORT_MODE_MESSAGE); 272 _EnableSettings(); 273 274 window->Unlock(); 275 } 276 277 // ExportMode 278 int32 279 SavePanel::ExportMode() const 280 { 281 int32 mode = fExportMode; 282 BWindow* window = Window(); 283 if (!window || !window->Lock()) 284 return mode; 285 286 if (fFormatMF->IsEnabled()) { 287 // means we are actually in export mode 288 SaveItem* item = _GetCurrentMenuItem(); 289 mode = item->ExportMode(); 290 } 291 window->Unlock(); 292 293 return mode; 294 } 295 296 // AdjustExtension 297 void 298 SavePanel::AdjustExtension() 299 { 300 // if (!Window()->Lock()) 301 // return; 302 // 303 // BView* background = Window()->ChildAt(0); 304 // BTextControl* textview = dynamic_cast<BTextControl*>( 305 // background->FindView("text view")); 306 // 307 // if (textview) { 308 // 309 // translator_id id = 0; 310 // uint32 format = 0; 311 // int32 mode = ExportMode(); 312 // SaveItem* exportItem = dynamic_cast<SaveItem*>(_GetCurrentMenuItem()); 313 // if (mode == EXPORT_TRANSLATOR && exportItem) { 314 // id = exportItem->id; 315 // format = exportItem->format; 316 // } 317 // 318 // Exporter* exporter = Exporter::ExporterFor(mode, id, format); 319 // 320 // if (exporter) { 321 // BString name(textview->Text()); 322 // 323 // // adjust the name extension 324 // const char* extension = exporter->Extension(); 325 // if (strlen(extension) > 0) { 326 // int32 cutPos = name.FindLast('.'); 327 // int32 cutCount = name.Length() - cutPos; 328 // if (cutCount > 0 && cutCount <= 4) { 329 // name.Remove(cutPos, cutCount); 330 // } 331 // name << "." << extension; 332 // } 333 // 334 // SetSaveText(name.String()); 335 // } 336 // 337 // delete exporter; 338 // } 339 // Window()->Unlock(); 340 } 341 342 // _GetCurrentMenuItem 343 SaveItem* 344 SavePanel::_GetCurrentMenuItem() const 345 { 346 SaveItem* item = dynamic_cast<SaveItem*>(fFormatM->FindMarked()); 347 if (!item) 348 return fNativeMI; 349 return item; 350 } 351 352 // _ExportSettings 353 void 354 SavePanel::_ExportSettings() 355 { 356 // SaveItem *item = dynamic_cast<SaveItem*>(_GetCurrentMenuItem()); 357 // if (item == NULL) 358 // return; 359 // 360 // BTranslatorRoster *roster = BTranslatorRoster::Default(); 361 // BView *view; 362 // BRect rect(0, 0, 239, 239); 363 // 364 // // Build a window around this translator's configuration view 365 // status_t err = roster->MakeConfigurationView(item->id, NULL, &view, &rect); 366 // if (err < B_OK || view == NULL) { 367 // BAlert *alert = new BAlert(NULL, strerror(err), "OK"); 368 // alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 369 // alert->Go(); 370 // } else { 371 // if (fConfigWindow != NULL) { 372 // if (fConfigWindow->Lock()) 373 // fConfigWindow->Quit(); 374 // } 375 // fConfigWindow = new Panel(rect, "Translator Settings", 376 // B_TITLED_WINDOW_LOOK, 377 // B_NORMAL_WINDOW_FEEL, 378 // B_NOT_ZOOMABLE | B_NOT_RESIZABLE); 379 // fConfigWindow->AddChild(view); 380 // // Just to make sure 381 // view->MoveTo(0, 0); 382 // view->ResizeTo(rect.Width(), rect.Height()); 383 // view->ResizeToPreferred(); 384 // fConfigWindow->MoveTo(100, 100); 385 // fConfigWindow->Show(); 386 // } 387 } 388 389 // _BuildMenu 390 void 391 SavePanel::_BuildMenu() 392 { 393 fFormatM = new BPopUpMenu(B_TRANSLATE("Format")); 394 395 fNativeMI = new SaveItem("Icon-O-Matic", 396 new BMessage(MSG_FORMAT), EXPORT_MODE_MESSAGE); 397 fFormatM->AddItem(fNativeMI); 398 fNativeMI->SetEnabled(false); 399 400 fFormatM->AddSeparatorItem(); 401 402 fHVIFMI = new SaveItem("HVIF", 403 new BMessage(MSG_FORMAT), EXPORT_MODE_FLAT_ICON); 404 fFormatM->AddItem(fHVIFMI); 405 406 fRDefMI = new SaveItem("HVIF RDef", 407 new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_RDEF); 408 fFormatM->AddItem(fRDefMI); 409 410 fSourceMI = new SaveItem(B_TRANSLATE("HVIF Source Code"), 411 new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_SOURCE); 412 fFormatM->AddItem(fSourceMI); 413 414 fFormatM->AddSeparatorItem(); 415 416 fSVGMI = new SaveItem("SVG", 417 new BMessage(MSG_FORMAT), EXPORT_MODE_SVG); 418 419 fFormatM->AddItem(fSVGMI); 420 421 fFormatM->AddSeparatorItem(); 422 423 fBitmap16MI = new SaveItem("PNG 16x16", 424 new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_16); 425 fFormatM->AddItem(fBitmap16MI); 426 427 fBitmap32MI = new SaveItem("PNG 32x32", 428 new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_32); 429 fFormatM->AddItem(fBitmap32MI); 430 431 fBitmap64MI = new SaveItem("PNG 64x64", 432 new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_64); 433 fFormatM->AddItem(fBitmap64MI); 434 435 fBitmapSetMI = new SaveItem(B_TRANSLATE("PNG Set"), 436 new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_SET); 437 fFormatM->AddItem(fBitmapSetMI); 438 439 fFormatM->AddSeparatorItem(); 440 441 fIconAttrMI = new SaveItem(B_TRANSLATE("BEOS:ICON Attribute"), 442 new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_ATTR); 443 fFormatM->AddItem(fIconAttrMI); 444 445 fIconMimeAttrMI = new SaveItem(B_TRANSLATE("META:ICON Attribute"), 446 new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_MIME_ATTR); 447 448 fFormatM->AddItem(fIconMimeAttrMI); 449 450 451 fFormatM->SetTargetForItems(this); 452 453 // pick the RDef item in the list 454 fRDefMI->SetMarked(true); 455 } 456 457 // _EnableSettings 458 void 459 SavePanel::_EnableSettings() const 460 { 461 // no settings currently necessary 462 fSettingsB->SetEnabled(false); 463 } 464 465