summaryrefslogtreecommitdiffstats
path: root/src/uri-references.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/uri-references.cpp')
-rw-r--r--src/uri-references.cpp48
1 files changed, 18 insertions, 30 deletions
diff --git a/src/uri-references.cpp b/src/uri-references.cpp
index db46a156f..7d6abd10a 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.
@@ -10,18 +11,19 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include "uri-references.h"
+
#include <iostream>
#include <cstring>
-#include <string>
+#include <glibmm/miscutils.h>
+
+#include "bad-uri-exception.h"
#include "document.h"
#include "sp-object.h"
#include "uri.h"
-#include "uri-references.h"
#include "extract-uri.h"
#include "sp-tag-use.h"
-#include <glibmm/miscutils.h>
-#include <sigc++/functors/mem_fun.h>
namespace Inkscape {
@@ -50,13 +52,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.
@@ -72,28 +71,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;
- SPObject *c = owner->parent->firstChild();
- while (c != owner && dynamic_cast<SPObject *>(c)) {
- position++;
- c = c->next;
- }
- 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 = 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)
@@ -118,7 +106,7 @@ bool URIReference::_acceptObject(SPObject *obj) const
-void URIReference::attach(const URI &uri) throw(BadURIException)
+void URIReference::attach(const URI &uri)
{
SPDocument *document = NULL;