xref: /haiku/src/apps/icon-o-matic/import_export/message/MessageExporter.cpp (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
1 /*
2  * Copyright 2006, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 
9 #include "MessageExporter.h"
10 
11 #include <DataIO.h>
12 #include <Message.h>
13 #include <TypeConstants.h>
14 
15 #include "Icon.h"
16 #include "PathContainer.h"
17 #include "Shape.h"
18 #include "Style.h"
19 #include "StyleContainer.h"
20 #include "Transformer.h"
21 #include "VectorPath.h"
22 
23 // constructor
24 MessageExporter::MessageExporter()
25 {
26 }
27 
28 // destructor
29 MessageExporter::~MessageExporter()
30 {
31 }
32 
33 // Export
34 status_t
35 MessageExporter::Export(const Icon* icon, BPositionIO* stream)
36 {
37 	status_t ret = B_OK;
38 	BMessage archive;
39 
40 	PathContainer* paths = icon->Paths();
41 	StyleContainer* styles = icon->Styles();
42 
43 	// paths
44 	if (ret == B_OK) {
45 		BMessage allPaths;
46 		int32 count = paths->CountPaths();
47 		for (int32 i = 0; i < count; i++) {
48 			VectorPath* path = paths->PathAtFast(i);
49 			BMessage pathArchive;
50 			ret = _Export(path, &pathArchive);
51 			if (ret < B_OK)
52 				break;
53 			ret = allPaths.AddMessage("path", &pathArchive);
54 			if (ret < B_OK)
55 				break;
56 		}
57 
58 		if (ret == B_OK)
59 			ret = archive.AddMessage("paths", &allPaths);
60 	}
61 
62 	// styles
63 	if (ret == B_OK) {
64 		BMessage allStyles;
65 		int32 count = styles->CountStyles();
66 		for (int32 i = 0; i < count; i++) {
67 			Style* style = styles->StyleAtFast(i);
68 			BMessage styleArchive;
69 			ret = _Export(style, &styleArchive);
70 			if (ret < B_OK)
71 				break;
72 			ret = allStyles.AddMessage("style", &styleArchive);
73 			if (ret < B_OK)
74 				break;
75 		}
76 
77 		if (ret == B_OK)
78 			ret = archive.AddMessage("styles", &allStyles);
79 	}
80 
81 	// shapes
82 	if (ret == B_OK) {
83 		BMessage allShapes;
84 		ShapeContainer* shapes = icon->Shapes();
85 		int32 count = shapes->CountShapes();
86 		for (int32 i = 0; i < count; i++) {
87 			Shape* shape = shapes->ShapeAtFast(i);
88 			BMessage shapeArchive;
89 			ret = _Export(shape, paths, styles, &shapeArchive);
90 			if (ret < B_OK)
91 				break;
92 			ret = allShapes.AddMessage("shape", &shapeArchive);
93 			if (ret < B_OK)
94 				break;
95 		}
96 
97 		if (ret == B_OK)
98 			ret = archive.AddMessage("shapes", &allShapes);
99 	}
100 
101 	if (ret == B_OK)
102 		ret = archive.Flatten(stream);
103 
104 	return ret;
105 }
106 
107 // MIMEType
108 const char*
109 MessageExporter::MIMEType()
110 {
111 	// TODO: come up with a MIME type
112 	return NULL;
113 }
114 
115 // #pragma mark -
116 
117 // _Export
118 status_t
119 MessageExporter::_Export(const VectorPath* path, BMessage* into) const
120 {
121 	return path->Archive(into, true);
122 }
123 
124 // _Export
125 status_t
126 MessageExporter::_Export(const Style* style, BMessage* into) const
127 {
128 	return style->Archive(into, true);
129 }
130 
131 // _Export
132 status_t
133 MessageExporter::_Export(const Shape* shape,
134 						 const PathContainer* globalPaths,
135 						 const StyleContainer* globalStyles,
136 						 BMessage* into) const
137 {
138 	// NOTE: when the same path is used in two different
139 	// documents, and these are to be merged, each path
140 	// having a "globally unique" id would make it possible
141 	// to reference the same path across documents...
142 	// For now, we simply use the index of the path in the
143 	// globalPaths container.
144 
145 	// index of used style
146 	Style* style = shape->Style();
147 	status_t ret = into->AddInt32("style ref", globalStyles->IndexOf(style));
148 
149 	// indices of used paths
150 	if (ret == B_OK) {
151 		int32 count = shape->Paths()->CountPaths();
152 		for (int32 i = 0; i < count; i++) {
153 			VectorPath* path = shape->Paths()->PathAtFast(i);
154 			ret = into->AddInt32("path ref", globalPaths->IndexOf(path));
155 			if (ret < B_OK)
156 				break;
157 		}
158 	}
159 
160 	// Shape properties
161 	if (ret == B_OK)
162 		ret = shape->Archive(into);
163 
164 	return ret;
165 }
166 
167