big clean up of Save and Export stuff:

* implemented SavePanel that let's you chose the Export format
* introduced DocumentSaver class and several implementations
* Document no longer remembers any entry_refs, but a native
  and export document saver, for other export formats than
  HVIF, it is no longer necessary to go through the file panel,
  simply invoking Export will do
* this makes it much easier to have a custom saver that sends
  a message with an HVIF icon to another app instead of saving
  to a file
* cleaned up File menu
* last used export format is persistent


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19307 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2006-11-17 01:37:36 +00:00
parent 6cc8eecf5e
commit 774831e7c2
19 changed files with 948 additions and 181 deletions

View File

@ -20,8 +20,10 @@
#include "support_settings.h"
#include "AttributeSaver.h"
#include "AutoLocker.h"
#include "BitmapExporter.h"
#include "BitmapSetSaver.h"
#include "CommandStack.h"
#include "Document.h"
#include "FlatIconExporter.h"
@ -33,7 +35,9 @@
#include "MessageImporter.h"
#include "PathContainer.h"
#include "RDefExporter.h"
#include "SavePanel.h"
#include "ShapeContainer.h"
#include "SimpleFileSaver.h"
#include "SVGExporter.h"
#include "SVGImporter.h"
@ -107,28 +111,20 @@ IconEditorApp::MessageReceived(BMessage* message)
}
case MSG_SAVE:
case MSG_EXPORT: {
const entry_ref* ref;
DocumentSaver* saver;
if (message->what == MSG_SAVE)
ref = fDocument->Ref();
saver = fDocument->NativeSaver();
else
ref = fDocument->ExportRef();
if (ref) {
_Save(*ref, message->what == MSG_EXPORT ?
EXPORT_MODE_FLAT_ICON :
EXPORT_MODE_MESSAGE);
saver = fDocument->ExportSaver();
if (saver) {
saver->Save(fDocument);
break;
} // else fall through
}
case MSG_SAVE_AS:
case MSG_EXPORT_AS:
case MSG_EXPORT_BITMAP:
case MSG_EXPORT_BITMAP_SET:
case MSG_EXPORT_SVG:
case MSG_EXPORT_ICON_ATTRIBUTE:
case MSG_EXPORT_ICON_MIME_ATTRIBUTE:
case MSG_EXPORT_ICON_RDEF: {
uint32 exportMode;
if (message->FindInt32("mode", (int32*)&exportMode) < B_OK)
case MSG_EXPORT_AS: {
int32 exportMode;
if (message->FindInt32("export mode", &exportMode) < B_OK)
exportMode = EXPORT_MODE_MESSAGE;
entry_ref ref;
const char* name;
@ -141,49 +137,34 @@ IconEditorApp::MessageReceived(BMessage* message)
&& entry.SetTo(&dir, name, true) >= B_OK
&& entry.GetRef(&ref) >= B_OK) {
_Save(ref, exportMode);
// create the document saver and remember it for later
DocumentSaver* saver = _CreateSaver(ref, exportMode);
if (saver) {
if (exportMode == EXPORT_MODE_MESSAGE)
fDocument->SetNativeSaver(saver);
else
fDocument->SetExportSaver(saver);
saver->Save(fDocument);
}
}
_SyncPanels(fSavePanel, fOpenPanel);
} else {
// configure the file panel
const char* saveText = NULL;
if (fDocument->Ref())
saveText = fDocument->Ref()->name;
FileSaver* saver = dynamic_cast<FileSaver*>(
fDocument->NativeSaver());
switch (message->what) {
case MSG_EXPORT_AS:
case MSG_EXPORT:
exportMode = EXPORT_MODE_FLAT_ICON;
if (fDocument->ExportRef())
saveText = fDocument->ExportRef()->name;
break;
case MSG_EXPORT_BITMAP:
exportMode = EXPORT_MODE_BITMAP;
break;
case MSG_EXPORT_BITMAP_SET:
exportMode = EXPORT_MODE_BITMAP_SET;
break;
case MSG_EXPORT_SVG:
exportMode = EXPORT_MODE_SVG;
break;
case MSG_EXPORT_ICON_ATTRIBUTE:
exportMode = EXPORT_MODE_ICON_ATTR;
break;
case MSG_EXPORT_ICON_MIME_ATTRIBUTE:
exportMode = EXPORT_MODE_ICON_MIME_ATTR;
break;
case MSG_EXPORT_ICON_RDEF:
exportMode = EXPORT_MODE_ICON_RDEF;
break;
case MSG_SAVE_AS:
case MSG_SAVE:
default:
exportMode = EXPORT_MODE_MESSAGE;
break;
bool exportMode = message->what == MSG_EXPORT_AS
|| message->what == MSG_EXPORT;
if (exportMode) {
saver = dynamic_cast<FileSaver*>(
fDocument->ExportSaver());
}
BMessage fpMessage(MSG_SAVE_AS);
fpMessage.AddInt32("mode", exportMode);
fSavePanel->SetMessage(&fpMessage);
if (saver)
saveText = saver->Ref()->name;
fSavePanel->SetExportMode(exportMode);
// fSavePanel->Refresh();
if (saveText)
fSavePanel->SetSaveText(saveText);
@ -211,14 +192,14 @@ IconEditorApp::ReadyToRun()
true,
new BMessage(B_REFS_RECEIVED));
fSavePanel = new BFilePanel(B_SAVE_PANEL,
&messenger,
fSavePanel = new SavePanel("save panel",
&messenger,
NULL,
B_FILE_NODE
| B_DIRECTORY_NODE
| B_SYMLINK_NODE,
false,
new BMessage(MSG_SAVE));
new BMessage(MSG_SAVE_AS));
// create main window
fMainWindow = new MainWindow(this, fDocument);
@ -297,7 +278,8 @@ IconEditorApp::_Open(const entry_ref& ref, bool append)
enum {
REF_NONE = 0,
REF_MESSAGE,
REF_FLAT
REF_FLAT,
REF_SVG
};
uint32 refMode = REF_NONE;
@ -316,6 +298,8 @@ IconEditorApp::_Open(const entry_ref& ref, bool append)
file.Seek(0, SEEK_SET);
SVGImporter svgImporter;
ret = svgImporter.Import(icon, &ref);
if (ret >= B_OK)
refMode = REF_SVG;
}
}
@ -342,35 +326,24 @@ IconEditorApp::_Open(const entry_ref& ref, bool append)
// incorporate the loaded icon into the document
// (either replace it or append to it)
if (append) {
// preserve the entry_refs
entry_ref saveRef;
if (fDocument->Ref())
saveRef = *fDocument->Ref();
entry_ref exportRef;
if (fDocument->ExportRef())
exportRef = *fDocument->ExportRef();
fDocument->MakeEmpty();
fDocument->SetIcon(icon);
// restore refs after "append"
if (saveRef.name)
fDocument->SetRef(saveRef);
if (exportRef.name)
fDocument->SetExportRef(exportRef);
} else {
fDocument->MakeEmpty();
fDocument->SetIcon(icon);
fDocument->MakeEmpty(!append);
// if append, the document savers are preserved
fDocument->SetIcon(icon);
if (!append) {
// document got replaced, but we have at
// least one ref already
switch (refMode) {
case REF_MESSAGE:
fDocument->SetRef(ref);
fDocument->SetNativeSaver(
new SimpleFileSaver(new MessageExporter(), ref));
break;
case REF_FLAT:
fDocument->SetExportRef(ref);
fDocument->SetExportSaver(
new SimpleFileSaver(new FlatIconExporter(), ref));
break;
case REF_SVG:
fDocument->SetExportSaver(
new SimpleFileSaver(new SVGExporter(), ref));
break;
}
}
@ -385,74 +358,49 @@ IconEditorApp::_Open(const entry_ref& ref, bool append)
}
}
// _Save
void
IconEditorApp::_Save(const entry_ref& ref, uint32 exportMode)
// _CreateSaver
DocumentSaver*
IconEditorApp::_CreateSaver(const entry_ref& ref, uint32 exportMode)
{
Exporter* exporter;
DocumentSaver* saver;
switch (exportMode) {
case EXPORT_MODE_FLAT_ICON:
exporter = new FlatIconExporter();
fDocument->SetExportRef(ref);
saver = new SimpleFileSaver(new FlatIconExporter(), ref);
break;
case EXPORT_MODE_ICON_ATTR:
case EXPORT_MODE_ICON_MIME_ATTR: {
BNode node(&ref);
FlatIconExporter iconExporter;
const char* attrName
= exportMode == EXPORT_MODE_ICON_ATTR ?
kVectorAttrNodeName : kVectorAttrMimeName;
iconExporter.Export(fDocument->Icon(), &node, attrName);
return;
saver = new AttributeSaver(ref, attrName);
break;
}
case EXPORT_MODE_ICON_RDEF:
exporter = new RDefExporter();
saver = new SimpleFileSaver(new RDefExporter(), ref);
break;
case EXPORT_MODE_BITMAP:
exporter = new BitmapExporter(64);
saver = new SimpleFileSaver(new BitmapExporter(64), ref);
break;
case EXPORT_MODE_BITMAP_SET: {
entry_ref smallRef(ref);
// 64x64
char name[B_OS_NAME_LENGTH];
sprintf(name, "%s_64.png", ref.name);
smallRef.set_name(name);
exporter = new BitmapExporter(64);
exporter->SetSelfDestroy(true);
exporter->Export(fDocument, smallRef);
// 16x16
sprintf(name, "%s_16.png", ref.name);
smallRef.set_name(name);
Exporter* smallExporter = new BitmapExporter(16);
smallExporter->SetSelfDestroy(true);
smallExporter->Export(fDocument, smallRef);
// 32x32
sprintf(name, "%s_32.png", ref.name);
smallRef.set_name(name);
smallExporter = new BitmapExporter(32);
smallExporter->SetSelfDestroy(true);
smallExporter->Export(fDocument, smallRef);
return;
}
case EXPORT_MODE_BITMAP_SET:
saver = new BitmapSetSaver(ref);
break;
case EXPORT_MODE_SVG:
exporter = new SVGExporter();
saver = new SimpleFileSaver(new SVGExporter(), ref);
break;
case EXPORT_MODE_MESSAGE:
default:
exporter = new MessageExporter();
fDocument->SetRef(ref);
saver = new SimpleFileSaver(new MessageExporter(), ref);
break;
}
exporter->SetSelfDestroy(true);
// we don't wait for the export thread to finish here
exporter->Export(fDocument, ref);
return saver;
}
// _SyncPanels
@ -523,6 +471,9 @@ IconEditorApp::_StoreSettings()
fMainWindow->StoreSettings(&settings);
if (settings.ReplaceInt32("export mode", fSavePanel->ExportMode()) < B_OK)
settings.AddInt32("export mode", fSavePanel->ExportMode());
save_settings(&settings, "Icon-O-Matic");
}
@ -533,6 +484,10 @@ IconEditorApp::_RestoreSettings()
BMessage settings('stns');
load_settings(&settings, "Icon-O-Matic");
int32 mode;
if (settings.FindInt32("export mode", &mode) >= B_OK)
fSavePanel->SetExportMode(mode);
fMainWindow->RestoreSettings(&settings);
}

View File

@ -14,7 +14,9 @@
class BFilePanel;
class Document;
class DocumentSaver;
class MainWindow;
class SavePanel;
enum {
MSG_NEW = 'newi',
@ -27,16 +29,6 @@ enum {
MSG_EXPORT = 'xprt',
MSG_EXPORT_AS = 'xpas',
// TODO: remove once export format can be chosen
MSG_EXPORT_BITMAP = 'xpbm',
MSG_EXPORT_BITMAP_SET = 'xpbs',
MSG_EXPORT_SVG = 'xpsv',
MSG_EXPORT_ICON_ATTRIBUTE = 'xpia',
MSG_EXPORT_ICON_MIME_ATTRIBUTE = 'xpma',
MSG_EXPORT_ICON_RDEF = 'xprd',
};
enum {
@ -74,8 +66,8 @@ class IconEditorApp : public BApplication {
void _MakeIconEmpty();
void _Open(const entry_ref& ref,
bool append = false);
void _Save(const entry_ref& ref,
uint32 exportMode);
DocumentSaver* _CreateSaver(const entry_ref& ref,
uint32 exportMode);
void _SyncPanels(BFilePanel* from,
BFilePanel* to);
@ -89,7 +81,7 @@ class IconEditorApp : public BApplication {
Document* fDocument;
BFilePanel* fOpenPanel;
BFilePanel* fSavePanel;
SavePanel* fSavePanel;
BString fLastOpenPath;
BString fLastSavePath;

View File

@ -28,6 +28,7 @@ for iconSourceDir in $(iconSourceDirs) {
# source directories
local sourceDirs =
document
document/savers
generic
generic/command
generic/gui
@ -109,6 +110,13 @@ Application Icon-O-Matic :
IconObject.cpp
SetPropertiesCommand.cpp
# document/savers
AttributeSaver.cpp
BitmapSetSaver.cpp
DocumentSaver.cpp
FileSaver.cpp
SimpleFileSaver.cpp
# generic/command
Command.cpp
CommandStack.cpp
@ -194,6 +202,7 @@ Application Icon-O-Matic :
GradientControl.cpp
IconObjectListView.cpp
PathListView.cpp
SavePanel.cpp
ShapeListView.cpp
StyleListView.cpp
StyleView.cpp

View File

@ -972,26 +972,12 @@ MainWindow::_CreateMenuBar(BRect frame)
new BMessage(MSG_SAVE_AS),
'S', B_SHIFT_KEY));
fileMenu->AddSeparatorItem();
fileMenu->AddItem(new BMenuItem("Export Flat",
fileMenu->AddItem(new BMenuItem("Export",
new BMessage(MSG_EXPORT),
'E'));
fileMenu->AddItem(new BMenuItem("Export Flat As",
fileMenu->AddItem(new BMenuItem("Export As",
new BMessage(MSG_EXPORT_AS),
'E', B_SHIFT_KEY));
fileMenu->AddItem(new BMenuItem("Export RDef As",
new BMessage(MSG_EXPORT_ICON_RDEF)));
fileMenu->AddItem(new BMenuItem("Export SVG As",
new BMessage(MSG_EXPORT_SVG)));
fileMenu->AddSeparatorItem();
fileMenu->AddItem(new BMenuItem("Export Bitmap As",
new BMessage(MSG_EXPORT_BITMAP)));
fileMenu->AddItem(new BMenuItem("Export Bitmap Set As",
new BMessage(MSG_EXPORT_BITMAP_SET)));
fileMenu->AddSeparatorItem();
fileMenu->AddItem(new BMenuItem("Export Icon Attribute",
new BMessage(MSG_EXPORT_ICON_ATTRIBUTE)));
fileMenu->AddItem(new BMenuItem("Export Icon Mime Attribute",
new BMessage(MSG_EXPORT_ICON_MIME_ATTRIBUTE)));
fileMenu->AddSeparatorItem();
fileMenu->AddItem(new BMenuItem("Quit",
new BMessage(B_QUIT_REQUESTED),

View File

@ -14,6 +14,7 @@
#include <Entry.h>
#include "CommandStack.h"
#include "DocumentSaver.h"
#include "Icon.h"
#include "Selection.h"
@ -27,8 +28,9 @@ Document::Document(const char* name)
fSelection(new (nothrow) ::Selection()),
fName(name),
fRef(NULL),
fExportRef(NULL)
fNativeSaver(NULL),
fExportSaver(NULL)
{
}
@ -38,8 +40,8 @@ Document::~Document()
delete fCommandStack;
delete fSelection;
fIcon->Release();
delete fRef;
delete fExportRef;
delete fNativeSaver;
delete fExportSaver;
}
// SetName
@ -60,24 +62,20 @@ Document::Name() const
return fName.String();
}
// SetRef
// SetNativeSaver
void
Document::SetRef(const entry_ref& ref)
Document::SetNativeSaver(::DocumentSaver* saver)
{
if (!fRef)
fRef = new (nothrow) entry_ref(ref);
else
*fRef = ref;
delete fNativeSaver;
fNativeSaver = saver;
}
// SetExportRef
// SetExportSaver
void
Document::SetExportRef(const entry_ref& ref)
Document::SetExportSaver(::DocumentSaver* saver)
{
if (!fExportRef)
fExportRef = new (nothrow) entry_ref(ref);
else
*fExportRef = ref;
delete fExportSaver;
fExportSaver = saver;
}
// SetIcon
@ -96,16 +94,18 @@ Document::SetIcon(::Icon* icon)
// MakeEmpty
void
Document::MakeEmpty()
Document::MakeEmpty(bool includingSavers)
{
fCommandStack->Clear();
fSelection->DeselectAll();
fIcon->MakeEmpty();
delete fRef;
fRef = NULL;
delete fExportRef;
fExportRef = NULL;
if (includingSavers) {
delete fNativeSaver;
fNativeSaver = NULL;
delete fExportSaver;
fExportSaver = NULL;
}
}

View File

@ -17,6 +17,7 @@
struct entry_ref;
class CommandStack;
class DocumentSaver;
class Icon;
class Selection;
@ -35,18 +36,19 @@ class Document : public RWLocker,
void SetName(const char* name);
const char* Name() const;
void SetRef(const entry_ref& ref);
inline const entry_ref* Ref() const
{ return fRef; }
void SetExportRef(const entry_ref& ref);
inline const entry_ref* ExportRef() const
{ return fExportRef; }
void SetNativeSaver(::DocumentSaver* saver);
inline ::DocumentSaver* NativeSaver() const
{ return fNativeSaver; }
void SetExportSaver(::DocumentSaver* saver);
inline ::DocumentSaver* ExportSaver() const
{ return fExportSaver; }
void SetIcon(::Icon* icon);
inline ::Icon* Icon() const
{ return fIcon; }
void MakeEmpty();
void MakeEmpty(bool includingSavers = true);
private:
::Icon* fIcon;
@ -54,8 +56,9 @@ class Document : public RWLocker,
::Selection* fSelection;
BString fName;
entry_ref* fRef;
entry_ref* fExportRef;
::DocumentSaver* fNativeSaver;
::DocumentSaver* fExportSaver;
};
#endif // DOCUMENT_H

View File

@ -0,0 +1,36 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "AttributeSaver.h"
#include <Node.h>
#include "Document.h"
#include "FlatIconExporter.h"
// constructor
AttributeSaver::AttributeSaver(const entry_ref& ref, const char* attrName)
: fRef(ref),
fAttrName(attrName)
{
}
// destructor
AttributeSaver::~AttributeSaver()
{
}
// Save
status_t
AttributeSaver::Save(Document* document)
{
BNode node(&fRef);
FlatIconExporter iconExporter;
return iconExporter.Export(document->Icon(), &node, fAttrName.String());
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef ATTRIBUTE_SAVER_H
#define ATTRIBUTE_SAVER_H
#include <Entry.h>
#include <String.h>
#include "DocumentSaver.h"
class AttributeSaver : public DocumentSaver {
public:
AttributeSaver(const entry_ref& ref,
const char* attrName);
virtual ~AttributeSaver();
virtual status_t Save(Document* document);
protected:
entry_ref fRef;
BString fAttrName;
};
#endif // ATTRIBUTE_SAVER_H

View File

@ -0,0 +1,56 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "BitmapSetSaver.h"
#include <stdio.h>
#include "BitmapExporter.h"
// constructor
BitmapSetSaver::BitmapSetSaver(const entry_ref& ref)
: FileSaver(ref)
{
}
// destructor
BitmapSetSaver::~BitmapSetSaver()
{
}
// Save
status_t
BitmapSetSaver::Save(Document* document)
{
entry_ref actualRef(fRef);
char name[B_OS_NAME_LENGTH];
// 64x64
sprintf(name, "%s_64.png", fRef.name);
actualRef.set_name(name);
Exporter* exporter = new BitmapExporter(64);
exporter->SetSelfDestroy(true);
exporter->Export(document, actualRef);
// 16x16
sprintf(name, "%s_16.png", fRef.name);
actualRef.set_name(name);
exporter = new BitmapExporter(16);
exporter->SetSelfDestroy(true);
exporter->Export(document, actualRef);
// 32x32
sprintf(name, "%s_32.png", fRef.name);
actualRef.set_name(name);
exporter = new BitmapExporter(32);
exporter->SetSelfDestroy(true);
exporter->Export(document, actualRef);
return B_OK;
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef BITMAP_SET_SAVER_H
#define BITMAP_SET_SAVER_H
#include "FileSaver.h"
class BitmapSetSaver : public FileSaver {
public:
BitmapSetSaver(const entry_ref& ref);
virtual ~BitmapSetSaver();
virtual status_t Save(Document* document);
};
#endif // BITMAP_SET_SAVER_H

View File

@ -0,0 +1,19 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "DocumentSaver.h"
// constructor
DocumentSaver::DocumentSaver()
{
}
// destructor
DocumentSaver::~DocumentSaver()
{
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef DOCUMENT_SAVER_H
#define DOCUMENT_SAVER_H
#include <SupportDefs.h>
class Document;
class DocumentSaver {
public:
DocumentSaver();
virtual ~DocumentSaver();
virtual status_t Save(Document* document) = 0;
};
#endif // DOCUMENT_SAVER_H

View File

@ -0,0 +1,28 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "FileSaver.h"
// constructor
FileSaver::FileSaver(const entry_ref& ref)
: fRef(ref)
{
}
// destructor
FileSaver::~FileSaver()
{
}
// SetRef
void
FileSaver::SetRef(const entry_ref& ref)
{
fRef = ref;
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef FILE_SAVER_H
#define FILE_SAVER_H
#include <Entry.h>
#include "DocumentSaver.h"
class FileSaver : public DocumentSaver {
public:
FileSaver(const entry_ref& ref);
virtual ~FileSaver();
void SetRef(const entry_ref& ref);
const entry_ref* Ref() const
{ return &fRef; }
protected:
entry_ref fRef;
};
#endif // FILE_SAVER_H

View File

@ -0,0 +1,34 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#include "SimpleFileSaver.h"
#include "Exporter.h"
// constructor
SimpleFileSaver::SimpleFileSaver(Exporter* exporter,
const entry_ref& ref)
: FileSaver(ref),
fExporter(exporter)
{
fExporter->SetSelfDestroy(false);
}
// destructor
SimpleFileSaver::~SimpleFileSaver()
{
delete fExporter;
}
// Save
status_t
SimpleFileSaver::Save(Document* document)
{
return fExporter->Export(document, fRef);
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2006, Haiku. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef SIMPLE_FILE_SAVER_H
#define SIMPLE_FILE_SAVER_H
#include "FileSaver.h"
class Exporter;
class SimpleFileSaver : public FileSaver {
public:
SimpleFileSaver(Exporter* exporter,
const entry_ref& ref);
virtual ~SimpleFileSaver();
virtual status_t Save(Document* document);
private:
Exporter* fExporter;
};
#endif // SIMPLE_FILE_SAVER_H

View File

@ -0,0 +1,429 @@
/*
* 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 <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"
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;
window->SetTitle("Save Image");
// 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", "Format", fFormatM, true,
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM,
B_WILL_DRAW | B_NAVIGABLE);
fFormatMF->SetDivider(be_plain_font->StringWidth("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", "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());
window->Unlock();
}
// destructor
SavePanel::~SavePanel()
{
}
// SendMessage
void
SavePanel::SendMessage(const BMessenger* messenger, BMessage* message)
{
// add the current translator information to the message
if (message) {
int32 mode = ExportMode();
message->AddInt32("export mode", mode);
}
// 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:
// TODO: make this behaviour a setting
AdjustExtension();
_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 helper("Icon-O-Matic: ");
if (exportMode) {
fFormatMF->SetEnabled(true);
SetExportMode(fExportMode);
_EnableSettings();
helper << "Export Icon";
} 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);
helper << "Save Icon";
}
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:
fBitmapMI->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;
}
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->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("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);
fFormatM->AddSeparatorItem();
fSVGMI = new SaveItem("SVG", new BMessage(MSG_FORMAT),
EXPORT_MODE_SVG);
fFormatM->AddItem(fSVGMI);
fFormatM->AddSeparatorItem();
fBitmapMI = new SaveItem("PNG", new BMessage(MSG_FORMAT),
EXPORT_MODE_BITMAP);
fFormatM->AddItem(fBitmapMI);
fBitmapSetMI = new SaveItem("PNG Set", new BMessage(MSG_FORMAT),
EXPORT_MODE_BITMAP_SET);
fFormatM->AddItem(fBitmapSetMI);
fFormatM->AddSeparatorItem();
fIconAttrMI = new SaveItem("BEOS:ICON Attribute", new BMessage(MSG_FORMAT),
EXPORT_MODE_ICON_ATTR);
fFormatM->AddItem(fIconAttrMI);
fIconMimeAttrMI = new SaveItem("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);
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef EXPORT_SAVE_PANEL_H
#define EXPORT_SAVE_PANEL_H
#include <FilePanel.h>
#include <MenuItem.h>
#include <TranslationDefs.h>
#include <String.h>
class BButton;
class BMenuField;
class BPopUpMenu;
class BWindow;
class SaveItem : public BMenuItem {
public:
SaveItem(const char* name,
BMessage* message,
uint32 exportMode);
uint32 ExportMode() const
{ return fExportMode; }
private:
uint32 fExportMode;
};
class SavePanel : public BFilePanel,
public BHandler {
public:
SavePanel(const char* name,
BMessenger* target = NULL,
entry_ref* startDirectory = NULL,
uint32 nodeFlavors = 0,
bool allowMultipleSelection = true,
BMessage* message = NULL,
BRefFilter *filter = NULL,
bool modal = false,
bool hideWhenDone = true);
virtual ~SavePanel();
// BFilePanel
virtual void SendMessage(const BMessenger* messenger,
BMessage* message);
// BHandler
virtual void MessageReceived(BMessage* message);
// SavePanel
// setting and retrieving settings
void SetExportMode(bool exportMode);
void SetExportMode(int32 mode);
int32 ExportMode() const;
void AdjustExtension();
private:
SaveItem* _GetCurrentMenuItem() const;
void _BuildMenu();
void _ExportSettings();
void _EnableSettings() const;
BWindow* fConfigWindow;
BPopUpMenu* fFormatM;
BMenuField* fFormatMF;
BButton* fSettingsB;
SaveItem* fNativeMI;
SaveItem* fHVIFMI;
SaveItem* fRDefMI;
SaveItem* fSVGMI;
SaveItem* fBitmapMI;
SaveItem* fBitmapSetMI;
SaveItem* fIconAttrMI;
SaveItem* fIconMimeAttrMI;
int32 fExportMode;
};
#endif // EXPORT_SAVE_PANEL_H

View File

@ -235,8 +235,8 @@ FlatIconExporter::_WriteStyles(LittleEndianBuffer& buffer,
if (styleType == STYLE_TYPE_SOLID_COLOR) {
// solid color
uint32 color = *(uint32*)&style->Color();
if (!buffer.Write(color))
rgb_color color = style->Color();
if (!buffer.Write(*(uint32*)&color))
return B_NO_MEMORY;
} else if (styleType == STYLE_TYPE_SOLID_COLOR_NO_ALPHA) {
// solid color without alpha