diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2012-10-11 17:54:14 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2012-10-11 17:54:14 +0000 |
| commit | f304ab600788b02cb02a4413f68f466e35cf1539 (patch) | |
| tree | 0dc39d0d1075471992d1adb4cb75fae7d75ee396 /src/selection-chemistry.cpp | |
| parent | Fix for 1058402 : Inconsistent opacity indication (diff) | |
| download | inkscape-f304ab600788b02cb02a4413f68f466e35cf1539.tar.gz inkscape-f304ab600788b02cb02a4413f68f466e35cf1539.zip | |
Add symbols dialog. See: http://wiki.inkscape.org/wiki/index.php/SymbolsDialog
(bzr r11782)
Diffstat (limited to 'src/selection-chemistry.cpp')
| -rw-r--r-- | src/selection-chemistry.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 332e9a34e..904e21960 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -11,6 +11,7 @@ * Martin Sucha <martin.sucha-inkscape@jts-sro.sk> * Abhishek Sharma * Kris De Gussem <Kris.DeGussem@gmail.com> + * Tavmjong Bah <tavmjong@free.fr> (Symbol additions) * * Copyright (C) 1999-2010,2012 authors * Copyright (C) 2001-2002 Ximian, Inc. @@ -71,6 +72,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-gradient-reference.h" #include "sp-linear-gradient-fns.h" #include "sp-pattern.h" +#include "sp-symbol.h" #include "sp-radial-gradient-fns.h" #include "gradient-context.h" #include "sp-namedview.h" @@ -2887,6 +2889,162 @@ void sp_selection_to_guides(SPDesktop *desktop) DocumentUndo::done(doc, SP_VERB_EDIT_SELECTION_2_GUIDES, _("Objects to guides")); } +/* + * Convert <g> to <symbol>, leaving all <use> elements referencing group unchanged. + */ +void sp_selection_symbol(SPDesktop *desktop, bool apply ) +{ + + if (desktop == NULL) { + return; + } + + SPDocument *doc = sp_desktop_document(desktop); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + + // Check if something is selected. + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select one <b>group</b> to convert to symbol.")); + return; + } + + SPObject* group = selection->single(); + + // Make sure we have only one object in selection. + if( group == NULL ) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select only one <b>group</b> to convert to symbol.")); + return; + } + + // Make sure we convert the original. + if( SP_IS_USE( group ) ) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select original (<b>Shift+D</b>) to convert to symbol.")); + return; + } + + // Require that we really have a group. + if( !SP_IS_GROUP( group ) ) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Group selection first to convert to symbol.")); + return; + } + + doc->ensureUpToDate(); + + Inkscape::XML::Node *symbol = xml_doc->createElement("svg:symbol"); + symbol->setAttribute("style", group->getAttribute("style")); + symbol->setAttribute("title", group->getAttribute("title")); + symbol->setAttribute("transform", group->getAttribute("transform")); + + Glib::ustring id = group->getAttribute("id"); + + // Now we need to copy all children of group + GSList* children = group->childList(false); + children = g_slist_reverse(children); + for (GSList* i = children; i != NULL; i = i->next ) { + SPObject* child = SP_OBJECT(i->data); + Inkscape::XML::Node *dup = child->getRepr()->duplicate(xml_doc); + symbol->appendChild(dup); + child->deleteObject(true); + } + + // Need to delete <g>; all <use> elements that referenced <g> should + // auto-magically reference <symbol>. + doc->getDefs()->getRepr()->appendChild(symbol); + symbol->setAttribute("id",id.c_str()); // After we delete group with same id. + // Mysterious, must set symbol ID before deleting group or all <use> + // refering to symbol get turned into groups. (Linked to unlinking clones?) + group->deleteObject(true); + + Inkscape::GC::release(symbol); + selection->clear(); + // Group just disappears, nothing to select. + + // Need to signal Symbol dialog to update + + g_slist_free(children); + + DocumentUndo::done(doc, SP_VERB_EDIT_SYMBOL, _("Group to symbol")); +} + +/* + * Convert <symbol> to <g>. All <use> elements referencing symbol remain unchanged. + */ +void sp_selection_unsymbol(SPDesktop *desktop) +{ + + if (desktop == NULL) { + return; + } + + SPDocument *doc = sp_desktop_document(desktop); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + + // Check if something is selected. + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a <b>symbol</b> to extract objects from.")); + return; + } + + SPObject* use = selection->single(); + + // Make sure we have only one object in selection. + if( use == NULL ) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select only one <b>symbol</b> to convert to group.")); + return; + } + + // Require that we really have a <use> that references a <symbol>. + if( !SP_IS_USE( use ) && !SP_IS_SYMBOL( use->firstChild() ) ) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select only one <b>symbol</b> to convert to group.")); + return; + } + + doc->ensureUpToDate(); + + SPObject* symbol = use->firstChild(); + + Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); + group->setAttribute("style", symbol->getAttribute("style")); + group->setAttribute("title", symbol->getAttribute("title")); + group->setAttribute("transform", symbol->getAttribute("transform")); + + Glib::ustring id = symbol->getAttribute("id"); + + // Now we need to copy all children of symbol + GSList* children = symbol->childList(false); + children = g_slist_reverse(children); + for (GSList* i = children; i != NULL; i = i->next ) { + SPObject* child = SP_OBJECT(i->data); + Inkscape::XML::Node *dup = child->getRepr()->duplicate(xml_doc); + group->appendChild(dup); + child->deleteObject(true); + } + + SPObject* parent = use->parent; // So we insert <g> next to <use> (easier to find) + + // Need to delete <symbol>; all other <use> elements that referenced <symbol> should + // auto-magically reference <g>. + symbol->deleteObject(true); + group->setAttribute("id",id.c_str()); // After we delete symbol with same id. + parent->getRepr()->appendChild(group); + //use->deleteObject(true); + + SPItem *group_item = static_cast<SPItem *>(sp_desktop_document(desktop)->getObjectByRepr(group)); + Inkscape::GC::release(group); + selection->clear(); + selection->set(group_item); + + // Need to signal Symbol dialog to update + + g_slist_free(children); + + DocumentUndo::done(doc, SP_VERB_EDIT_UNSYMBOL, _("Group from symbol")); +} + void sp_selection_tile(SPDesktop *desktop, bool apply) { |
