Code

SPObject c++ification finalized along with the beginning of XML Privatisation tweaks
[inkscape.git] / src / sp-object.h
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"
74 namespace Inkscape {
75 namespace XML {
76 class Node;
77 class Document;
78 }
79 }
82 typedef enum {
83     SP_NO_EXCEPTION,
84     SP_INDEX_SIZE_ERR,
85     SP_DOMSTRING_SIZE_ERR,
86     SP_HIERARCHY_REQUEST_ERR,
87     SP_WRONG_DOCUMENT_ERR,
88     SP_INVALID_CHARACTER_ERR,
89     SP_NO_DATA_ALLOWED_ERR,
90     SP_NO_MODIFICATION_ALLOWED_ERR,
91     SP_NOT_FOUND_ERR,
92     SP_NOT_SUPPORTED_ERR,
93     SP_INUSE_ATTRIBUTE_ERR,
94     SP_INVALID_STATE_ERR,
95     SP_SYNTAX_ERR,
96     SP_INVALID_MODIFICATION_ERR,
97     SP_NAMESPACE_ERR,
98     SP_INVALID_ACCESS_ERR
99 } SPExceptionType;
101 class SPException;
103 /// An attempt to implement exceptions, unused?
104 struct SPException {
105     SPExceptionType code;
106 };
108 #define SP_EXCEPTION_INIT(ex) {(ex)->code = SP_NO_EXCEPTION;}
109 #define SP_EXCEPTION_IS_OK(ex) (!(ex) || ((ex)->code == SP_NO_EXCEPTION))
111 class SPCtx;
113 /// Unused
114 struct SPCtx {
115     unsigned int flags;
116 };
118 enum {
119     SP_XML_SPACE_DEFAULT,
120     SP_XML_SPACE_PRESERVE
121 };
123 class SPIXmlSpace;
125 /// Internal class consisting of two bits.
126 struct SPIXmlSpace {
127     guint set : 1;
128     guint value : 1;
129 };
131 class SPObject;
133 /*
134  * Refcounting
135  *
136  * Owner is here for debug reasons, you can set it to NULL safely
137  * Ref should return object, NULL is error, unref return always NULL
138  */
140 SPObject *sp_object_ref(SPObject *object, SPObject *owner=NULL);
141 SPObject *sp_object_unref(SPObject *object, SPObject *owner=NULL);
143 SPObject *sp_object_href(SPObject *object, gpointer owner);
144 SPObject *sp_object_hunref(SPObject *object, gpointer owner);
146 /// A refcounting tree node object.
147 class SPObject : public GObject {
148         public:
149     enum CollectionPolicy {
150         COLLECT_WITH_PARENT,
151         ALWAYS_COLLECT
152     };
154     unsigned int cloned : 1;
155     unsigned int uflags : 8;
156     unsigned int mflags : 8;
157     SPIXmlSpace xml_space;
158     unsigned int hrefcount; /* number of xlink:href references */
159     unsigned int _total_hrefcount; /* our hrefcount + total descendants */
160     SPDocument *document; /* Document we are part of */
161     SPObject *parent; /* Our parent (only one allowed) */
162     SPObject *children; /* Our children */
163     SPObject *_last_child; /* Remembered last child */
164     SPObject *next; /* Next object in linked list */
165     //Inkscape::XML::Node *repr; /* Our xml representation */
167 private:
168     gchar *id; /* Our very own unique id */
169     Inkscape::XML::Node *repr; /* Our xml representation */
170 public:
172     /**
173      * Returns the objects current ID string.
174      */
175     gchar const* getId() const;
177         /**
178          * Returns the XML representation of tree
179          */
180         //Inkscape::XML::Node const* getRepr() const;
181 //protected:    
182         Inkscape::XML::Node * getRepr();
184         /**
185          * Returns the XML representation of tree
186          */
187         Inkscape::XML::Node const* getRepr() const;
188 public: 
189         
190     /** @brief cleans up an SPObject, releasing its references and
191      *         requesting that references to it be released
192      */
193     void releaseReferences();
195     /** @brief connects to the release request signal
196      *
197      *  @param slot the slot to connect
198      *
199      *  @returns the sigc::connection formed
200      */
201     sigc::connection connectRelease(sigc::slot<void, SPObject *> slot) {
202         return _release_signal.connect(slot);
203     }
205     /**
206      * Represents the style properties, whether from presentation attributes, the <tt>style</tt>
207      * attribute, or inherited.
208      *
209      * sp_object_private_set doesn't handle SP_ATTR_STYLE or any presentation attributes at the
210      * time of writing, so this is probably NULL for all SPObject's that aren't an SPItem.
211      *
212      * However, this gives rise to the bugs mentioned in sp_object_get_style_property.
213      * Note that some non-SPItem SPObject's, such as SPStop, do need styling information,
214      * and need to inherit properties even through other non-SPItem parents like \<defs\>.
215      */
216     SPStyle *style;
218     /// Switch containing next() method.
219     struct ParentIteratorStrategy {
220         static SPObject const *next(SPObject const *object) {
221             return object->parent;
222         }
223     };
224     /// Switch containing next() method.
225     struct SiblingIteratorStrategy {
226         static SPObject const *next(SPObject const *object) {
227             return object->next;
228         }
229     };
231     typedef Inkscape::Util::ForwardPointerIterator<SPObject, ParentIteratorStrategy> ParentIterator;
232     typedef Inkscape::Util::ForwardPointerIterator<SPObject const, ParentIteratorStrategy> ConstParentIterator;
233     typedef Inkscape::Util::ForwardPointerIterator<SPObject, SiblingIteratorStrategy> SiblingIterator;
234     typedef Inkscape::Util::ForwardPointerIterator<SPObject const, SiblingIteratorStrategy> ConstSiblingIterator;
236     bool isSiblingOf(SPObject const *object) const {
237         g_return_val_if_fail(object != NULL, false);
238         return this->parent && this->parent == object->parent;
239     }
240     bool isAncestorOf(SPObject const *object) const;
242     SPObject const *nearestCommonAncestor(SPObject const *object) const;
243     /* A non-const version can be similarly constructed if you want one.
244      * (Don't just cast away the constness, which would be ill-formed.) */
246     SPObject *getNext();
247     SPObject *getPrev();
249     bool hasChildren() const { return ( children != NULL ); }
251     SPObject *firstChild() { return children; }
252     SPObject const *firstChild() const { return children; }
253     SPObject *lastChild() { return _last_child; }
254     SPObject const *lastChild() const { return _last_child; }
256     enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow };
257     /** @brief Retrieves children as a GSList */
258     GSList *childList(bool add_ref, Action action = ActionGeneral);
260     SPObject *appendChildRepr(Inkscape::XML::Node *repr);
262     /** @brief Gets the author-visible label for this object. */
263     gchar const *label() const;
264     /** @brief Returns a default label for this object. */
265     gchar const *defaultLabel() const;
266     /** @brief Sets the author-visible label for this object.
267      *
268      * Sets the author-visible label for the object.
269      *
270      * @param label the new label
271      */
272     void setLabel(gchar const *label);
274     /** Retrieves the title of this object */
275     gchar *title() const;
276     /** Sets the title of this object */
277     bool setTitle(gchar const *title, bool verbatim=false);
279     /** Retrieves the description of this object */
280     gchar *desc() const;
281     /** Sets the description of this object */
282     bool setDesc(gchar const *desc, bool verbatim=false);
284     /** @brief Set the policy under which this object will be
285      *         orphan-collected.
286      *
287      * Orphan-collection is the process of deleting all objects which no longer have
288      * hyper-references pointing to them.  The policy determines when this happens.  Many objects
289      * should not be deleted simply because they are no longer referred to; other objects (like
290      * "intermediate" gradients) are more or less throw-away and should always be collected when no
291      * longer in use.
292      *
293      * Along these lines, there are currently two orphan-collection policies:
294      *
295      *  COLLECT_WITH_PARENT - don't worry about the object's hrefcount;
296      *                        if its parent is collected, this object
297      *                        will be too
298      *
299      *  COLLECT_ALWAYS - always collect the object as soon as its
300      *                   hrefcount reaches zero
301      *
302      * @returns the current collection policy in effect for this object
303      */
304     CollectionPolicy collectionPolicy() const { return _collection_policy; }
306     /** @brief Sets the orphan-collection policy in effect for this object.
307      *
308      * @see SPObject::collectionPolicy
309      *
310      * @param policy the new policy to adopt
311      */
312     void setCollectionPolicy(CollectionPolicy policy) {
313         _collection_policy = policy;
314     }
316     /** @brief Requests a later automatic call to collectOrphan().
317      *
318      * This method requests that collectOrphan() be called during the document update cycle,
319      * deleting the object if it is no longer used.
320      *
321      * If the current collection policy is COLLECT_WITH_PARENT, this function has no effect.
322      *
323      * @see SPObject::collectOrphan
324      */
325     void requestOrphanCollection();
327     /** @brief Unconditionally delete the object if it is not referenced.
328      *
329      * Unconditionally delete the object if there are no outstanding hyper-references to it.
330      * Observers are not notified of the object's deletion (at the SPObject level; XML tree
331      * notifications still fire).
332      *
333      * @see SPObject::deleteObject
334      */
335     void collectOrphan() {
336         if ( _total_hrefcount == 0 ) {
337             deleteObject(false);
338         }
339     }
341     /** @brief Check if object is referenced by any other object.
342      */
343     bool isReferenced() { return ( _total_hrefcount > 0 ); }
345     /** @brief Deletes an object.
346      *
347      * Detaches the object's repr, and optionally sends notification that the object has been
348      * deleted.
349      *
350      * @param propagate notify observers that the object has been deleted?
351      *
352      * @param propagate_descendants notify observers of children that they have been deleted?
353      */
354     void deleteObject(bool propagate, bool propagate_descendants);
356     /** @brief Deletes on object.
357      *
358      * @param propagate Notify observers of this object and its children that they have been
359      *                  deleted?
360      */
361     void deleteObject(bool propagate=true) {
362         deleteObject(propagate, propagate);
363     }
365     /** @brief Connects a slot to be called when an object is deleted.
366      *
367      * This connects a slot to an object's internal delete signal, which is invoked when the object
368      * is deleted
369      *
370      * The signal is mainly useful for e.g. knowing when to break hrefs or dissociate clones.
371      *
372      * @param slot the slot to connect
373      *
374      * @see SPObject::deleteObject
375      */
376     sigc::connection connectDelete(sigc::slot<void, SPObject *> slot) {
377         return _delete_signal.connect(slot);
378     }
380     sigc::connection connectPositionChanged(sigc::slot<void, SPObject *> slot) {
381         return _position_changed_signal.connect(slot);
382     }
384     /** @brief Returns the object which supercedes this one (if any).
385      *
386      * This is mainly useful for ensuring we can correctly perform a series of moves or deletes,
387      * even if the objects in question have been replaced in the middle of the sequence.
388      */
389     SPObject *successor() { return _successor; }
391     /** @brief Indicates that another object supercedes this one. */
392     void setSuccessor(SPObject *successor) {
393         g_assert(successor != NULL);
394         g_assert(_successor == NULL);
395         g_assert(successor->_successor == NULL);
396         sp_object_ref(successor, NULL);
397         _successor = successor;
398     }
400     /* modifications; all three sets of methods should probably ultimately be protected, as they
401      * are not really part of its public interface.  However, other parts of the code to
402      * occasionally use them at present. */
404     /* the no-argument version of updateRepr() is intended to be a bit more public, however -- it
405      * essentially just flushes any changes back to the backing store (the repr layer); maybe it
406      * should be called something else and made public at that point. */
408     /** @brief Updates the object's repr based on the object's state.
409      *
410      *  This method updates the the repr attached to the object to reflect the object's current
411      *  state; see the three-argument version for details.
412      *
413      *  @param flags object write flags that apply to this update
414      *
415      *  @return the updated repr
416      */
417     Inkscape::XML::Node *updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT);
419     /** @brief Updates the given repr based on the object's state.
420      *
421      *  This method updates the given repr to reflect the object's current state.  There are
422      *  several flags that affect this:
423      *
424      *   SP_OBJECT_WRITE_BUILD - create new reprs
425      *
426      *   SP_OBJECT_WRITE_EXT   - write elements and attributes
427      *                           which are not part of pure SVG
428      *                           (i.e. the Inkscape and Sodipodi
429      *                           namespaces)
430      *
431      *   SP_OBJECT_WRITE_ALL   - create all nodes and attributes,
432      *                           even those which might be redundant
433      *
434      *  @param repr the repr to update
435      *  @param flags object write flags that apply to this update
436      *
437      *  @return the updated repr
438      */
439     Inkscape::XML::Node *updateRepr(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, unsigned int flags);
441     /** @brief Queues an deferred update of this object's display.
442      *
443      *  This method sets flags to indicate updates to be performed later, during the idle loop.
444      *
445      *  There are several flags permitted here:
446      *
447      *   SP_OBJECT_MODIFIED_FLAG - the object has been modified
448      *
449      *   SP_OBJECT_CHILD_MODIFIED_FLAG - a child of the object has been
450      *                                   modified
451      *
452      *   SP_OBJECT_STYLE_MODIFIED_FLAG - the object's style has been
453      *                                   modified
454      *
455      *  There are also some subclass-specific modified flags which are hardly ever used.
456      *
457      *  One of either MODIFIED or CHILD_MODIFIED is required.
458      *
459      *  @param flags flags indicating what to update
460      */
461     void requestDisplayUpdate(unsigned int flags);
463     /** @brief Updates the object's display immediately
464      *
465      *  This method is called during the idle loop by SPDocument in order to update the object's
466      *  display.
467      *
468      *  One additional flag is legal here:
469      *
470      *   SP_OBJECT_PARENT_MODIFIED_FLAG - the parent has been
471      *                                    modified
472      *
473      *  @param ctx an SPCtx which accumulates various state
474      *             during the recursive update -- beware! some
475      *             subclasses try to cast this to an SPItemCtx *
476      *
477      *  @param flags flags indicating what to update (in addition
478      *               to any already set flags)
479      */
480     void updateDisplay(SPCtx *ctx, unsigned int flags);
482     /** @brief Requests that a modification notification signal
483      *         be emitted later (e.g. during the idle loop)
484      *
485      *  @param flags flags indicating what has been modified
486      */
487     void requestModified(unsigned int flags);
489     /** @brief Emits a modification notification signal
490      *
491      *  @param flags indicating what has been modified
492      */
493     void emitModified(unsigned int flags);
495     /** @brief Connects to the modification notification signal
496      *
497      *  @param slot the slot to connect
498      *
499      *  @returns the connection formed thereby
500      */
501     sigc::connection connectModified(
502       sigc::slot<void, SPObject *, unsigned int> slot
503     ) {
504         return _modified_signal.connect(slot);
505     }
507     void _sendDeleteSignalRecursive();
508     void _updateTotalHRefCount(int increment);
510     void _requireSVGVersion(unsigned major, unsigned minor) {
511         _requireSVGVersion(Inkscape::Version(major, minor));
512     }
513     void _requireSVGVersion(Inkscape::Version version);
515     sigc::signal<void, SPObject *> _release_signal;
516     sigc::signal<void, SPObject *> _delete_signal;
517     sigc::signal<void, SPObject *> _position_changed_signal;
518     sigc::signal<void, SPObject *, unsigned int> _modified_signal;
519     SPObject *_successor;
520     CollectionPolicy _collection_policy;
521     gchar *_label;
522     mutable gchar *_default_label;
523         void attach(SPObject *object, SPObject *prev);
524         void reorder(SPObject *prev);
525         void detach(SPObject *object);
526         SPObject *get_child_by_repr(Inkscape::XML::Node *repr);
527         SPObject *first_child() {
528                     return firstChild();
529         }
530         void invoke_build(SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned);
531         long long int getIntAttribute(char const *key, long long int def);
532         unsigned getPosition();
533         gchar const * getAttribute(gchar const *name,SPException *ex=0) const;
534         void appendChild(Inkscape::XML::Node *child);
535         void setKeyValue(unsigned int key, gchar const *value);
536         void setAttribute(gchar const *key, gchar const *value, SPException *ex=0);
537         void readAttr(gchar const *key);
538         gchar const *getTagName(SPException *ex) const;
539         void removeAttribute(gchar const *key, SPException *ex=0);
540         gchar const *getStyleProperty(gchar const *key, gchar const *def) const;
541         SPObject *prev();
543 private:
544     // Private member functions used in the definitions of setTitle(),
545     // setDesc(), title() and desc().
546     bool setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool verbatim);
547     gchar * getTitleOrDesc(gchar const *svg_tagname) const;
548     SPObject * findFirstChild(gchar const *tagname) const;
549     GString * textualContent() const;
551         static void sp_object_init(SPObject *object);
552         static void sp_object_finalize(GObject *object);
554         static void sp_object_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref);
555         static void sp_object_remove_child(SPObject *object, Inkscape::XML::Node *child);
556         static void sp_object_order_changed(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref);
558         static void sp_object_release(SPObject *object);
559         static void sp_object_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
561         static void sp_object_private_set(SPObject *object, unsigned int key, gchar const *value);
562         static Inkscape::XML::Node *sp_object_private_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
563         static gchar *sp_object_get_unique_id(SPObject *object, gchar const *defid);
565         /* Real handlers of repr signals */
566         
567         public:
568         static GType sp_object_get_type();
569         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);
571         static void sp_object_repr_content_changed(Inkscape::XML::Node *repr, gchar const *oldcontent, gchar const *newcontent, gpointer data);
573         static void sp_object_repr_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data);
574         static void sp_object_repr_child_removed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void *data);
576         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);
579         friend class SPObjectClass;     
580     friend class SPObjectImpl;
581 };
583 /// The SPObject vtable.
584 class SPObjectClass {
585         public:
586     GObjectClass parent_class;
588     void (* build) (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr);
589     void (* release) (SPObject *object);
591     /* Virtual handlers of repr signals */
592     void (* child_added) (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref);
593     void (* remove_child) (SPObject *object, Inkscape::XML::Node *child);
595     void (* order_changed) (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *new_repr);
597     void (* set) (SPObject *object, unsigned int key, gchar const *value);
599     void (* read_content) (SPObject *object);
601     /* Update handler */
602     void (* update) (SPObject *object, SPCtx *ctx, unsigned int flags);
603     /* Modification handler */
604     void (* modified) (SPObject *object, unsigned int flags);
606     Inkscape::XML::Node * (* write) (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, unsigned int flags);
608         private:
609         static GObjectClass *static_parent_class;
610         static void sp_object_class_init(SPObjectClass *klass);
612         friend class SPObject;
613 };
616 /*
617  * Attaching/detaching
618  */
620 //void sp_object_attach(SPObject *parent, SPObject *object, SPObject *prev);
621 //void sp_object_reorder(SPObject *object, SPObject *prev);
622 //void sp_object_detach(SPObject *parent, SPObject *object);
624 /*inline SPObject *sp_object_first_child(SPObject *parent) {
625     return parent->firstChild();
626 }*/
627 //SPObject *sp_object_get_child_by_repr(SPObject *object, Inkscape::XML::Node *repr);
629 //void sp_object_invoke_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned);
631 //void sp_object_set(SPObject *object, unsigned int key, gchar const *value);
633 //void sp_object_read_attr(SPObject *object, gchar const *key);
635 /* Public */
637 //gchar const *sp_object_tagName_get(SPObject const *object, SPException *ex);
638 //gchar const *sp_object_getAttribute(SPObject const *object, gchar const *key, SPException *ex);
639 //void sp_object_setAttribute(SPObject *object, gchar const *key, gchar const *value, SPException *ex);
640 //void sp_object_removeAttribute(SPObject *object, gchar const *key, SPException *ex);
642 /* Style */
644 //gchar const *sp_object_get_style_property(SPObject const *object,
645 //                                          gchar const *key, gchar const *def);
647 int sp_object_compare_position(SPObject const *first, SPObject const *second);
649 //SPObject *sp_object_prev(SPObject *child);
652 #endif // SP_OBJECT_H_SEEN
655 /*
656   Local Variables:
657   mode:c++
658   c-file-style:"stroustrup"
659   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
660   indent-tabs-mode:nil
661   fill-column:99
662   End:
663 */
664 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :