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