Code

A simple layout document as to what, why and how is cppification.
[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.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 = SPDocument::createNewDoc(markers, FALSE);
60         }
61         g_free(markers);
62         if (doc) {
63             doc->ensure_up_to_date();
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 = SPDocument::createNewDoc(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 = SPDocument::createNewDoc(patterns, FALSE);
103         }
104         g_free(patterns);
105         if (doc) {
106             doc->ensure_up_to_date();
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;
128 static SPObject *
129 sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc)
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 = SPDocument::createNewDoc(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 = SPDocument::createNewDoc(gradients, FALSE);
146         }
147         g_free(gradients);
148         if (doc) {
149             doc->ensure_up_to_date();
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;
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)
176     g_assert(urn != NULL);
177     
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         }
189         
190         if (*name_p ==':') {
191             name_p++;
192         }
193         
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(defs)->first_child();
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             }
213             
214         }
215         else if (!strcmp(base,"pattern"))  {
216             for (SPObject *child = SP_OBJECT(defs)->first_child() ;
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             }
227             
228         }
229         else if (!strcmp(base,"gradient"))  {
230             for (SPObject *child = SP_OBJECT(defs)->first_child();
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             }
241             
242         }
243         
244         if (object == NULL) {
245             
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         }
256         
257         g_free(base);
258         g_free(name);
259         
260         return object;
261     }
262     
263     else {
264         
265         SPDesktop *desktop = inkscape_active_desktop();
266         SPDocument *doc = sp_desktop_document(desktop);
267         SPObject *object = doc->getObjectById(urn);
269         return object;
270     }
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 :