Code

new command: relink clone to copied object
authorbuliabyak <buliabyak@users.sourceforge.net>
Sun, 15 Jun 2008 16:22:56 +0000 (16:22 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Sun, 15 Jun 2008 16:22:56 +0000 (16:22 +0000)
src/menus-skeleton.h
src/selection-chemistry.cpp
src/selection-chemistry.h
src/ui/clipboard.cpp
src/ui/clipboard.h
src/verbs.cpp
src/verbs.h

index 4ae213bc012811cc8a4706e7b89d9c2c067fdf9a..c712b52a9fe79783a71f9db08d2d20ce50264dcb 100644 (file)
@@ -73,6 +73,7 @@ static char const menus_skeleton[] =
 "           <verb verb-id=\"EditClone\" />\n"
 "           <verb verb-id=\"DialogClonetiler\" />\n"
 "           <verb verb-id=\"EditUnlinkClone\" />\n"
+"           <verb verb-id=\"EditRelinkClone\" />\n"
 "           <verb verb-id=\"EditCloneSelectOriginal\" />\n"
 "       </submenu>\n"
 "       <verb verb-id=\"SelectionCreateBitmap\" />\n"
index 0f92f96805aa93f1907f795fe1b2000d3c48cba8..d4964c284525d6859bd64cf8176257d3301e035c 100644 (file)
@@ -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 <b>clones</b> 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 <b>object</b> 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, _("<b>No clones to relink</b> 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 <b>clone</b> to unlink."));
+        desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to unlink."));
         return;
     }
 
index aa3c2b10054706661bb6949c3ce8f1df3b961f7f..e67d679307e2ce79fb245015055f4000524fcae3 100644 (file)
@@ -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);
index 991a699114e30e78ff94c7df0ca77884a6578a97..8907b3b0c6d443ef08f8177d1de588e741d1da11 100644 (file)
@@ -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
index 609f2a93cfbe11ad7b53d56cd1db9c524c6f9323..54c05ac0def1f16419b74c559e7c3d25d81ad495 100644 (file)
@@ -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:
index 4d859bab712c2f069fa40395a2e4dffcd6504899..da3c7c1820cf7d1b4c69734a719549abf451bfba 100644 (file)
@@ -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
index c1611092221f323d5300a72e0bb16a5b3fbd6265..657716bc3e3471757224ceff2eff7117766598f0 100644 (file)
@@ -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,