diff options
| author | John Smith <john.smith7545@yahoo.com> | 2012-09-19 01:52:19 +0000 |
|---|---|---|
| committer | John Smith <john.smith7545@yahoo.com> | 2012-09-19 01:52:19 +0000 |
| commit | bf7c3e8d98b557cb64447804399797d93e1cedc0 (patch) | |
| tree | 80848f225cad4c163c32ce4d2ec963982558adba /src | |
| parent | Fix for 900602 : Enter key returns focus to canvas for Font family selector (diff) | |
| download | inkscape-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.cpp | 29 | ||||
| -rw-r--r-- | src/file.cpp | 9 | ||||
| -rw-r--r-- | src/id-clash.cpp | 28 | ||||
| -rw-r--r-- | src/id-clash.h | 1 | ||||
| -rw-r--r-- | src/ink-comboboxentry-action.cpp | 2 | ||||
| -rw-r--r-- | src/sp-gradient.cpp | 36 | ||||
| -rw-r--r-- | src/sp-gradient.h | 1 |
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 **************/ |
