diff --git a/src/apps/icon-o-matic/Icon-O-Matic.rdef b/src/apps/icon-o-matic/Icon-O-Matic.rdef index d6ba361453..400229bb2d 100644 --- a/src/apps/icon-o-matic/Icon-O-Matic.rdef +++ b/src/apps/icon-o-matic/Icon-O-Matic.rdef @@ -63,9 +63,3 @@ resource vector_icon { $"D413BED4133ED4133ED41347F4A24A588915FF" }; - -//resource large_icon array { -//}; -// -//resource mini_icon array { -//}; diff --git a/src/apps/icon-o-matic/IconEditorApp.cpp b/src/apps/icon-o-matic/IconEditorApp.cpp index befa81e946..cf7323aa43 100644 --- a/src/apps/icon-o-matic/IconEditorApp.cpp +++ b/src/apps/icon-o-matic/IconEditorApp.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "support_settings.h" @@ -33,6 +34,7 @@ #include "MainWindow.h" #include "MessageExporter.h" #include "MessageImporter.h" +#include "MessengerSaver.h" #include "PathContainer.h" #include "RDefExporter.h" #include "SavePanel.h" @@ -172,6 +174,23 @@ IconEditorApp::MessageReceived(BMessage* message) } break; } + case B_EDIT_ICON_DATA: { + BMessenger messenger; + if (message->FindMessenger("reply to", &messenger) < B_OK) { + // required + break; + } + const uint8* data; + ssize_t size; + if (message->FindData("icon data", B_VECTOR_ICON_TYPE, + (const void**)&data, &size) < B_OK) { + // optional (new icon will be created) + data = NULL; + size = 0; + } + _Open(messenger, data, size); + break; + } default: BApplication::MessageReceived(message); @@ -358,6 +377,66 @@ IconEditorApp::_Open(const entry_ref& ref, bool append) } } +// _Open +void +IconEditorApp::_Open(const BMessenger& externalObserver, + const uint8* data, size_t size) +{ + if (!externalObserver.IsValid()) + return; + + Icon* icon = new (nothrow) Icon(); + if (!icon) + return; + + if (data && size > 0) { + // try to open the icon from the provided data + FlatIconImporter flatImporter; + status_t ret = flatImporter.Import(icon, const_cast(data), size); + // NOTE: the const_cast is a bit ugly, but no harm is done + // the reason is that the LittleEndianBuffer knows read and write + // mode, in this case it is used read-only, and it does not assume + // ownership of the buffer + + if (ret < B_OK) { + // inform user of failure at this point + BString helper("Opening the icon failed!"); + helper << "\n\n" << "Error: " << strerror(ret); + BAlert* alert = new BAlert("bad news", helper.String(), + "Bummer", NULL, NULL); + // launch alert asynchronously + alert->Go(NULL); + + delete icon; + return; + } + } + + // keep the mainwindow locked while switching icons + bool mainWindowLocked = fMainWindow && fMainWindow->Lock(); + + AutoWriteLocker locker(fDocument); + + if (mainWindowLocked) + fMainWindow->SetIcon(NULL); + + // incorporate the loaded icon into the document + // (either replace it or append to it) + fDocument->MakeEmpty(); + fDocument->SetIcon(icon); + + fDocument->SetNativeSaver(new MessengerSaver(externalObserver)); + + locker.Unlock(); + + if (mainWindowLocked) { + fMainWindow->Unlock(); + // cause the mainwindow to adopt icon in + // it's own thread + fMainWindow->PostMessage(MSG_SET_ICON); + } +} + // _CreateSaver DocumentSaver* IconEditorApp::_CreateSaver(const entry_ref& ref, uint32 exportMode) diff --git a/src/apps/icon-o-matic/IconEditorApp.h b/src/apps/icon-o-matic/IconEditorApp.h index 7ab9e0482b..8708a3eb4f 100644 --- a/src/apps/icon-o-matic/IconEditorApp.h +++ b/src/apps/icon-o-matic/IconEditorApp.h @@ -66,6 +66,8 @@ class IconEditorApp : public BApplication { void _MakeIconEmpty(); void _Open(const entry_ref& ref, bool append = false); + void _Open(const BMessenger& externalObserver, + const uint8* data, size_t size); DocumentSaver* _CreateSaver(const entry_ref& ref, uint32 exportMode); diff --git a/src/apps/icon-o-matic/Jamfile b/src/apps/icon-o-matic/Jamfile index d01748d6ac..ffcb055511 100644 --- a/src/apps/icon-o-matic/Jamfile +++ b/src/apps/icon-o-matic/Jamfile @@ -63,7 +63,7 @@ for sourceDir in $(sourceDirs) { } # system headers -UseLibraryHeaders agg expat ; +UseLibraryHeaders agg expat icon ; @@ -115,6 +115,7 @@ Application Icon-O-Matic : BitmapSetSaver.cpp DocumentSaver.cpp FileSaver.cpp + MessengerSaver.cpp SimpleFileSaver.cpp # generic/command diff --git a/src/apps/icon-o-matic/document/savers/MessengerSaver.cpp b/src/apps/icon-o-matic/document/savers/MessengerSaver.cpp new file mode 100644 index 0000000000..0d8506ba24 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/MessengerSaver.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "MessengerSaver.h" + +#include +#include + +#include "Document.h" +#include "FlatIconExporter.h" + +// constructor +MessengerSaver::MessengerSaver(const BMessenger& messenger) + : fMessenger(messenger) +{ +} + +// destructor +MessengerSaver::~MessengerSaver() +{ +} + +// Save +status_t +MessengerSaver::Save(Document* document) +{ +#if HAIKU_TARGET_PLATFORM_HAIKU + if (!fMessenger.IsValid()) + return B_NO_INIT; + + FlatIconExporter exporter; + BMallocIO stream; + status_t ret = exporter.Export(document->Icon(), &stream); + if (ret < B_OK) + return ret; + + BMessage message(B_ICON_DATA_EDITED); + ret = message.AddData("icon data", B_VECTOR_ICON_TYPE, + stream.Buffer(), stream.BufferLength()); + if (ret < B_OK) + return ret; + + return fMessenger.SendMessage(&message); +#else + return B_ERROR; +#endif +} + diff --git a/src/apps/icon-o-matic/document/savers/MessengerSaver.h b/src/apps/icon-o-matic/document/savers/MessengerSaver.h new file mode 100644 index 0000000000..28fc12e1a6 --- /dev/null +++ b/src/apps/icon-o-matic/document/savers/MessengerSaver.h @@ -0,0 +1,27 @@ +/* + * Copyright 2006, Haiku. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef MESSENGER_SAVER_H +#define MESSENGER_SAVER_H + +#include + +#include "DocumentSaver.h" + +class MessengerSaver : public DocumentSaver { + public: + MessengerSaver(const BMessenger& messenger); + virtual ~MessengerSaver(); + + virtual status_t Save(Document* document); + + private: + BMessenger fMessenger; +}; + +#endif // MESSENGER_SAVER_H