Code

Patch from Debian bug tracker from Daniel Kahn Gillmor
[inkscape.git] / src / nodepath.cpp
index 59a6bcce36f75dd354945c502eea594287d8a1eb..69827bd848552cf30a67afce908b5d2fad9f871a 100644 (file)
@@ -1608,8 +1608,10 @@ sp_nodepath_add_node_near_point(Inkscape::NodePath::Path *nodepath, NR::Point p)
  * cf. app/vectors/gimpbezierstroke.c, gimp_bezier_stroke_point_move_relative()
  */
 void
-sp_nodepath_curve_drag(Inkscape::NodePath::Node * e, double t, NR::Point delta)
+sp_nodepath_curve_drag(int node, double t, NR::Point delta)
 {
+    Inkscape::NodePath::Node *e = sp_nodepath_get_node_by_index(node);
+
     //fixme: e and e->p can be NULL, so check for those before proceeding
     g_return_if_fail(e != NULL);
     g_return_if_fail(&e->p != NULL);
@@ -1725,8 +1727,11 @@ void sp_node_selected_join()
    Inkscape::NodePath::Node *b = (Inkscape::NodePath::Node *) nodepath->selected->next->data;
 
     g_assert(a != b);
-    g_assert(a->p.other || a->n.other);
-    g_assert(b->p.other || b->n.other);
+    if (!(a->p.other || a->n.other) || !(b->p.other || b->n.other)) { 
+        // someone tried to join an orphan node (i.e. a single-node subpath).
+        // this is not worth an error message, just fail silently.
+        return;
+    }
 
     if (((a->subpath->closed) || (b->subpath->closed)) || (a->p.other && a->n.other) || (b->p.other && b->n.other)) {
         nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have <b>two endnodes</b> selected."));
@@ -1824,8 +1829,11 @@ void sp_node_selected_join_segment()
    Inkscape::NodePath::Node *b = (Inkscape::NodePath::Node *) nodepath->selected->next->data;
 
     g_assert(a != b);
-    g_assert(a->p.other || a->n.other);
-    g_assert(b->p.other || b->n.other);
+    if (!(a->p.other || a->n.other) || !(b->p.other || b->n.other)) { 
+        // someone tried to join an orphan node (i.e. a single-node subpath).
+        // this is not worth an error message, just fail silently.
+        return;
+    }
 
     if (((a->subpath->closed) || (b->subpath->closed)) || (a->p.other && a->n.other) || (b->p.other && b->n.other)) {
         nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have <b>two endnodes</b> selected."));
@@ -2211,7 +2219,10 @@ sp_node_selected_delete_segment(void)
         //Copy everything after 'end' to a new subpath
        Inkscape::NodePath::SubPath *t = sp_nodepath_subpath_new(nodepath);
         for (curr=end ; curr ; curr=curr->n.other) {
-            sp_nodepath_node_new(t, NULL, (Inkscape::NodePath::NodeType)curr->type, (NRPathcode)curr->code,
+            NRPathcode code = (NRPathcode) curr->code;
+            if (curr == end)
+                code = NR_MOVETO;
+            sp_nodepath_node_new(t, NULL, (Inkscape::NodePath::NodeType)curr->type, code,
                                  &curr->p.pos, &curr->pos, &curr->n.pos);
         }
 
@@ -2864,6 +2875,33 @@ static gboolean node_event(SPKnot *knot, GdkEvent *event, Inkscape::NodePath::No
         case GDK_LEAVE_NOTIFY:
             active_node = NULL;
             break;
+        case GDK_SCROLL:
+            if ((event->scroll.state & GDK_CONTROL_MASK) && !(event->scroll.state & GDK_SHIFT_MASK)) { // linearly
+                switch (event->scroll.direction) {
+                    case GDK_SCROLL_UP:
+                        nodepath_grow_selection_linearly (n->subpath->nodepath, n, +1);
+                        break;
+                    case GDK_SCROLL_DOWN:
+                        nodepath_grow_selection_linearly (n->subpath->nodepath, n, -1);
+                        break;
+                    default:
+                        break;
+                }
+                ret = TRUE;
+            } else if (!(event->scroll.state & GDK_SHIFT_MASK)) { // spatially
+                switch (event->scroll.direction) {
+                    case GDK_SCROLL_UP:
+                        nodepath_grow_selection_spatially (n->subpath->nodepath, n, +1);
+                        break;
+                    case GDK_SCROLL_DOWN:
+                        nodepath_grow_selection_spatially (n->subpath->nodepath, n, -1);
+                        break;
+                    default:
+                        break;
+                }
+                ret = TRUE;
+            }
+            break;
         case GDK_KEY_PRESS:
             switch (get_group0_keyval (&event->key)) {
                 case GDK_space:
@@ -2875,16 +2913,16 @@ static gboolean node_event(SPKnot *knot, GdkEvent *event, Inkscape::NodePath::No
                     break;
                 case GDK_Page_Up:
                     if (event->key.state & GDK_CONTROL_MASK) {
-                        nodepath_grow_selection_spatially (n->subpath->nodepath, n, +1);
-                    } else {
                         nodepath_grow_selection_linearly (n->subpath->nodepath, n, +1);
+                    } else {
+                        nodepath_grow_selection_spatially (n->subpath->nodepath, n, +1);
                     }
                     break;
                 case GDK_Page_Down:
                     if (event->key.state & GDK_CONTROL_MASK) {
-                        nodepath_grow_selection_spatially (n->subpath->nodepath, n, -1);
-                    } else {
                         nodepath_grow_selection_linearly (n->subpath->nodepath, n, -1);
+                    } else {
+                        nodepath_grow_selection_spatially (n->subpath->nodepath, n, -1);
                     }
                     break;
                 default:
@@ -3284,7 +3322,6 @@ static void node_handle_ungrabbed(SPKnot *knot, guint state, gpointer data)
     }
 
     sp_nodepath_update_repr(n->subpath->nodepath, _("Move node handle"));
-    sp_canvas_end_forced_full_redraws(n->subpath->nodepath->desktop->canvas);
 }
 
 /**
@@ -4000,6 +4037,7 @@ static void sp_nodepath_node_destroy(Inkscape::NodePath::Node *node)
         g_signal_handlers_disconnect_by_func(G_OBJECT(node->p.knot), (gpointer) G_CALLBACK(node_handle_moved), node);
         g_signal_handlers_disconnect_by_func(G_OBJECT(node->p.knot), (gpointer) G_CALLBACK(node_handle_event), node);
         g_object_unref(G_OBJECT(node->p.knot));
+        node->p.knot = NULL;
     }
 
     if (node->n.knot) {
@@ -4010,6 +4048,7 @@ static void sp_nodepath_node_destroy(Inkscape::NodePath::Node *node)
         g_signal_handlers_disconnect_by_func(G_OBJECT(node->n.knot), (gpointer) G_CALLBACK(node_handle_moved), node);
         g_signal_handlers_disconnect_by_func(G_OBJECT(node->n.knot), (gpointer) G_CALLBACK(node_handle_event), node);
         g_object_unref(G_OBJECT(node->n.knot));
+        node->n.knot = NULL;
     }
 
     if (node->p.line)