/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "SavePanel.h"
#include <stdio.h>
#include <string.h>
#include <Alert.h>
#include <Button.h>
#include <Catalog.h>
#include <Locale.h>
#include <MenuBar.h>
#include <MenuField.h>
#include <PopUpMenu.h>
#include <ScrollBar.h>
#include <TextControl.h>
#include <TranslationKit.h>
#include <View.h>
#include <Window.h>
#include "Exporter.h"
#include "IconEditorApp.h"
#include "Panel.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-SavePanel"
enum {
MSG_FORMAT = 'sfpf',
MSG_SETTINGS = 'sfps',
};
// SaveItem class
SaveItem::SaveItem(const char* name,
BMessage* message,
uint32 exportMode)
: BMenuItem(name, message),
fExportMode(exportMode)
{
}
// #pragma mark -
// SavePanel class
SavePanel::SavePanel(const char* name,
BMessenger* target,
entry_ref* startDirectory,
uint32 nodeFlavors,
bool allowMultipleSelection,
BMessage* message,
BRefFilter* filter,
bool modal,
bool hideWhenDone)
: BFilePanel(B_SAVE_PANEL, target, startDirectory,
nodeFlavors, allowMultipleSelection,
message, filter, modal, hideWhenDone),
BHandler(name),
fConfigWindow(NULL),
fFormatM(NULL),
fExportMode(EXPORT_MODE_ICON_RDEF)
{
BWindow* window = Window();
if (!window || !window->Lock())
return;
// add this instance as BHandler to the window's looper
window->AddHandler(this);
// find a couple of important views and mess with their layout
BView* background = Window()->ChildAt(0);
BButton* cancel = dynamic_cast<BButton*>(
background->FindView("cancel button"));
BView* textview = background->FindView("text view");
BScrollBar* hscrollbar = dynamic_cast<BScrollBar*>(
background->FindView("HScrollBar"));
if (!background || !cancel || !textview || !hscrollbar) {
printf("SavePanel::SavePanel() - couldn't find necessary controls.\n");
return;
}
_BuildMenu();
BRect rect = textview->Frame();
rect.top = cancel->Frame().top;
font_height fh;
be_plain_font->GetHeight(&fh);
rect.bottom = rect.top + fh.ascent + fh.descent + 5.0;
fFormatMF = new BMenuField(rect, "format popup", B_TRANSLATE("Format"),
fFormatM, true,
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_WILL_DRAW | B_NAVIGABLE);
fFormatMF->SetDivider(be_plain_font->StringWidth(
B_TRANSLATE("Format")) + 7);
fFormatMF->MenuBar()->ResizeToPreferred();
fFormatMF->ResizeToPreferred();
float height = fFormatMF->Bounds().Height() + 8.0;
// find all the views that are in the way and
// move up them up the height of the menu field
BView *poseview = background->FindView("PoseView");
if (poseview) poseview->ResizeBy(0, -height);
BButton *insert = (BButton *)background->FindView("default button");
if (hscrollbar) hscrollbar->MoveBy(0, -height);
BScrollBar *vscrollbar = (BScrollBar *)background->FindView("VScrollBar");
if (vscrollbar) vscrollbar->ResizeBy(0, -height);
BView *countvw = (BView *)background->FindView("CountVw");
if (countvw) countvw->MoveBy(0, -height);
textview->MoveBy(0, -height);
#if HAIKU_TARGET_PLATFORM_DANO
fFormatMF->MoveTo(textview->Frame().left, fFormatMF->Frame().top + 2);
#else
fFormatMF->MoveTo(textview->Frame().left, fFormatMF->Frame().top);
#endif
background->AddChild(fFormatMF);
// Build the "Settings" button relative to the format menu
rect = cancel->Frame();
rect.OffsetTo(fFormatMF->Frame().right + 5.0, rect.top);
fSettingsB = new BButton(rect, "settings",
B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
new BMessage(MSG_SETTINGS),
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_WILL_DRAW | B_NAVIGABLE);
fSettingsB->ResizeToPreferred();
background->AddChild(fSettingsB);
fSettingsB->SetTarget(this);
textview->ResizeTo(fSettingsB->Frame().right - fFormatMF->Frame().left,
textview->Frame().Height());
// Make sure the smallest window won't draw the "Settings" button over
// anything else
float minWindowWidth = textview->Bounds().Width()
+ cancel->Bounds().Width()
+ (insert ? insert->Bounds().Width() : 0.0)
+ 90;
Window()->SetSizeLimits(minWindowWidth, 10000, 250, 10000);
if (Window()->Bounds().IntegerWidth() + 1 < minWindowWidth)
Window()->ResizeTo(minWindowWidth, Window()->Bounds().Height());
// Init window title
SetExportMode(true);
window->Unlock();
}
// destructor
SavePanel::~SavePanel()
{
}
// SendMessage
void
SavePanel::SendMessage(const BMessenger* messenger, BMessage* message)
{
// add the current format information to the message,
// bot only if we are indeed in export mode
if (message && fFormatM->IsEnabled())
message->AddInt32("export mode", ExportMode());
// let the original file panel code handle the rest
BFilePanel::SendMessage(messenger, message);
}
// MessageReceived
void
SavePanel::MessageReceived(BMessage* message)
{
// Handle messages from controls we've added
switch (message->what) {
case MSG_FORMAT:
fExportMode = ExportMode();
AdjustExtension();
// TODO: make this behaviour a setting
_EnableSettings();
break;
case MSG_SETTINGS:
_ExportSettings();
break;
default:
BHandler::MessageReceived(message);
break;
}
}
// SetExportMode
void
SavePanel::SetExportMode(bool exportMode)
{
BWindow* window = Window();
if (!window || !window->Lock())
return;
// adjust window title and enable format menu
BString title("Icon-O-Matic: ");
if (exportMode) {
fFormatMF->SetEnabled(true);
SetExportMode(fExportMode);
_EnableSettings();
title << B_TRANSLATE_CONTEXT("Export icon", "Dialog title");
} else {
fExportMode = ExportMode();
// does not overwrite fExportMode in case we already were
// in native save mode
fNativeMI->SetMarked(true);
fFormatMF->SetEnabled(false);
fSettingsB->SetEnabled(false);
title << B_TRANSLATE_CONTEXT("Save icon", "Dialog title");
}
window->SetTitle(title);
window->Unlock();
}
// SetExportMode
void
SavePanel::SetExportMode(int32 mode)
{
BWindow* window = Window();
if (!window || !window->Lock())
return;
switch (mode) {
case EXPORT_MODE_MESSAGE:
fNativeMI->SetMarked(true);
break;
case EXPORT_MODE_FLAT_ICON:
fHVIFMI->SetMarked(true);
break;
case EXPORT_MODE_SVG:
fSVGMI->SetMarked(true);
break;
case EXPORT_MODE_BITMAP_16:
fBitmap16MI->SetMarked(true);
break;
case EXPORT_MODE_BITMAP_32:
fBitmap32MI->SetMarked(true);
break;
case EXPORT_MODE_BITMAP_64:
fBitmap64MI->SetMarked(true);
break;
case EXPORT_MODE_BITMAP_SET:
fBitmapSetMI->SetMarked(true);
break;
case EXPORT_MODE_ICON_ATTR:
fIconAttrMI->SetMarked(true);
break;
case EXPORT_MODE_ICON_MIME_ATTR:
fIconMimeAttrMI->SetMarked(true);
break;
case EXPORT_MODE_ICON_RDEF:
fRDefMI->SetMarked(true);
break;
case EXPORT_MODE_ICON_SOURCE:
fSourceMI->SetMarked(true);
break;
}
if (mode != EXPORT_MODE_MESSAGE)
fExportMode = mode;
fFormatMF->SetEnabled(mode != EXPORT_MODE_MESSAGE);
_EnableSettings();
window->Unlock();
}
// ExportMode
int32
SavePanel::ExportMode() const
{
int32 mode = fExportMode;
BWindow* window = Window();
if (!window || !window->Lock())
return mode;
if (fFormatMF->IsEnabled()) {
// means we are actually in export mode
SaveItem* item = _GetCurrentMenuItem();
mode = item->ExportMode();
}
window->Unlock();
return mode;
}
// AdjustExtension
void
SavePanel::AdjustExtension()
{
// if (!Window()->Lock())
// return;
//
// BView* background = Window()->ChildAt(0);
// BTextControl* textview = dynamic_cast<BTextControl*>(
// background->FindView("text view"));
//
// if (textview) {
//
// translator_id id = 0;
// uint32 format = 0;
// int32 mode = ExportMode();
// SaveItem* exportItem = dynamic_cast<SaveItem*>(_GetCurrentMenuItem());
// if (mode == EXPORT_TRANSLATOR && exportItem) {
// id = exportItem->id;
// format = exportItem->format;
// }
//
// Exporter* exporter = Exporter::ExporterFor(mode, id, format);
//
// if (exporter) {
// BString name(textview->Text());
//
// // adjust the name extension
// const char* extension = exporter->Extension();
// if (strlen(extension) > 0) {
// int32 cutPos = name.FindLast('.');
// int32 cutCount = name.Length() - cutPos;
// if (cutCount > 0 && cutCount <= 4) {
// name.Remove(cutPos, cutCount);
// }
// name << "." << extension;
// }
//
// SetSaveText(name.String());
// }
//
// delete exporter;
// }
// Window()->Unlock();
}
// _GetCurrentMenuItem
SaveItem*
SavePanel::_GetCurrentMenuItem() const
{
SaveItem* item = dynamic_cast<SaveItem*>(fFormatM->FindMarked());
if (!item)
return fNativeMI;
return item;
}
// _ExportSettings
void
SavePanel::_ExportSettings()
{
// SaveItem *item = dynamic_cast<SaveItem*>(_GetCurrentMenuItem());
// if (item == NULL)
// return;
//
// BTranslatorRoster *roster = BTranslatorRoster::Default();
// BView *view;
// BRect rect(0, 0, 239, 239);
//
// // Build a window around this translator's configuration view
// status_t err = roster->MakeConfigurationView(item->id, NULL, &view, &rect);
// if (err < B_OK || view == NULL) {
// BAlert *alert = new BAlert(NULL, strerror(err), "OK");
// alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
// alert->Go();
// } else {
// if (fConfigWindow != NULL) {
// if (fConfigWindow->Lock())
// fConfigWindow->Quit();
// }
// fConfigWindow = new Panel(rect, "Translator Settings",
// B_TITLED_WINDOW_LOOK,
// B_NORMAL_WINDOW_FEEL,
// B_NOT_ZOOMABLE | B_NOT_RESIZABLE);
// fConfigWindow->AddChild(view);
// // Just to make sure
// view->MoveTo(0, 0);
// view->ResizeTo(rect.Width(), rect.Height());
// view->ResizeToPreferred();
// fConfigWindow->MoveTo(100, 100);
// fConfigWindow->Show();
// }
}
// _BuildMenu
void
SavePanel::_BuildMenu()
{
fFormatM = new BPopUpMenu(B_TRANSLATE("Format"));
fNativeMI = new SaveItem("Icon-O-Matic",
new BMessage(MSG_FORMAT), EXPORT_MODE_MESSAGE);
fFormatM->AddItem(fNativeMI);
fNativeMI->SetEnabled(false);
fFormatM->AddSeparatorItem();
fHVIFMI = new SaveItem("HVIF",
new BMessage(MSG_FORMAT), EXPORT_MODE_FLAT_ICON);
fFormatM->AddItem(fHVIFMI);
fRDefMI = new SaveItem("HVIF RDef",
new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_RDEF);
fFormatM->AddItem(fRDefMI);
fSourceMI = new SaveItem(B_TRANSLATE("HVIF Source Code"),
new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_SOURCE);
fFormatM->AddItem(fSourceMI);
fFormatM->AddSeparatorItem();
fSVGMI = new SaveItem("SVG",
new BMessage(MSG_FORMAT), EXPORT_MODE_SVG);
fFormatM->AddItem(fSVGMI);
fFormatM->AddSeparatorItem();
fBitmap16MI = new SaveItem("PNG 16x16",
new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_16);
fFormatM->AddItem(fBitmap16MI);
fBitmap32MI = new SaveItem("PNG 32x32",
new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_32);
fFormatM->AddItem(fBitmap32MI);
fBitmap64MI = new SaveItem("PNG 64x64",
new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_64);
fFormatM->AddItem(fBitmap64MI);
fBitmapSetMI = new SaveItem(B_TRANSLATE("PNG Set"),
new BMessage(MSG_FORMAT), EXPORT_MODE_BITMAP_SET);
fFormatM->AddItem(fBitmapSetMI);
fFormatM->AddSeparatorItem();
fIconAttrMI = new SaveItem(B_TRANSLATE("BEOS:ICON Attribute"),
new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_ATTR);
fFormatM->AddItem(fIconAttrMI);
fIconMimeAttrMI = new SaveItem(B_TRANSLATE("META:ICON Attribute"),
new BMessage(MSG_FORMAT), EXPORT_MODE_ICON_MIME_ATTR);
fFormatM->AddItem(fIconMimeAttrMI);
fFormatM->SetTargetForItems(this);
// pick the RDef item in the list
fRDefMI->SetMarked(true);
}
// _EnableSettings
void
SavePanel::_EnableSettings() const
{
// no settings currently necessary
fSettingsB->SetEnabled(false);
}
↑ V595 The 'background' pointer was utilized before it was verified against nullptr. Check lines: 80, 85.