summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9b7a0e5)
raw | patch | inline | side by side (parent: 9b7a0e5)
author | tweenk <tweenk@users.sourceforge.net> | |
Tue, 23 Sep 2008 23:34:58 +0000 (23:34 +0000) | ||
committer | tweenk <tweenk@users.sourceforge.net> | |
Tue, 23 Sep 2008 23:34:58 +0000 (23:34 +0000) |
* Doxygen fixes for a few files
* Garbage-collected allocator for STL containers
* Garbage-collected allocator for STL containers
48 files changed:
diff --git a/src/2geom/geom.cpp b/src/2geom/geom.cpp
index fc6d930dcf8ef7c00ca44ab9f4a42d3c72318071..ded1a19402a74d143c5376d37a86d2d32b000d81 100644 (file)
--- a/src/2geom/geom.cpp
+++ b/src/2geom/geom.cpp
-/**
- * \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 1a40c04e184d52ae73194c7f336e7d8350a6501c..210d236a1a9c91fdcd61c52a94bb392c7651fc13 100644 (file)
--- a/src/2geom/geom.h
+++ b/src/2geom/geom.h
-/**
- * \file geom.h
- * \brief Various geometrical calculations
- *
- * Authors:
+/** @file
+ * @brief Various geometrical calculations
+ */
+/* Authors:
* Nathan Hurst <njh@mail.csse.monash.edu.au>
*
* Copyright (C) 1999-2002 authors
diff --git a/src/Makefile_insert b/src/Makefile_insert
index 2aaf3607b41af4fe1c72b5716e28d5190409fad2..33e4f07f8887ae659473407c47d18f3cdb4ecb81 100644 (file)
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
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 0b4904bdf722e4a5d1aa5b39bcf2ef41bf1faa7d..1409d1d64a75be2c3c3a053d345535ecab8137e4 100644 (file)
--- a/src/arc-context.cpp
+++ b/src/arc-context.cpp
-#define __SP_ARC_CONTEXT_C__
-
-/** \file Ellipse drawing context. */
-
-/*
- * Authors:
+/** @file
+ * @brief Ellipse drawing context
+ */
+/* Authors:
* Mitsuru Oka
* Lauris Kaplinski <lauris@kaplinski.com>
* bulia byak <buliabyak@users.sf.net>
+ * Johan Engelen <johan@shouraizou.nl>
*
- * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
- * 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 <config.h>
#endif
diff --git a/src/dir-util.cpp b/src/dir-util.cpp
index 7cc69f89df3b90a7502e9610577db60b14e5c6c3..75f7ca5247821166f8d57e1115839db8d7adc034 100644 (file)
--- a/src/dir-util.cpp
+++ b/src/dir-util.cpp
-/** \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 d0b174dca7be6326784afabccb7b2f35412b40cf..e4195324f8df991d93e49ad7ccb4ed53c0271771 100644 (file)
--- a/src/fill-or-stroke.h
+++ b/src/fill-or-stroke.h
+/** @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
--- /dev/null
+++ b/src/gc-allocator.h
@@ -0,0 +1,106 @@
+/** @file
+ * @brief Garbage-collected STL allocator for standard containers
+ */
+/* Authors:
+ * Krzysztof KosiĆski <tweenk.pl@gmail.com>
+ *
+ * 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 <cstddef>
+#include <limits>
+#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<int, Glib::ustring, less<int>, 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 <typename T>
+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 <typename U>
+ struct rebind {
+ typedef Allocator<U> other;
+ };
+
+ // constructors - no-ops since the allocator doesn't have any state
+ Allocator() throw() {}
+ Allocator(Allocator const &) throw() {}
+ template <typename U> Allocator(Allocator<U> 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<void*>(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<size_type>::max() / sizeof(T);
+ }
+
+ // allocate memory for num elements without initializing them
+ pointer allocate(size_type num, Allocator<void>::const_pointer) {
+ return static_cast<pointer>( 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 <typename T1, typename T2>
+bool operator==(Allocator<T1> const &, Allocator<T2> const &) { return true; }
+template <typename T1, typename T2>
+bool operator!=(Allocator<T1> const &, Allocator<T2> 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 faf7eb4de9b1b4a63426c33dc5126186b39ad43c..af327dc55f6256c13529b4b778563782374e9673 100644 (file)
--- a/src/gc-core.h
+++ b/src/gc-core.h
-/*
- * Inkscape::GC - Wrapper for Boehm GC
- *
- * Authors:
+/** @file
+ * @brief Wrapper for Boehm GC
+ */
+/* Authors:
* MenTaLguY <mental@rydia.net>
*
* Copyright (C) 2004 MenTaLguY
diff --git a/src/gc-finalized.h b/src/gc-finalized.h
index 738d37692f205bf618f2fa268d4174dfb4821349..cf47cb09b1da2b4ed3fc33caa2887acc44b93137 100644 (file)
--- a/src/gc-finalized.h
+++ b/src/gc-finalized.h
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
* 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
* @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 80d9c94111a43d226d3d98c54df1a52431de3894..954c8103b4dea86a5c16b954c5b8ef23f060e279 100644 (file)
--- a/src/gc-managed.h
+++ b/src/gc-managed.h
-/** \file
- * Inkscape::GC::Managed - base class for GC-managed objects
- *
- * Copyright 2004 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Base class for GC-managed objects
+ */
+/* Copyright 2004 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 8a55a3b15eb6a970dcd7560a8493e98d4b699f27..ee988afbbc7811a3105edbc3b690299a4f825a9f 100644 (file)
--- a/src/gc.cpp
+++ b/src/gc.cpp
-/*
- * Inkscape::GC - Wrapper for Boehm GC
- *
- * Authors:
+/** @file
+ * @brief Wrapper for Boehm GC
+ */
+/* Authors:
* MenTaLguY <mental@rydia.net>
*
* Copyright (C) 2004 MenTaLguY
index 6bfcab59b6599597b68d08666a6ef1a266d11359..419ac485cd4b1c2c5776fb85cf6c4236d78d9b57 100644 (file)
void handleChange(Message::Wrapper &wrapper, Pedro::Element* data);
- NodeObserver *logger() { return this; }
-
//
// XML::Session methods
//
{
return new InkboardDocument(*this);
}
+ NodeObserver *logger() { return this; }
private:
void _initBindings();
index 58e06fc6de032e40e0ba0de1c12f81309979be6a..81e351103a71d0968a38370588fb56c57fd29200 100644 (file)
-/** \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
index 7f8ecea90a8ce242156e18ea42ac72741f0d5ae7..27baf43b714099753d18f15cfe7e19a704a4d985 100644 (file)
+/** @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.
index 1040e2be988609a93f96610d13c92ec45b2f8a22..7e1d90b72574a5da8eefda3255f491976bbfa4ba 100644 (file)
--- a/src/libnrtype/one-box.h
+++ b/src/libnrtype/one-box.h
-/** \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
index 667c7743b14ae1fb63bc1be260b1a41066a6ae47..9467e69e96afb7412feb8e0d2ec2e6317d36f10f 100644 (file)
-/** \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
index 83a825b554811a3e83b67f20ca29f729274f3f69..82532df1f67171488d955a91fa95cd740bd3d2ca 100644 (file)
+/** @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"
index 68af4c5c59de585c10d5ab175d166d43acf72c58..4d2750b9ebd68ef3a9f457595dc4256ecf72a4cc 100644 (file)
-/**
- * \brief remove overlaps between a set of rectangles.
+/** @file
+ * @brief remove overlaps between a set of rectangles.
*
* Authors:
* Tim Dwyer <tgdwyer@gmail.com>
index baa15b5945a70ca9111c04476a3cc3434c9d6ec3..1af90a754524a8c205c084595c507ae980a78b2b 100644 (file)
-#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 <tgdwyer@gmail.com>
*
* 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;
}
index 271a6baae6b8b8d83f672b584c1f89f561075640..b6e765e13bdea56b6289baeb9aa56bf97e318da5 100644 (file)
+/** @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;
index 9ac38b84bf75be514e424d6c92b0061351026833..477aa1c191851f19ac29a6ad149df22952827ab5 100644 (file)
-#ifndef __COLOR_PICKER_H__
-#define __COLOR_PICKER_H__
-
-/**
- * \file Color picker button \& window.
+/** @file
+ * @brief Color picker button and window.
*/
-/*
- * Authors:
+/* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* Ralf Stephan <ralf@ark.in-berlin.de>
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#ifndef __COLOR_PICKER_H__
+#define __COLOR_PICKER_H__
+
#include <sigc++/sigc++.h>
#include <gtkmm/button.h>
#include <gtkmm/dialog.h>
index 8f7d56c768400f7cc7b9e276571826cce44be20d..aae34ed98166b5b13dceaed05b7cf9fc7fb72bdc 100644 (file)
} 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<SPDesktopWidget*>::iterator it = dtws.begin(); it != dtws.end(); ++it ) {
SPDesktopWidget* dtw = *it;
(*it)->requestCanvasUpdate();
}
}
+ }
#else
- {
- (void)node;
- (void)name;
+ (void)node;
+ (void)name;
#endif // ENABLE_LCMS
- }
}
static PrefWatcher* watcher = 0;
index 46be9edfaf3c8163a14ff50dd31d8b1ccf385deb..84e90712659a3d38178ac5095d7a84359f73276f 100644 (file)
--- a/src/xml/Makefile_insert
+++ b/src/xml/Makefile_insert
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)
index bfae19e21cb9f714f6119f0c6bf6895e8d239d55..bab0b5aa4ba8321104f768db6aa70ec4c3707394 100644 (file)
+/** @file
+ * @brief Key-value pair representing an attribute
+ */
+
#ifndef SEEN_XML_SP_REPR_ATTR_H
#define SEEN_XML_SP_REPR_ATTR_H
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<char> 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<char> value;
// accept default copy constructor and assignment operator
diff --git a/src/xml/comment-node.h b/src/xml/comment-node.h
index 5cff9caf6f218e28faee4fe3233f6cc916fa61ee..698a30a908e3d57da3e7a18636da7bec8997f99c 100644 (file)
--- a/src/xml/comment-node.h
+++ b/src/xml/comment-node.h
-/*
- * Inkscape::XML::CommentNode - simple XML comment implementation
- *
- * Copyright 2004-2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Comment node implementation
+ */
+/* Copyright 2004-2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
namespace XML {
+/**
+ * @brief Comment node, e.g. <!-- Some comment -->
+ */
struct CommentNode : public SimpleNode {
CommentNode(Util::ptr_shared<char> content, Document *doc)
: SimpleNode(g_quark_from_static_string("comment"), doc)
index 7b5a24d538da89a342898f6535613d92aa2353e2..826467dc48aa7ff928021da3c86fb35ba2159ec2 100644 (file)
-/*
+/** @file
* Inkscape::XML::CompositeNodeObserver - combine multiple observers
- *
- * Copyright 2005 MenTaLguY <mental@rydia.net>
+ */
+/* Copyright 2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
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<> {
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);
void _finishIteration();
};
-}
-
-}
+} // namespace XML
+} // namespace Inkscape
#endif
/*
index a40ddd661239899df2c2ab6dc5c66037b8298eaf..db98e3d016d4d6765edc87bdc4200e88a84ac1d1 100644 (file)
static gboolean is_element_node(CRXMLNodePtr n) { return static_cast<Node const *>(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 5065092d0ab6efea163326033bf38141516b7ae6..2b9ea5cc3c8ebd12648af2d8cdbfbd51ff1747c7 100644 (file)
--- a/src/xml/document.h
+++ b/src/xml/document.h
-/*
- * Inkscape::XML::Document - interface for XML documents
- *
- * Copyright 2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Interface for XML documents
+ */
+/* Copyright 2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#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 11bc8e03a34eb59bf29eb53a46b74c03b3f999f3..7b75f8080812fd9359b4c88d178a1bca72a8cedd 100644 (file)
--- a/src/xml/element-node.h
+++ b/src/xml/element-node.h
-/*
- * Inkscape::XML::ElementNode - simple XML element implementation
- *
- * Copyright 2004-2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Element node implementation
+ */
+/* Copyright 2004-2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
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 59dbe7c7bc5ab4f2b561d7b733af89e133870f2a..c62257751e712bf7ee0e985ac9cad276299c0265 100644 (file)
--- a/src/xml/event.h
+++ b/src/xml/event.h
+/** @file
+ * @brief Event object representing a change of the XML document
+ */
+/* Authors:
+ * Unknown author(s)
+ * Krzysztof KosiĆski <tweenk.pl@gmail.com> (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
#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<Inkscape::GC::SCANNED, Inkscape::GC::MANUAL>
{
-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<Event, IteratorStrategy> Iterator;
- typedef Inkscape::Util::ForwardPointerIterator<Event const, IteratorStrategy> 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<Event, IteratorStrategy> Iterator;
+ typedef Inkscape::Util::ForwardPointerIterator<Event const, IteratorStrategy> 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<char> ov,
- Inkscape::Util::ptr_shared<char> nv,
- Event *next)
- : Event(repr, next), key(k),
- oldval(ov), newval(nv) {}
-
- GQuark key;
- Inkscape::Util::ptr_shared<char> oldval;
- Inkscape::Util::ptr_shared<char> newval;
+ EventChgAttr(Node *repr, GQuark k,
+ Inkscape::Util::ptr_shared<char> ov,
+ Inkscape::Util::ptr_shared<char> 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<char> oldval;
+ /// Value of the attribute after the change
+ Inkscape::Util::ptr_shared<char> 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<char> ov,
- Inkscape::Util::ptr_shared<char> nv,
- Event *next)
- : Event(repr, next), oldval(ov), newval(nv) {}
+ EventChgContent(Node *repr,
+ Inkscape::Util::ptr_shared<char> ov,
+ Inkscape::Util::ptr_shared<char> nv,
+ Event *next)
+ : Event(repr, next), oldval(ov), newval(nv) {}
- Inkscape::Util::ptr_shared<char> oldval;
- Inkscape::Util::ptr_shared<char> newval;
+ /// Content of the node before the change
+ Inkscape::Util::ptr_shared<char> oldval;
+ /// Content of the node after the change
+ Inkscape::Util::ptr_shared<char> 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 :
index e8b7c707e121a0dc1b6511d9e8f89be6846da19b..5ff09a0e00738bd00a8320681aa133190cd73849 100644 (file)
--- a/src/xml/log-builder.cpp
+++ b/src/xml/log-builder.cpp
-/*
- * Inkscape::XML::LogBuilder - NodeObserver which builds an event log
- *
- * Copyright 2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Object building an event log
+ */
+/* Copyright 2005 MenTaLguY <mental@rydia.net>
*
* 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 478bf295fd1b9a8de33837706e9e30cb21fb5904..0a161d18f71d5e0597a464a3547edbc9622cf3d0 100644 (file)
--- a/src/xml/log-builder.h
+++ b/src/xml/log-builder.h
-/*
- * Inkscape::XML::LogBuilder - NodeObserver which builds an event log
- *
- * Copyright 2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Object building an event log
+ */
+/* Copyright 2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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);
void setAttribute(Node &node, GQuark name,
Util::ptr_shared<char> old_value,
Util::ptr_shared<char> new_value);
+ /*@}*/
private:
Event *_log;
index 920e28475adab90837032a7ca94a0d8405c3a8e2..0c291c23041e9eff02c7941372fc077f31bac42b 100644 (file)
-#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 <lauris@kaplinski.com>
* Frank Felfe <innerspace@iname.com>
*
* 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 <glib/gtypes.h>
#include "xml/node.h"
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);
}
}
+/**
+ * @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 cb41611415b5ecd0af118fa6662ace6086e03d66..deb88fb5e03421c03fac19932499ed0999793aac 100644 (file)
--- a/src/xml/node-fns.cpp
+++ b/src/xml/node-fns.cpp
bool id_permitted_internal_memoized(GQuark qname) {
typedef std::map<GQuark, bool> IdPermittedMap;
- IdPermittedMap id_permitted_names;
+ static IdPermittedMap id_permitted_names;
IdPermittedMap::iterator found;
found = id_permitted_names.find(qname);
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;
}
}
-
/*
Local Variables:
mode:c++
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 54366e61fd918e0437b78d6db0859183fb597d37..4c64087893fe53d26774128ec5a7ce7b17ced7d0 100644 (file)
--- a/src/xml/node-fns.h
+++ b/src/xml/node-fns.h
-#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 <tweenk.pl@gmail.com> (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 *>(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++
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 :
index 584505e4e273ef5ab49f321b2793611d95588468..6052e48b60e09aaf3fefb950770f7f65fe9fc82c 100644 (file)
--- a/src/xml/node-observer.h
+++ b/src/xml/node-observer.h
-/*
- * Inkscape::XML::NodeObserver - interface implemented by observers of XML nodes
+/** @file
+ * @brief Interface for XML node observers
+ */
+/* Authors:
+ * MenTaLguY <mental@rydia.net>
+ * Krzysztof KosiĆski <tweenk.pl@gmail.com> (documentation)
*
- * Copyright 2005 MenTaLguY <mental@rydia.net>
+ * 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
* of the License, or (at your option) any later version.
*
* See the file COPYING for details.
- *
*/
#ifndef SEEN_INKSCAPE_XML_NODE_OBSERVER_H
#include <glib/gquark.h>
#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<char> old_content,
Util::ptr_shared<char> 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<char> old_value,
Util::ptr_shared<char> new_value)=0;
};
-}
-
-}
+} // namespace XML
+} // namespace Inkscape
#endif
/*
diff --git a/src/xml/node.h b/src/xml/node.h
index aac2db191fcf4beb31cf827a4c1d414532cfe486..abcccdb9a68483123cbc293fb2d366b8d6c572bf 100644 (file)
--- a/src/xml/node.h
+++ b/src/xml/node.h
-/*
- * Node - interface for XML nodes
+/** @file
+ * @brief Interface for XML nodes
+ */
+/* Authors:
+ * MenTaLguY <mental@rydia.net>
+ * Krzysztof KosiĆski <tweenk.pl@gmail.com> (documentation)
*
- * Copyright 2005 MenTaLguY <mental@rydia.net>
+ * 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
* of the License, or (at your option) any later version.
*
* See the file COPYING for details.
- *
*/
#ifndef SEEN_INKSCAPE_XML_NODE_H
#include <glib/gtypes.h>
#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<Glib::Quark const, gchar const *>
+ * or something similar with a custom allocator
+ */
+ virtual Inkscape::Util::List<AttributeRecord const> 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<AttributeRecord const> 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 502c5cd714e388cb19ec92dfe30fe68f0194f8d6..4aa1f840b0e58905dcbe2cd7f9abed4297823e85 100644 (file)
--- a/src/xml/pi-node.h
+++ b/src/xml/pi-node.h
-/*
- * Inkscape::XML::PINode - simple XML comment implementation
- *
- * Copyright 2004-2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Processing instruction node implementation
+ */
+/* Copyright 2004-2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* of the License, or (at your option) any later version.
*
* See the file COPYING for details.
- *
*/
#ifndef SEEN_INKSCAPE_XML_PI_NODE_H
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<char> content, Document *doc)
: SimpleNode(target, doc)
diff --git a/src/xml/repr-sorting.h b/src/xml/repr-sorting.h
index 534caa2d16aacd56bf1597be4fc8c3b3b3de668d..37f719622a0f291d2f73e6304708de2f7eb72713 100644 (file)
--- a/src/xml/repr-sorting.h
+++ b/src/xml/repr-sorting.h
-/** \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 59563a7fc754f8a6d9c3a55b67a30b1aac283ffa..528902fef6505edc8609b29262f960465be0a5cf 100644 (file)
--- 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,
}
/**
- * \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 a16a3c4f4e1fb7091c172f322683bc0a5ab72a2f..162896c3f70105daaada88648f6bcd78f922141b 100644 (file)
--- a/src/xml/repr.h
+++ b/src/xml/repr.h
-#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 <lauris@kaplinski.com>
*
* Copyright (C) 1999-2002 authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+
+#ifndef __SP_REPR_H__
+#define __SP_REPR_H__
#include <stdio.h>
#include <glib/gtypes.h>
#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.
- *
- * <b> Inkscape::XML::Node mini-FAQ </b>
- *
- * 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? <br>
- * A: If you have an SPDocument, use doc->rroot. For example:
- *
- * \code SP_ACTIVE_DOCUMENT->rroot \endcode <br>
- *
- * (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? <br>
- * A: Use sp_repr_lookup_child
- *
- * \arg
- * Q: How do I find an Inkscape::XML::Node by unique namespace name? <br>
- * A: Use sp_repr_lookup_name
- *
- * \arg
- * Q: How do I make an Inkscape::XML::Node namespace prefix constant in
- * the application? <br>
- * A: Add the XML namespace URL as a #define to repr.h at the top with the
- * other SP_<NAMESPACE>_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? <br>
- * 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? <br>
- * A: I have no idea yet...
- *
- * \arg
- * Q: How do I add a namespace to a newly created document? <br>
- * 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);
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<Inkscape::XML::Node *>(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++
index d854f92fb384365ab445d4b8ac0b9e8c0c3870cc..c2f7c8c1cebf15da2b9f51c2cd386bb9fc36843f 100644 (file)
-/*
- * Inkscape::XML::SimpleDocument - generic XML document implementation
- *
- * Copyright 2004-2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Garbage collected XML document implementation
+ */
+/* Copyright 2004-2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
index 504be824829f18d3e427d9a7eda52696ad6abcb9..0a20f121ed2e5db505d75475a8f21aaa120c423c 100644 (file)
NodeType type() const { return Inkscape::XML::DOCUMENT_NODE; }
- NodeObserver *logger() { return this; }
-
bool inTransaction() { return _in_transaction; }
void beginTransaction();
{
return new SimpleDocument(*this);
}
+ NodeObserver *logger() { return this; }
private:
bool _in_transaction;
index a229c33fe124be7917efafbb690c2c8aab439b80..3cca393d228366d7b013d9109d7c207ebaddd85f 100644 (file)
--- a/src/xml/simple-node.cpp
+++ b/src/xml/simple-node.cpp
-/*
- * SimpleNode - simple XML node implementation
- *
- * Copyright 2003-2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Garbage collected XML node implementation
+ */
+/* Copyright 2003-2005 MenTaLguY <mental@rydia.net>
* Copyright 2003 Nathan Hurst
* Copyright 1999-2003 Lauris Kaplinski
* Copyright 2000-2002 Ximian Inc.
* of the License, or (at your option) any later version.
*
* See the file COPYING for details.
- *
*/
#include <cstring>
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 98d363f3487269ead181fda29094162ecf212056..044068eb12171b18f3702a79eb4d01056535798a 100644 (file)
--- a/src/xml/simple-node.h
+++ b/src/xml/simple-node.h
-/*
- * SimpleNode - generic XML node implementation
- *
- * Copyright 2004-2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief GC-managed XML node implementation
+ */
+/* Copyright 2004-2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* of the License, or (at your option) any later version.
*
* See the file COPYING for details.
- *
*/
#ifndef SEEN_INKSCAPE_XML_SIMPLE_NODE_H
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 9e2512e83786a294cb2e47171d0fcc171047bbfd..07996e6a68b5c1a246b6c2c78fb947ccfdb13d0e 100644 (file)
--- a/src/xml/subtree.h
+++ b/src/xml/subtree.h
-/*
- * XML::Subtree - proxy for an XML subtree
- *
- * Copyright 2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Object representing a subtree of the XML document
+ */
+/* Copyright 2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
#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<GC::SCANNED, GC::MANUAL> {
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 8fb79727617aeddf653ea33313fcbec325597639..ef6e477abad5a22bfc0c86bf17d13c803b291936 100644 (file)
--- a/src/xml/text-node.h
+++ b/src/xml/text-node.h
-/*
- * Inkscape::XML::TextNode - simple text node implementation
- *
- * Copyright 2004-2005 MenTaLguY <mental@rydia.net>
+/** @file
+ * @brief Text node implementation
+ */
+/* Copyright 2004-2005 MenTaLguY <mental@rydia.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
namespace XML {
+/**
+ * @brief Text node, e.g. "Some text" in <group>Some text</group>
+ */
struct TextNode : public SimpleNode {
TextNode(Util::ptr_shared<char> 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 17271c1c376da2e146e4169e4db046c8d5bffc82..33218c8ae2378131c88559fca59125d9af1f1066 100644 (file)
--- a/src/xml/xml-forward.h
+++ b/src/xml/xml-forward.h
struct NodeParentIteratorStrategy;
class NodeObserver;
class Node;
+struct PINode;
class SimpleDocument;
class SimpleNode;
class Subtree;