Code

Cherry pick node duplication from 0.48 stable
authorKrzysztof Kosiński <tweenk.pl@gmail.com>
Tue, 12 Oct 2010 16:11:17 +0000 (18:11 +0200)
committerKrzysztof Kosiński <tweenk.pl@gmail.com>
Tue, 12 Oct 2010 16:11:17 +0000 (18:11 +0200)
src/ui/tool/multi-path-manipulator.cpp
src/ui/tool/multi-path-manipulator.h
src/ui/tool/path-manipulator.cpp
src/ui/tool/path-manipulator.h

index 2025a12d7b4826cc54f7de1d9306792eec78dabc..6101a35567da7d69d0095a707fc719cf0c26bb06 100644 (file)
@@ -244,6 +244,12 @@ void MultiPathManipulator::insertNodes()
     _done(_("Add nodes"));
 }
 
+void MultiPathManipulator::duplicateNodes()
+{
+    invokeForAll(&PathManipulator::duplicateNodes);
+    _done(_("Duplicate nodes"));
+}
+
 void MultiPathManipulator::joinNodes()
 {
     invokeForAll(&PathManipulator::hideDragPoint);
@@ -513,6 +519,12 @@ bool MultiPathManipulator::event(GdkEvent *event)
                 return true;
             }
             break;
+        case GDK_d:
+        case GDK_D:
+            if (held_only_shift(event->key)) {
+                duplicateNodes();
+                return true;
+            }
         case GDK_j:
         case GDK_J:
             if (held_only_shift(event->key)) {
index 181ae6d1d6c32643447b916d79b0cb609362fe5a..7a4cfdb5d706d6e9875d9a2de7da8a2954692637 100644 (file)
@@ -53,6 +53,7 @@ public:
     void setSegmentType(SegmentType t);
 
     void insertNodes();
+    void duplicateNodes();
     void joinNodes();
     void breakNodes();
     void deleteNodes(bool keep_shape = true);
index f5c27e1d6ea80ac1ea2db289aedcd257a93f135c..81fc336ceb721d40599e2f26c3e1bc98d1620056 100644 (file)
@@ -319,6 +319,39 @@ void PathManipulator::insertNodes()
     }
 }
 
+/** Insert new nodes exactly at the positions of selected nodes while preserving shape.
+ * This is equivalent to breaking, except that it doesn't split into subpaths. */
+void PathManipulator::duplicateNodes()
+{
+    if (_num_selected == 0) return;
+
+    for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
+        for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) {
+            if (j->selected()) {
+                NodeList::iterator k = j.next();
+                Node *n = new Node(_multi_path_manipulator._path_data.node_data, *j);
+
+                // Move the new node to the bottom of the Z-order. This way you can drag all
+                // nodes that were selected before this operation without deselecting
+                // everything because there is a new node above.
+                n->sink();
+
+                n->front()->setPosition(*j->front());
+                j->front()->retract();
+                j->setType(NODE_CUSP, false);
+                (*i)->insert(k, n);
+
+                // We need to manually call the selection change callback to refresh
+                // the handle display correctly.
+                // This call changes num_selected, but we call this once for a selected node
+                // and once for an unselected node, so in the end the number stays correct.
+                _selectionChanged(j.ptr(), true);
+                _selectionChanged(n, false);
+            }
+        }
+    }
+}
+
 /** Replace contiguous selections of nodes in each subpath with one node. */
 void PathManipulator::weldNodes(NodeList::iterator preserve_pos)
 {
index a8f1c957ee5f4a2a499afb3ae1035d4f72c8c41b..c57b6497eea80056121a112dd86dfb3d74332348 100644 (file)
@@ -69,6 +69,7 @@ public:
     void invertSelectionInSubpaths();
 
     void insertNodes();
+    void duplicateNodes();
     void weldNodes(NodeList::iterator preserve_pos = NodeList::iterator());
     void weldSegments();
     void breakNodes();