diff options
| author | Marc Jeanmougin <marc@jeanmougin.fr> | 2016-10-27 00:01:14 +0000 |
|---|---|---|
| committer | Marc Jeanmougin <marcjeanmougin@free.fr> | 2016-10-27 00:01:14 +0000 |
| commit | 71f7e3e517b5d7f87d30a27b683c57df05ab5368 (patch) | |
| tree | 34e8796399dbb9cfa63a47a491fb37f51ce6b101 /src/uri-references.cpp | |
| parent | Prevent image drag/drop from grouping (diff) | |
| download | inkscape-71f7e3e517b5d7f87d30a27b683c57df05ab5368.tar.gz inkscape-71f7e3e517b5d7f87d30a27b683c57df05ab5368.zip | |
Fix regression in loop prevention
Fixed bugs:
- https://launchpad.net/bugs/1636533
(bzr r15193)
Diffstat (limited to 'src/uri-references.cpp')
| -rw-r--r-- | src/uri-references.cpp | 38 |
1 files changed, 12 insertions, 26 deletions
diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 07f2d168b..170c98beb 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -3,6 +3,7 @@ * * Authors: * Lauris Kaplinski <lauris@kaplinski.com> + * Marc Jeanmougin * * Copyright (C) 2001-2002 Lauris Kaplinski * Copyright (C) 2001 Ximian, Inc. @@ -48,13 +49,10 @@ URIReference::~URIReference() { detach(); } * The main ideas here are: * (1) "If we are inside a clone, then we can accept if and only if our "original thing" can accept the reference" * (this caused problems when there are clones because a change in ids triggers signals for the object hrefing this id, - *but also its cloned reprs - * (descendants of <use> referencing an ancestor of the href'ing object)). The way it is done here is *atrocious*, but i - *could not find a better way. - * FIXME: find a better and safer way to find the "original object" of anyone with the flag ->cloned + * but also its cloned reprs(descendants of <use> referencing an ancestor of the href'ing object)). * * (2) Once we have an (potential owner) object, it can accept a href to obj, iff the graph of objects where directed - *edges are + * edges are * either parent->child relations , *** or href'ing to href'ed *** relations, stays acyclic. * We can go either from owner and up in the tree, or from obj and down, in either case this will be in the worst case *linear in the number of objects. @@ -70,29 +68,17 @@ bool URIReference::_acceptObject(SPObject *obj) const SPObject *owner = getOwner(); if (!owner) return true; + while (owner->cloned) { - std::vector<int> positions; - while (owner->cloned) { - int position = 0; - for (auto &child: owner->parent->children) { - if(&child == owner) { - break; - } - position++; - } - positions.push_back(position); + if(!owner->clone_original)//happens when the clone is existing and linking to something, even before the original objects exists. + //for instance, it can happen when you paste a filtered object in a already cloned group: The construction of the + //clone representation of the filtered object will finish before the original object, so the cloned repr will + //have to _accept the filter even though the original does not exist yet. In that case, we'll accept iff the parent of the + //original can accept it: loops caused by other relations than parent-child would be prevented when created on their base object. + //Fixes bug 1636533. owner = owner->parent; - } - if (dynamic_cast<SPUse *>(owner)) - owner = ((SPUse *)owner)->get_original(); - else if (dynamic_cast<SPTagUse *>(owner)) - owner = ((SPTagUse *)owner)->get_original(); - else { - g_warning("cloned object with no known type\n"); - return false; - } - for (int i = (int) (positions.size() - 2); i >= 0; i--) - owner = owner->childList(false)[positions[i]]; + else + owner = owner->clone_original; } // once we have the "original" object (hopefully) we look at who is referencing it if (obj == owner) |
