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 36enum { 37 MSG_FORMAT = 'sfpf', 38 MSG_SETTINGS = 'sfps', 39}; 40 41// SaveItem class 42SaveItem::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 53SavePanel::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 162SavePanel::~SavePanel() 163{ 164} 165 166// SendMessage 167void 168SavePanel::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 179void 180SavePanel::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 200void 201SavePanel::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 231void 232SavePanel::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 284int32 285SavePanel::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 303void 304SavePanel::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 349SaveItem* 350SavePanel::_GetCurrentMenuItem() const 351{ 352 SaveItem* item = dynamic_cast<SaveItem*>(fFormatM->FindMarked()); 353 if (!item) 354 return fNativeMI; 355 return item; 356} 357 358// _ExportSettings 359void 360SavePanel::_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 396void 397SavePanel::_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 464void 465SavePanel::_EnableSettings() const 466{ 467 // no settings currently necessary 468 fSettingsB->SetEnabled(false); 469} 470 471