summaryrefslogtreecommitdiffstats
path: root/src/xml/repr-util.cpp
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2018-12-04 12:40:43 +0000
committerTavmjong Bah <tavmjong@free.fr>2018-12-04 12:40:43 +0000
commitb0be54c82565f7e476187365ccb6c65d0729810d (patch)
treec0b8133fa3a57934f4b57a5e5aaa5da0697864b0 /src/xml/repr-util.cpp
parentMinor comment/alignment changes. (diff)
downloadinkscape-b0be54c82565f7e476187365ccb6c65d0729810d.tar.gz
inkscape-b0be54c82565f7e476187365ccb6c65d0729810d.zip
Add a few useful lookup functions.
Diffstat (limited to 'src/xml/repr-util.cpp')
-rw-r--r--src/xml/repr-util.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp
index a5dea02a2..a02997105 100644
--- a/src/xml/repr-util.cpp
+++ b/src/xml/repr-util.cpp
@@ -21,6 +21,8 @@
#include <glib.h>
+#include <glibmm.h>
+
#include <2geom/point.h>
#include "svg/stringstream.h"
#include "svg/css-ostringstream.h"
@@ -334,6 +336,36 @@ Inkscape::XML::Node *sp_repr_lookup_child(Inkscape::XML::Node *repr,
return nullptr;
}
+/**
+ * Recursive version of sp_repr_lookup_child().
+ */
+Inkscape::XML::Node const *sp_repr_lookup_descendant(Inkscape::XML::Node const *repr,
+ gchar const *key,
+ gchar const *value)
+{
+ Inkscape::XML::Node const *found = nullptr;
+ g_return_val_if_fail(repr != nullptr, NULL);
+ gchar const *repr_value = repr->attribute(key);
+ if ( (repr_value == value) ||
+ (repr_value && value && strcmp(repr_value, value) == 0) ) {
+ found = repr;
+ } else {
+ for (Inkscape::XML::Node const *child = repr->firstChild() ; child && !found; child = child->next() ) {
+ found = sp_repr_lookup_descendant( child, key, value );
+ }
+ }
+ return found;
+}
+
+
+Inkscape::XML::Node *sp_repr_lookup_descendant(Inkscape::XML::Node *repr,
+ gchar const *key,
+ gchar const *value)
+{
+ Inkscape::XML::Node const *found = sp_repr_lookup_descendant( const_cast<Inkscape::XML::Node const *>(repr), key, value );
+ return const_cast<Inkscape::XML::Node *>(found);
+}
+
Inkscape::XML::Node const *sp_repr_lookup_name( Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth )
{
Inkscape::XML::Node const *found = nullptr;
@@ -391,6 +423,34 @@ std::vector<Inkscape::XML::Node const *> sp_repr_lookup_name_many( Inkscape::XML
return nodes;
}
+std::vector<Inkscape::XML::Node *>
+sp_repr_lookup_property_many( Inkscape::XML::Node *repr, Glib::ustring const& property,
+ Glib::ustring const &value, int maxdepth )
+{
+ std::vector<Inkscape::XML::Node *> nodes;
+ std::vector<Inkscape::XML::Node *> found;
+ g_return_val_if_fail(repr != nullptr, nodes);
+
+ SPCSSAttr* css = sp_repr_css_attr (repr, "style");
+ if (value == sp_repr_css_property (css, property, "")) {
+ nodes.push_back(repr);
+ }
+
+ if ( maxdepth != 0 ) {
+ // maxdepth == -1 means unlimited
+ if ( maxdepth == -1 ) {
+ maxdepth = 0;
+ }
+
+ for (Inkscape::XML::Node *child = repr->firstChild() ; child; child = child->next() ) {
+ found = sp_repr_lookup_property_many( child, property, value, maxdepth - 1);
+ nodes.insert(nodes.end(), found.begin(), found.end());
+ }
+ }
+
+ return nodes;
+}
+
/**
* Determine if the node is a 'title', 'desc' or 'metadata' element.
*/