summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Smith <john.smith7545@yahoo.com>2012-09-19 01:52:19 +0000
committerJohn Smith <john.smith7545@yahoo.com>2012-09-19 01:52:19 +0000
commitbf7c3e8d98b557cb64447804399797d93e1cedc0 (patch)
tree80848f225cad4c163c32ce4d2ec963982558adba /src
parentFix for 900602 : Enter key returns focus to canvas for Font family selector (diff)
downloadinkscape-bf7c3e8d98b557cb64447804399797d93e1cedc0.tar.gz
inkscape-bf7c3e8d98b557cb64447804399797d93e1cedc0.zip
Fix for 643150 : Auto-palette swatches duplicated on copy and paste
(bzr r11677)
Diffstat (limited to 'src')
-rw-r--r--src/document.cpp29
-rw-r--r--src/file.cpp9
-rw-r--r--src/id-clash.cpp28
-rw-r--r--src/id-clash.h1
-rw-r--r--src/ink-comboboxentry-action.cpp2
-rw-r--r--src/sp-gradient.cpp36
-rw-r--r--src/sp-gradient.h1
7 files changed, 96 insertions, 10 deletions
diff --git a/src/document.cpp b/src/document.cpp
index 9efd9d923..e28356969 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -1453,10 +1453,33 @@ void SPDocument::importDefs(SPDocument *source)
prevent_id_clashes(source, this);
for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) {
- Inkscape::XML::Node * dup = def->duplicate(this->getReprDoc());
- target_defs->appendChild(dup);
- Inkscape::GC::release(dup);
+
+ // Prevent duplicates of solid swatches by checking if equivalent swatch already exists
+ gboolean duplicate = false;
+ SPObject *src = source->getObjectByRepr(def);
+ if (src && SP_IS_GRADIENT(src)) {
+ SPGradient *gr = SP_GRADIENT(src);
+ if (gr->isSolid() || gr->getVector()->isSolid()) {
+ for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) {
+ if (trg && SP_IS_GRADIENT(trg) && src != trg) {
+ if (gr->isEquivalent(SP_GRADIENT(trg))) {
+ // Change object references to the existing equivalent gradient
+ change_def_references(src, trg);
+ duplicate = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (!duplicate) {
+ Inkscape::XML::Node * dup = def->duplicate(this->getReprDoc());
+ target_defs->appendChild(dup);
+ Inkscape::GC::release(dup);
+ }
}
+
}
/*
diff --git a/src/file.cpp b/src/file.cpp
index dcdae1700..778306d5d 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -1142,6 +1142,8 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
place_to_insert = in_doc->getRoot();
}
+ in_doc->importDefs(doc);
+
// Construct a new object representing the imported image,
// and insert it into the current document.
SPObject *new_obj = NULL;
@@ -1162,12 +1164,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
// don't lose top-level defs or style elements
else if (child->getRepr()->type() == Inkscape::XML::ELEMENT_NODE) {
const gchar *tag = child->getRepr()->name();
- if (!strcmp(tag, "svg:defs")) {
- for ( SPObject *x = child->firstChild(); x; x = x->getNext() ) {
- in_defs->getRepr()->addChild(x->getRepr()->duplicate(xml_in_doc), last_def);
- }
- }
- else if (!strcmp(tag, "svg:style")) {
+ if (!strcmp(tag, "svg:style")) {
in_doc->getRoot()->appendChildRepr(child->getRepr()->duplicate(xml_in_doc));
}
}
diff --git a/src/id-clash.cpp b/src/id-clash.cpp
index d8299652b..05a3149fc 100644
--- a/src/id-clash.cpp
+++ b/src/id-clash.cpp
@@ -26,6 +26,7 @@
#include "xml/node.h"
#include "xml/repr.h"
#include "sp-root.h"
+#include "sp-gradient.h"
typedef enum { REF_HREF, REF_STYLE, REF_URL, REF_CLIPBOARD } ID_REF_TYPE;
@@ -292,6 +293,33 @@ prevent_id_clashes(SPDocument *imported_doc, SPDocument *current_doc)
}
/*
+ * Change any references of svg:def from_obj into to_obj
+ */
+void
+change_def_references(SPObject *from_obj, SPObject *to_obj)
+{
+ refmap_type *refmap = new refmap_type;
+ id_changelist_type id_changes;
+ SPDocument *current_doc = from_obj->document;
+ std::string old_id(from_obj->getId());
+
+ find_references(current_doc->getRoot(), refmap);
+
+ refmap_type::const_iterator pos = refmap->find(old_id);
+ if (pos != refmap->end()) {
+ std::list<IdReference>::const_iterator it;
+ const std::list<IdReference>::const_iterator it_end = pos->second.end();
+ for (it = pos->second.begin(); it != it_end; ++it) {
+ if (it->type == REF_STYLE) {
+ sp_style_set_property_url(it->elem, it->attr, to_obj, false);
+ }
+ }
+ }
+
+ delete refmap;
+}
+
+/*
* Change the id of a SPObject to new_name
* If there is an id clash then rename to something similar
*/
diff --git a/src/id-clash.h b/src/id-clash.h
index de3cd29d3..f93bd3d72 100644
--- a/src/id-clash.h
+++ b/src/id-clash.h
@@ -5,6 +5,7 @@
void prevent_id_clashes(SPDocument *imported_doc, SPDocument *current_doc);
void rename_id(SPObject *elem, Glib::ustring const &newname);
+void change_def_references(SPObject *replace_obj, SPObject *with_obj);
#endif /* !SEEN_ID_CLASH_H */
diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp
index 6e6071654..99a48ae5d 100644
--- a/src/ink-comboboxentry-action.cpp
+++ b/src/ink-comboboxentry-action.cpp
@@ -807,7 +807,7 @@ gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data )
switch ( key ) {
- // TODO Add bindings for Esc/Tab/LeftTab
+ // TODO Add bindings for Tab/LeftTab
case GDK_KEY_Escape:
{
//gtk_spin_button_set_value( GTK_SPIN_BUTTON(widget), action->private_data->lastVal );
diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp
index 262c35db1..5efa3c84f 100644
--- a/src/sp-gradient.cpp
+++ b/src/sp-gradient.cpp
@@ -346,6 +346,41 @@ void SPGradient::setSwatch( bool swatch )
}
}
+
+/**
+ * return true if this gradient is "equivalent" to that gradient.
+ * Equivalent meaning they have the same stop count, same stop colors and same stop opacity
+ * @param that - A gradient to compare this to
+ */
+gboolean SPGradient::isEquivalent(SPGradient *that)
+{
+ //TODO Make this work for mesh gradients
+
+ if (this->getStopCount() != that->getStopCount())
+ return FALSE;
+
+ if (this->hasStops() != that->hasStops())
+ return FALSE;
+
+ if (!this->getVector() || !that->getVector())
+ return FALSE;
+
+ SPStop *as = this->getVector()->getFirstStop();
+ SPStop *bs = that->getVector()->getFirstStop();
+
+ while (as && bs) {
+ if (!as->getEffectiveColor().isClose(bs->getEffectiveColor(), 0.001) ||
+ as->offset != bs->offset) {
+ return FALSE;
+ }
+ as = as->getNextStop();
+ bs = bs->getNextStop();
+ }
+
+ return TRUE;
+}
+
+
/**
* Return stop's color as 32bit value.
*/
@@ -2211,6 +2246,7 @@ sp_meshgradient_repr_write(SPMeshGradient *mg)
mg->array.write( mg );
}
+
/*
Local Variables:
mode:c++
diff --git a/src/sp-gradient.h b/src/sp-gradient.h
index 61b459eee..a21a413f4 100644
--- a/src/sp-gradient.h
+++ b/src/sp-gradient.h
@@ -143,6 +143,7 @@ public:
SPStop* getFirstStop();
int getStopCount() const;
+ gboolean isEquivalent(SPGradient *b);
/** Mesh Gradients **************/