Code

Node tool: special case node duplication for endnodes - select new endnode
[inkscape.git] / src / sp-conn-end.cpp
index 2287a182d16a0bbebc02125a7ef339a5037b4578..07dd852f230fe988b809d812b4ad7fc215e5fc7d 100644 (file)
@@ -21,6 +21,9 @@ static void change_endpts(SPCurve *const curve, double const endPos[2]);
 SPConnEnd::SPConnEnd(SPObject *const owner) :
     ref(owner),
     href(NULL),
+    // Default to center connection endpoint
+    type(ConnPointDefault),
+    id(4),
     _changed_connection(),
     _delete_connection(),
     _transformed_connection()
@@ -48,12 +51,12 @@ static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_p
         SPGroup* group = SP_GROUP(item);
 
         // consider all first-order children
-        double child_pos = std::numeric_limits<double>::max();
+        double child_pos = 0.0;
         for (GSList const* i = sp_item_group_item_list(group); i != NULL; i = i->next) {
             SPItem* child_item = SP_ITEM(i->data);
             try_get_intersect_point_with_item_recursive(conn_pv, child_item,
                     item_transform * child_item->transform, child_pos);
-            if (intersect_pos > child_pos)
+            if (intersect_pos < child_pos)
                 intersect_pos = child_pos;
         }
         return intersect_pos != initial_pos;
@@ -63,7 +66,7 @@ static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_p
     if (!SP_IS_SHAPE(item)) return false;
 
     // make sure it has an associated curve
-    SPCurve* item_curve = sp_shape_get_curve(SP_SHAPE(item));
+    SPCurve* item_curve = SP_SHAPE(item)->getCurve();
     if (!item_curve) return false;
 
     // apply transformations (up to common ancestor)
@@ -77,7 +80,7 @@ static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_p
 
         for (Geom::Crossings::const_iterator i = cr.begin(); i != cr.end(); i++) {
             const Geom::Crossing& cr_pt = *i;
-            if ( intersect_pos > cr_pt.ta)
+            if ( intersect_pos < cr_pt.ta)
                 intersect_pos = cr_pt.ta;
         }
     }
@@ -109,8 +112,8 @@ static bool try_get_intersect_point_with_item(SPPath* conn, SPItem* item,
         conn_pv[0] = conn_pv[0].reverse();
     }
 
-    // We start with the intersection point at the end of the path
-    intersect_pos = conn_pv[0].size();
+    // We start with the intersection point at the beginning of the path
+    intersect_pos = 0.0;
 
     // Find the intersection.
     bool result = try_get_intersect_point_with_item_recursive(conn_pv, item, item_transform, intersect_pos);
@@ -228,9 +231,10 @@ sp_conn_end_deleted(SPObject *, SPObject *const owner, unsigned const handle_ix)
     // todo: The first argument is the deleted object, or just NULL if
     //       called by sp_conn_end_detach.
     g_return_if_fail(handle_ix < 2);
-    char const *const attr_str[] = {"inkscape:connection-start",
-                                    "inkscape:connection-end"};
-    SP_OBJECT_REPR(owner)->setAttribute(attr_str[handle_ix], NULL);
+    char const * const attr_strs[] = {"inkscape:connection-start", "inkscape:connection-start-point",
+                                      "inkscape:connection-end", "inkscape:connection-end-point"};
+    SP_OBJECT_REPR(owner)->setAttribute(attr_strs[2*handle_ix], NULL);
+    SP_OBJECT_REPR(owner)->setAttribute(attr_strs[2*handle_ix+1], NULL);
     /* I believe this will trigger sp_conn_end_href_changed. */
 }
 
@@ -245,7 +249,9 @@ SPConnEnd::setAttacherHref(gchar const *value, SPPath* /*path*/)
 {
     if ( value && href && ( strcmp(value, href) == 0 ) ) {
         /* No change, do nothing. */
-    } else {
+    } 
+    else 
+    {
         if (!value)
         {
             ref.detach();
@@ -254,138 +260,104 @@ SPConnEnd::setAttacherHref(gchar const *value, SPPath* /*path*/)
         }
         else
         {
-
-            /* References to the connection points have the following format
-               #svguri_t_id, where #svguri is the id of the item the
-               connector is attached to, t is the type of the point, which
-               can be either "d" for default or "u" for user-defined, and
-               id is the local (inside the item) id of the connection point.
-               In the case of default points id represents the position on the
-               item (i.e. Top-Left, Centre-Centre, etc.).
-            */
-
-            gchar ** href_strarray = NULL;
-            if (href)
-                href_strarray = g_strsplit(href, "_", 0);
-            gchar ** value_strarray = g_strsplit(value, "_", 0);
-
-            g_free(href);
-            href = NULL;
-
-            bool changed = false;
             bool validRef = true;
+            href = g_strdup(value);
+            // Now do the attaching, which emits the changed signal.
+            try {
+                ref.attach(Inkscape::URI(value));
+            } catch (Inkscape::BadURIException &e) {
+                /* TODO: Proper error handling as per
+                * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing.  (Also needed for
+                * sp-use.) */
+                g_warning("%s", e.what());
+                validRef = false;
+            }
 
-            if ( !href_strarray || g_strcmp0(href_strarray[0], value_strarray[0]) != 0 )
+            if ( !validRef )
             {
-                // The href has changed, so update it.
-                changed = true;
-                // Set the href field, because sp_conn_end_href_changed will need it.
-                href = g_strdup(value);
-                // Now do the attaching, which emits the changed signal.
-                try {
-                    ref.attach(Inkscape::URI(value_strarray[0]));
-                } catch (Inkscape::BadURIException &e) {
-                    /* TODO: Proper error handling as per
-                    * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing.  (Also needed for
-                    * sp-use.) */
-                    g_warning("%s", e.what());
-                    validRef = false;
-                }
+                ref.detach();
+                g_free(href);
+                href = NULL;
             }
-            // Check to see if the connection point changed and update it.
-            //
+        }
+    }
+}
 
-            if ( !value_strarray[1] )
-            {
-                /* Treat the old references to connection points
-                   as default points that connect to the centre
-                   of the item.
-                */
-                if ( type != ConnPointDefault )
+void
+SPConnEnd::setAttacherEndpoint(gchar const *value, SPPath* /*path*/)
+{
+    
+    /* References to the connection points have the following format
+        <t><id>, where t is the type of the point, which
+        can be either "d" for default or "u" for user-defined, and
+        id is the local (inside the item) id of the connection point.
+        In the case of default points id represents the position on the
+        item (i.e. Top-Left, Center-Center, etc.).
+    */
+    
+    bool changed = false;
+    ConnPointType newtype = type;
+    
+    if (!value)
+    {
+        // Default to center endpoint
+        type = ConnPointDefault;
+        id = 4;
+    }
+    else
+    {
+        switch (value[0])
+        {
+            case 'd':
+                if ( newtype != ConnPointDefault )
                 {
-                    type = ConnPointDefault;
+                    newtype = ConnPointDefault;
                     changed = true;
                 }
-                if ( id != ConnPointPosCC )
+                break;
+            case 'u':
+                if ( newtype != ConnPointUserDefined)
                 {
-                    id = ConnPointPosCC;
+                    newtype = ConnPointUserDefined;
                     changed = true;
                 }
-            }
-            else
+                break;
+            default:
+                g_warning("Bad reference to a connection point.");
+        }
+        
+        int newid = (int) g_ascii_strtod( value+1, 0 );
+        if ( id != newid )
+        {
+            id = newid;
+            changed = true;
+        }
+
+        // We have to verify that the reference to the
+        // connection point is a valid one.
+        
+        if ( changed )
+        {
+
+            // Get the item the connector is attached to
+            SPItem* item = ref.getObject();
+            if ( item )
             {
-                switch (value_strarray[1][0])
-                {
-                    case 'd':
-                        if ( type != ConnPointDefault )
-                        {
-                            type = ConnPointDefault;
-                            changed = true;
-                        }
-                        break;
-                    case 'u':
-                        if ( type != ConnPointUserDefined)
-                        {
-                            type = ConnPointUserDefined;
-                            changed = true;
-                        }
-                        break;
-                    default:
-                        g_warning("Bad reference to a connection point.");
-                        validRef = false;
-                }
-                if ( value_strarray[2] )
+                if (!item->avoidRef->isValidConnPointId( newtype, newid ) )
                 {
-                    int newId = (int) g_ascii_strtod( value_strarray[2], 0 );
-                    if ( id != newId )
-                    {
-                        id = newId;
-                        changed = true;
-                    }
-
+                    g_warning("Bad reference to a connection point.");
                 }
                 else
                 {
-                    // We have a malformed reference to a connection point,
-                    // emit a warning, clear href and detach ref.
-                    changed = true;
-                    g_warning("Bad reference to a connection point.");\
-                    validRef = false;
+                    type = newtype;
+                    id = newid;
                 }
-            }
-
-            if ( changed )
-            {
-                // We still have to verify that the reference to the
-                // connection point is a valid one.
-
-                // Get the item the connector is attached to
-                SPItem* item = ref.getObject();
-                if ( item && !item->avoidRef->isValidConnPointId( type, id ) )
-                {
-                    g_warning("Bad reference to a connection point.");
-                    validRef = false;
+    /*          // Update the connector
+                if (path->connEndPair.isAutoRoutingConn()) {
+                    path->connEndPair.tellLibavoidNewEndpoints();
                 }
-/*                else
-                    // Update the connector
-                    if (path->connEndPair.isAutoRoutingConn()) {
-                        path->connEndPair.tellLibavoidNewEndpoints();
-                    }
-*/
-            }
-
-            if ( !validRef )
-            {
-                ref.detach();
-                g_free(href);
-                href = NULL;
+    */
             }
-            else
-                if (!href)
-                    href = g_strdup(value);
-
-            g_strfreev(href_strarray);
-            g_strfreev(value_strarray);
         }
     }
 }