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 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 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(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 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 285 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 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* 350 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 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 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 465 SavePanel::_EnableSettings() const 466 { 467 // no settings currently necessary 468 fSettingsB->SetEnabled(false); 469 } 470 471