b531eef96c5e19cf39d94b004872e0632029621b
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 "sp-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::Node *mark_repr = SP_OBJECT_REPR(object)->duplicate();
74 SP_OBJECT_REPR(defs)->addChild(mark_repr, NULL);
75 SPObject *cloned_item = current_doc->getObjectByRepr(mark_repr);
76 Inkscape::GC::release(mark_repr);
77 return cloned_item;
78 }
79 }
80 return NULL;
81 }
84 static SPObject *
85 sp_pattern_load_from_svg(gchar const *name, SPDocument *current_doc)
86 {
87 static SPDocument *doc = NULL;
88 static unsigned int edoc = FALSE;
89 if (!current_doc) {
90 return NULL;
91 }
92 /* Try to load from document */
93 if (!edoc && !doc) {
94 gchar *patterns = g_build_filename(INKSCAPE_PATTERNSDIR, "/patterns.svg", NULL);
95 if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) {
96 doc = sp_document_new(patterns, FALSE);
97 }
98 if (!doc) {
99 gchar *patterns = g_build_filename(CREATE_PATTERNSDIR, "/patterns.svg", NULL);
100 if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) {
101 doc = sp_document_new(patterns, FALSE);
102 }
103 g_free(patterns);
104 if (doc) {
105 sp_document_ensure_up_to_date(doc);
106 } else {
107 edoc = TRUE;
108 }
109 }
110 }
111 if (!edoc && doc) {
112 /* Get the pattern we want */
113 SPObject *object = doc->getObjectById(name);
114 if (object && SP_IS_PATTERN(object)) {
115 SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
116 Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate();
117 SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
118 Inkscape::GC::release(pat_repr);
119 return object;
120 }
121 }
122 return NULL;
123 }
126 static SPObject *
127 sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc)
128 {
129 static SPDocument *doc = NULL;
130 static unsigned int edoc = FALSE;
131 if (!current_doc) {
132 return NULL;
133 }
134 /* Try to load from document */
135 if (!edoc && !doc) {
136 gchar *gradients = g_build_filename(INKSCAPE_GRADIENTSDIR, "/gradients.svg", NULL);
137 if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) {
138 doc = sp_document_new(gradients, FALSE);
139 }
140 if (!doc) {
141 gchar *gradients = g_build_filename(CREATE_GRADIENTSDIR, "/gradients.svg", NULL);
142 if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) {
143 doc = sp_document_new(gradients, FALSE);
144 }
145 g_free(gradients);
146 if (doc) {
147 sp_document_ensure_up_to_date(doc);
148 } else {
149 edoc = TRUE;
150 }
151 }
152 }
153 if (!edoc && doc) {
154 /* Get the gradient we want */
155 SPObject *object = doc->getObjectById(name);
156 if (object && SP_IS_GRADIENT(object)) {
157 SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
158 Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate();
159 SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
160 Inkscape::GC::release(pat_repr);
161 return object;
162 }
163 }
164 return NULL;
165 }
167 // get_stock_item returns a pointer to an instance of the desired stock object in the current doc
168 // if necessary it will import the object. Copes with name clashes through use of the inkscape:stockid property
169 // This should be set to be the same as the id in the libary file.
171 SPObject *get_stock_item(gchar const *urn)
172 {
173 g_assert(urn != NULL);
175 /* check its an inkscape URN */
176 if (!strncmp (urn, "urn:inkscape:", 13)) {
178 gchar const *e = urn + 13;
179 int a = 0;
180 gchar * name = g_strdup(e);
181 gchar *name_p = name;
182 while (*name_p != ':' && *name_p != '\0'){
183 name_p++;
184 a++;
185 }
187 if (*name_p ==':') {
188 name_p++;
189 }
191 gchar * base = g_strndup(e, a);
193 SPDesktop *desktop = inkscape_active_desktop();
194 SPDocument *doc = sp_desktop_document(desktop);
195 SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(doc);
197 SPObject *object = NULL;
198 if (!strcmp(base, "marker")) {
199 for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
200 child != NULL;
201 child = SP_OBJECT_NEXT(child))
202 {
203 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
204 !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
205 SP_IS_MARKER(child))
206 {
207 object = child;
208 }
209 }
211 }
212 else if (!strcmp(base,"pattern")) {
213 for (SPObject *child = sp_object_first_child(SP_OBJECT(defs)) ;
214 child != NULL;
215 child = SP_OBJECT_NEXT(child) )
216 {
217 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
218 !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
219 SP_IS_PATTERN(child))
220 {
221 object = child;
222 }
223 }
225 }
226 else if (!strcmp(base,"gradient")) {
227 for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
228 child != NULL;
229 child = SP_OBJECT_NEXT(child))
230 {
231 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
232 !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
233 SP_IS_GRADIENT(child))
234 {
235 object = child;
236 }
237 }
239 }
241 if (object == NULL) {
243 if (!strcmp(base, "marker")) {
244 object = sp_marker_load_from_svg(name_p, doc);
245 }
246 else if (!strcmp(base, "pattern")) {
247 object = sp_pattern_load_from_svg(name_p, doc);
248 }
249 else if (!strcmp(base, "gradient")) {
250 object = sp_gradient_load_from_svg(name_p, doc);
251 }
252 }
254 g_free(base);
255 g_free(name);
257 return object;
258 }
260 else {
262 SPDesktop *desktop = inkscape_active_desktop();
263 SPDocument *doc = sp_desktop_document(desktop);
264 SPObject *object = doc->getObjectById(urn);
266 return object;
267 }
268 }
270 /*
271 Local Variables:
272 mode:c++
273 c-file-style:"stroustrup"
274 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
275 indent-tabs-mode:nil
276 fill-column:99
277 End:
278 */
279 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :