Code

Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in...
[inkscape.git] / src / connector-context.cpp
index 294e129b3f4e40bdda229aeedd30fd44d9bbb9f8..adc54a1ae228b68e08b129030f19b17415caec16 100644 (file)
@@ -218,7 +218,7 @@ static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item);
 static void cc_clear_active_shape(SPConnectorContext *cc);
 static void cc_set_active_conn(SPConnectorContext *cc, SPItem *item);
 static void cc_clear_active_conn(SPConnectorContext *cc);
-static gchar *conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& w);
+static bool conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid);
 static void cc_select_handle(SPKnot* knot);
 static void cc_deselect_handle(SPKnot* knot);
 static bool cc_item_is_shape(SPItem *item);
@@ -233,6 +233,9 @@ static void shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *nam
         gpointer data);
 
 
+static char* cc_knot_tips[] = { _("<b>Connection point</b>: click or drag to create a new connector"),
+                           _("<b>Connection point</b>: click to select, drag to move") };
+
 /*static Geom::Point connector_drag_origin_w(0, 0);
 static bool connector_within_tolerance = false;*/
 static SPEventContextClass *parent_class;
@@ -338,8 +341,10 @@ sp_connector_context_init(SPConnectorContext *cc)
         cc->endpt_handle[i] = NULL;
         cc->endpt_handler_id[i] = 0;
     }
-    cc->sid = NULL;
-    cc->eid = NULL;
+    cc->shref = NULL;
+    cc->scpid = NULL;
+    cc->ehref = NULL;
+    cc->ecpid = NULL;
     cc->npoints = 0;
     cc->state = SP_CONNECTOR_CONTEXT_IDLE;
 }
@@ -366,13 +371,21 @@ sp_connector_context_dispose(GObject *object)
             cc->endpt_handle[i] = NULL;
         }
     }
-    if (cc->sid) {
-        g_free(cc->sid);
-        cc->sid = NULL;
+    if (cc->shref) {
+        g_free(cc->shref);
+        cc->shref = NULL;
+    }
+    if (cc->scpid) {
+        g_free(cc->scpid);
+        cc->scpid = NULL;
+    }
+    if (cc->ehref) {
+        g_free(cc->shref);
+        cc->shref = NULL;
     }
-    if (cc->eid) {
-        g_free(cc->eid);
-        cc->eid = NULL;
+    if (cc->ecpid) {
+        g_free(cc->scpid);
+        cc->scpid = NULL;
     }
     g_assert( cc->newConnRef == NULL );
 
@@ -570,8 +583,8 @@ cc_clear_active_conn(SPConnectorContext *cc)
 }
 
 
-static gchar *
-conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p)
+static bool
+conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid)
 {
     // TODO: this will need to change when there are more connection
     //       points available for each shape.
@@ -580,10 +593,13 @@ conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p)
     {
         p = cc->active_handle->pos;
         const ConnectionPoint& cp = cc->connpthandles[cc->active_handle];
-        return g_strdup_printf("#%s_%c_%d", SP_OBJECT_ID(cc->active_shape),
-                               cp.type == ConnPointDefault ? 'd' : 'u' , cp.id);
+        *href = g_strdup_printf("#%s", cc->active_shape->getId());
+        *cpid = g_strdup_printf("%c%d", cp.type == ConnPointDefault ? 'd' : 'u' , cp.id);
+        return true;
     }
-    return NULL;
+    *href = NULL;
+    *cpid = NULL;
+    return false;
 }
 
 static void
@@ -752,7 +768,6 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
             Geom::Point const event_dt = cc->desktop->w2d(event_w);
 
             SnapManager &m = cc->desktop->namedview->snap_manager;
-            m.setup(cc->desktop);
 
             switch (cc->state) {
                 case SP_CONNECTOR_CONTEXT_STOP:
@@ -769,12 +784,14 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
                         Geom::Point p = event_dt;
 
                         // Test whether we clicked on a connection point
-                        cc->sid = conn_pt_handle_test(cc, p);
+                        bool found = conn_pt_handle_test(cc, p, &cc->shref, &cc->scpid);
 
-                        if (!cc->sid) {
+                        if (!found) {
                             // This is the first point, so just snap it to the grid
                             // as there's no other points to go off.
+                            m.setup(cc->desktop);
                             m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                            m.unSetup();
                         }
                         spcc_connector_set_initial_point(cc, p);
 
@@ -786,12 +803,14 @@ connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const
                 case SP_CONNECTOR_CONTEXT_DRAGGING:
                 {
                     // This is the second click of a connector creation.
+                    m.setup(cc->desktop);
                     m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                    m.unSetup();
 
                     spcc_connector_set_subsequent_point(cc, p);
                     spcc_connector_finish_segment(cc, p);
                     // Test whether we clicked on a connection point
-                    cc->eid = conn_pt_handle_test(cc, p);
+                    /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
                     if (cc->npoints != 0) {
                         spcc_connector_finish(cc);
                     }
@@ -926,7 +945,6 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons
     if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
     {
         SnapManager &m = dt->namedview->snap_manager;
-        m.setup(dt);
 
         switch (cc->state) {
             case SP_CONNECTOR_CONTEXT_DRAGGING:
@@ -934,7 +952,9 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons
                 gobble_motion_events(mevent.state);
                 // This is movement during a connector creation.
                 if ( cc->npoints > 0 ) {
+                    m.setup(dt);
                     m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                    m.unSetup();
                     cc->selection->clear();
                     spcc_connector_set_subsequent_point(cc, p);
                     ret = TRUE;
@@ -946,7 +966,9 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons
                 gobble_motion_events(GDK_BUTTON1_MASK);
                 g_assert( SP_IS_PATH(cc->clickeditem));
 
+                m.setup(dt);
                 m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                m.unSetup();
 
                 // Update the hidden path
                 Geom::Matrix i2d = sp_item_i2d_affine(cc->clickeditem);
@@ -976,8 +998,10 @@ connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion cons
                 /* This is perfectly valid */
                 break;
             default:
-                if (sp_event_context_knot_mouseover(cc)) {
+                if (!sp_event_context_knot_mouseover(cc)) {
+                    m.setup(dt);
                     m.preSnap(Inkscape::SnapCandidatePoint(p, Inkscape::SNAPSOURCE_OTHER_HANDLE));
+                    m.unSetup();
                 }
                 break;
         }
@@ -1012,7 +1036,6 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
         SPDocument *doc = sp_desktop_document(desktop);
 
         SnapManager &m = desktop->namedview->snap_manager;
-        m.setup(desktop);
 
         Geom::Point const event_w(revent.x, revent.y);
 
@@ -1024,7 +1047,9 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
                 //case SP_CONNECTOR_CONTEXT_POINT:
                 case SP_CONNECTOR_CONTEXT_DRAGGING:
                 {
+                    m.setup(desktop);
                     m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                    m.unSetup();
 
                     if (cc->within_tolerance)
                     {
@@ -1035,7 +1060,7 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
                     spcc_connector_set_subsequent_point(cc, p);
                     spcc_connector_finish_segment(cc, p);
                     // Test whether we clicked on a connection point
-                    cc->eid = conn_pt_handle_test(cc, p);
+                    /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
                     if (cc->npoints != 0) {
                         spcc_connector_finish(cc);
                     }
@@ -1045,7 +1070,9 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
                 }
                 case SP_CONNECTOR_CONTEXT_REROUTING:
                 {
+                    m.setup(desktop);
                     m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                    m.unSetup();
                     cc_connector_rerouting_finish(cc, &p);
 
                     sp_document_ensure_up_to_date(doc);
@@ -1069,7 +1096,9 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
 
                     if (!cc->within_tolerance)
                     {
+                        m.setup(desktop);
                         m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                        m.unSetup();
                         sp_knot_set_position(cc->selected_handle, p, 0);
                         ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
                         cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
@@ -1082,7 +1111,9 @@ connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton con
 
 
                 case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
+                    m.setup(desktop);
                     m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                    m.unSetup();
 
                     sp_knot_set_position(cc->selected_handle, p, 0);
 
@@ -1177,15 +1208,15 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval)
                 {
                     // Put connection point at current position
 
-                    SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
-                    SnapManager &m = desktop->namedview->snap_manager;
-                    m.setup(desktop);
                     Geom::Point p = cc->selected_handle->pos;
-//                     SPEventContext* event_context = SP_EVENT_CONTEXT( cc );
 
                     if (!cc->within_tolerance)
                     {
+                        SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
+                        SnapManager &m = desktop->namedview->snap_manager;
+                        m.setup(desktop);
                         m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+                        m.unSetup();
                         sp_knot_set_position(cc->selected_handle, p, 0);
                         ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
                         cp.pos = p * sp_item_dt2i_affine(cc->active_shape);
@@ -1212,9 +1243,8 @@ connector_handle_key_press(SPConnectorContext *const cc, guint const keyval)
                     SnapManager &m = desktop->namedview->snap_manager;
                     m.setup(desktop);
                     Geom::Point p = cc->selected_handle->pos;
-
                     m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
-
+                    m.unSetup();
                     sp_knot_set_position(cc->selected_handle, p, 0);
 
                     ConnectionPoint cp;
@@ -1265,16 +1295,21 @@ cc_connector_rerouting_finish(SPConnectorContext *const cc, Geom::Point *const p
     if (p != NULL)
     {
         // Test whether we clicked on a connection point
-        gchar *shape_label = conn_pt_handle_test(cc, *p);
+        gchar *shape_label, *cpid;
+        bool found = conn_pt_handle_test(cc, *p, &shape_label, &cpid);
 
-        if (shape_label) {
+        if (found) {
             if (cc->clickedhandle == cc->endpt_handle[0]) {
                 sp_object_setAttribute(cc->clickeditem,
-                        "inkscape:connection-start",shape_label, false);
+                        "inkscape:connection-start", shape_label, false);
+                sp_object_setAttribute(cc->clickeditem,
+                        "inkscape:connection-start-point", cpid, false);
             }
             else {
                 sp_object_setAttribute(cc->clickeditem,
-                        "inkscape:connection-end",shape_label, false);
+                        "inkscape:connection-end", shape_label, false);
+                sp_object_setAttribute(cc->clickeditem,
+                        "inkscape:connection-end-point", cpid, false);
             }
             g_free(shape_label);
         }
@@ -1417,17 +1452,23 @@ spcc_flush_white(SPConnectorContext *cc, SPCurve *gc)
                 cc->isOrthogonal ? "orthogonal" : "polyline", false);
         sp_object_setAttribute(cc->newconn, "inkscape:connector-curvature",
                 Glib::Ascii::dtostr(cc->curvature).c_str(), false);
-        if (cc->sid)
+        if (cc->shref)
         {
             sp_object_setAttribute(cc->newconn, "inkscape:connection-start",
-                    cc->sid, false);
+                    cc->shref, false);
+            if (cc->scpid)
+                sp_object_setAttribute(cc->newconn, "inkscape:connection-start-point",
+                        cc->scpid, false);
             connection = true;
         }
 
-        if (cc->eid)
+        if (cc->ehref)
         {
             sp_object_setAttribute(cc->newconn, "inkscape:connection-end",
-                    cc->eid, false);
+                    cc->ehref, false);
+            if (cc->ecpid)
+                sp_object_setAttribute(cc->newconn, "inkscape:connection-end-point",
+                        cc->ecpid, false);
             connection = true;
         }
         // Process pending updates.
@@ -1729,12 +1770,22 @@ cc_set_active_conn(SPConnectorContext *cc, SPItem *item)
 
     if (cc->active_conn == item)
     {
-        // Just adjust handle positions.
-        Geom::Point startpt = *(curve->first_point()) * i2d;
-        sp_knot_set_position(cc->endpt_handle[0], startpt, 0);
+        if (curve->is_empty())
+        {
+            // Connector is invisible because it is clipped to the boundary of
+            // two overlpapping shapes.
+            sp_knot_hide(cc->endpt_handle[0]);
+            sp_knot_hide(cc->endpt_handle[1]);
+        }
+        else
+        {
+            // Just adjust handle positions.
+            Geom::Point startpt = *(curve->first_point()) * i2d;
+            sp_knot_set_position(cc->endpt_handle[0], startpt, 0);
 
-        Geom::Point endpt = *(curve->last_point()) * i2d;
-        sp_knot_set_position(cc->endpt_handle[1], endpt, 0);
+            Geom::Point endpt = *(curve->last_point()) * i2d;
+            sp_knot_set_position(cc->endpt_handle[1], endpt, 0);
+        }
 
         return;
     }
@@ -1797,6 +1848,13 @@ cc_set_active_conn(SPConnectorContext *cc, SPItem *item)
                 G_CALLBACK(endpt_handler), cc);
     }
 
+    if (curve->is_empty())
+    {
+        // Connector is invisible because it is clipped to the boundary 
+        // of two overlpapping shapes.  So, it doesn't need endpoints.
+        return;
+    }
+
     Geom::Point startpt = *(curve->first_point()) * i2d;
     sp_knot_set_position(cc->endpt_handle[0], startpt, 0);
 
@@ -1860,8 +1918,10 @@ static bool cc_item_is_shape(SPItem *item)
 bool cc_item_is_connector(SPItem *item)
 {
     if (SP_IS_PATH(item)) {
-        if (SP_PATH(item)->connEndPair.isAutoRoutingConn()) {
-            g_assert( SP_PATH(item)->original_curve ? !(SP_PATH(item)->original_curve->is_closed()) : !(SP_PATH(item)->curve->is_closed()) );
+        bool closed = SP_PATH(item)->original_curve ? SP_PATH(item)->original_curve->is_closed() : SP_PATH(item)->curve->is_closed();
+        if (SP_PATH(item)->connEndPair.isAutoRoutingConn() && !closed) {
+            // To be considered a connector, an object must be a non-closed 
+            // path that is marked with a "inkscape:connector-type" attribute.
             return true;
         }
     }
@@ -1992,4 +2052,4 @@ shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :