From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/object/sp-tag-use.cpp | 198 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 src/object/sp-tag-use.cpp (limited to 'src/object/sp-tag-use.cpp') diff --git a/src/object/sp-tag-use.cpp b/src/object/sp-tag-use.cpp new file mode 100644 index 0000000..e4e664b --- /dev/null +++ b/src/object/sp-tag-use.cpp @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * SVG implementation + * + * Authors: + * Theodore Janeczko + * Liam P White + * + * Copyright (C) Theodore Janeczko 2012-2014 + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "sp-tag-use.h" + +#include +#include + +#include + +#include "bad-uri-exception.h" +#include "display/drawing-group.h" +#include "attributes.h" +#include "document.h" +#include "uri.h" +#include "xml/repr.h" +#include "preferences.h" +#include "style.h" +#include "sp-factory.h" +#include "sp-symbol.h" +#include "sp-tag-use-reference.h" + +SPTagUse::SPTagUse() +{ + href = nullptr; + //new (_changed_connection) sigc::connection; + ref = new SPTagUseReference(this); + + _changed_connection = ref->changedSignal().connect(sigc::mem_fun(*this, &SPTagUse::href_changed)); +} + +SPTagUse::~SPTagUse() +{ + + if (child) { + detach(child); + child = nullptr; + } + + ref->detach(); + delete ref; + ref = nullptr; + + _changed_connection.~connection(); //FIXME why? +} + +void +SPTagUse::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + SPObject::build(document, repr); + readAttr(SPAttr::XLINK_HREF); + + // We don't need to create child here: + // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, + // which will call sp_tag_use_href_changed, and that will take care of the child +} + +void +SPTagUse::release() +{ + + if (child) { + detach(child); + child = nullptr; + } + + _changed_connection.disconnect(); + + g_free(href); + href = nullptr; + + ref->detach(); + + SPObject::release(); +} + +void +SPTagUse::set(SPAttr key, gchar const *value) +{ + + switch (key) { + case SPAttr::XLINK_HREF: { + if ( value && href && ( strcmp(value, href) == 0 ) ) { + /* No change, do nothing. */ + } else { + g_free(href); + href = nullptr; + if (value) { + // First, set the href field, because sp_tag_use_href_changed will need it. + href = g_strdup(value); + + // Now do the attaching, which emits the changed signal. + try { + ref->attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + ref->detach(); + } + } else { + ref->detach(); + } + } + break; + } + + default: + SPObject::set(key, value); + break; + } +} + +Inkscape::XML::Node * +SPTagUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("inkscape:tagref"); + } + + SPObject::write(xml_doc, repr, flags); + + if (ref->getURI()) { + auto uri_string = ref->getURI()->str(); + repr->setAttributeOrRemoveIfEmpty("xlink:href", uri_string); + } + + return repr; +} + +/** + * Returns the ultimate original of a SPTagUse (i.e. the first object in the chain of its originals + * which is not an SPTagUse). If no original is found, NULL is returned (it is the responsibility + * of the caller to make sure that this is handled correctly). + * + * Note that the returned is the clone object, i.e. the child of an SPTagUse (of the argument one for + * the trivial case) and not the "true original". + */ + +SPItem * SPTagUse::root() +{ + SPObject *orig = child; + while (orig && SP_IS_TAG_USE(orig)) { + orig = SP_TAG_USE(orig)->child; + } + if (!orig || !SP_IS_ITEM(orig)) + return nullptr; + return SP_ITEM(orig); +} + +void +SPTagUse::href_changed(SPObject */*old_ref*/, SPObject */*ref*/) +{ + if (href) { + SPItem *refobj = ref->getObject(); + if (refobj) { + Inkscape::XML::Node *childrepr = refobj->getRepr(); + const std::string typeString = NodeTraits::get_type_string(*childrepr); + + SPObject* child_ = SPFactory::createObject(typeString); + if (child_) { + child = child_; + attach(child_, lastChild()); + sp_object_unref(child_, nullptr); + child_->invoke_build(this->document, childrepr, TRUE); + + } + } + } +} + +SPItem * SPTagUse::get_original() +{ + SPItem *ref_ = nullptr; + if (ref) { + ref_ = ref->getObject(); + } + return ref_; +} + +/* + 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 : -- cgit v1.2.3