1 #ifndef SP_OBJECT_H_SEEN
2 #define SP_OBJECT_H_SEEN
4 /** \file
5 * Abstract base class for all nodes
6 *
7 * Authors:
8 * Lauris Kaplinski <lauris@kaplinski.com>
9 *
10 * Copyright (C) 1999-2002 authors
11 * Copyright (C) 2001-2002 Ximian, Inc.
12 *
13 * Released under GNU GPL, read the file 'COPYING' for more information
14 */
16 /* SPObject flags */
18 class SPObject;
19 class SPObjectClass;
21 #define SP_TYPE_OBJECT (SPObject::sp_object_get_type ())
22 #define SP_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_OBJECT, SPObject))
23 #define SP_OBJECT_CLASS(clazz) (G_TYPE_CHECK_CLASS_CAST((clazz), SP_TYPE_OBJECT, SPObjectClass))
24 #define SP_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_OBJECT))
26 /* Async modification flags */
27 #define SP_OBJECT_MODIFIED_FLAG (1 << 0)
28 #define SP_OBJECT_CHILD_MODIFIED_FLAG (1 << 1)
29 #define SP_OBJECT_PARENT_MODIFIED_FLAG (1 << 2)
30 #define SP_OBJECT_STYLE_MODIFIED_FLAG (1 << 3)
31 #define SP_OBJECT_VIEWPORT_MODIFIED_FLAG (1 << 4)
32 #define SP_OBJECT_USER_MODIFIED_FLAG_A (1 << 5)
33 #define SP_OBJECT_USER_MODIFIED_FLAG_B (1 << 6)
34 #define SP_OBJECT_USER_MODIFIED_FLAG_C (1 << 7)
36 /* Conveneience */
37 #define SP_OBJECT_FLAGS_ALL 0xff
39 /* Flags that mark object as modified */
40 /* Object, Child, Style, Viewport, User */
41 #define SP_OBJECT_MODIFIED_STATE (SP_OBJECT_FLAGS_ALL & ~(SP_OBJECT_PARENT_MODIFIED_FLAG))
43 /* Flags that will propagate downstreams */
44 /* Parent, Style, Viewport, User */
45 #define SP_OBJECT_MODIFIED_CASCADE (SP_OBJECT_FLAGS_ALL & ~(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))
47 /* Generic */
48 #define SP_OBJECT_IS_CLONED(o) (((SPObject *) (o))->cloned)
50 /* Write flags */
51 #define SP_OBJECT_WRITE_BUILD (1 << 0)
52 #define SP_OBJECT_WRITE_EXT (1 << 1)
53 #define SP_OBJECT_WRITE_ALL (1 << 2)
55 /* Convenience stuff */
56 #define SP_OBJECT_ID(o) (((SPObject *) (o))->getId())
57 #define SP_OBJECT_REPR(o) (((SPObject *) (o))->getRepr())
58 #define SP_OBJECT_DOCUMENT(o) (((SPObject *) (o))->document)
59 #define SP_OBJECT_PARENT(o) (((SPObject *) (o))->parent)
60 #define SP_OBJECT_NEXT(o) (((SPObject *) (o))->next)
61 #define SP_OBJECT_PREV(o) (((SPObject *) (o))->prev())
62 #define SP_OBJECT_HREFCOUNT(o) (((SPObject *) (o))->hrefcount)
63 #define SP_OBJECT_STYLE(o) (((SPObject *) (o))->style)
65 #include <glib-object.h>
66 #include <sigc++/connection.h>
67 #include <sigc++/functors/slot.h>
68 #include <sigc++/signal.h>
70 #include "forward.h"
71 #include "version.h"
72 #include "util/forward-pointer-iterator.h"
73 #include "desktop-style.h"
75 namespace Inkscape {
76 namespace XML {
77 class Node;
78 class Document;
79 }
80 }
83 typedef enum {
84 SP_NO_EXCEPTION,
85 SP_INDEX_SIZE_ERR,
86 SP_DOMSTRING_SIZE_ERR,
87 SP_HIERARCHY_REQUEST_ERR,
88 SP_WRONG_DOCUMENT_ERR,
89 SP_INVALID_CHARACTER_ERR,
90 SP_NO_DATA_ALLOWED_ERR,
91 SP_NO_MODIFICATION_ALLOWED_ERR,
92 SP_NOT_FOUND_ERR,
93 SP_NOT_SUPPORTED_ERR,
94 SP_INUSE_ATTRIBUTE_ERR,
95 SP_INVALID_STATE_ERR,
96 SP_SYNTAX_ERR,
97 SP_INVALID_MODIFICATION_ERR,
98 SP_NAMESPACE_ERR,
99 SP_INVALID_ACCESS_ERR
100 } SPExceptionType;
102 class SPException;
104 /// An attempt to implement exceptions, unused?
105 struct SPException {
106 SPExceptionType code;
107 };
109 #define SP_EXCEPTION_INIT(ex) {(ex)->code = SP_NO_EXCEPTION;}
110 #define SP_EXCEPTION_IS_OK(ex) (!(ex) || ((ex)->code == SP_NO_EXCEPTION))
112 class SPCtx;
114 /// Unused
115 struct SPCtx {
116 unsigned int flags;
117 };
119 enum {
120 SP_XML_SPACE_DEFAULT,
121 SP_XML_SPACE_PRESERVE
122 };
124 class SPIXmlSpace;
126 /// Internal class consisting of two bits.
127 struct SPIXmlSpace {
128 guint set : 1;
129 guint value : 1;
130 };
132 class SPObject;
134 /*
135 * Refcounting
136 *
137 * Owner is here for debug reasons, you can set it to NULL safely
138 * Ref should return object, NULL is error, unref return always NULL
139 */
141 SPObject *sp_object_ref(SPObject *object, SPObject *owner=NULL);
142 SPObject *sp_object_unref(SPObject *object, SPObject *owner=NULL);
144 SPObject *sp_object_href(SPObject *object, gpointer owner);
145 SPObject *sp_object_hunref(SPObject *object, gpointer owner);
147 /// A refcounting tree node object.
148 class SPObject : public GObject {
149 public:
150 enum CollectionPolicy {
151 COLLECT_WITH_PARENT,
152 ALWAYS_COLLECT
153 };
155 unsigned int cloned : 1;
156 unsigned int uflags : 8;
157 unsigned int mflags : 8;
158 SPIXmlSpace xml_space;
159 unsigned int hrefcount; /* number of xlink:href references */
160 unsigned int _total_hrefcount; /* our hrefcount + total descendants */
161 SPDocument *document; /* Document we are part of */
162 SPObject *parent; /* Our parent (only one allowed) */
163 SPObject *children; /* Our children */
164 SPObject *_last_child; /* Remembered last child */
165 SPObject *next; /* Next object in linked list */
166 //Inkscape::XML::Node *repr; /* Our xml representation */
168 private:
169 gchar *id; /* Our very own unique id */
170 Inkscape::XML::Node *repr; /* Our xml representation */
171 public:
173 /**
174 * Returns the objects current ID string.
175 */
176 gchar const* getId() const;
178 /**
179 * Returns the XML representation of tree
180 */
181 //Inkscape::XML::Node const* getRepr() const;
182 //protected:
183 Inkscape::XML::Node * getRepr();
185 /**
186 * Returns the XML representation of tree
187 */
188 Inkscape::XML::Node const* getRepr() const;
189 public:
191 /** @brief cleans up an SPObject, releasing its references and
192 * requesting that references to it be released
193 */
194 void releaseReferences();
196 /** @brief connects to the release request signal
197 *
198 * @param slot the slot to connect
199 *
200 * @returns the sigc::connection formed
201 */
202 sigc::connection connectRelease(sigc::slot<void, SPObject *> slot) {
203 return _release_signal.connect(slot);
204 }
206 /**
207 * Represents the style properties, whether from presentation attributes, the <tt>style</tt>
208 * attribute, or inherited.
209 *
210 * sp_object_private_set doesn't handle SP_ATTR_STYLE or any presentation attributes at the
211 * time of writing, so this is probably NULL for all SPObject's that aren't an SPItem.
212 *
213 * However, this gives rise to the bugs mentioned in sp_object_get_style_property.
214 * Note that some non-SPItem SPObject's, such as SPStop, do need styling information,
215 * and need to inherit properties even through other non-SPItem parents like \<defs\>.
216 */
217 SPStyle *style;
219 /// Switch containing next() method.
220 struct ParentIteratorStrategy {
221 static SPObject const *next(SPObject const *object) {
222 return object->parent;
223 }
224 };
225 /// Switch containing next() method.
226 struct SiblingIteratorStrategy {
227 static SPObject const *next(SPObject const *object) {
228 return object->next;
229 }
230 };
232 typedef Inkscape::Util::ForwardPointerIterator<SPObject, ParentIteratorStrategy> ParentIterator;
233 typedef Inkscape::Util::ForwardPointerIterator<SPObject const, ParentIteratorStrategy> ConstParentIterator;
234 typedef Inkscape::Util::ForwardPointerIterator<SPObject, SiblingIteratorStrategy> SiblingIterator;
235 typedef Inkscape::Util::ForwardPointerIterator<SPObject const, SiblingIteratorStrategy> ConstSiblingIterator;
237 bool isSiblingOf(SPObject const *object) const {
238 g_return_val_if_fail(object != NULL, false);
239 return this->parent && this->parent == object->parent;
240 }
241 bool isAncestorOf(SPObject const *object) const;
243 SPObject const *nearestCommonAncestor(SPObject const *object) const;
244 /* A non-const version can be similarly constructed if you want one.
245 * (Don't just cast away the constness, which would be ill-formed.) */
247 SPObject *getNext();
248 SPObject *getPrev();
250 bool hasChildren() const { return ( children != NULL ); }
252 SPObject *firstChild() { return children; }
253 SPObject const *firstChild() const { return children; }
254 SPObject *lastChild() { return _last_child; }
255 SPObject const *lastChild() const { return _last_child; }
257 enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow };
258 /** @brief Retrieves children as a GSList */
259 GSList *childList(bool add_ref, Action action = ActionGeneral);
261 SPObject *appendChildRepr(Inkscape::XML::Node *repr);
263 /** @brief Gets the author-visible label for this object. */
264 gchar const *label() const;
265 /** @brief Returns a default label for this object. */
266 gchar const *defaultLabel() const;
267 /** @brief Sets the author-visible label for this object.
268 *
269 * Sets the author-visible label for the object.
270 *
271 * @param label the new label
272 */
273 void setLabel(gchar const *label);
275 /** Retrieves the title of this object */
276 gchar *title() const;
277 /** Sets the title of this object */
278 bool setTitle(gchar const *title, bool verbatim=false);
280 /** Retrieves the description of this object */
281 gchar *desc() const;
282 /** Sets the description of this object */
283 bool setDesc(gchar const *desc, bool verbatim=false);
285 /** @brief Set the policy under which this object will be
286 * orphan-collected.
287 *
288 * Orphan-collection is the process of deleting all objects which no longer have
289 * hyper-references pointing to them. The policy determines when this happens. Many objects
290 * should not be deleted simply because they are no longer referred to; other objects (like
291 * "intermediate" gradients) are more or less throw-away and should always be collected when no
292 * longer in use.
293 *
294 * Along these lines, there are currently two orphan-collection policies:
295 *
296 * COLLECT_WITH_PARENT - don't worry about the object's hrefcount;
297 * if its parent is collected, this object
298 * will be too
299 *
300 * COLLECT_ALWAYS - always collect the object as soon as its
301 * hrefcount reaches zero
302 *
303 * @returns the current collection policy in effect for this object
304 */
305 CollectionPolicy collectionPolicy() const { return _collection_policy; }
307 /** @brief Sets the orphan-collection policy in effect for this object.
308 *
309 * @see SPObject::collectionPolicy
310 *
311 * @param policy the new policy to adopt
312 */
313 void setCollectionPolicy(CollectionPolicy policy) {
314 _collection_policy = policy;
315 }
317 /** @brief Requests a later automatic call to collectOrphan().
318 *
319 * This method requests that collectOrphan() be called during the document update cycle,
320 * deleting the object if it is no longer used.
321 *
322 * If the current collection policy is COLLECT_WITH_PARENT, this function has no effect.
323 *
324 * @see SPObject::collectOrphan
325 */
326 void requestOrphanCollection();
328 /** @brief Unconditionally delete the object if it is not referenced.
329 *
330 * Unconditionally delete the object if there are no outstanding hyper-references to it.
331 * Observers are not notified of the object's deletion (at the SPObject level; XML tree
332 * notifications still fire).
333 *
334 * @see SPObject::deleteObject
335 */
336 void collectOrphan() {
337 if ( _total_hrefcount == 0 ) {
338 deleteObject(false);
339 }
340 }
342 /** @brief Check if object is referenced by any other object.
343 */
344 bool isReferenced() { return ( _total_hrefcount > 0 ); }
346 /** @brief Deletes an object.
347 *
348 * Detaches the object's repr, and optionally sends notification that the object has been
349 * deleted.
350 *
351 * @param propagate notify observers that the object has been deleted?
352 *
353 * @param propagate_descendants notify observers of children that they have been deleted?
354 */
355 void deleteObject(bool propagate, bool propagate_descendants);
357 /** @brief Deletes on object.
358 *
359 * @param propagate Notify observers of this object and its children that they have been
360 * deleted?
361 */
362 void deleteObject(bool propagate=true) {
363 deleteObject(propagate, propagate);
364 }
366 /** @brief Connects a slot to be called when an object is deleted.
367 *
368 * This connects a slot to an object's internal delete signal, which is invoked when the object
369 * is deleted
370 *
371 * The signal is mainly useful for e.g. knowing when to break hrefs or dissociate clones.
372 *
373 * @param slot the slot to connect
374 *
375 * @see SPObject::deleteObject
376 */
377 sigc::connection connectDelete(sigc::slot<void, SPObject *> slot) {
378 return _delete_signal.connect(slot);
379 }
381 sigc::connection connectPositionChanged(sigc::slot<void, SPObject *> slot) {
382 return _position_changed_signal.connect(slot);
383 }
385 /** @brief Returns the object which supercedes this one (if any).
386 *
387 * This is mainly useful for ensuring we can correctly perform a series of moves or deletes,
388 * even if the objects in question have been replaced in the middle of the sequence.
389 */
390 SPObject *successor() { return _successor; }
392 /** @brief Indicates that another object supercedes this one. */
393 void setSuccessor(SPObject *successor) {
394 g_assert(successor != NULL);
395 g_assert(_successor == NULL);
396 g_assert(successor->_successor == NULL);
397 sp_object_ref(successor, NULL);
398 _successor = successor;
399 }
401 /* modifications; all three sets of methods should probably ultimately be protected, as they
402 * are not really part of its public interface. However, other parts of the code to
403 * occasionally use them at present. */
405 /* the no-argument version of updateRepr() is intended to be a bit more public, however -- it
406 * essentially just flushes any changes back to the backing store (the repr layer); maybe it
407 * should be called something else and made public at that point. */
409 /** @brief Updates the object's repr based on the object's state.
410 *
411 * This method updates the the repr attached to the object to reflect the object's current
412 * state; see the three-argument version for details.
413 *
414 * @param flags object write flags that apply to this update
415 *
416 * @return the updated repr
417 */
418 Inkscape::XML::Node *updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT);
420 /** @brief Updates the given repr based on the object's state.
421 *
422 * This method updates the given repr to reflect the object's current state. There are
423 * several flags that affect this:
424 *
425 * SP_OBJECT_WRITE_BUILD - create new reprs
426 *
427 * SP_OBJECT_WRITE_EXT - write elements and attributes
428 * which are not part of pure SVG
429 * (i.e. the Inkscape and Sodipodi
430 * namespaces)
431 *
432 * SP_OBJECT_WRITE_ALL - create all nodes and attributes,
433 * even those which might be redundant
434 *
435 * @param repr the repr to update
436 * @param flags object write flags that apply to this update
437 *
438 * @return the updated repr
439 */
440 Inkscape::XML::Node *updateRepr(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, unsigned int flags);
442 /** @brief Queues an deferred update of this object's display.
443 *
444 * This method sets flags to indicate updates to be performed later, during the idle loop.
445 *
446 * There are several flags permitted here:
447 *
448 * SP_OBJECT_MODIFIED_FLAG - the object has been modified
449 *
450 * SP_OBJECT_CHILD_MODIFIED_FLAG - a child of the object has been
451 * modified
452 *
453 * SP_OBJECT_STYLE_MODIFIED_FLAG - the object's style has been
454 * modified
455 *
456 * There are also some subclass-specific modified flags which are hardly ever used.
457 *
458 * One of either MODIFIED or CHILD_MODIFIED is required.
459 *
460 * @param flags flags indicating what to update
461 */
462 void requestDisplayUpdate(unsigned int flags);
464 /** @brief Updates the object's display immediately
465 *
466 * This method is called during the idle loop by SPDocument in order to update the object's
467 * display.
468 *
469 * One additional flag is legal here:
470 *
471 * SP_OBJECT_PARENT_MODIFIED_FLAG - the parent has been
472 * modified
473 *
474 * @param ctx an SPCtx which accumulates various state
475 * during the recursive update -- beware! some
476 * subclasses try to cast this to an SPItemCtx *
477 *
478 * @param flags flags indicating what to update (in addition
479 * to any already set flags)
480 */
481 void updateDisplay(SPCtx *ctx, unsigned int flags);
483 /** @brief Requests that a modification notification signal
484 * be emitted later (e.g. during the idle loop)
485 *
486 * @param flags flags indicating what has been modified
487 */
488 void requestModified(unsigned int flags);
490 /** @brief Emits a modification notification signal
491 *
492 * @param flags indicating what has been modified
493 */
494 void emitModified(unsigned int flags);
496 /** @brief Connects to the modification notification signal
497 *
498 * @param slot the slot to connect
499 *
500 * @returns the connection formed thereby
501 */
502 sigc::connection connectModified(
503 sigc::slot<void, SPObject *, unsigned int> slot
504 ) {
505 return _modified_signal.connect(slot);
506 }
508 void _sendDeleteSignalRecursive();
509 void _updateTotalHRefCount(int increment);
511 void _requireSVGVersion(unsigned major, unsigned minor) {
512 _requireSVGVersion(Inkscape::Version(major, minor));
513 }
514 void _requireSVGVersion(Inkscape::Version version);
516 sigc::signal<void, SPObject *> _release_signal;
517 sigc::signal<void, SPObject *> _delete_signal;
518 sigc::signal<void, SPObject *> _position_changed_signal;
519 sigc::signal<void, SPObject *, unsigned int> _modified_signal;
520 SPObject *_successor;
521 CollectionPolicy _collection_policy;
522 gchar *_label;
523 mutable gchar *_default_label;
524 void attach(SPObject *object, SPObject *prev);
525 void reorder(SPObject *prev);
526 void detach(SPObject *object);
527 SPObject *get_child_by_repr(Inkscape::XML::Node *repr);
528 SPObject *first_child() {
529 return firstChild();
530 }
531 void invoke_build(SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned);
532 long long int getIntAttribute(char const *key, long long int def);
533 unsigned getPosition();
534 gchar const * getAttribute(gchar const *name,SPException *ex=0) const;
535 void appendChild(Inkscape::XML::Node *child);
536 void addChild(Inkscape::XML::Node *child,Inkscape::XML::Node *prev=0);
537 void setKeyValue(unsigned int key, gchar const *value);
538 void setAttribute(gchar const *key, gchar const *value, SPException *ex=0);
539 void readAttr(gchar const *key);
540 gchar const *getTagName(SPException *ex) const;
541 void removeAttribute(gchar const *key, SPException *ex=0);
542 gchar const *getStyleProperty(gchar const *key, gchar const *def) const;
543 SPObject *prev();
544 void setCSS(SPCSSAttr *css, gchar const *attr);
545 void changeCSS(SPCSSAttr *css, gchar const *attr);
546 bool storeAsDouble( gchar const *key, double *val ) const;
548 private:
549 // Private member functions used in the definitions of setTitle(),
550 // setDesc(), title() and desc().
551 bool setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool verbatim);
552 gchar * getTitleOrDesc(gchar const *svg_tagname) const;
553 SPObject * findFirstChild(gchar const *tagname) const;
554 GString * textualContent() const;
556 static void sp_object_init(SPObject *object);
557 static void sp_object_finalize(GObject *object);
559 static void sp_object_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref);
560 static void sp_object_remove_child(SPObject *object, Inkscape::XML::Node *child);
561 static void sp_object_order_changed(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref);
563 static void sp_object_release(SPObject *object);
564 static void sp_object_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
566 static void sp_object_private_set(SPObject *object, unsigned int key, gchar const *value);
567 static Inkscape::XML::Node *sp_object_private_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
568 static gchar *sp_object_get_unique_id(SPObject *object, gchar const *defid);
570 /* Real handlers of repr signals */
572 public:
573 static GType sp_object_get_type();
574 static void sp_object_repr_attr_changed(Inkscape::XML::Node *repr, gchar const *key, gchar const *oldval, gchar const *newval, bool is_interactive, gpointer data);
576 static void sp_object_repr_content_changed(Inkscape::XML::Node *repr, gchar const *oldcontent, gchar const *newcontent, gpointer data);
578 static void sp_object_repr_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data);
579 static void sp_object_repr_child_removed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void *data);
581 static void sp_object_repr_order_changed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *newer, gpointer data);
584 friend class SPObjectClass;
585 friend class SPObjectImpl;
586 };
588 /// The SPObject vtable.
589 class SPObjectClass {
590 public:
591 GObjectClass parent_class;
593 void (* build) (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr);
594 void (* release) (SPObject *object);
596 /* Virtual handlers of repr signals */
597 void (* child_added) (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref);
598 void (* remove_child) (SPObject *object, Inkscape::XML::Node *child);
600 void (* order_changed) (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *new_repr);
602 void (* set) (SPObject *object, unsigned int key, gchar const *value);
604 void (* read_content) (SPObject *object);
606 /* Update handler */
607 void (* update) (SPObject *object, SPCtx *ctx, unsigned int flags);
608 /* Modification handler */
609 void (* modified) (SPObject *object, unsigned int flags);
611 Inkscape::XML::Node * (* write) (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, unsigned int flags);
613 private:
614 static GObjectClass *static_parent_class;
615 static void sp_object_class_init(SPObjectClass *klass);
617 friend class SPObject;
618 };
621 /*
622 * Attaching/detaching
623 */
625 //void sp_object_attach(SPObject *parent, SPObject *object, SPObject *prev);
626 //void sp_object_reorder(SPObject *object, SPObject *prev);
627 //void sp_object_detach(SPObject *parent, SPObject *object);
629 /*inline SPObject *sp_object_first_child(SPObject *parent) {
630 return parent->firstChild();
631 }*/
632 //SPObject *sp_object_get_child_by_repr(SPObject *object, Inkscape::XML::Node *repr);
634 //void sp_object_invoke_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned);
636 //void sp_object_set(SPObject *object, unsigned int key, gchar const *value);
638 //void sp_object_read_attr(SPObject *object, gchar const *key);
640 /* Public */
642 //gchar const *sp_object_tagName_get(SPObject const *object, SPException *ex);
643 //gchar const *sp_object_getAttribute(SPObject const *object, gchar const *key, SPException *ex);
644 //void sp_object_setAttribute(SPObject *object, gchar const *key, gchar const *value, SPException *ex);
645 //void sp_object_removeAttribute(SPObject *object, gchar const *key, SPException *ex);
647 /* Style */
649 //gchar const *sp_object_get_style_property(SPObject const *object,
650 // gchar const *key, gchar const *def);
652 int sp_object_compare_position(SPObject const *first, SPObject const *second);
654 //SPObject *sp_object_prev(SPObject *child);
657 #endif // SP_OBJECT_H_SEEN
660 /*
661 Local Variables:
662 mode:c++
663 c-file-style:"stroustrup"
664 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
665 indent-tabs-mode:nil
666 fill-column:99
667 End:
668 */
669 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :