From 4a1e71245a59ac66f74e88fe5a8326a7caeaff88 Mon Sep 17 00:00:00 2001 From: buliabyak Date: Sun, 15 Jun 2008 16:22:56 +0000 Subject: [PATCH] new command: relink clone to copied object --- src/menus-skeleton.h | 1 + src/selection-chemistry.cpp | 52 ++++++++++++++++++++++++++++++++++++- src/selection-chemistry.h | 1 + src/ui/clipboard.cpp | 35 +++++++++++++++++++++++++ src/ui/clipboard.h | 1 + src/verbs.cpp | 7 ++++- src/verbs.h | 1 + 7 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 4ae213bc0..c712b52a9 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -73,6 +73,7 @@ static char const menus_skeleton[] = " \n" " \n" " \n" +" \n" " \n" " \n" " \n" diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 0f92f9680..d4964c284 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1864,6 +1864,56 @@ sp_selection_clone() g_slist_free(newsel); } +void +sp_selection_relink() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (!desktop) + return; + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to relink.")); + return; + } + + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + const gchar *newid = cm->getFirstObjectID(); + if (!newid) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Copy an object to clipboard to relink clones to.")); + return; + } + gchar *newref = g_strdup_printf ("#%s", newid); + + // Get a copy of current selection. + GSList *new_select = NULL; + bool relinked = false; + for (GSList *items = (GSList *) selection->itemList(); + items != NULL; + items = items->next) + { + SPItem *item = (SPItem *) items->data; + + if (!SP_IS_USE(item)) + continue; + + SP_OBJECT_REPR(item)->setAttribute("xlink:href", newref); + SP_OBJECT(item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + relinked = true; + } + + g_free(newref); + + if (!relinked) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to relink in the selection.")); + } else { + sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_UNLINK_CLONE, + _("Relink clone")); + } +} + + void sp_selection_unlink() { @@ -1874,7 +1924,7 @@ sp_selection_unlink() Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a clone to unlink.")); + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to unlink.")); return; } diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index aa3c2b100..e67d67930 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -39,6 +39,7 @@ void sp_edit_invert_in_all_layers (); void sp_selection_clone(); void sp_selection_unlink(); +void sp_selection_relink(); void sp_select_clone_original (); void sp_selection_to_marker(bool apply = true); diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 991a69911..8907b3b0c 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -95,6 +95,7 @@ public: virtual bool pastePathEffect(); virtual Glib::ustring getPathParameter(); virtual Glib::ustring getShapeOrTextObjectId(); + virtual const gchar *getFirstObjectID(); ClipboardManagerImpl(); ~ClipboardManagerImpl(); @@ -273,6 +274,40 @@ bool ClipboardManagerImpl::paste(bool in_place) return true; } +/** + * @brief Returns the id of the first visible copied object + */ +const gchar *ClipboardManagerImpl::getFirstObjectID() +{ + SPDocument *tempdoc = _retrieveClipboard("image/x-inkscape-svg"); + if ( tempdoc == NULL ) { + return NULL; + } + + Inkscape::XML::Node + *root = sp_document_repr_root(tempdoc); + + if (!root) + return NULL; + + Inkscape::XML::Node *ch = sp_repr_children(root); + while (ch != NULL && + strcmp(ch->name(), "svg:g") && + strcmp(ch->name(), "svg:path") && + strcmp(ch->name(), "svg:use") && + strcmp(ch->name(), "svg:text") && + strcmp(ch->name(), "svg:image") && + strcmp(ch->name(), "svg:rect") + ) + ch = ch->next(); + + if (ch) { + return ch->attribute("id"); + } + + return NULL; +} + /** * @brief Implements the Paste Style action diff --git a/src/ui/clipboard.h b/src/ui/clipboard.h index 609f2a93c..54c05ac0d 100644 --- a/src/ui/clipboard.h +++ b/src/ui/clipboard.h @@ -47,6 +47,7 @@ public: virtual bool pastePathEffect() = 0; virtual Glib::ustring getPathParameter() = 0; virtual Glib::ustring getShapeOrTextObjectId() = 0; + virtual const gchar *getFirstObjectID() = 0; static ClipboardManager *get(); protected: diff --git a/src/verbs.cpp b/src/verbs.cpp index 4d859bab7..da3c7c182 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -897,6 +897,9 @@ EditVerb::perform(SPAction *action, void *data, void */*pdata*/) case SP_VERB_EDIT_UNLINK_CLONE: sp_selection_unlink(); break; + case SP_VERB_EDIT_RELINK_CLONE: + sp_selection_relink(); + break; case SP_VERB_EDIT_CLONE_SELECT_ORIGINAL: sp_select_clone_original(); break; @@ -2264,7 +2267,9 @@ Verb *Verb::_base_verbs[] = { new EditVerb(SP_VERB_EDIT_CLONE, "EditClone", N_("Create Clo_ne"), N_("Create a clone (a copy linked to the original) of selected object"), "edit_clone"), new EditVerb(SP_VERB_EDIT_UNLINK_CLONE, "EditUnlinkClone", N_("Unlin_k Clone"), - N_("Cut the selected clone's link to its original, turning it into a standalone object"), "edit_unlink_clone"), + N_("Cut the selected clones' links to the originals, turning them into standalone objects"), "edit_unlink_clone"), + new EditVerb(SP_VERB_EDIT_RELINK_CLONE, "EditRelinkClone", N_("Relink to Copied"), + N_("Relink the selected clones to the object currently on the clipboard"), NULL), new EditVerb(SP_VERB_EDIT_CLONE_SELECT_ORIGINAL, "EditCloneSelectOriginal", N_("Select _Original"), N_("Select the object to which the selected clone is linked"), "edit_select_original"), // TRANSLATORS: Convert selection to a line marker diff --git a/src/verbs.h b/src/verbs.h index c16110922..657716bc3 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -70,6 +70,7 @@ enum { SP_VERB_EDIT_DUPLICATE, SP_VERB_EDIT_CLONE, SP_VERB_EDIT_UNLINK_CLONE, + SP_VERB_EDIT_RELINK_CLONE, SP_VERB_EDIT_CLONE_SELECT_ORIGINAL, SP_VERB_EDIT_SELECTION_2_MARKER, SP_VERB_EDIT_SELECTION_2_GUIDES, -- 2.30.2