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