1 /*
2 * SimpleNode - generic XML node implementation
3 *
4 * Copyright 2004-2005 MenTaLguY <mental@rydia.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * See the file COPYING for details.
12 *
13 */
15 #ifndef SEEN_INKSCAPE_XML_SIMPLE_NODE_H
16 #define SEEN_INKSCAPE_XML_SIMPLE_NODE_H
18 #include "xml/node.h"
19 #include "xml/attribute-record.h"
20 #include "xml/transaction-logger.h"
21 #include "xml/composite-node-observer.h"
22 #include "util/list-container.h"
24 namespace Inkscape {
26 namespace XML {
28 class SimpleNode
29 : virtual public Node, public Inkscape::GC::Managed<>
30 {
31 public:
32 Session *session() {
33 return ( _logger ? &_logger->session() : NULL );
34 }
36 gchar const *name() const;
37 int code() const { return _name; }
38 void setCodeUnsafe(int code) {
39 g_assert(_logger == NULL);
40 _name = code;
41 }
43 Document *document() { return _document; }
44 Document const *document() const {
45 return const_cast<SimpleNode *>(this)->document();
46 }
48 Node *duplicate() const { return _duplicate(); }
50 Node *root();
51 Node const *root() const {
52 return const_cast<SimpleNode *>(this)->root();
53 }
55 Node *parent() { return _parent; }
56 Node const *parent() const { return _parent; }
58 Node *next() { return _next; }
59 Node const *next() const { return _next; }
61 Node *firstChild() { return _first_child; }
62 Node const *firstChild() const { return _first_child; }
63 Node *lastChild() { return _last_child; }
64 Node const *lastChild() const { return _last_child; }
66 unsigned childCount() const { return _child_count; }
67 Node *nthChild(unsigned index);
68 Node const *nthChild(unsigned index) const {
69 return const_cast<SimpleNode *>(this)->nthChild(index);
70 }
72 void addChild(Node *child, Node *ref);
73 void appendChild(Node *child) {
74 SimpleNode::addChild(child, _last_child);
75 }
76 void removeChild(Node *child);
77 void changeOrder(Node *child, Node *ref);
79 unsigned position() const;
80 void setPosition(int pos);
82 gchar const *attribute(gchar const *key) const;
83 void setAttribute(gchar const *key, gchar const *value, bool is_interactive=false);
84 bool matchAttributeName(gchar const *partial_name) const;
86 gchar const *content() const;
87 void setContent(gchar const *value);
89 void mergeFrom(Node const *src, gchar const *key);
91 Inkscape::Util::List<AttributeRecord const> attributeList() const {
92 return _attributes;
93 }
95 void synthesizeEvents(NodeEventVector const *vector, void *data);
96 void synthesizeEvents(NodeObserver &observer);
98 void addListener(NodeEventVector const *vector, void *data) {
99 g_assert(vector != NULL);
100 _observers.addListener(*vector, data);
101 }
102 void addObserver(NodeObserver &observer) {
103 _observers.add(observer);
104 }
105 void removeListenerByData(void *data) {
106 _observers.removeListenerByData(data);
107 }
108 void removeObserver(NodeObserver &observer) {
109 _observers.remove(observer);
110 }
112 protected:
113 SimpleNode(int code);
114 SimpleNode(SimpleNode const &repr);
116 virtual SimpleNode *_duplicate() const=0;
118 public: // ideally these should be protected somehow...
119 void _setParent(Node *parent) { _parent = parent; }
120 void _setNext(Node *next) { _next = next; }
121 void _bindDocument(Document &document);
122 void _bindLogger(TransactionLogger &logger);
124 unsigned _childPosition(Node const &child) const;
125 unsigned _cachedPosition() const { return _cached_position; }
126 void _setCachedPosition(unsigned position) const {
127 _cached_position = position;
128 }
130 private:
131 void operator=(Node const &); // no assign
133 Node *_parent;
134 Node *_next;
135 Document *_document;
136 TransactionLogger *_logger;
137 mutable unsigned _cached_position;
139 int _name;
141 Inkscape::Util::MutableList<AttributeRecord> _attributes;
143 Inkscape::Util::ptr_shared<char> _content;
145 unsigned _child_count;
146 mutable bool _cached_positions_valid;
147 Node *_first_child;
148 Node *_last_child;
150 CompositeNodeObserver _observers;
151 };
153 }
155 }
157 #endif
158 /*
159 Local Variables:
160 mode:c++
161 c-file-style:"stroustrup"
162 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
163 indent-tabs-mode:nil
164 fill-column:99
165 End:
166 */
167 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :