1 /** @file
2 * @brief Interface for XML node observers
3 */
4 /* Authors:
5 * MenTaLguY <mental@rydia.net>
6 * Krzysztof KosiĆski <tweenk.pl@gmail.com> (documentation)
7 *
8 * Copyright 2005-2008 Authors
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * See the file COPYING for details.
16 */
18 #ifndef SEEN_INKSCAPE_XML_NODE_OBSERVER_H
19 #define SEEN_INKSCAPE_XML_NODE_OBSERVER_H
21 #include <glib/gquark.h>
22 #include "util/share.h"
23 #include "xml/xml-forward.h"
25 #ifndef INK_UNUSED
26 #define INK_UNUSED(x) ((void)(x))
27 #endif // INK_UNUSED
29 namespace Inkscape {
30 namespace XML {
32 /**
33 * @brief Interface for XML node observers
34 *
35 * This class defines an interface for objects that can receive
36 * XML node state change notifications. The observer has to be registered using
37 * the Node::addObserver() method to be notified of changes of this node only,
38 * or using Node::addSubtreeObserver() to also receive notifications about its
39 * descendants. All observer methods are called when the operations in question have
40 * been completed, just before returning from the modifying methods.
41 *
42 * Be careful when e.g. changing an attribute of @c node in notifyAttributeChanged().
43 * The method will be called again due to the XML modification performed in it. If you
44 * don't take special precautions to ignore the second call, it will result in infinite
45 * recursion.
46 *
47 * The virtual methods of this class do nothing by default, so you don't need to provide
48 * stubs for things you don't use. A good idea is to make the observer register itself
49 * on construction and unregister itself on destruction. This will ensure there are
50 * no dangling references.
51 */
52 class NodeObserver {
53 protected:
54 /* the constructor is protected to prevent instantiation */
55 NodeObserver() {}
56 public:
57 virtual ~NodeObserver() {}
59 /**
60 * @brief Child addition callback
61 *
62 * This method is called whenever a child is added to the observed node. The @c prev
63 * parameter is NULL when the newly added child is first in the sibling order.
64 *
65 * @param node The changed XML node
66 * @param child The newly added child node
67 * @param prev The node after which the new child was inserted into the sibling order, or NULL
68 */
69 virtual void notifyChildAdded(Node &node, Node &child, Node *prev) {
70 INK_UNUSED(node);
71 INK_UNUSED(child);
72 INK_UNUSED(prev);
73 }
75 /**
76 * @brief Child removal callback
77 *
78 * This method is called whenever a child is removed from the observed node. The @c prev
79 * parameter is NULL when the removed child was first in the sibling order.
80 *
81 * @param node The changed XML node
82 * @param child The removed child node
83 * @param prev The node that was before the removed node in sibling order, or NULL
84 */
85 virtual void notifyChildRemoved(Node &node, Node &child, Node *prev) {
86 INK_UNUSED(node);
87 INK_UNUSED(child);
88 INK_UNUSED(prev);
89 }
91 /**
92 * @brief Child order change callback
93 *
94 * This method is called whenever the order of a node's children is changed using
95 * Node::changeOrder(). The @c old_prev parameter is NULL if the relocated node
96 * was first in the sibling order before the order change, and @c new_prev is NULL
97 * if it was moved to the first position by this operation.
98 *
99 * @param node The changed XML node
100 * @param child The child node that was relocated in the sibling order
101 * @param old_prev The node that was before @c child prior to the order change
102 * @param new_prev The node that is before @c child after the order change
103 */
104 virtual void notifyChildOrderChanged(Node &node, Node &child,
105 Node *old_prev, Node *new_prev) {
106 INK_UNUSED(node);
107 INK_UNUSED(child);
108 INK_UNUSED(old_prev);
109 INK_UNUSED(new_prev);
110 }
112 /**
113 * @brief Content change callback
114 *
115 * This method is called whenever a node's content is changed using Node::setContent(),
116 * e.g. for text or comment nodes.
117 *
118 * @param node The changed XML node
119 * @param old_content Old content of @c node
120 * @param new_content New content of @c node
121 */
122 virtual void notifyContentChanged(Node &node,
123 Util::ptr_shared<char> old_content,
124 Util::ptr_shared<char> new_content) {
125 INK_UNUSED(node);
126 INK_UNUSED(old_content);
127 INK_UNUSED(new_content);
128 }
130 /**
131 * @brief Attribute change callback
132 *
133 * This method is called whenever one of a node's attributes is changed.
134 *
135 * @param node The changed XML node
136 * @param name GQuark corresponding to the attribute's name
137 * @param old_value Old value of the modified attribute
138 * @param new_value New value of the modified attribute
139 */
140 virtual void notifyAttributeChanged(Node &node, GQuark name,
141 Util::ptr_shared<char> old_value,
142 Util::ptr_shared<char> new_value) {
143 INK_UNUSED(node);
144 INK_UNUSED(name);
145 INK_UNUSED(old_value);
146 INK_UNUSED(new_value);
147 }
148 };
150 } // namespace XML
151 } // namespace Inkscape
153 #endif
154 /*
155 Local Variables:
156 mode:c++
157 c-file-style:"stroustrup"
158 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
159 indent-tabs-mode:nil
160 fill-column:99
161 End:
162 */
163 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :