From: tweenk Date: Tue, 23 Sep 2008 23:34:58 +0000 (+0000) Subject: * Lots of documentation for the Inkscape::XML namespace X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=cb9f00490c21d085087d6db4fe89294e3890ed2d;p=inkscape.git * Lots of documentation for the Inkscape::XML namespace * Doxygen fixes for a few files * Garbage-collected allocator for STL containers --- diff --git a/src/2geom/geom.cpp b/src/2geom/geom.cpp index fc6d930dc..ded1a1940 100644 --- a/src/2geom/geom.cpp +++ b/src/2geom/geom.cpp @@ -1,6 +1,5 @@ -/** - * \file src/geom.cpp - * \brief Various geometrical calculations. +/** @file + * @brief Various geometrical calculations. */ #ifdef HAVE_CONFIG_H diff --git a/src/2geom/geom.h b/src/2geom/geom.h index 1a40c04e1..210d236a1 100644 --- a/src/2geom/geom.h +++ b/src/2geom/geom.h @@ -1,8 +1,7 @@ -/** - * \file geom.h - * \brief Various geometrical calculations - * - * Authors: +/** @file + * @brief Various geometrical calculations + */ +/* Authors: * Nathan Hurst * * Copyright (C) 1999-2002 authors diff --git a/src/Makefile_insert b/src/Makefile_insert index 2aaf3607b..33e4f07f8 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -331,6 +331,7 @@ libinkpost_a_SOURCES = \ gc-finalized.h gc-finalized.cpp \ gc-managed.h \ gc-soft-ptr.h \ + gc-allocator.h \ gc.cpp \ gradient-chemistry.cpp gradient-chemistry.h \ ink-action.cpp \ diff --git a/src/arc-context.cpp b/src/arc-context.cpp index 0b4904bdf..1409d1d64 100644 --- a/src/arc-context.cpp +++ b/src/arc-context.cpp @@ -1,21 +1,20 @@ -#define __SP_ARC_CONTEXT_C__ - -/** \file Ellipse drawing context. */ - -/* - * Authors: +/** @file + * @brief Ellipse drawing context + */ +/* Authors: * Mitsuru Oka * Lauris Kaplinski * bulia byak + * Johan Engelen * - * Copyright (C) 2006 Johan Engelen - * Copyright (C) 2002 Mitsuru Oka - * Copyright (C) 2000-2002 Lauris Kaplinski + * Copyright (C) 2000-2006 Authors * Copyright (C) 2000-2001 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information */ +#define __SP_ARC_CONTEXT_C__ + #ifdef HAVE_CONFIG_H # include #endif diff --git a/src/dir-util.cpp b/src/dir-util.cpp index 7cc69f89d..75f7ca524 100644 --- a/src/dir-util.cpp +++ b/src/dir-util.cpp @@ -1,4 +1,6 @@ -/** \file Some utility functions for filenames. */ +/** @file + * @brief Utility functions for filenames + */ #define DIR_UTIL_C diff --git a/src/fill-or-stroke.h b/src/fill-or-stroke.h index d0b174dca..e4195324f 100644 --- a/src/fill-or-stroke.h +++ b/src/fill-or-stroke.h @@ -1,8 +1,10 @@ +/** @file + * @brief Definition of the FillOrStroke enum. + */ + #ifndef SEEN_FILL_OR_STROKE_H #define SEEN_FILL_OR_STROKE_H -/** \file Definition of the FillOrStroke enum. */ - /** \post STROKE == 0, FILL != 0. */ enum FillOrStroke { STROKE = 0, FILL = 1 }; diff --git a/src/gc-allocator.h b/src/gc-allocator.h new file mode 100644 index 000000000..4d809cfe4 --- /dev/null +++ b/src/gc-allocator.h @@ -0,0 +1,106 @@ +/** @file + * @brief Garbage-collected STL allocator for standard containers + */ +/* Authors: + * Krzysztof Kosiński + * + * Copyright 2008 Authors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + */ + +#ifndef SEEN_INKSCAPE_GC_ALLOCATOR_H +#define SEEN_INKSCAPE_GC_ALLOCATOR_H + +#include +#include +#include "gc-core.h" + +namespace Inkscape { +namespace GC { + +/** + * @brief Garbage-collected allocator for the standard containers + * + * STL containers with default parameters cannot be used as members in garbage-collected + * objects, because by default the destructors are not called, causing a memory leak + * (the memory allocated by the container is not freed). To address this, STL containers + * can be told to use this garbage-collected allocator. It usually is the last template + * parameter. For example, to define a GC-managed map of ints to Unicode strings: + * + * @code typedef std::map, Inkscape::GC::Allocator> gcmap; @endcode + * + * Afterwards, you can place gcmap as a member in a non-finalized GC-managed object, because + * all memory used by gcmap will also be reclaimable by the garbage collector, therefore + * avoiding memory leaks. + */ +template +class Allocator { + // required typedefs + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T * pointer; + typedef T const * const_pointer; + typedef T & reference; + typedef T const & const_reference; + + // required structure that allows accessing the same allocator for a different type + template + struct rebind { + typedef Allocator other; + }; + + // constructors - no-ops since the allocator doesn't have any state + Allocator() throw() {} + Allocator(Allocator const &) throw() {} + template Allocator(Allocator const &) throw() {} + ~Allocator() throw() {} + + // trivial required methods + pointer address(reference ref) { return &ref; } + const_pointer address(const_reference ref) { return &ref; } + void construct(pointer p, T const &value) { new (static_cast(p)) T(value); } + void destroy(pointer p) { p->~T(); } + + // maximum meaningful memory amount that can be requested from the allocator + size_type max_size() { + return numeric_limits::max() / sizeof(T); + } + + // allocate memory for num elements without initializing them + pointer allocate(size_type num, Allocator::const_pointer) { + return static_cast( Inkscape::GC::Core::malloc(num * sizeof(T)) ); + } + + // deallocate memory at p + void deallocate(pointer p, size_type) { + Inkscape::GC::Core::free(p); + } +}; + +// required comparison operators +template +bool operator==(Allocator const &, Allocator const &) { return true; } +template +bool operator!=(Allocator const &, Allocator const &) { return false; } + +} // namespace GC +} // namespace Inkscape + +#endif // !SEEN_INKSCAPE_GC_ALLOCATOR_H +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/gc-core.h b/src/gc-core.h index faf7eb4de..af327dc55 100644 --- a/src/gc-core.h +++ b/src/gc-core.h @@ -1,7 +1,7 @@ -/* - * Inkscape::GC - Wrapper for Boehm GC - * - * Authors: +/** @file + * @brief Wrapper for Boehm GC + */ +/* Authors: * MenTaLguY * * Copyright (C) 2004 MenTaLguY diff --git a/src/gc-finalized.h b/src/gc-finalized.h index 738d37692..cf47cb09b 100644 --- a/src/gc-finalized.h +++ b/src/gc-finalized.h @@ -23,7 +23,7 @@ namespace Inkscape { namespace GC { -/* @brief a mix-in ensuring that a object's destructor will get called before +/* @brief A mix-in ensuring that an object's destructor will get called before * the garbage collector destroys it * * Normally, the garbage collector does not call destructors before destroying @@ -39,7 +39,7 @@ namespace GC { * happens. * * The best way to limit this effect is to only make "leaf" objects - * (i.e. those that don't point to other finalizaable objects) + * (i.e. those that don't point to other finalizable objects) * finalizable, and otherwise use GC::soft_ptr<> instead of a regular * pointer for "backreferences" (e.g. parent pointers in a tree * structure), so that those references can be cleared to break any @@ -48,22 +48,19 @@ namespace GC { * @see Inkscape::GC::soft_ptr<> * * 2. Because there is no guarantee when the collector will destroy - * objects, there is no guarantee when the destructor will get called. - * - * It may not get called until the very end of the program, or ever. + * objects, it is impossible to tell in advance when the destructor + * will get called. It may not get called until the very end + * of the program, or ever. * * 3. If allocated in arrays, only the first object in the array will * have its destructor called, unless you make other arrangements by * registering your own finalizer instead. * - * 4. Similarly, making multiple GC::Finalized-derived objects members - * of a non-finalized but garbage-collected object generally won't - * work unless you take care of registering finalizers yourself. - * - * [n.b., by "member", I mean an actual by-value-member of a type that - * derives from GC::Finalized, not simply a member that's a pointer or a - * reference to such a type] - * + * 4. Similarly, putting a finalized object as a member in another + * garbage collected but non-finalized object will cause the member + * object's destructor not to be called when the parent object is + * collected, unless you register the finalizer yourself (by "member" + * we mean an actual by-value member, not a reference or a pointer). */ class Finalized { public: diff --git a/src/gc-managed.h b/src/gc-managed.h index 80d9c9411..954c8103b 100644 --- a/src/gc-managed.h +++ b/src/gc-managed.h @@ -1,7 +1,7 @@ -/** \file - * Inkscape::GC::Managed - base class for GC-managed objects - * - * Copyright 2004 MenTaLguY +/** @file + * @brief Base class for GC-managed objects + */ +/* Copyright 2004 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -9,7 +9,6 @@ * of the License, or (at your option) any later version. * * See the file COPYING for details. - * */ #ifndef SEEN_INKSCAPE_GC_MANAGED_H diff --git a/src/gc.cpp b/src/gc.cpp index 8a55a3b15..ee988afbb 100644 --- a/src/gc.cpp +++ b/src/gc.cpp @@ -1,7 +1,7 @@ -/* - * Inkscape::GC - Wrapper for Boehm GC - * - * Authors: +/** @file + * @brief Wrapper for Boehm GC + */ +/* Authors: * MenTaLguY * * Copyright (C) 2004 MenTaLguY diff --git a/src/jabber_whiteboard/inkboard-document.h b/src/jabber_whiteboard/inkboard-document.h index 6bfcab59b..419ac485c 100644 --- a/src/jabber_whiteboard/inkboard-document.h +++ b/src/jabber_whiteboard/inkboard-document.h @@ -65,8 +65,6 @@ public: void handleChange(Message::Wrapper &wrapper, Pedro::Element* data); - NodeObserver *logger() { return this; } - // // XML::Session methods // @@ -135,6 +133,7 @@ protected: { return new InkboardDocument(*this); } + NodeObserver *logger() { return this; } private: void _initBindings(); diff --git a/src/libnr/nr-point-matrix-ops.h b/src/libnr/nr-point-matrix-ops.h index 58e06fc6d..81e351103 100644 --- a/src/libnr/nr-point-matrix-ops.h +++ b/src/libnr/nr-point-matrix-ops.h @@ -1,4 +1,6 @@ -/** \file operator functions over (NR::Point, NR::Matrix). */ +/** @file + * @brief Operator functions over (NR::Point, NR::Matrix) + */ #ifndef SEEN_NR_POINT_MATRIX_OPS_H #define SEEN_NR_POINT_MATRIX_OPS_H diff --git a/src/libnrtype/boundary-type.h b/src/libnrtype/boundary-type.h index 7f8ecea90..27baf43b7 100644 --- a/src/libnrtype/boundary-type.h +++ b/src/libnrtype/boundary-type.h @@ -1,8 +1,10 @@ +/** @file + * @brief Definition of the BoundaryType enum + */ + #ifndef LIBNRTYPE_BOUNDARY_TYPE_H_INKSCAPE #define LIBNRTYPE_BOUNDARY_TYPE_H_INKSCAPE -/** \file Definition of the BoundaryType enum. */ - /** * The different kinds of semantic boundaries in text; or rather, * the different things that may be delimited by a text_boundary. diff --git a/src/libnrtype/one-box.h b/src/libnrtype/one-box.h index 1040e2be9..7e1d90b72 100644 --- a/src/libnrtype/one-box.h +++ b/src/libnrtype/one-box.h @@ -1,4 +1,6 @@ -/** \file Definition of struct one_box. */ +/** @file + * @brief Definition of struct one_box + */ #ifndef LIBNRTYPE_ONE_BOX_H_INKSCAPE #define LIBNRTYPE_ONE_BOX_H_INKSCAPE diff --git a/src/libnrtype/one-glyph.h b/src/libnrtype/one-glyph.h index 667c7743b..9467e69e9 100644 --- a/src/libnrtype/one-glyph.h +++ b/src/libnrtype/one-glyph.h @@ -1,9 +1,12 @@ -/** \file Definition of struct one_glyph. */ - -/* - * License: May be redistributed with or without modifications under the terms of the Gnu General - * Public License as published by the Free Software Foundation, version 2 or (at your option) any - * later version. +/** @file + * @brief Definition of struct one_glyph + */ +/* This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. */ #ifndef LIBNRTYPE_ONE_GLYPH_H_INKSCAPE diff --git a/src/libnrtype/text-boundary.h b/src/libnrtype/text-boundary.h index 83a825b55..82532df1f 100644 --- a/src/libnrtype/text-boundary.h +++ b/src/libnrtype/text-boundary.h @@ -1,14 +1,17 @@ +/** @file + * @brief Definition of the structure text_boundary + */ +/* This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + */ + #ifndef TEXT_BOUNDARY_H_INKSCAPE #define TEXT_BOUNDARY_H_INKSCAPE -/** \file Definition of text_boundary. */ - -/* - * License: May be redistributed with or without modifications under the terms of the Gnu General - * Public License as published by the Free Software Foundation, version 2 or (at your option) any - * later version. - */ - #include "libnrtype/boundary-type.h" diff --git a/src/libvpsc/remove_rectangle_overlap.cpp b/src/libvpsc/remove_rectangle_overlap.cpp index 68af4c5c5..4d2750b9e 100644 --- a/src/libvpsc/remove_rectangle_overlap.cpp +++ b/src/libvpsc/remove_rectangle_overlap.cpp @@ -1,5 +1,5 @@ -/** - * \brief remove overlaps between a set of rectangles. +/** @file + * @brief remove overlaps between a set of rectangles. * * Authors: * Tim Dwyer diff --git a/src/libvpsc/remove_rectangle_overlap.h b/src/libvpsc/remove_rectangle_overlap.h index baa15b594..1af90a754 100644 --- a/src/libvpsc/remove_rectangle_overlap.h +++ b/src/libvpsc/remove_rectangle_overlap.h @@ -1,17 +1,17 @@ -#ifndef REMOVE_RECTANGLE_OVERLAP_H_SEEN -#define REMOVE_RECTANGLE_OVERLAP_H_SEEN - -/** - * \file Declaration of main internal remove-overlaps function. +/** @file + * @brief Declaration of main internal remove-overlaps function. */ -/* - * Authors: +/* Authors: * Tim Dwyer * * Copyright (C) 2005 Authors * * Released under GNU LGPL. Read the file 'COPYING' for more information. */ + +#ifndef REMOVE_RECTANGLE_OVERLAP_H_SEEN +#define REMOVE_RECTANGLE_OVERLAP_H_SEEN + namespace vpsc { class Rectangle; } diff --git a/src/livarot/sweep-tree-list.h b/src/livarot/sweep-tree-list.h index 271a6baae..b6e765e13 100644 --- a/src/livarot/sweep-tree-list.h +++ b/src/livarot/sweep-tree-list.h @@ -1,6 +1,9 @@ +/** @file + * @brief SweepTreeList definition + */ + #ifndef INKSCAPE_LIVAROT_SWEEP_TREE_LIST_H #define INKSCAPE_LIVAROT_SWEEP_TREE_LIST_H -/** \file SweepTreeList definition. */ class Shape; class SweepTree; diff --git a/src/ui/widget/color-picker.h b/src/ui/widget/color-picker.h index 9ac38b84b..477aa1c19 100644 --- a/src/ui/widget/color-picker.h +++ b/src/ui/widget/color-picker.h @@ -1,11 +1,7 @@ -#ifndef __COLOR_PICKER_H__ -#define __COLOR_PICKER_H__ - -/** - * \file Color picker button \& window. +/** @file + * @brief Color picker button and window. */ -/* - * Authors: +/* Authors: * Lauris Kaplinski * Ralf Stephan * @@ -14,6 +10,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef __COLOR_PICKER_H__ +#define __COLOR_PICKER_H__ + #include #include #include diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 8f7d56c76..aae34ed98 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -190,7 +190,7 @@ void PrefWatcher::notifyAttributeChanged( Node &node, GQuark name, } else if (strcmp("displayprofile", id) == 0) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring current = prefs->getString("options.displayprofile", "uri"); - bool enabled = current.length() > 0; + bool enabled = !current.empty(); for ( std::list::iterator it = dtws.begin(); it != dtws.end(); ++it ) { SPDesktopWidget* dtw = *it; @@ -208,12 +208,11 @@ void PrefWatcher::notifyAttributeChanged( Node &node, GQuark name, (*it)->requestCanvasUpdate(); } } + } #else - { - (void)node; - (void)name; + (void)node; + (void)name; #endif // ENABLE_LCMS - } } static PrefWatcher* watcher = 0; diff --git a/src/xml/Makefile_insert b/src/xml/Makefile_insert index 46be9edfa..84e907126 100644 --- a/src/xml/Makefile_insert +++ b/src/xml/Makefile_insert @@ -50,7 +50,8 @@ xml_libspxml_a_SOURCES = \ xml/subtree.cpp \ xml/subtree.h \ xml/text-node.h \ - xml/invalid-operation-exception.h + xml/invalid-operation-exception.h \ + xml/xml-forward.h xml/test-xml-main.cpp: xml/test-xml.cpp $(xml_test_xml_includes) $(top_srcdir)/cxxtest/cxxtestgen.pl --template=$(srcdir)/selfname.tpl -root -o xml/test-xml-main.cpp $(xml_test_xml_includes) diff --git a/src/xml/attribute-record.h b/src/xml/attribute-record.h index bfae19e21..bab0b5aa4 100644 --- a/src/xml/attribute-record.h +++ b/src/xml/attribute-record.h @@ -1,3 +1,7 @@ +/** @file + * @brief Key-value pair representing an attribute + */ + #ifndef SEEN_XML_SP_REPR_ATTR_H #define SEEN_XML_SP_REPR_ATTR_H @@ -12,11 +16,19 @@ namespace Inkscape { namespace XML { +/** + * @brief Key-value pair representing an attribute + * + * Internally, the attributes of each node in the XML tree are + * represented by this structure. + */ struct AttributeRecord : public Inkscape::GC::Managed<> { AttributeRecord(GQuark k, Inkscape::Util::ptr_shared v) : key(k), value(v) {} + /** @brief GQuark corresponding to the name of the attribute */ GQuark key; + /** @brief Shared pointer to the value of the attribute */ Inkscape::Util::ptr_shared value; // accept default copy constructor and assignment operator diff --git a/src/xml/comment-node.h b/src/xml/comment-node.h index 5cff9caf6..698a30a90 100644 --- a/src/xml/comment-node.h +++ b/src/xml/comment-node.h @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::CommentNode - simple XML comment implementation - * - * Copyright 2004-2005 MenTaLguY +/** @file + * @brief Comment node implementation + */ +/* Copyright 2004-2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,6 +22,9 @@ namespace Inkscape { namespace XML { +/** + * @brief Comment node, e.g. <!-- Some comment --> + */ struct CommentNode : public SimpleNode { CommentNode(Util::ptr_shared content, Document *doc) : SimpleNode(g_quark_from_static_string("comment"), doc) diff --git a/src/xml/composite-node-observer.h b/src/xml/composite-node-observer.h index 7b5a24d53..826467dc4 100644 --- a/src/xml/composite-node-observer.h +++ b/src/xml/composite-node-observer.h @@ -1,7 +1,7 @@ -/* +/** @file * Inkscape::XML::CompositeNodeObserver - combine multiple observers - * - * Copyright 2005 MenTaLguY + */ +/* Copyright 2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -25,6 +25,14 @@ namespace XML { class NodeEventVector; +/** + * @brief An observer that relays notifications to multiple other observers + * + * This special observer keeps a list of other observer objects and sends + * the notifications it receives to all of them. The implementation of the class + * allows an observer to remove itself from this object during a method call. + * For the documentation of callback methods, see NodeObserver. + */ class CompositeNodeObserver : public NodeObserver, public GC::Managed<> { public: struct ObserverRecord : public GC::Managed<> { @@ -38,9 +46,25 @@ public: CompositeNodeObserver() : _iterating(0), _active_marked(0), _pending_marked(0) {} + /** + * @brief Add an observer to the list + * @param observer The observer object to add + */ void add(NodeObserver &observer); - void addListener(NodeEventVector const &vector, void *data); + /** + * @brief Remove an observer from the list + * @param observer The observer object to remove + */ void remove(NodeObserver &observer); + /** + * @brief Add a set of callbacks with associated data + * @deprecated Use add() instead + */ + void addListener(NodeEventVector const &vector, void *data); + /** + * @brief Remove a set of callbacks by its associated data + * @deprecated Use remove() instead + */ void removeListenerByData(void *data); void notifyChildAdded(Node &node, Node &child, Node *prev); @@ -69,9 +93,8 @@ private: void _finishIteration(); }; -} - -} +} // namespace XML +} // namespace Inkscape #endif /* diff --git a/src/xml/croco-node-iface.cpp b/src/xml/croco-node-iface.cpp index a40ddd661..db98e3d01 100644 --- a/src/xml/croco-node-iface.cpp +++ b/src/xml/croco-node-iface.cpp @@ -45,6 +45,12 @@ static char const *get_local_name(CRXMLNodePtr n) { return local_part(static_cas static gboolean is_element_node(CRXMLNodePtr n) { return static_cast(n)->type() == ELEMENT_NODE; } } +/** + * @brief Interface for XML nodes used by libcroco + * + * This structure defines operations on Inkscape::XML::Node used by the libcroco + * CSS parsing library. + */ CRNodeIface const croco_node_iface = { get_parent, get_first_child, diff --git a/src/xml/document.h b/src/xml/document.h index 5065092d0..2b9ea5cc3 100644 --- a/src/xml/document.h +++ b/src/xml/document.h @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::Document - interface for XML documents - * - * Copyright 2005 MenTaLguY +/** @file + * @brief Interface for XML documents + */ +/* Copyright 2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,29 +15,94 @@ #ifndef SEEN_INKSCAPE_XML_SP_REPR_DOC_H #define SEEN_INKSCAPE_XML_SP_REPR_DOC_H +#include "xml/xml-forward.h" #include "xml/node.h" namespace Inkscape { namespace XML { -class Event; -class NodeObserver; - +/** + * @brief Interface for XML documents + * + * This class represents a complete document tree. You have to go through this class + * to create new nodes. It also contains transaction support, which forms the base + * of the undo system. + * + * The document is also a node. It usually contains only two child nodes - a processing + * instruction node (PINode) containing the XML prolog, and the root node. You can get + * the root node of the document by calling the root() method. + * + * The name "transaction" can be misleading, because they are not atomic. Their main feature + * is that they provide rollback. After starting a transaction, + * all changes made to the document are stored in an internal event log. At any time + * after starting the transaction, you can call the rollback() method, which restores + * the document to the state it was before starting the transaction. Calling the commit() + * method causes the internal event log to be discarded, and you can estabilish a new + * "restore point" by calling beginTransaction() again. There can be only one active + * transaction at a time for a given document. + */ struct Document : virtual public Node { public: - virtual NodeObserver *logger()=0; - + /** + * @name Document transactions + * @{ + */ + /** + * @brief Checks whether there is an active transaction for this document + * @return true if there's an established transaction for this document, false otherwise + */ virtual bool inTransaction()=0; - + /** + * @brief Begin a transaction and start recording changes + * + * By calling this method you effectively establish a resotre point. + * You can undo all changes made to the document after this call using rollback(). + */ virtual void beginTransaction()=0; + /** + * @brief Restore the state of the document prior to the transaction + * + * This method applies the inverses of all recorded changes in reverse order, + * restoring the document state from before the transaction. For some implementations, + * this function may do nothing. + */ virtual void rollback()=0; + /** + * @brief Commit a transaction and discard change data + * + * This method finishes the active transaction and discards the recorded changes. + */ virtual void commit()=0; - virtual Inkscape::XML::Event *commitUndoable()=0; + /** + * @brief Commit a transaction and store the events for later use + * + * This method finishes a transaction and returns an event chain + * that describes the changes made to the document. This method may return NULL, + * which means that the document implementation doesn't support event logging, + * or that no changes were made. + * + * @return Event chain describing the changes, or NULL + */ + virtual Event *commitUndoable()=0; + /*@}*/ + /** + * @name Create new nodes + * @{ + */ virtual Node *createElement(char const *name)=0; virtual Node *createTextNode(char const *content)=0; virtual Node *createComment(char const *content)=0; virtual Node *createPI(char const *target, char const *content)=0; + /*@}*/ + + /** + * @brief Get the event logger for this document + * + * This is an implementation detail that should not be used outside of node implementations. + * It should be made non-public in the future. + */ + virtual NodeObserver *logger()=0; }; } diff --git a/src/xml/element-node.h b/src/xml/element-node.h index 11bc8e03a..7b75f8080 100644 --- a/src/xml/element-node.h +++ b/src/xml/element-node.h @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::ElementNode - simple XML element implementation - * - * Copyright 2004-2005 MenTaLguY +/** @file + * @brief Element node implementation + */ +/* Copyright 2004-2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,6 +21,9 @@ namespace Inkscape { namespace XML { +/** + * @brief Element node, e.g. <group /> + */ class ElementNode : public SimpleNode { public: ElementNode(int code, Document *doc) diff --git a/src/xml/event.h b/src/xml/event.h index 59dbe7c7b..c62257751 100644 --- a/src/xml/event.h +++ b/src/xml/event.h @@ -1,3 +1,20 @@ +/** @file + * @brief Event object representing a change of the XML document + */ +/* Authors: + * Unknown author(s) + * Krzysztof Kosiński (documentation) + * + * Copyright 2008 Authors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + */ + #ifndef SEEN_INKSCAPE_XML_SP_REPR_ACTION_H #define SEEN_INKSCAPE_XML_SP_REPR_ACTION_H @@ -9,142 +26,223 @@ #include "util/share.h" #include "util/forward-pointer-iterator.h" #include "gc-managed.h" +#include "xml/xml-forward.h" #include "xml/node.h" namespace Inkscape { namespace XML { -class Node; -class NodeObserver; - +/** + * @brief Enumeration of all XML event types + */ enum EventType { - EVENT_ADD, - EVENT_DEL, - EVENT_CHG_ATTR, - EVENT_CHG_CONTENT, - EVENT_CHG_ORDER + EVENT_ADD, ///< Child added + EVENT_DEL, ///< Child removed + EVENT_CHG_ATTR, ///< Attribute changed + EVENT_CHG_CONTENT, ///< Content changed + EVENT_CHG_ORDER ///< Order of children changed }; - + +/** + * @brief Generic XML modification event + * + * This is the base class for all other modification events. It is actually a singly-linked + * list of events, called an event chain or an event log. Logs of events that happened + * in a transaction can be obtained from Document::commitUndoable(). Events can be replayed + * to a NodeObserver, or undone (which is equivalent to replaying opposite events in reverse + * order). + * + * Event logs are built by appending to the front, so by walking the list one iterates over + * the events in reverse chronological order. + */ class Event : public Inkscape::GC::Managed { -public: - - virtual ~Event() {} - - Event *next; - int serial; - Node *repr; - - struct IteratorStrategy { - static Event const *next(Event const *action) { - return action->next; - } - }; - - typedef Inkscape::Util::ForwardPointerIterator Iterator; - typedef Inkscape::Util::ForwardPointerIterator ConstIterator; - - Event *optimizeOne() { return _optimizeOne(); } - void undoOne(NodeObserver &observer) const { - _undoOne(observer); - } - void replayOne(NodeObserver &observer) const { - _replayOne(observer); - } +public: + virtual ~Event() {} + + /** + * @brief Pointer to the next event in the event chain + * + * Note that the event this pointer points to actually happened before this event. + * This is because the event log is built by appending to the front. + */ + Event *next; + /** + * @brief Serial number of the event, not used at the moment + */ + int serial; + /** + * @brief Pointer to the node that was the object of the event + * + * Because the nodes are garbage-collected, this pointer guarantees that the node + * will stay in memory as long as the event does. This simplifies rolling back + * extensive deletions. + */ + Node *repr; + + struct IteratorStrategy { + static Event const *next(Event const *action) { + return action->next; + } + }; + + typedef Inkscape::Util::ForwardPointerIterator Iterator; + typedef Inkscape::Util::ForwardPointerIterator ConstIterator; + + /** + * @brief If possible, combine this event with the next to reduce memory use + * @return Pointer to the optimized event chain, which may have changed + */ + Event *optimizeOne() { return _optimizeOne(); } + /** + * @brief Undo this event to an observer + * + * This method notifies the specified observer of an action opposite to the one that + * is described by this event. + */ + void undoOne(NodeObserver &observer) const { + _undoOne(observer); + } + /** + * @brief Replay this event to an observer + * + * This method notifies the specified event of the same action that it describes. + */ + void replayOne(NodeObserver &observer) const { + _replayOne(observer); + } protected: - Event(Node *r, Event *n) - : next(n), serial(_next_serial++), repr(r) {} + Event(Node *r, Event *n) + : next(n), serial(_next_serial++), repr(r) {} - virtual Event *_optimizeOne()=0; - virtual void _undoOne(NodeObserver &) const=0; - virtual void _replayOne(NodeObserver &) const=0; + virtual Event *_optimizeOne()=0; + virtual void _undoOne(NodeObserver &) const=0; + virtual void _replayOne(NodeObserver &) const=0; private: - static int _next_serial; + static int _next_serial; }; +/** + * @brief Object representing child addition + */ class EventAdd : public Event { public: - EventAdd(Node *repr, Node *c, Node *rr, Event *next) - : Event(repr, next), child(c), ref(rr) {} + EventAdd(Node *repr, Node *c, Node *rr, Event *next) + : Event(repr, next), child(c), ref(rr) {} - Node *child; - Node *ref; + /// The added child node + Node *child; + /// The node after which the child has been added, or NULL if it was added as first + Node *ref; private: - Event *_optimizeOne(); - void _undoOne(NodeObserver &observer) const; - void _replayOne(NodeObserver &observer) const; + Event *_optimizeOne(); + void _undoOne(NodeObserver &observer) const; + void _replayOne(NodeObserver &observer) const; }; +/** + * @brief Object representing child removal + */ class EventDel : public Event { public: - EventDel(Node *repr, Node *c, Node *rr, Event *next) - : Event(repr, next), child(c), ref(rr) {} + EventDel(Node *repr, Node *c, Node *rr, Event *next) + : Event(repr, next), child(c), ref(rr) {} - Node *child; - Node *ref; + /// The child node that was removed + Node *child; + /// The node after which the removed node was in the sibling order, or NULL if it was first + Node *ref; private: - Event *_optimizeOne(); - void _undoOne(NodeObserver &observer) const; - void _replayOne(NodeObserver &observer) const; + Event *_optimizeOne(); + void _undoOne(NodeObserver &observer) const; + void _replayOne(NodeObserver &observer) const; }; +/** + * @brief Object representing attribute change + */ class EventChgAttr : public Event { public: - EventChgAttr(Node *repr, GQuark k, - Inkscape::Util::ptr_shared ov, - Inkscape::Util::ptr_shared nv, - Event *next) - : Event(repr, next), key(k), - oldval(ov), newval(nv) {} - - GQuark key; - Inkscape::Util::ptr_shared oldval; - Inkscape::Util::ptr_shared newval; + EventChgAttr(Node *repr, GQuark k, + Inkscape::Util::ptr_shared ov, + Inkscape::Util::ptr_shared nv, + Event *next) + : Event(repr, next), key(k), + oldval(ov), newval(nv) {} + + /// GQuark corresponding to the changed attribute's name + GQuark key; + /// Value of the attribute before the change + Inkscape::Util::ptr_shared oldval; + /// Value of the attribute after the change + Inkscape::Util::ptr_shared newval; private: - Event *_optimizeOne(); - void _undoOne(NodeObserver &observer) const; - void _replayOne(NodeObserver &observer) const; + Event *_optimizeOne(); + void _undoOne(NodeObserver &observer) const; + void _replayOne(NodeObserver &observer) const; }; +/** + * @brief Object representing content change + */ class EventChgContent : public Event { public: - EventChgContent(Node *repr, - Inkscape::Util::ptr_shared ov, - Inkscape::Util::ptr_shared nv, - Event *next) - : Event(repr, next), oldval(ov), newval(nv) {} + EventChgContent(Node *repr, + Inkscape::Util::ptr_shared ov, + Inkscape::Util::ptr_shared nv, + Event *next) + : Event(repr, next), oldval(ov), newval(nv) {} - Inkscape::Util::ptr_shared oldval; - Inkscape::Util::ptr_shared newval; + /// Content of the node before the change + Inkscape::Util::ptr_shared oldval; + /// Content of the node after the change + Inkscape::Util::ptr_shared newval; private: - Event *_optimizeOne(); - void _undoOne(NodeObserver &observer) const; - void _replayOne(NodeObserver &observer) const; + Event *_optimizeOne(); + void _undoOne(NodeObserver &observer) const; + void _replayOne(NodeObserver &observer) const; }; +/** + * @brief Obect representing child order change + */ class EventChgOrder : public Event { public: - EventChgOrder(Node *repr, Node *c, Node *orr, Node *nrr, Event *next) - : Event(repr, next), child(c), - oldref(orr), newref(nrr) {} + EventChgOrder(Node *repr, Node *c, Node *orr, Node *nrr, Event *next) + : Event(repr, next), child(c), + oldref(orr), newref(nrr) {} - Node *child; - Node *oldref, *newref; + /// The node that was relocated in sibling order + Node *child; + /// The node after which the relocated node was in the sibling order before the change, or NULL if it was first + Node *oldref; + /// The node after which the relocated node is after the change, or if it's first + Node *newref; private: - Event *_optimizeOne(); - void _undoOne(NodeObserver &observer) const; - void _replayOne(NodeObserver &observer) const; + Event *_optimizeOne(); + void _undoOne(NodeObserver &observer) const; + void _replayOne(NodeObserver &observer) const; }; } } #endif +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/xml/log-builder.cpp b/src/xml/log-builder.cpp index e8b7c707e..5ff09a0e0 100644 --- a/src/xml/log-builder.cpp +++ b/src/xml/log-builder.cpp @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::LogBuilder - NodeObserver which builds an event log - * - * Copyright 2005 MenTaLguY +/** @file + * @brief Object building an event log + */ +/* Copyright 2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/src/xml/log-builder.h b/src/xml/log-builder.h index 478bf295f..0a161d18f 100644 --- a/src/xml/log-builder.h +++ b/src/xml/log-builder.h @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::LogBuilder - NodeObserver which builds an event log - * - * Copyright 2005 MenTaLguY +/** @file + * @brief Object building an event log + */ +/* Copyright 2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -9,28 +9,45 @@ * of the License, or (at your option) any later version. * * See the file COPYING for details. - * */ #ifndef SEEN_INKSCAPE_XML_LOG_BUILDER_H #define SEEN_INKSCAPE_XML_LOG_BUILDER_H #include "gc-managed.h" +#include "xml/xml-forward.h" #include "xml/node-observer.h" namespace Inkscape { namespace XML { -class Event; - +/** + * @brief Event log builder + * + * This object records all events sent to it via the public methods in an internal event log. + * Calling detach() then returns the built log. Calling discard() will clear all the events + * recorded so far. + */ class LogBuilder { public: LogBuilder() : _log(NULL) {} ~LogBuilder() { discard(); } + /** @name Manipulate the recorded event log + * @{ */ + /** + * @brief Clear the internal log + */ void discard(); + /** + * @brief Get the internal event log + * @return The recorded event chain + */ Event *detach(); + /*@}*/ + /** @name Record events in the log + * @{ */ void addChild(Node &node, Node &child, Node *prev); void removeChild(Node &node, Node &child, Node *prev); @@ -45,6 +62,7 @@ public: void setAttribute(Node &node, GQuark name, Util::ptr_shared old_value, Util::ptr_shared new_value); + /*@}*/ private: Event *_log; diff --git a/src/xml/node-event-vector.h b/src/xml/node-event-vector.h index 920e28475..0c291c230 100644 --- a/src/xml/node-event-vector.h +++ b/src/xml/node-event-vector.h @@ -1,10 +1,7 @@ -#ifndef SEEN_INKSCAPE_XML_SP_REPR_EVENT_VECTOR -#define SEEN_INKSCAPE_XML_SP_REPR_EVENT_VECTOR - -/* - * Fuzzy DOM-like tree implementation - * - * Authors: +/** @file + * @brief Deprecated structure for a set of callbacks for node state changes + */ +/* Authors: * Lauris Kaplinski * Frank Felfe * @@ -14,6 +11,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_INKSCAPE_XML_SP_REPR_EVENT_VECTOR +#define SEEN_INKSCAPE_XML_SP_REPR_EVENT_VECTOR + #include #include "xml/node.h" @@ -21,6 +21,10 @@ namespace Inkscape { namespace XML { +/** + * @brief Structure holding callbacks for node state changes + * @deprecated Derive an observer object from the NodeObserver class instead + */ struct NodeEventVector { /* Immediate signals */ void (* child_added) (Node *repr, Node *child, Node *ref, void * data); @@ -33,13 +37,24 @@ struct NodeEventVector { } } +/** + * @brief Generate events corresponding to the node's state + * @deprecated Use Node::synthesizeEvents(NodeObserver &) instead + */ inline void sp_repr_synthesize_events (Inkscape::XML::Node *repr, const Inkscape::XML::NodeEventVector *vector, void * data) { repr->synthesizeEvents(vector, data); } - +/** + * @brief Add a set of callbacks for node state changes and its associated data + * @deprecated Use Node::addObserver() instead + */ inline void sp_repr_add_listener (Inkscape::XML::Node *repr, const Inkscape::XML::NodeEventVector *vector, void * data) { repr->addListener(vector, data); } +/** + * @brief Remove a set of callbacks based on associated data + * @deprecated Use Node::removeObserver() instead + */ inline void sp_repr_remove_listener_by_data (Inkscape::XML::Node *repr, void * data) { repr->removeListenerByData(data); } diff --git a/src/xml/node-fns.cpp b/src/xml/node-fns.cpp index cb4161141..deb88fb5e 100644 --- a/src/xml/node-fns.cpp +++ b/src/xml/node-fns.cpp @@ -26,7 +26,7 @@ bool id_permitted_internal(GQuark qname) { bool id_permitted_internal_memoized(GQuark qname) { typedef std::map IdPermittedMap; - IdPermittedMap id_permitted_names; + static IdPermittedMap id_permitted_names; IdPermittedMap::iterator found; found = id_permitted_names.find(qname); @@ -57,21 +57,7 @@ struct node_matches { Node const &node; }; -/** Returns the sibling before \a node in \a node's parent's children, - * or NULL if \a node is the first of those children (or if child is - * NULL or has no parent). - * - * Useful in combination with Node::addChild, when you want to insert - * a new child _before_ a given existing child. - * - * Note: Involves a linear search (unlike next_node). - * - * \pre Links are correct, i.e. \a node isin its parent's children. - * - * \post (ret == NULL - * ? node == NULL || node->parent() == NULL || node->parent()->firstChild() == node - * : ret->next() == node). - */ +// documentation moved to header Node *previous_node(Node *node) { using Inkscape::Algorithms::find_if_before; @@ -93,7 +79,6 @@ Node *previous_node(Node *node) { } } - /* Local Variables: mode:c++ @@ -103,4 +88,4 @@ Node *previous_node(Node *node) { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/xml/node-fns.h b/src/xml/node-fns.h index 54366e61f..4c6408789 100644 --- a/src/xml/node-fns.h +++ b/src/xml/node-fns.h @@ -1,37 +1,81 @@ -#ifndef SEEN_REPR_GET_CHILDREN_H -#define SEEN_REPR_GET_CHILDREN_H +/** @file + * @brief Helper functions for XML nodes + */ +/* Authors: + * Unknown author + * Krzysztof Kosiński (documentation) + * + * Copyright 2008 Authors + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + */ + +#ifndef SEEN_XML_NODE_FNS_H +#define SEEN_XML_NODE_FNS_H #include "xml/node.h" namespace Inkscape { namespace XML { -class Node; - bool id_permitted(Node const *node); +//@{ +/** + * @brief Get the next node in sibling order + * @param node The origin node + * @return The next node in sibling order + * @relates Inkscape::XML::Node + */ inline Node *next_node(Node *node) { return ( node ? node->next() : NULL ); } inline Node const *next_node(Node const *node) { return ( node ? node->next() : NULL ); } +//@} + +//@{ +/** + * @brief Get the previous node in sibling order + * + * This method, unlike Node::next(), is a linear search over the children of @c node's parent. + * The return value is NULL when the node has no parent or is first in the sibling order. + * + * @param node The origin node + * @return The previous node in sibling order, or NULL + * @relates Inkscape::XML::Node + */ Node *previous_node(Node *node); inline Node const *previous_node(Node const *node) { return previous_node(const_cast(node)); } +//@} + +//@{ +/** + * @brief Get the node's parent + * @param node The origin node + * @return The node's parent + * @relates Inkscape::XML::Node + */ inline Node *parent_node(Node *node) { return ( node ? node->parent() : NULL ); } inline Node const *parent_node(Node const *node) { return ( node ? node->parent() : NULL ); } +//@} } } -#endif /* !SEEN_REPR_GET_CHILDREN_H */ - +#endif /* !SEEN_XML_NODE_FNS_H */ /* Local Variables: mode:c++ @@ -41,4 +85,4 @@ inline Node const *parent_node(Node const *node) { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/xml/node-observer.h b/src/xml/node-observer.h index 584505e4e..6052e48b6 100644 --- a/src/xml/node-observer.h +++ b/src/xml/node-observer.h @@ -1,7 +1,11 @@ -/* - * Inkscape::XML::NodeObserver - interface implemented by observers of XML nodes +/** @file + * @brief Interface for XML node observers + */ +/* Authors: + * MenTaLguY + * Krzysztof Kosiński (documentation) * - * Copyright 2005 MenTaLguY + * Copyright 2005-2008 Authors * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -9,7 +13,6 @@ * of the License, or (at your option) any later version. * * See the file COPYING for details. - * */ #ifndef SEEN_INKSCAPE_XML_NODE_OBSERVER_H @@ -17,43 +20,103 @@ #include #include "util/share.h" - -namespace Inkscape { -namespace XML { -class Node; -} -} +#include "xml/xml-forward.h" namespace Inkscape { - namespace XML { +/** + * @brief Interface for XML node observers + * + * This pure abstract class defines an interface for objects that can receive + * XML node state change notifications. The observer has to be registered using + * the Node::addObserver() method to be notified of changes of this node only, + * or using Node::addSubtreeObserver() to also receive notifications about its + * descendants. All observer methods are called when the operations in question have + * been completed, just before returning from the modifying methods. + * + * Be careful when e.g. changing an attribute of @c node in notifyAttributeChanged(). + * The method will be called again due to the XML modification performed in it. If you + * don't take special precautions to ignore the second call, it will result in infinite + * recursion. + */ class NodeObserver { public: NodeObserver() {} - virtual ~NodeObserver() {} + /** + * @brief Child addition callback + * + * This method is called whenever a child is added to the observed node. The @c prev + * parameter is NULL when the newly added child is first in the sibling order. + * + * @param node The changed XML node + * @param child The newly added child node + * @param prev The node after which the new child was inserted into the sibling order, or NULL + */ virtual void notifyChildAdded(Node &node, Node &child, Node *prev)=0; + /** + * @brief Child removal callback + * + * This method is called whenever a child is removed from the observed node. The @c prev + * parameter is NULL when the removed child was first in the sibling order. + * + * @param node The changed XML node + * @param child The removed child node + * @param prev The node that was before the removed node in sibling order, or NULL + */ virtual void notifyChildRemoved(Node &node, Node &child, Node *prev)=0; + /** + * @brief Child order change callback + * + * This method is called whenever the order of a node's children is changed using + * Node::changeOrder(). The @c old_prev parameter is NULL if the relocated node + * was first in the sibling order before the order change, and @c new_prev is NULL + * if it was moved to the first position by this operation. + * + * @param node The changed XML node + * @param child The child node that was relocated in the sibling order + * @param old_prev The node that was before @c child prior to the order change + * @param new_prev The node that is before @c child after the order change + */ virtual void notifyChildOrderChanged(Node &node, Node &child, Node *old_prev, Node *new_prev)=0; + /** + * @brief Content change callback + * + * This method is called whenever a node's content is changed using Node::setContent(), + * e.g. for text or comment nodes. + * + * @param node The changed XML node + * @param old_content Old content of @c node + * @param new_content New content of @c node + */ virtual void notifyContentChanged(Node &node, Util::ptr_shared old_content, Util::ptr_shared new_content)=0; + /** + * @brief Attribute change callback + * + * This method is called whenever one of a node's attributes is changed. + * + * @param node The changed XML node + * @param name GQuark corresponding to the attribute's name + * @param old_value Old value of the modified attribute + * @param new_value New value of the modified attribute + */ virtual void notifyAttributeChanged(Node &node, GQuark name, Util::ptr_shared old_value, Util::ptr_shared new_value)=0; }; -} - -} +} // namespace XML +} // namespace Inkscape #endif /* diff --git a/src/xml/node.h b/src/xml/node.h index aac2db191..abcccdb9a 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -1,7 +1,11 @@ -/* - * Node - interface for XML nodes +/** @file + * @brief Interface for XML nodes + */ +/* Authors: + * MenTaLguY + * Krzysztof Kosiński (documentation) * - * Copyright 2005 MenTaLguY + * Copyright 2005-2008 Authors * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -9,7 +13,6 @@ * of the License, or (at your option) any later version. * * See the file COPYING for details. - * */ #ifndef SEEN_INKSCAPE_XML_NODE_H @@ -18,89 +21,439 @@ #include #include "gc-anchored.h" #include "util/list.h" +#include "xml/xml-forward.h" namespace Inkscape { namespace XML { -class AttributeRecord; -class Document; -class NodeEventVector; -class NodeObserver; - +/** + * @brief Enumeration containing all supported node types. + */ enum NodeType { - DOCUMENT_NODE, - ELEMENT_NODE, - TEXT_NODE, - COMMENT_NODE, - PI_NODE + DOCUMENT_NODE, ///< Top-level document node. Do not confuse with the root node. + ELEMENT_NODE, ///< Regular element node, e.g. <group />. + TEXT_NODE, ///< Text node, e.g. "Some text" in <group>Some text</group> is represented by a text node. + COMMENT_NODE, ///< Comment node, e.g. <!-- some comment --> + PI_NODE ///< Processing instruction node, e.g. <?xml version="1.0" encoding="utf-8" standalone="no"?> }; // careful; GC::Anchored should only appear once in the inheritance -// hierarcy; else there will be leaks +// hierarchy; otherwise there will be leaks + +/** + * @brief Interface for refcounted XML nodes + * + * This class is an abstract base type for all nodes in an XML document - this includes + * everything except attributes. An XML document is also a node itself. This is the main + * class used for interfacing with Inkscape's documents. Everything that has to be stored + * in the SVG has to go through this class at some point. + * + * Each node unconditionally has to belong to a document. There no "documentless" nodes, + * and it's not possible to move nodes between documents - they have to be duplicated. + * Each node can only refer to the nodes in the same document. Name of the node is immutable, + * it cannot be changed after its creation. Same goes for the type of the node. To simplify + * the use of this class, you can perform all operations on all nodes, but only some of them + * make any sense. For example, only element nodes can have attributes, only element and + * document nodes can have children, and all nodes except element and document nodes can + * have content. Although you can set content for element nodes, it won't make any difference + * in the XML output. + * + * To create new nodes, use the methods of the Inkscape::XML::Document class. You can obtain + * the nodes' document using the document() method. To destroy a node, just unparent it + * by calling sp_repr_unparent() or node->parent->removeChild() and release any references + * to it. The garbage collector will reclaim the memory in the next pass. There are additional + * convenience functions defined in @ref xml/repr.h + * + * In addition to regular DOM manipulations, you can register observer objects that will + * receive notifications about changes made to the node. See the NodeObserver class. + * + * @see Inkscape::XML::Document + * @see Inkscape::XML::NodeObserver + */ class Node : public Inkscape::GC::Anchored { public: Node() {} - virtual ~Node() {} + /** + * @name Retrieve information about the node + * @{ + */ + + /** + * @brief Get the type of the node + * @return NodeType enumeration member corresponding to the type of the node. + */ virtual NodeType type() const=0; + /** + * @brief Get the name of the element node + * + * This method only makes sense for element nodes. Names are stored as + * GQuarks to accelerate conversions. + * + * @return Name for element nodes, NULL for others + */ virtual gchar const *name() const=0; + /** + * @brief Get the integer code corresponding to the node's name + * @return GQuark code corresponding to the name + */ virtual int code() const=0; + + /** + * @brief Get the index of this node in parent's child order + * + * If this method is used on a node that doesn't have a parent, the method will return 0, + * and a warning will be printed on the console. + * + * @return The node's index, or 0 if the node does not have a parent + */ + virtual unsigned position() const=0; + + /** + * @brief Get the number of children of this node + * @return The number of children + */ + virtual unsigned childCount() const=0; + + /** + * @brief Get the content of a text or comment node + * + * This method makes no sense for element nodes. To retrieve the element node's name, + * use the name() method. + * + * @return The node's content + */ + virtual gchar const *content() const=0; + + /** + * @brief Get the string representation of a node's attribute + * + * If there is no attribute with the given name, the method will return NULL. + * All strings returned by this method are owned by the node and may not be freed. + * The returned pointer will become invalid when the attribute changes. If you need + * to store the return value, use g_strdup(). To parse the string, use methods + * in repr.h + * + * @param key The name of the node's attribute + */ + virtual gchar const *attribute(gchar const *key) const=0; + + /** + * @brief Get a list of the node's attributes + * + * The returned list is a functional programming style list rather than a standard one. + * + * @return A list of AttributeRecord structures describing the attributes + * @todo This method should return std::map + * or something similar with a custom allocator + */ + virtual Inkscape::Util::List attributeList() const=0; + + /** + * @brief Check whether this node has any attribute that matches a string + * + * This method checks whether this node has any attributes whose names + * have @c partial_name as their substrings. The check is done using + * the strstr() function of the C library. I don't know what would require that + * functionality, because matchAttributeName("id") matches both "identity" and "hidden". + * + * @param partial_name The string to match against all attributes + * @return true if there is such an attribute, false otherwise + */ + virtual bool matchAttributeName(gchar const *partial_name) const=0; + + /*@}*/ + + /** + * @name Modify the node + * @{ + */ + + /** + * @brief Set the position of this node in parent's child order + * + * To move the node to the end of the parent's child order, pass a negative argument. + * + * @param pos The new position in parent's child order + */ + virtual void setPosition(int pos)=0; + + /** + * @brief Set the content of a text or comment node + * + * This method doesn't make sense for element nodes. + * + * @param value The node's new content + */ + virtual void setContent(gchar const *value)=0; + + /** + * @brief Change an attribute of this node + * + * The strings passed to this method are copied, so you can free them after use. + * + * @param key Name of the attribute to change + * @param value The new value of the attribute + * @param is_interactive Ignored + */ + virtual void setAttribute(gchar const *key, gchar const *value, bool is_interactive=false)=0; + + /** + * @brief Directly set the integer GQuark code for the name of the node + * + * This function is a hack to easily move elements with no namespace to the SVG namespace. + * Do not use this function unless you really have a good reason. + * + * @param code The integer value corresponding to the string to be set as the name of this node + */ virtual void setCodeUnsafe(int code)=0; + + /*@}*/ + + /** + * @name Traverse the XML tree + * @{ + */ + + //@{ + /** + * @brief Get the node's associated document + * @return The document to which the node belongs. Never NULL. + */ virtual Document *document()=0; virtual Document const *document() const=0; + //@} - virtual Node *duplicate(Document *doc) const=0; - + //@{ + /** + * @brief Get the root node of this node's document + * + * This method works on any node that is part of an XML document, and returns + * the root node of the document in which it resides. For detached node hierarchies + * (i.e. nodes that are not descendants of a document node) this method + * returns the highest-level element node. For detached non-element nodes this method + * returns NULL. + * + * @return A pointer to the root element node, or NULL if the node is detached + */ virtual Node *root()=0; virtual Node const *root() const=0; + //@} + //@{ + /** + * @brief Get the parent of this node + * + * This method will return NULL for detached nodes. + * + * @return Pointer to the parent, or NULL + */ virtual Node *parent()=0; virtual Node const *parent() const=0; + //@} + //@{ + /** + * @brief Get the next sibling of this node + * + * This method will return NULL if the node is the last sibling element of the parent. + * The nodes form a singly-linked list, so there is no "prev()" method. Use the provided + * external function for that. + * + * @return Pointer to the next sibling, or NULL + * @see Inkscape::XML::previous_node() + */ virtual Node *next()=0; virtual Node const *next() const=0; + //@} + //@{ + /** + * @brief Get the first child of this node + * + * For nodes without any children, this method returns NULL. + * + * @return Pointer to the first child, or NULL + */ virtual Node *firstChild()=0; virtual Node const *firstChild() const=0; + //@} + + //@{ + /** + * @brief Get the last child of this node + * + * For nodes without any children, this method returns NULL. + * + * @return Pointer to the last child, or NULL + */ virtual Node *lastChild()=0; virtual Node const *lastChild() const=0; - - virtual unsigned childCount() const=0; + //@} + + //@{ + /** + * @brief Get the child of this node with a given index + * + * If there is no child with the specified index number, this method will return NULL. + * + * @param index The zero-based index of the child to retrieve + * @return Pointer to the appropriate child, or NULL + */ virtual Node *nthChild(unsigned index)=0; virtual Node const *nthChild(unsigned index) const=0; + //@} + + /*@}*/ + + /** + * @name Manipulate the XML tree + * @{ + */ + + /** + * @brief Create a duplicate of this node + * + * The newly created node has no parent, and a refcount equal 1. + * You need to manually insert it into the document, using e.g. appendChild(). + * Afterwards, call Inkscape::GC::release on it, so that it will be + * automatically collected when the parent is collected. + * + * @param doc The document in which the duplicate should be created + * @return A pointer to the duplicated node + */ + virtual Node *duplicate(Document *doc) const=0; - virtual void addChild(Node *child, Node *ref)=0; + /** + * @brief Insert another node as a child of this node + * + * When @c after is NULL, the inserted node will be placed as the first child + * of this node. @c after must be a child of this node. + * + * @param child The node to insert + * @param after The node after which the inserted node should be placed, or NULL + */ + virtual void addChild(Node *child, Node *after)=0; + + /** + * @brief Append a node as the last child of this node + * @param child The node to append + */ virtual void appendChild(Node *child)=0; + + /** + * @brief Remove a child of this node + * + * Once the pointer to the removed node disappears from the stack, the removed node + * will be collected in the next GC pass, but only as long as its refcount is zero. + * You should keep a refcount of zero for all nodes in the document except for + * the document node itself, because they will be held in memory by the parent. + * + * @param child The child to remove + */ virtual void removeChild(Node *child)=0; - virtual void changeOrder(Node *child, Node *ref)=0; - - virtual unsigned position() const=0; - virtual void setPosition(int pos)=0; - - virtual gchar const *attribute(gchar const *key) const=0; - virtual void setAttribute(gchar const *key, gchar const *value, bool is_interactive=false)=0; - virtual bool matchAttributeName(gchar const *partial_name) const=0; - - virtual gchar const *content() const=0; - virtual void setContent(gchar const *value)=0; + + /** + * @brief Move a given node in this node's child order + * + * Both @c child and @c after must be children of this node for the method to work. + * + * @param child The node to move in the order + * @param after The sibling node after which the moved node should be placed + */ + virtual void changeOrder(Node *child, Node *after)=0; + /** + * @brief Merge all children of another node with the current + * + * This method merges two node hierarchies, where @c src takes precedence. + * @c key is the name of the attribute that determines whether two nodes are + * corresponding (it must be the same for both, and all of their ancestors). If there is + * a corresponding node in @c src hierarchy, their attributes and content override the ones + * already present in this node's hierarchy. If there is no corresponding node, + * it is copied from @c src to this node. This method is used when merging the user's + * preferences file with the defaults, and has little use beyond that. + * + * @param src The node to merge into this node + * @param key The attribute to use as the identity attribute + */ virtual void mergeFrom(Node const *src, gchar const *key)=0; + + /*@}*/ - virtual Inkscape::Util::List attributeList() const=0; - virtual void synthesizeEvents(NodeEventVector const *vector, void *data)=0; - virtual void synthesizeEvents(NodeObserver &observer)=0; + /** + * @name Notify observers about operations on the node + * @{ + */ + + /** + * @brief Add an object that will be notified of the changes to this node + * + * @c observer must be an object deriving from the NodeObserver class. + * The virtual methods of this object will be called when a corresponding change + * happens to this node. You can also notify the observer of the node's current state + * using synthesizeEvents(NodeObserver &). + * + * @param observer The observer object + */ virtual void addObserver(NodeObserver &observer)=0; - virtual void addListener(NodeEventVector const *vector, void *data)=0; + /** + * @brief Remove an object from the list of observers + * @param observer The object to be removed + */ virtual void removeObserver(NodeObserver &observer)=0; - virtual void removeListenerByData(void *data)=0; + /** + * @brief Generate a sequence of events corresponding to the state of this node + * + * This function notifies the specified observer of all the events that would + * recreate the current state of this node; e.g. the observer is notified of + * all the attributes, children and content like they were just created. + * This function can greatly simplify observer logic. + * + * @param observer The node observer to notify of the events + */ + virtual void synthesizeEvents(NodeObserver &observer)=0; + /** + * @brief Add an object that will be notified of the changes to this node and its descendants + * + * The difference between adding a regular observer and a subtree observer is that + * the subtree observer will also be notified if a change occurs to any of the node's + * descendants, while a regular observer will only be notified of changes to the node + * it was assigned to. + * + * @param observer The observer object + */ virtual void addSubtreeObserver(NodeObserver &observer)=0; + + /** + * @brief Remove an object from the subtree observers list + * @param observer The object to be removed + */ virtual void removeSubtreeObserver(NodeObserver &observer)=0; + /** + * @brief Add a set node change callbacks with an associated data + * @deprecated Use addObserver(NodeObserver &) instead + */ + virtual void addListener(NodeEventVector const *vector, void *data)=0; + /** + * @brief Remove a set of node change callbacks by their associated data + * @deprecated Use removeObserver(NodeObserver &) instead + */ + virtual void removeListenerByData(void *data)=0; + /** + * @brief Generate a sequence of events corresponding to the state of this node + * @deprecated Use synthesizeEvents(NodeObserver &) instead + */ + virtual void synthesizeEvents(NodeEventVector const *vector, void *data)=0; + + /*@}*/ + protected: Node(Node const &) : Anchored() {} }; diff --git a/src/xml/pi-node.h b/src/xml/pi-node.h index 502c5cd71..4aa1f840b 100644 --- a/src/xml/pi-node.h +++ b/src/xml/pi-node.h @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::PINode - simple XML comment implementation - * - * Copyright 2004-2005 MenTaLguY +/** @file + * @brief Processing instruction node implementation + */ +/* Copyright 2004-2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -9,7 +9,6 @@ * of the License, or (at your option) any later version. * * See the file COPYING for details. - * */ #ifndef SEEN_INKSCAPE_XML_PI_NODE_H @@ -22,6 +21,9 @@ namespace Inkscape { namespace XML { +/** + * @brief Processing instruction node, e.g. <?xml version="1.0" encoding="utf-8" standalone="no"?> + */ struct PINode : public SimpleNode { PINode(GQuark target, Util::ptr_shared content, Document *doc) : SimpleNode(target, doc) diff --git a/src/xml/repr-sorting.h b/src/xml/repr-sorting.h index 534caa2d1..37f719622 100644 --- a/src/xml/repr-sorting.h +++ b/src/xml/repr-sorting.h @@ -1,11 +1,25 @@ -/** \file Some functions relevant sorting reprs by position within document. */ - -namespace Inkscape { -namespace XML { -class Node; -} -} +/** @file + * @brief Some functions relevant sorting reprs by position within document. + * @todo Functions in this file have non-English names. Determine what they do and rename + * accordingly. + */ + +#ifndef SEEN_XML_REPR_SORTING_H +#define SEEN_XML_REPR_SORTING_H +#include "xml/xml-forward.h" Inkscape::XML::Node *LCA(Inkscape::XML::Node *a, Inkscape::XML::Node *b); Inkscape::XML::Node *AncetreFils(Inkscape::XML::Node *descendent, Inkscape::XML::Node *ancestor); + +#endif // SEEN_XML_REPR_SOTRING_H +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 59563a7fc..528902fef 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -344,6 +344,7 @@ long long int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, char const *k * 0 positions are equivalent * 1 first object's position is greater than the second * -1 first object's position is less than the second + * @todo Rewrite this function's description to be understandable */ int sp_repr_compare_position(Inkscape::XML::Node *first, Inkscape::XML::Node *second) @@ -397,7 +398,15 @@ sp_repr_compare_position(Inkscape::XML::Node *first, Inkscape::XML::Node *second } /** - * lookup child by \a key, \a value. + * @brief Find an element node using an unique attribute + * + * This function returns the first child of the specified node that has the attribute + * @c key equal to @c value. Note that this function does not recurse. + * + * @param repr The node to start from + * @param key The name of the attribute to use for comparisons + * @param value The value of the attribute to look for + * @relatesalso Inkscape::XML::Node */ Inkscape::XML::Node * sp_repr_lookup_child(Inkscape::XML::Node *repr, @@ -417,11 +426,16 @@ sp_repr_lookup_child(Inkscape::XML::Node *repr, } /** - * \brief Recursively find the Inkscape::XML::Node matching the given XML name. - * \return A pointer to the matching Inkscape::XML::Node - * \param repr The Inkscape::XML::Node to start from - * \param name The desired XML name - * + * @brief Find an element node with the given name + * + * This function searches the descendants of the specified node depth-first for + * the first XML node with the specified name. + * + * @param repr The node to start from + * @param name The name of the element node to find + * @param maxdepth Maximum search depth, or -1 for an unlimited depth + * @return A pointer to the matching Inkscape::XML::Node + * @relatesalso Inkscape::XML::Node */ Inkscape::XML::Node * sp_repr_lookup_name( Inkscape::XML::Node *repr, gchar const *name, gint maxdepth ) diff --git a/src/xml/repr.h b/src/xml/repr.h index a16a3c4f4..162896c3f 100644 --- a/src/xml/repr.h +++ b/src/xml/repr.h @@ -1,10 +1,7 @@ -#ifndef __SP_REPR_H__ -#define __SP_REPR_H__ - -/** \file - * C facade to Inkscape::XML::Node. - * - * Authors: +/** @file + * @brief C facade to Inkscape::XML::Node + */ +/* Authors: * Lauris Kaplinski * * Copyright (C) 1999-2002 authors @@ -12,6 +9,9 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#ifndef __SP_REPR_H__ +#define __SP_REPR_H__ #include #include @@ -34,102 +34,6 @@ #define SP_OLD_CC_NS_URI "http://web.resource.org/cc/" #define SP_DC_NS_URI "http://purl.org/dc/elements/1.1/" -/** - * \note NB! Unless explicitly stated all methods are noref/nostrcpy - */ - -/** \todo - * Though Inkscape::XML::Node provides "signals" for notification when - * individual nodes change, there is no mechanism to receive notification - * for overall document changes. - * However, with the addition of the transactions code, it would not be - * very hard to implement if you wanted it. - * - * \class Inkscape::XML::Node - * \note - * Inkscape::XML::Node itself doesn't use GObject signals at present -- - * Inkscape::XML::Nodes maintain lists of Inkscape::XML::NodeEventVectors - * (added via sp_repr_add_listener), which are used to specify callbacks - * when something changes. - * - * Here are the current callbacks in an event vector (they may be NULL): - * - * void (* child_added)(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, - * Inkscape::XML::Node *ref, void *data); Called once a child has been added. - * - * void (* child_removed)(Inkscape::XML::Node *repr, - * Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void *data); - * Called after a child is removed; ref is the child that used to precede - * the removed child. - * - * void (* attr_changed)(Inkscape::XML::Node *repr, gchar const *key, - * gchar const *oldval, gchar const *newval, void *data); - * Called after an attribute has been changed. - * - * void (* content_changed)(Inkscape::XML::Node *repr, gchar const *oldcontent, - * gchar const *newcontent, void *data); - * Called after an element's content has been changed. - * - * void (* order_changed)(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, - * Inkscape::XML::Node *oldref, Inkscape::XML::Node *newref, void *data); - * Called once the child has been moved to its new position in the child order. - * - * Inkscape::XML::Node mini-FAQ - * - * Since I'm not very familiar with this section of code but I need to use - * it heavily for the RDF work, I'm going to answer various questions I run - * into with my best-guess answers so others can follow along too. - * - * \arg - * Q: How do I find the root Inkscape::XML::Node?
- * A: If you have an SPDocument, use doc->rroot. For example: - * - * \code SP_ACTIVE_DOCUMENT->rroot \endcode
- * - * (but it's better to arrange for your caller to pass in the relevent - * document rather than assuming it's necessarily the active one and - * using SP_ACTIVE_DOCUMENT) - * - * \arg - * Q: How do I find an Inkscape::XML::Node by unique key/value?
- * A: Use sp_repr_lookup_child - * - * \arg - * Q: How do I find an Inkscape::XML::Node by unique namespace name?
- * A: Use sp_repr_lookup_name - * - * \arg - * Q: How do I make an Inkscape::XML::Node namespace prefix constant in - * the application?
- * A: Add the XML namespace URL as a #define to repr.h at the top with the - * other SP__NS_URI #define's, and then in repr-util.cpp, - * in sp_xml_ns_register_defaults, bump "defaults" up in size one, and - * add another section. Don't forget to increment the array offset and - * keep ".next" pointed to the next (if any) array entry. - * - * \arg - * Q: How do I create a new Inkscape::XML::Node?
- * A: Use the appropriate create* method on Inkscape::XML::Document, - * parent->appendChild(child), and then use Inkscape::GC::release(child) to - * let go of it (the parent will hold it in memory). - * - * \arg - * Q: How do I destroy an Inkscape::XML::Node? - * A: Just call "sp_repr_unparent" on it and release any references - * you may be retaining to it. Any attached SPObjects will - * clean themselves up automatically, as will any children. - * - * \arg - * Q: What about listeners?
- * A: I have no idea yet... - * - * \arg - * Q: How do I add a namespace to a newly created document?
- * A: The current hack is in document.cpp:sp_document_create - * - * Kees Cook 2004-07-01, updated MenTaLguY 2005-01-25 - */ - /* SPXMLNs */ char const *sp_xml_ns_uri_prefix(gchar const *uri, gchar const *suggested); char const *sp_xml_ns_prefix_uri(gchar const *prefix); @@ -137,27 +41,27 @@ char const *sp_xml_ns_prefix_uri(gchar const *prefix); Inkscape::XML::Document *sp_repr_document_new(gchar const *rootname); /* Tree */ -/// Returns the node's parent. +/// @deprecated Use the equivalent member function Inkscape::XML::Node::parent() inline Inkscape::XML::Node *sp_repr_parent(Inkscape::XML::Node const *repr) { return const_cast(repr->parent()); } -/// Returns first child of node, resets iterator. +/// @deprecated Use the equivalent member function Inkscape::XML::Node::firstChild() inline Inkscape::XML::Node const *sp_repr_children(Inkscape::XML::Node const *repr) { return ( repr ? repr->firstChild() : NULL ); } -/// Returns first child of node, resets iterator. +/// @deprecated Use the equivalent member function Inkscape::XML::Node::firstChild() inline Inkscape::XML::Node *sp_repr_children(Inkscape::XML::Node *repr) { return ( repr ? repr->firstChild() : NULL ); } -/// Returns next child of node or NULL. +/// @deprecated Use the equivalent member function Inkscape::XML::Node::next() inline Inkscape::XML::Node const *sp_repr_next(Inkscape::XML::Node const *repr) { return ( repr ? repr->next() : NULL ); } -/// Returns next child of node or NULL. +/// @deprecated Use the equivalent member function Inkscape::XML::Node::next() inline Inkscape::XML::Node *sp_repr_next(Inkscape::XML::Node *repr) { return ( repr ? repr->next() : NULL ); } @@ -220,11 +124,10 @@ unsigned sp_repr_set_svg_double(Inkscape::XML::Node *repr, gchar const *key, dou unsigned sp_repr_set_point(Inkscape::XML::Node *repr, gchar const *key, Geom::Point const & val); unsigned sp_repr_get_point(Inkscape::XML::Node *repr, gchar const *key, Geom::Point *val); -/// \deprecated ! +/// \deprecated Use sp_repr_get_double to check for success double sp_repr_get_double_attribute(Inkscape::XML::Node *repr, gchar const *key, double def); -/// \deprecated ! +/// \deprecated Use sp_repr_get_int to check for success long long int sp_repr_get_int_attribute(Inkscape::XML::Node *repr, gchar const *key, long long int def); -/* End Deprecated? */ int sp_repr_compare_position(Inkscape::XML::Node *first, Inkscape::XML::Node *second); @@ -242,8 +145,6 @@ inline Inkscape::XML::Node *sp_repr_document_first_child(Inkscape::XML::Document } #endif - - /* Local Variables: mode:c++ diff --git a/src/xml/simple-document.cpp b/src/xml/simple-document.cpp index d854f92fb..c2f7c8c1c 100644 --- a/src/xml/simple-document.cpp +++ b/src/xml/simple-document.cpp @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::SimpleDocument - generic XML document implementation - * - * Copyright 2004-2005 MenTaLguY +/** @file + * @brief Garbage collected XML document implementation + */ +/* Copyright 2004-2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/src/xml/simple-document.h b/src/xml/simple-document.h index 504be8248..0a20f121e 100644 --- a/src/xml/simple-document.h +++ b/src/xml/simple-document.h @@ -35,8 +35,6 @@ public: NodeType type() const { return Inkscape::XML::DOCUMENT_NODE; } - NodeObserver *logger() { return this; } - bool inTransaction() { return _in_transaction; } void beginTransaction(); @@ -73,6 +71,7 @@ protected: { return new SimpleDocument(*this); } + NodeObserver *logger() { return this; } private: bool _in_transaction; diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index a229c33fe..3cca393d2 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -1,7 +1,7 @@ -/* - * SimpleNode - simple XML node implementation - * - * Copyright 2003-2005 MenTaLguY +/** @file + * @brief Garbage collected XML node implementation + */ +/* Copyright 2003-2005 MenTaLguY * Copyright 2003 Nathan Hurst * Copyright 1999-2003 Lauris Kaplinski * Copyright 2000-2002 Ximian Inc. @@ -12,7 +12,6 @@ * of the License, or (at your option) any later version. * * See the file COPYING for details. - * */ #include @@ -628,4 +627,4 @@ void SimpleNode::mergeFrom(Node const *src, gchar const *key) { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/xml/simple-node.h b/src/xml/simple-node.h index 98d363f34..044068eb1 100644 --- a/src/xml/simple-node.h +++ b/src/xml/simple-node.h @@ -1,7 +1,7 @@ -/* - * SimpleNode - generic XML node implementation - * - * Copyright 2004-2005 MenTaLguY +/** @file + * @brief GC-managed XML node implementation + */ +/* Copyright 2004-2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -9,7 +9,6 @@ * of the License, or (at your option) any later version. * * See the file COPYING for details. - * */ #ifndef SEEN_INKSCAPE_XML_SIMPLE_NODE_H @@ -26,6 +25,11 @@ namespace Inkscape { namespace XML { +/** + * @brief Default implementation of the XML node stored in memory. + * + * @see Inkscape::XML::Node + */ class SimpleNode : virtual public Node, public Inkscape::GC::Managed<> { diff --git a/src/xml/subtree.h b/src/xml/subtree.h index 9e2512e83..07996e6a6 100644 --- a/src/xml/subtree.h +++ b/src/xml/subtree.h @@ -1,7 +1,7 @@ -/* - * XML::Subtree - proxy for an XML subtree - * - * Copyright 2005 MenTaLguY +/** @file + * @brief Object representing a subtree of the XML document + */ +/* Copyright 2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -15,22 +15,45 @@ #ifndef SEEN_INKSCAPE_XML_SUBTREE_H #define SEEN_INKSCAPE_XML_SUBTREE_H -#include "xml/node-observer.h" +#include "gc-managed.h" +#include "xml/xml-forward.h" #include "xml/composite-node-observer.h" -#include "gc-finalized.h" namespace Inkscape { namespace XML { -class Node; - +/** + * @brief Represents a node and all its descendants + * + * This is a convenience object for node operations that affect all of the node's descendants. + * Currently the only such operations are adding and removing subtree observers + * and synthesizing events for the entire subtree. + */ class Subtree : public GC::Managed { public: Subtree(Node &root); ~Subtree(); + /** + * @brief Synthesize events for the entire subtree + * + * This method notifies the specified observer of node changes equivalent to creating + * this subtree from scratch. The notifications recurse into the tree depth-first. + * Currently this is the only method that provides extra functionality compared to + * the public methods of Node. + */ void synthesizeEvents(NodeObserver &observer); + /** + * @brief Add an observer watching for subtree changes + * + * Equivalent to Node::addSubtreeObserver(). + */ void addObserver(NodeObserver &observer); + /** + * @brief Add an observer watching for subtree changes + * + * Equivalent to Node::removeSubtreeObserver(). + */ void removeObserver(NodeObserver &observer); private: diff --git a/src/xml/text-node.h b/src/xml/text-node.h index 8fb797276..ef6e477ab 100644 --- a/src/xml/text-node.h +++ b/src/xml/text-node.h @@ -1,7 +1,7 @@ -/* - * Inkscape::XML::TextNode - simple text node implementation - * - * Copyright 2004-2005 MenTaLguY +/** @file + * @brief Text node implementation + */ +/* Copyright 2004-2005 MenTaLguY * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,6 +22,9 @@ namespace Inkscape { namespace XML { +/** + * @brief Text node, e.g. "Some text" in <group>Some text</group> + */ struct TextNode : public SimpleNode { TextNode(Util::ptr_shared content, Document *doc) : SimpleNode(g_quark_from_static_string("string"), doc) diff --git a/src/xml/xml-forward.h b/src/xml/xml-forward.h index 17271c1c3..33218c8ae 100644 --- a/src/xml/xml-forward.h +++ b/src/xml/xml-forward.h @@ -35,6 +35,7 @@ struct NodeSiblingIteratorStrategy; struct NodeParentIteratorStrategy; class NodeObserver; class Node; +struct PINode; class SimpleDocument; class SimpleNode; class Subtree;