From ea3737623c19fa92b97ec6c3e228ea0f8db7a03b Mon Sep 17 00:00:00 2001 From: Ben Scholzen 'DASPRiD Date: Fri, 29 May 2015 19:21:52 +0200 Subject: Import all defs from clipboard or imported files Fixed bugs: - https://launchpad.net/bugs/1460057 (bzr r14185) --- src/document.cpp | 9 ++++++++- src/document.h | 1 + src/xml/repr-util.cpp | 28 ++++++++++++++++++++++++++++ src/xml/repr.h | 5 +++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/document.cpp b/src/document.cpp index 741e7c812..ebf5d312f 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1634,11 +1634,18 @@ void SPDocument::setModifiedSinceSave(bool modified) { void SPDocument::importDefs(SPDocument *source) { Inkscape::XML::Node *root = source->getReprRoot(); - Inkscape::XML::Node *defs = sp_repr_lookup_name(root, "svg:defs", 1); Inkscape::XML::Node *target_defs = this->getDefs()->getRepr(); + std::vector defsNodes = sp_repr_lookup_name_many(root, "svg:defs"); prevent_id_clashes(source, this); + for (std::vector::iterator defs = defsNodes.begin(); defs != defsNodes.end(); ++defs) { + importDefsNode(source, const_cast(*defs), target_defs); + } +} + +void SPDocument::importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, Inkscape::XML::Node *target_defs) +{ int stagger=0; /* Note, "clipboard" throughout the comments means "the document that is either the clipboard diff --git a/src/document.h b/src/document.h index 16b9bb28d..dd1e295a2 100644 --- a/src/document.h +++ b/src/document.h @@ -275,6 +275,7 @@ public: private: void do_change_uri(char const *const filename, bool const rebase); void setupViewport(SPItemCtx *ctx); + void importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, Inkscape::XML::Node *target_defs); }; /* diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 4cbe930a1..f7a437163 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -371,6 +371,34 @@ Inkscape::XML::Node *sp_repr_lookup_name( Inkscape::XML::Node *repr, gchar const return const_cast(found); } +std::vector sp_repr_lookup_name_many( Inkscape::XML::Node const *repr, gchar const *name, gint maxdepth ) +{ + std::vector nodes; + std::vector found; + g_return_val_if_fail(repr != NULL, nodes); + g_return_val_if_fail(name != NULL, nodes); + + GQuark const quark = g_quark_from_string(name); + + if ( (GQuark)repr->code() == quark ) { + nodes.push_back(repr); + } + + if ( maxdepth != 0 ) { + // maxdepth == -1 means unlimited + if ( maxdepth == -1 ) { + maxdepth = 0; + } + + for (Inkscape::XML::Node const *child = repr->firstChild() ; child; child = child->next() ) { + found = sp_repr_lookup_name_many( child, name, maxdepth - 1); + nodes.insert(nodes.end(), found.begin(), found.end()); + } + } + + return nodes; +} + /** * Determine if the node is a 'title', 'desc' or 'metadata' element. */ diff --git a/src/xml/repr.h b/src/xml/repr.h index 17763195a..e84b89813 100644 --- a/src/xml/repr.h +++ b/src/xml/repr.h @@ -14,6 +14,7 @@ #ifndef SEEN_SP_REPR_H #define SEEN_SP_REPR_H +#include #include #include "xml/node.h" @@ -144,6 +145,10 @@ Inkscape::XML::Node *sp_repr_lookup_name(Inkscape::XML::Node *repr, Inkscape::XML::Node const *sp_repr_lookup_name(Inkscape::XML::Node const *repr, char const *name, int maxdepth = -1); + +std::vector sp_repr_lookup_name_many(Inkscape::XML::Node const *repr, + char const *name, + int maxdepth = -1); Inkscape::XML::Node *sp_repr_lookup_child(Inkscape::XML::Node *repr, char const *key, -- cgit v1.2.3