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