From 774831e7c242f07168f07e1d804d93fe63687702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Fri, 17 Nov 2006 01:37:36 +0000 Subject: [PATCH] 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 --- src/apps/icon-o-matic/IconEditorApp.cpp | 195 +++----- src/apps/icon-o-matic/IconEditorApp.h | 18 +- src/apps/icon-o-matic/Jamfile | 9 + src/apps/icon-o-matic/MainWindow.cpp | 18 +- src/apps/icon-o-matic/document/Document.cpp | 42 +- src/apps/icon-o-matic/document/Document.h | 21 +- .../document/savers/AttributeSaver.cpp | 36 ++ .../document/savers/AttributeSaver.h | 30 ++ .../document/savers/BitmapSetSaver.cpp | 56 +++ .../document/savers/BitmapSetSaver.h | 22 + .../document/savers/DocumentSaver.cpp | 19 + .../document/savers/DocumentSaver.h | 24 + .../document/savers/FileSaver.cpp | 28 ++ .../icon-o-matic/document/savers/FileSaver.h | 29 ++ .../document/savers/SimpleFileSaver.cpp | 34 ++ .../document/savers/SimpleFileSaver.h | 28 ++ src/apps/icon-o-matic/gui/SavePanel.cpp | 429 ++++++++++++++++++ src/apps/icon-o-matic/gui/SavePanel.h | 87 ++++ .../flat_icon/FlatIconExporter.cpp | 4 +- 19 files changed, 948 insertions(+), 181 deletions(-) create mode 100644 src/apps/icon-o-matic/document/savers/AttributeSaver.cpp create mode 100644 src/apps/icon-o-matic/document/savers/AttributeSaver.h create mode 100644 src/apps/icon-o-matic/document/savers/BitmapSetSaver.cpp create mode 100644 src/apps/icon-o-matic/document/savers/BitmapSetSaver.h create mode 100644 src/apps/icon-o-matic/document/savers/DocumentSaver.cpp create mode 100644 src/apps/icon-o-matic/document/savers/DocumentSaver.h create mode 100644 src/apps/icon-o-matic/document/savers/FileSaver.cpp create mode 100644 src/apps/icon-o-matic/document/savers/FileSaver.h create mode 100644 src/apps/icon-o-matic/document/savers/SimpleFileSaver.cpp create mode 100644 src/apps/icon-o-matic/document/savers/SimpleFileSaver.h create mode 100644 src/apps/icon-o-matic/gui/SavePanel.cpp create mode 100644 src/apps/icon-o-matic/gui/SavePanel.h diff --git a/src/apps/icon-o-matic/IconEditorApp.cpp b/src/apps/icon-o-matic/IconEditorApp.cpp index 24d6e8e44b..befa81e946 100644 --- a/src/apps/icon-o-matic/IconEditorApp.cpp +++ b/src/apps/icon-o-matic/IconEditorApp.cpp @@ -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( + 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( + 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); } diff --git a/src/apps/icon-o-matic/IconEditorApp.h b/src/apps/icon-o-matic/IconEditorApp.h index 79f49d28a2..7ab9e0482b 100644 --- a/src/apps/icon-o-matic/IconEditorApp.h +++ b/src/apps/icon-o-matic/IconEditorApp.h @@ -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; diff --git a/src/apps/icon-o-matic/Jamfile b/src/apps/icon-o-matic/Jamfile index 04c48ef2f6..d01748d6ac 100644 --- a/src/apps/icon-o-matic/Jamfile +++ b/src/apps/icon-o-matic/Jamfile @@ -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 diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index 843f27a903..a93acd681b 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -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), diff --git a/src/apps/icon-o-matic/document/Document.cpp b/src/apps/icon-o-matic/document/Document.cpp index d8e5bededf..c6263d7b3c 100644 --- a/src/apps/icon-o-matic/document/Document.cpp +++ b/src/apps/icon-o-matic/document/Document.cpp @@ -14,6 +14,7 @@ #include #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; + } } diff --git a/src/apps/icon-o-matic/document/Document.h b/src/apps/icon-o-matic/document/Document.h index cd355ff4a3..72c14127b9 100644 --- a/src/apps/icon-o-matic/document/Document.h +++ b/src/apps/icon-o-matic/document/Document.h @@ -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 diff --git a/src/apps/icon-o-matic/document/savers/AttributeSaver.cpp b/src/apps/icon-o-matic/document/savers/AttributeSaver.cpp new file mode 100644 index 0000000000..1cd32bf2d9 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/AttributeSaver.cpp @@ -0,0 +1,36 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "AttributeSaver.h" + +#include + +#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()); +} + diff --git a/src/apps/icon-o-matic/document/savers/AttributeSaver.h b/src/apps/icon-o-matic/document/savers/AttributeSaver.h new file mode 100644 index 0000000000..98a3bb2b2e --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/AttributeSaver.h @@ -0,0 +1,30 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef ATTRIBUTE_SAVER_H +#define ATTRIBUTE_SAVER_H + +#include +#include + +#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 diff --git a/src/apps/icon-o-matic/document/savers/BitmapSetSaver.cpp b/src/apps/icon-o-matic/document/savers/BitmapSetSaver.cpp new file mode 100644 index 0000000000..ed6be4d25a --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/BitmapSetSaver.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "BitmapSetSaver.h" + +#include + +#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; +} + diff --git a/src/apps/icon-o-matic/document/savers/BitmapSetSaver.h b/src/apps/icon-o-matic/document/savers/BitmapSetSaver.h new file mode 100644 index 0000000000..97145e685c --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/BitmapSetSaver.h @@ -0,0 +1,22 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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 diff --git a/src/apps/icon-o-matic/document/savers/DocumentSaver.cpp b/src/apps/icon-o-matic/document/savers/DocumentSaver.cpp new file mode 100644 index 0000000000..efbc596130 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/DocumentSaver.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "DocumentSaver.h" + +// constructor +DocumentSaver::DocumentSaver() +{ +} + +// destructor +DocumentSaver::~DocumentSaver() +{ +} diff --git a/src/apps/icon-o-matic/document/savers/DocumentSaver.h b/src/apps/icon-o-matic/document/savers/DocumentSaver.h new file mode 100644 index 0000000000..53bb1850f0 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/DocumentSaver.h @@ -0,0 +1,24 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef DOCUMENT_SAVER_H +#define DOCUMENT_SAVER_H + +#include + +class Document; + +class DocumentSaver { + public: + DocumentSaver(); + virtual ~DocumentSaver(); + + virtual status_t Save(Document* document) = 0; +}; + +#endif // DOCUMENT_SAVER_H diff --git a/src/apps/icon-o-matic/document/savers/FileSaver.cpp b/src/apps/icon-o-matic/document/savers/FileSaver.cpp new file mode 100644 index 0000000000..e0d85cbaf2 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/FileSaver.cpp @@ -0,0 +1,28 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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; +} + diff --git a/src/apps/icon-o-matic/document/savers/FileSaver.h b/src/apps/icon-o-matic/document/savers/FileSaver.h new file mode 100644 index 0000000000..6e0ce45c01 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/FileSaver.h @@ -0,0 +1,29 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef FILE_SAVER_H +#define FILE_SAVER_H + +#include + +#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 diff --git a/src/apps/icon-o-matic/document/savers/SimpleFileSaver.cpp b/src/apps/icon-o-matic/document/savers/SimpleFileSaver.cpp new file mode 100644 index 0000000000..aa97c25667 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/SimpleFileSaver.cpp @@ -0,0 +1,34 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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); +} + diff --git a/src/apps/icon-o-matic/document/savers/SimpleFileSaver.h b/src/apps/icon-o-matic/document/savers/SimpleFileSaver.h new file mode 100644 index 0000000000..b1e2d299a4 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/SimpleFileSaver.h @@ -0,0 +1,28 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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 diff --git a/src/apps/icon-o-matic/gui/SavePanel.cpp b/src/apps/icon-o-matic/gui/SavePanel.cpp new file mode 100644 index 0000000000..7804a88d3c --- /dev/null +++ b/src/apps/icon-o-matic/gui/SavePanel.cpp @@ -0,0 +1,429 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "SavePanel.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(background->FindView("cancel button")); + BView* textview = background->FindView("text view"); + BScrollBar* hscrollbar = dynamic_cast(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( +// background->FindView("text view")); +// +// if (textview) { +// +// translator_id id = 0; +// uint32 format = 0; +// int32 mode = ExportMode(); +// SaveItem* exportItem = dynamic_cast(_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(fFormatM->FindMarked()); + if (!item) + return fNativeMI; + return item; +} + +// _ExportSettings +void +SavePanel::_ExportSettings() +{ +// SaveItem *item = dynamic_cast(_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); +} + diff --git a/src/apps/icon-o-matic/gui/SavePanel.h b/src/apps/icon-o-matic/gui/SavePanel.h new file mode 100644 index 0000000000..ede2cf517e --- /dev/null +++ b/src/apps/icon-o-matic/gui/SavePanel.h @@ -0,0 +1,87 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef EXPORT_SAVE_PANEL_H +#define EXPORT_SAVE_PANEL_H + +#include +#include +#include +#include + +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 diff --git a/src/apps/icon-o-matic/import_export/flat_icon/FlatIconExporter.cpp b/src/apps/icon-o-matic/import_export/flat_icon/FlatIconExporter.cpp index 5b0dceaef9..6259b65b11 100644 --- a/src/apps/icon-o-matic/import_export/flat_icon/FlatIconExporter.cpp +++ b/src/apps/icon-o-matic/import_export/flat_icon/FlatIconExporter.cpp @@ -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