#include "Exporter.h"
#include <fs_attr.h>
#include <new>
#include <stdio.h>
#include <Alert.h>
#include <Catalog.h>
#include <File.h>
#include <Locale.h>
#include <Node.h>
#include <NodeInfo.h>
#include <Path.h>
#include <Roster.h>
#include <String.h>
#include "CommandStack.h"
#include "Document.h"
#include "Icon.h"
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Icon-O-Matic-Exporter"
using std::nothrow;
Exporter::Exporter()
: fDocument(NULL),
fClonedIcon(NULL),
fRef(),
fExportThread(-1),
fSelfDestroy(false)
{
}
Exporter::~Exporter()
{
WaitForExportThread();
delete fClonedIcon;
}
status_t
Exporter::Export(Document* document, const entry_ref& ref)
{
if (!document || ref.name == NULL)
return B_BAD_VALUE;
fDocument = document;
fClonedIcon = fDocument->Icon()->Clone();
if (!fClonedIcon)
return B_NO_MEMORY;
fRef = ref;
fExportThread = spawn_thread(_ExportThreadEntry, "export",
B_NORMAL_PRIORITY, this);
if (fExportThread < 0)
return (status_t)fExportThread;
resume_thread(fExportThread);
return B_OK;
}
void
Exporter::SetSelfDestroy(bool selfDestroy)
{
fSelfDestroy = selfDestroy;
}
void
Exporter::WaitForExportThread()
{
if (fExportThread >= 0 && find_thread(NULL) != fExportThread) {
status_t ret;
wait_for_thread(fExportThread, &ret);
fExportThread = -1;
}
}
int32
Exporter::_ExportThreadEntry(void* cookie)
{
Exporter* exporter = (Exporter*)cookie;
return exporter->_ExportThread();
}
int32
Exporter::_ExportThread()
{
status_t ret = _Export(fClonedIcon, &fRef);
if (ret < B_OK) {
BString helper(B_TRANSLATE("Saving your document failed!"));
helper << "\n\n" << ErrorCodeToString(ret);
BAlert* alert = new BAlert(B_TRANSLATE_CONTEXT("Bad news", "Title of error alert"),
helper.String(),
B_TRANSLATE_COMMENT("Bleep!", "Exporter - Continue in error dialog"),
NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
alert->Go(NULL);
} else {
be_roster->AddToRecentDocuments(&fRef);
fDocument->CommandStack()->Save();
if (fDocument->WriteLock()) {
fDocument->SetName(fRef.name);
fDocument->WriteUnlock();
}
}
if (fSelfDestroy)
delete this;
return ret;
}
status_t
Exporter::_Export(const Icon* icon, const entry_ref* docRef)
{
BEntry entry(docRef, true);
if (entry.IsDirectory())
return B_BAD_VALUE;
const entry_ref* ref = docRef;
status_t ret = B_BAD_VALUE;
BFile outFile(ref, B_CREATE_FILE | B_READ_WRITE | B_ERASE_FILE);
ret = outFile.InitCheck();
if (ret == B_OK) {
try {
ret = Export(icon, &outFile);
} catch (...) {
printf("Exporter::_Export() - "
"unkown exception occured!\n");
ret = B_ERROR;
}
if (ret < B_OK) {
printf("Exporter::_Export() - "
"failed to export icon: %s\n", strerror(ret));
}
} else {
printf("Exporter::_Export() - "
"failed to create output file: %s\n", strerror(ret));
}
outFile.Unset();
if (ret >= B_OK && MIMEType()) {
BNode node(docRef);
if (node.InitCheck() == B_OK) {
BNodeInfo nodeInfo(&node);
if (nodeInfo.InitCheck() == B_OK)
nodeInfo.SetType(MIMEType());
}
}
return ret;
}