Code

69fe2adcefbd9294ff7ac69d090f5a02739b0c6d
[inkscape.git] / src / xml / repr.h
1 #ifndef __SP_REPR_H__
2 #define __SP_REPR_H__
4 /** \file
5  * C facade to Inkscape::XML::Node.
6  *
7  * Authors:
8  *   Lauris Kaplinski <lauris@kaplinski.com>
9  *
10  * Copyright (C) 1999-2002 authors
11  * Copyright (C) 2000-2002 Ximian, Inc.
12  *
13  * Released under GNU GPL, read the file 'COPYING' for more information
14  */
16 #include <stdio.h>
17 #include <glib/gtypes.h>
18 #include "gc-anchored.h"
20 #include "xml/node.h"
21 #include "xml/document.h"
22 #include "xml/sp-css-attr.h"
23 #include "io/inkscapestream.h"
25 #include <2geom/point.h>
27 #define SP_SODIPODI_NS_URI "http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
28 #define SP_BROKEN_SODIPODI_NS_URI "http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
29 #define SP_INKSCAPE_NS_URI "http://www.inkscape.org/namespaces/inkscape"
30 #define SP_XLINK_NS_URI "http://www.w3.org/1999/xlink"
31 #define SP_SVG_NS_URI "http://www.w3.org/2000/svg"
32 #define SP_RDF_NS_URI "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
33 #define SP_CC_NS_URI "http://creativecommons.org/ns#"
34 #define SP_OLD_CC_NS_URI "http://web.resource.org/cc/"
35 #define SP_DC_NS_URI "http://purl.org/dc/elements/1.1/"
37 /**
38  * \note NB! Unless explicitly stated all methods are noref/nostrcpy
39  */
41 /** \todo
42  * Though Inkscape::XML::Node provides "signals" for notification when 
43  * individual nodes change, there is no mechanism to receive notification 
44  * for overall document changes.
45  * However, with the addition of the transactions code, it would not be
46  * very hard to implement if you wanted it.
47  * 
48  * \class Inkscape::XML::Node
49  * \note
50  * Inkscape::XML::Node itself doesn't use GObject signals at present -- 
51  * Inkscape::XML::Nodes maintain lists of Inkscape::XML::NodeEventVectors 
52  * (added via sp_repr_add_listener), which are used to specify callbacks 
53  * when something changes.
54  *
55  * Here are the current callbacks in an event vector (they may be NULL):
56  *
57  * void (* child_added)(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, 
58  * Inkscape::XML::Node *ref, void *data); Called once a child has been added.
59  *
60  * void (* child_removed)(Inkscape::XML::Node *repr, 
61  * Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void *data);
62  * Called after a child is removed; ref is the child that used to precede
63  * the removed child.
64  *
65  * void (* attr_changed)(Inkscape::XML::Node *repr, gchar const *key, 
66  * gchar const *oldval, gchar const *newval, void *data);
67  * Called after an attribute has been changed.
68  *
69  * void (* content_changed)(Inkscape::XML::Node *repr, gchar const *oldcontent,
70  * gchar const *newcontent, void *data);
71  * Called after an element's content has been changed.
72  *
73  * void (* order_changed)(Inkscape::XML::Node *repr, Inkscape::XML::Node *child,
74  * Inkscape::XML::Node *oldref, Inkscape::XML::Node *newref, void *data);
75  * Called once the child has been moved to its new position in the child order.
76  *
77  * <b> Inkscape::XML::Node mini-FAQ </b>
78  *
79  * Since I'm not very familiar with this section of code but I need to use
80  * it heavily for the RDF work, I'm going to answer various questions I run
81  * into with my best-guess answers so others can follow along too.
82  *
83  * \arg
84  * Q: How do I find the root Inkscape::XML::Node? <br>
85  * A: If you have an SPDocument, use doc->rroot.  For example: 
86  * 
87  * \code    SP_ACTIVE_DOCUMENT->rroot       \endcode <br>
88  * 
89  * (but it's better to arrange for your caller to pass in the relevent
90  * document rather than assuming it's necessarily the active one and
91  * using SP_ACTIVE_DOCUMENT)
92  *
93  * \arg
94  * Q: How do I find an Inkscape::XML::Node by unique key/value? <br>
95  * A: Use sp_repr_lookup_child
96  *
97  * \arg
98  * Q: How do I find an Inkscape::XML::Node by unique namespace name? <br>
99  * A: Use sp_repr_lookup_name
100  *
101  * \arg
102  * Q: How do I make an Inkscape::XML::Node namespace prefix constant in 
103  * the application? <br>
104  * A: Add the XML namespace URL as a #define to repr.h at the top with the
105  * other SP_<NAMESPACE>_NS_URI #define's, and then in repr-util.cpp,
106  * in sp_xml_ns_register_defaults, bump "defaults" up in size one, and
107  * add another section.  Don't forget to increment the array offset and
108  * keep ".next" pointed to the next (if any) array entry.
109  *
110  * \arg
111  * Q: How do I create a new Inkscape::XML::Node? <br>
112  * A: Use the appropriate create* method on Inkscape::XML::Document,
113  * parent->appendChild(child), and then use Inkscape::GC::release(child) to
114  * let go of it (the parent will hold it in memory).
115  *
116  * \arg
117  * Q: How do I destroy an Inkscape::XML::Node?
118  * A: Just call "sp_repr_unparent" on it and release any references
119  * you may be retaining to it.  Any attached SPObjects will
120  * clean themselves up automatically, as will any children.
121  *
122  * \arg
123  * Q: What about listeners? <br>
124  * A: I have no idea yet...
125  *
126  * \arg
127  * Q: How do I add a namespace to a newly created document?  <br>
128  * A: The current hack is in document.cpp:sp_document_create
129  *
130  * Kees Cook  2004-07-01, updated MenTaLguY 2005-01-25
131  */
133 namespace Geom {
134 class Point;
137 /* SPXMLNs */
138 char const *sp_xml_ns_uri_prefix(gchar const *uri, gchar const *suggested);
139 char const *sp_xml_ns_prefix_uri(gchar const *prefix);
141 Inkscape::XML::Document *sp_repr_document_new(gchar const *rootname);
143 /* Contents */
144 /// Sets the node's \a key attribute to \a value.
145 inline unsigned sp_repr_set_attr(Inkscape::XML::Node *repr, gchar const *key, gchar const *value,
146                                  bool is_interactive = false) {
147     repr->setAttribute(key, value, is_interactive);
148     return true;
151 /* Tree */
152 /// Returns the node's parent.
153 inline Inkscape::XML::Node *sp_repr_parent(Inkscape::XML::Node const *repr) {
154     return const_cast<Inkscape::XML::Node *>(repr->parent());
157 /// Returns first child of node, resets iterator.
158 inline Inkscape::XML::Node const *sp_repr_children(Inkscape::XML::Node const *repr) {
159     return ( repr ? repr->firstChild() : NULL );
162 /// Returns first child of node, resets iterator.
163 inline Inkscape::XML::Node *sp_repr_children(Inkscape::XML::Node *repr) {
164     return ( repr ? repr->firstChild() : NULL );
167 /// Returns next child of node or NULL.
168 inline Inkscape::XML::Node const *sp_repr_next(Inkscape::XML::Node const *repr) {
169     return ( repr ? repr->next() : NULL );
172 /// Returns next child of node or NULL.
173 inline Inkscape::XML::Node *sp_repr_next(Inkscape::XML::Node *repr) {
174     return ( repr ? repr->next() : NULL );
177 /* IO */
179 Inkscape::XML::Document *sp_repr_read_file(gchar const *filename, gchar const *default_ns);
180 Inkscape::XML::Document *sp_repr_read_mem(gchar const *buffer, int length, gchar const *default_ns);
181 void sp_repr_write_stream (Inkscape::XML::Node *repr, Inkscape::IO::Writer &out,
182                  gint indent_level,  bool add_whitespace, Glib::QueryQuark elide_prefix,
183                                  int inlineattrs, int indent);
184 Inkscape::XML::Document *sp_repr_read_buf (const Glib::ustring &buf, const gchar *default_ns);
185 Glib::ustring sp_repr_write_buf(Inkscape::XML::Node *repr, gint indent_level,
186                       bool add_whitespace, Glib::QueryQuark elide_prefix,
187                                           int inlineattrs, int indent);
188 void sp_repr_save_stream(Inkscape::XML::Document *doc, FILE *to_file, gchar const *default_ns=NULL, bool compress = false);
189 bool sp_repr_save_file(Inkscape::XML::Document *doc, gchar const *filename, gchar const *default_ns=NULL);
191 void sp_repr_print(Inkscape::XML::Node *repr);
193 /* CSS stuff */
195 SPCSSAttr *sp_repr_css_attr_new(void);
196 void sp_repr_css_attr_unref(SPCSSAttr *css);
197 SPCSSAttr *sp_repr_css_attr(Inkscape::XML::Node *repr, gchar const *attr);
198 SPCSSAttr *sp_repr_css_attr_inherited(Inkscape::XML::Node *repr, gchar const *attr);
200 gchar const *sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval);
201 void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value);
202 void sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name);
203 bool sp_repr_css_property_is_unset(SPCSSAttr *css, gchar const *name);
204 double sp_repr_css_double_property(SPCSSAttr *css, gchar const *name, double defval);
206 gchar *sp_repr_css_write_string(SPCSSAttr *css);
207 void sp_repr_css_set(Inkscape::XML::Node *repr, SPCSSAttr *css, gchar const *key);
208 void sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src);
209 void sp_repr_css_attr_add_from_string(SPCSSAttr *css, const gchar *data);
210 void sp_repr_css_change(Inkscape::XML::Node *repr, SPCSSAttr *css, gchar const *key);
211 void sp_repr_css_change_recursive(Inkscape::XML::Node *repr, SPCSSAttr *css, gchar const *key);
213 void sp_repr_css_print(SPCSSAttr *css);
215 /* Utility finctions */
216 /// Remove \a repr from children of its parent node.
217 inline void sp_repr_unparent(Inkscape::XML::Node *repr) {
218     Inkscape::XML::Node *parent=repr->parent();
219     if (parent) {
220         parent->removeChild(repr);
221     }
224 /* Convenience */
225 unsigned sp_repr_get_boolean(Inkscape::XML::Node *repr, gchar const *key, unsigned *val);
226 unsigned sp_repr_get_int(Inkscape::XML::Node *repr, gchar const *key, int *val);
227 unsigned sp_repr_get_double(Inkscape::XML::Node *repr, gchar const *key, double *val);
228 unsigned sp_repr_set_boolean(Inkscape::XML::Node *repr, gchar const *key, unsigned val);
229 unsigned sp_repr_set_int(Inkscape::XML::Node *repr, gchar const *key, int val);
230 unsigned sp_repr_set_css_double(Inkscape::XML::Node *repr, gchar const *key, double val);
231 unsigned sp_repr_set_svg_double(Inkscape::XML::Node *repr, gchar const *key, double val);
232 unsigned sp_repr_set_point(Inkscape::XML::Node *repr, gchar const *key, Geom::Point val);
233 unsigned sp_repr_get_point(Inkscape::XML::Node *repr, gchar const *key, Geom::Point *val);
235 /// \deprecated !
236 double sp_repr_get_double_attribute(Inkscape::XML::Node *repr, gchar const *key, double def);
237 /// \deprecated !
238 long long int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, gchar const *key, long long int def);
239 /* End Deprecated? */
241 int sp_repr_compare_position(Inkscape::XML::Node *first, Inkscape::XML::Node *second);
243 /* Searching */
244 Inkscape::XML::Node *sp_repr_lookup_name(Inkscape::XML::Node *repr,
245                                          gchar const *name,
246                                          gint maxdepth = -1);
247 Inkscape::XML::Node *sp_repr_lookup_child(Inkscape::XML::Node *repr,
248                                           gchar const *key,
249                                           gchar const *value);
252 inline Inkscape::XML::Node *sp_repr_document_first_child(Inkscape::XML::Document const *doc) {
253     return const_cast<Inkscape::XML::Node *>(doc->firstChild());
256 #endif
259 /*
260   Local Variables:
261   mode:c++
262   c-file-style:"stroustrup"
263   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
264   indent-tabs-mode:nil
265   fill-column:99
266   End:
267 */
268 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :