Code

Get rid of the SP_DT_* macros which do nothing more than provide additional, confusin...
[inkscape.git] / src / helper / stock-items.cpp
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         g_free(patterns);
99         if (doc) {
100             sp_document_ensure_up_to_date(doc);
101         } else {
102             edoc = TRUE;
103         }
104     }
105     if (!edoc && doc) {
106         /* Get the pattern we want */
107         SPObject *object = doc->getObjectById(name);
108         if (object && SP_IS_PATTERN(object)) {
109             SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
110             Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate();
111             SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
112             Inkscape::GC::release(pat_repr);
113             return object;
114         }
115     }
116     return NULL;
120 static SPObject *
121 sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc)
123     static SPDocument *doc = NULL;
124     static unsigned int edoc = FALSE;
125     if (!current_doc) {
126         return NULL;
127     }
128     /* Try to load from document */
129     if (!edoc && !doc) {
130         gchar *gradients = g_build_filename(INKSCAPE_GRADIENTSDIR, "/gradients.svg", NULL);
131         if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) {
132             doc = sp_document_new(gradients, FALSE);
133         }
134         g_free(gradients);
135         if (doc) {
136             sp_document_ensure_up_to_date(doc);
137         } else {
138             edoc = TRUE;
139         }
140     }
141     if (!edoc && doc) {
142         /* Get the gradient we want */
143         SPObject *object = doc->getObjectById(name);
144         if (object && SP_IS_GRADIENT(object)) {
145             SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc);
146             Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate();
147             SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL);
148             Inkscape::GC::release(pat_repr);
149             return object;
150         }
151     }
152     return NULL;
155 // get_stock_item returns a pointer to an instance of the desired stock object in the current doc
156 // if necessary it will import the object. Copes with name clashes through use of the inkscape:stockid property
157 // This should be set to be the same as the id in the libary file.
159 SPObject *get_stock_item(gchar const *urn)
161     g_assert(urn != NULL);
162     
163     /* check its an inkscape URN */
164     if (!strncmp (urn, "urn:inkscape:", 13)) {
166         gchar const *e = urn + 13;
167         int a = 0;
168         gchar * name = g_strdup(e);
169         gchar *name_p = name;
170         while (*name_p != ':' && *name_p != '\0'){
171             name_p++;
172             a++;
173         }
174         
175         if (*name_p ==':') {
176             name_p++;
177         }
178         
179         gchar * base = g_strndup(e, a);
181         SPDesktop *desktop = inkscape_active_desktop();
182         SPDocument *doc = sp_desktop_document(desktop);
183         SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(doc);
185         SPObject *object = NULL;
186         if (!strcmp(base, "marker")) {
187             for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
188                  child != NULL;
189                  child = SP_OBJECT_NEXT(child))
190             {
191                 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
192                     !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
193                     SP_IS_MARKER(child))
194                 {
195                     object = child;
196                 }
197             }
198             
199         }
200         else if (!strcmp(base,"pattern"))  {
201             for (SPObject *child = sp_object_first_child(SP_OBJECT(defs)) ;
202                  child != NULL;
203                  child = SP_OBJECT_NEXT(child) )
204             {
205                 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
206                     !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
207                     SP_IS_PATTERN(child))
208                 {
209                     object = child;
210                 }
211             }
212             
213         }
214         else if (!strcmp(base,"gradient"))  {
215             for (SPObject *child = sp_object_first_child(SP_OBJECT(defs));
216                  child != NULL;
217                  child = SP_OBJECT_NEXT(child))
218             {
219                 if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") &&
220                     !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) &&
221                     SP_IS_GRADIENT(child))
222                 {
223                     object = child;
224                 }
225             }
226             
227         }
228         
229         if (object == NULL) {
230             
231             if (!strcmp(base, "marker"))  {
232                 object = sp_marker_load_from_svg(name_p, doc);
233             }
234             else if (!strcmp(base, "pattern"))  {
235                 object = sp_pattern_load_from_svg(name_p, doc);
236             }
237             else if (!strcmp(base, "gradient"))  {
238                 object = sp_gradient_load_from_svg(name_p, doc);
239             }
240         }
241         
242         g_free(base);
243         g_free(name);
244         
245         return object;
246     }
247     
248     else {
249         
250         SPDesktop *desktop = inkscape_active_desktop();
251         SPDocument *doc = sp_desktop_document(desktop);
252         SPObject *object = doc->getObjectById(urn);
254         return object;
255     }
258 /*
259   Local Variables:
260   mode:c++
261   c-file-style:"stroustrup"
262   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
263   indent-tabs-mode:nil
264   fill-column:99
265   End:
266 */
267 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :