Removal of non-Haiku target platform logic from build system (part 1.)
[haiku.git] / src / apps / icon-o-matic / import_export / Exporter.cpp
blob6440fdd95f27b499bf5db13974914459701c3c88
1 /*
2 * Copyright 2006, 2011, Stephan Aßmus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
7 #include "Exporter.h"
9 #include <fs_attr.h>
10 #include <new>
11 #include <stdio.h>
13 #include <Alert.h>
14 #include <Catalog.h>
15 #include <File.h>
16 #include <Locale.h>
17 #include <Node.h>
18 #include <NodeInfo.h>
19 #include <Path.h>
20 #include <Roster.h>
21 #include <String.h>
23 #include "CommandStack.h"
24 #include "Document.h"
25 #include "Icon.h"
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "Icon-O-Matic-Exporter"
32 using std::nothrow;
35 Exporter::Exporter()
36 : fDocument(NULL),
37 fClonedIcon(NULL),
38 fRef(),
39 fExportThread(-1),
40 fSelfDestroy(false)
45 Exporter::~Exporter()
47 WaitForExportThread();
49 delete fClonedIcon;
53 status_t
54 Exporter::Export(Document* document, const entry_ref& ref)
56 if (!document || ref.name == NULL)
57 return B_BAD_VALUE;
59 fDocument = document;
60 fClonedIcon = fDocument->Icon()->Clone();
61 if (!fClonedIcon)
62 return B_NO_MEMORY;
64 fRef = ref;
66 fExportThread = spawn_thread(_ExportThreadEntry, "export",
67 B_NORMAL_PRIORITY, this);
68 if (fExportThread < 0)
69 return (status_t)fExportThread;
71 resume_thread(fExportThread);
73 return B_OK;
77 void
78 Exporter::SetSelfDestroy(bool selfDestroy)
80 fSelfDestroy = selfDestroy;
84 void
85 Exporter::WaitForExportThread()
87 if (fExportThread >= 0 && find_thread(NULL) != fExportThread) {
88 status_t ret;
89 wait_for_thread(fExportThread, &ret);
90 fExportThread = -1;
95 // #pragma mark -
98 int32
99 Exporter::_ExportThreadEntry(void* cookie)
101 Exporter* exporter = (Exporter*)cookie;
102 return exporter->_ExportThread();
106 int32
107 Exporter::_ExportThread()
109 status_t ret = _Export(fClonedIcon, &fRef);
110 if (ret < B_OK) {
111 // inform user of failure at this point
112 BString helper(B_TRANSLATE("Saving your document failed!"));
113 helper << "\n\n" << B_TRANSLATE("Error: ") << strerror(ret);
114 BAlert* alert = new BAlert(B_TRANSLATE("bad news"), helper.String(),
115 B_TRANSLATE_CONTEXT("Bleep!",
116 "Exporter - Continue in error dialog"),
117 NULL, NULL);
118 // launch alert asynchronously
119 alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
120 alert->Go(NULL);
121 } else {
122 // success
124 // add to recent document list
125 be_roster->AddToRecentDocuments(&fRef);
126 // mark command stack state as saved,
127 fDocument->CommandStack()->Save();
128 // NOTE: CommandStack is thread safe
130 if (fDocument->WriteLock()) {
131 // set ref and name of document
132 // fDocument->SetRef(fRef);
133 fDocument->SetName(fRef.name);
135 fDocument->WriteUnlock();
139 if (fSelfDestroy)
140 delete this;
142 return ret;
146 status_t
147 Exporter::_Export(const Icon* icon, const entry_ref* docRef)
149 // TODO: reenable the commented out code, but make it work
150 // the opposite direction, ie *copy* the file contents
152 BEntry entry(docRef, true);
153 if (entry.IsDirectory())
154 return B_BAD_VALUE;
156 const entry_ref* ref = docRef;
157 // entry_ref tempRef;
159 // if (entry.Exists()) {
160 // // if the file exists create a temporary file in the same folder
161 // // and hope that it doesn't already exist...
162 // BPath tempPath(docRef);
163 // if (tempPath.GetParent(&tempPath) >= B_OK) {
164 // BString helper(docRef->name);
165 // helper << system_time();
166 // if (tempPath.Append(helper.String()) >= B_OK
167 // && entry.SetTo(tempPath.Path()) >= B_OK
168 // && entry.GetRef(&tempRef) >= B_OK) {
169 // // have the output ref point to the temporary
170 // // file instead
171 // ref = &tempRef;
172 // }
173 // }
174 // }
176 status_t ret = B_BAD_VALUE;
178 // do the actual save operation into a file
179 BFile outFile(ref, B_CREATE_FILE | B_READ_WRITE | B_ERASE_FILE);
180 ret = outFile.InitCheck();
181 if (ret == B_OK) {
182 try {
183 // export using the virtual Export() version
184 ret = Export(icon, &outFile);
185 } catch (...) {
186 printf("Exporter::_Export() - "
187 "unkown exception occured!\n");
188 ret = B_ERROR;
190 if (ret < B_OK) {
191 printf("Exporter::_Export() - "
192 "failed to export icon: %s\n", strerror(ret));
194 } else {
195 printf("Exporter::_Export() - "
196 "failed to create output file: %s\n", strerror(ret));
198 outFile.Unset();
200 // if (ret < B_OK && ref != docRef) {
201 // // in case of failure, remove temporary file
202 // entry.Remove();
203 // }
205 // if (ret >= B_OK && ref != docRef) {
206 // // move temp file overwriting actual document file
207 // BEntry docEntry(docRef, true);
208 // // copy attributes of previous document file
209 // BNode sourceNode(&docEntry);
210 // BNode destNode(&entry);
211 // if (sourceNode.InitCheck() >= B_OK && destNode.InitCheck() >= B_OK) {
212 // // lock the nodes
213 // if (sourceNode.Lock() >= B_OK) {
214 // if (destNode.Lock() >= B_OK) {
215 // // iterate over the attributes
216 // char attrName[B_ATTR_NAME_LENGTH];
217 // while (sourceNode.GetNextAttrName(attrName) >= B_OK) {
218 //// // skip the icon, since we probably wrote that
219 //// // before
220 //// if (strcmp(attrName, "BEOS:ICON") == 0)
221 //// continue;
222 // attr_info info;
223 // if (sourceNode.GetAttrInfo(attrName, &info) >= B_OK) {
224 // char *buffer = new (nothrow) char[info.size];
225 // if (buffer && sourceNode.ReadAttr(attrName, info.type, 0,
226 // buffer, info.size) == info.size) {
227 // destNode.WriteAttr(attrName, info.type, 0,
228 // buffer, info.size);
229 // }
230 // delete[] buffer;
231 // }
232 // }
233 // destNode.Unlock();
234 // }
235 // sourceNode.Unlock();
236 // }
237 // }
238 // // clobber the orginal file with the new temporary one
239 // ret = entry.Rename(docRef->name, true);
240 // }
242 if (ret >= B_OK && MIMEType()) {
243 // set file type
244 BNode node(docRef);
245 if (node.InitCheck() == B_OK) {
246 BNodeInfo nodeInfo(&node);
247 if (nodeInfo.InitCheck() == B_OK)
248 nodeInfo.SetType(MIMEType());
251 return ret;