summaryrefslogtreecommitdiffstats
path: root/src/uri-references.cpp
diff options
context:
space:
mode:
authorMarc Jeanmougin <marc@jeanmougin.fr>2016-10-27 00:01:14 +0000
committerMarc Jeanmougin <marcjeanmougin@free.fr>2016-10-27 00:01:14 +0000
commit71f7e3e517b5d7f87d30a27b683c57df05ab5368 (patch)
tree34e8796399dbb9cfa63a47a491fb37f51ce6b101 /src/uri-references.cpp
parentPrevent image drag/drop from grouping (diff)
downloadinkscape-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.cpp38
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)