1 #define __INK_STOCK_ITEMS__
3 /*
4 * Stock-items
5 *
6 * Stock Item management code
7 *
8 * Authors:
9 * John Cliff <simarilius@yahoo.com>
10 *
11 * Copyright 2004 John Cliff
12 *
13 *
14 * Released under GNU GPL, read the file 'COPYING' for more information
15 */
17 #define noSP_SS_VERBOSE
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22 #include "path-prefix.h"
25 #include <xml/repr.h>
26 #include "sp-gradient-fns.h"
27 #include "document-private.h"
28 #include "sp-pattern.h"
29 #include "marker.h"
30 #include "desktop-handles.h"
31 #include "inkscape.h"
33 #include "io/sys.h"
38 static SPObject *sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc);
39 static SPObject *sp_marker_load_from_svg(gchar const *name, SPDocument *current_doc);
40 static SPObject *sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc);
43 // FIXME: these should be merged with the icon loading code so they
44 // can share a common file/doc cache. This function should just
45 // take the dir to look in, and the file to check for, and cache
46 // against that, rather than the existing copy/paste code seen here.
48 static SPObject * sp_marker_load_from_svg(gchar const *name, SPDocument *current_doc)
49 {
50 static SPDocument *doc = NULL;
51 static unsigned int edoc = FALSE;
52 if (!current_doc) {
53 return NULL;
54 }
55 /* Try to load from document */
56 if (!edoc && !doc) {
57 gchar *markers = g_build_filename(INKSCAPE_MARKERSDIR, "/markers.svg", NULL);
58 if (Inkscape::IO::file_test(markers, G_FILE_TEST_IS_REGULAR)) {
59 doc = sp_document_new(markers, FALSE);
60 }
61 g_free(markers);
62 if (doc) {
63 sp_document_ensure_up_to_date(doc);
64 } else {
65 edoc = TRUE;
66 }
67 }
68 if (!edoc && doc) {
69 /* Get the marker we want */
70 SPObject *object = doc->getObjectById(name);
71 if (object && SP_IS_MARKER(object)) {
72 SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
73 Inkscape::XML::Document *xml_doc = sp_document_repr_doc(current_doc);
74 Inkscape::XML::Node *mark_repr = SP_OBJECT_REPR(object)->duplicate(xml_doc);
75 SP_OBJECT_REPR(defs)->addChild(mark_repr, NULL);
76 SPObject *cloned_item = current_doc->getObjectByRepr(mark_repr);
77 Inkscape::GC::release(mark_repr);
78 return cloned_item;
79 }
80 }
81 return NULL;
82 }
85 static SPObject *
86 sp_pattern_load_from_svg(gchar const *name, SPDocument *current_doc)
87 {
88 static SPDocument *doc = NULL;
89 static unsigned int edoc = FALSE;
90 if (!current_doc) {
91 return NULL;
92 }
93 /* Try to load from document */
94 if (!edoc && !doc) {
95 gchar *patterns = g_build_filename(INKSCAPE_PATTERNSDIR, "/patterns.svg", NULL);
96 if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) {
97 doc = sp_document_new(patterns, FALSE);
98 }
99 if (!doc) {
100 gchar *patterns = g_build_filename(CREATE_PATTERNSDIR, "/patterns.svg", NULL);
101 if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) {
102 doc = sp_document_new(patterns, FALSE);
103 }
104 g_free(patterns);
105 if (doc) {
106 sp_document_ensure_up_to_date(doc);
107 } else {
108 edoc = TRUE;
109 }
110 }
111 }
112 if (!edoc && doc) {
113 /* Get the pattern we want */
114 SPObject *object = doc->getObjectById(name);
115 if (object && SP_IS_PATTERN(object)) {
116 SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
117 Inkscape::XML::Document *xml_doc = sp_document_repr_doc(current_doc);
118 Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate(xml_doc);
119 SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
120 Inkscape::GC::release(pat_repr);
121 return object;
122 }
123 }
124 return NULL;
125 }
128 static SPObject *
129 sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc)
130 {
131 static SPDocument *doc = NULL;
132 static unsigned int edoc = FALSE;
133 if (!current_doc) {
134 return NULL;
135 }
136 /* Try to load from document */
137 if (!edoc && !doc) {
138 gchar *gradients = g_build_filename(INKSCAPE_GRADIENTSDIR, "/gradients.svg", NULL);
139 if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) {
140 doc = sp_document_new(gradients, FALSE);
141 }
142 if (!doc) {
143 gchar *gradients = g_build_filename(CREATE_GRADIENTSDIR, "/gradients.svg", NULL);
144 if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) {
145 doc = sp_document_new(gradients, FALSE);
146 }
147 g_free(gradients);
148 if (doc) {
149 sp_document_ensure_up_to_date(doc);
150 } else {
151 edoc = TRUE;
152 }
153 }
154 }
155 if (!edoc && doc) {
156 /* Get the gradient we want */
157 SPObject *object = doc->getObjectById(name);
158 if (object && SP_IS_GRADIENT(object)) {
159 SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
160 Inkscape::XML::Document *xml_doc = sp_document_repr_doc(current_doc);
161 Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate(xml_doc);
162 SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
163 Inkscape::GC::release(pat_repr);
164 return object;
165 }
166 }
167 return NULL;
168 }
170 // get_stock_item returns a pointer to an instance of the desired stock object in the current doc
171 // if necessary it will import the object. Copes with name clashes through use of the inkscape:stockid property
172 // This should be set to be the same as the id in the libary file.
174 SPObject *get_stock_item(gchar const *urn)
175 {
176 g_assert(urn != NULL);
178 /* check its an inkscape URN */
179 if (!strncmp (urn, "urn:inkscape:", 13)) {
181 gchar const *e = urn + 13;
182 int a = 0;
183 gchar * name = g_strdup(e);
184 gchar *name_p = name;
185 while (*name_p != ':' && *name_p != '\0'){
186 name_p++;
187 a++;
188 }
190 if (*name_p ==':') {
191 name_p++;
192 }
194 gchar * base = g_strndup(e, a);
196 SPDesktop *desktop = inkscape_active_desktop();
197 SPDocument *doc = sp_desktop_document(desktop);
198 SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(doc);
200 SPObject *object = NULL;
201 if (!strcmp(base, "marker")) {
202 for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
203 child != NULL;
204 child = SP_OBJECT_NEXT(child))
205 {
206 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
207 !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
208 SP_IS_MARKER(child))
209 {
210 object = child;
211 }
212 }
214 }
215 else if (!strcmp(base,"pattern")) {
216 for (SPObject *child = sp_object_first_child(SP_OBJECT(defs)) ;
217 child != NULL;
218 child = SP_OBJECT_NEXT(child) )
219 {
220 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
221 !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
222 SP_IS_PATTERN(child))
223 {
224 object = child;
225 }
226 }
228 }
229 else if (!strcmp(base,"gradient")) {
230 for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
231 child != NULL;
232 child = SP_OBJECT_NEXT(child))
233 {
234 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
235 !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
236 SP_IS_GRADIENT(child))
237 {
238 object = child;
239 }
240 }
242 }
244 if (object == NULL) {
246 if (!strcmp(base, "marker")) {
247 object = sp_marker_load_from_svg(name_p, doc);
248 }
249 else if (!strcmp(base, "pattern")) {
250 object = sp_pattern_load_from_svg(name_p, doc);
251 }
252 else if (!strcmp(base, "gradient")) {
253 object = sp_gradient_load_from_svg(name_p, doc);
254 }
255 }
257 g_free(base);
258 g_free(name);
260 return object;
261 }
263 else {
265 SPDesktop *desktop = inkscape_active_desktop();
266 SPDocument *doc = sp_desktop_document(desktop);
267 SPObject *object = doc->getObjectById(urn);
269 return object;
270 }
271 }
273 /*
274 Local Variables:
275 mode:c++
276 c-file-style:"stroustrup"
277 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
278 indent-tabs-mode:nil
279 fill-column:99
280 End:
281 */
282 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :