Code

LIBNR REMOVAL. Deleted nr-path.h/.cpp which is no longer used. (removed all referenc...
[inkscape.git] / src / sp-conn-end-pair.cpp
index 85d9ccce22bce79e97227003b211820c5fcec779..0753e144138638af97d91c9b0095523e27919a44 100644 (file)
@@ -10,6 +10,9 @@
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
+#include <cstring>
+#include <string>
+
 #include "attributes.h"
 #include "sp-conn-end.h"
 #include "uri.h"
@@ -19,6 +22,7 @@
 #include "libavoid/vertices.h"
 #include "libavoid/router.h"
 #include "document.h"
+#include "sp-item-group.h"
 
 
 SPConnEndPair::SPConnEndPair(SPPath *const owner)
@@ -48,7 +52,7 @@ SPConnEndPair::~SPConnEndPair()
         delete _connRef;
         _connRef = NULL;
     }
-    
+
     _invalid_path_connection.disconnect();
     _transformed_connection.disconnect();
 }
@@ -75,12 +79,9 @@ sp_conn_end_pair_build(SPObject *object)
 }
 
 
-static void 
-avoid_conn_move(NR::Matrix const *mp, SPItem *moved_item)
+static void
+avoid_conn_move(NR::Matrix const */*mp*/, SPItem *moved_item)
 {
-    // Detach from objects if attached.
-    sp_conn_end_detach(moved_item, 0);
-    sp_conn_end_detach(moved_item, 1);
     // Reroute connector
     SPPath *path = SP_PATH(moved_item);
     path->connEndPair.makePathInvalid();
@@ -94,7 +95,7 @@ SPConnEndPair::setAttr(unsigned const key, gchar const *const value)
     if (key == SP_ATTR_CONNECTOR_TYPE) {
         if (value && (strcmp(value, "polyline") == 0)) {
             _connType = SP_CONNECTOR_POLYLINE;
-            
+
             Avoid::Router *router = _path->document->router;
             GQuark itemID = g_quark_from_string(SP_OBJECT(_path)->id);
             _connRef = new Avoid::ConnRef(router, itemID);
@@ -105,7 +106,7 @@ SPConnEndPair::setAttr(unsigned const key, gchar const *const value)
         }
         else {
             _connType = SP_CONNECTOR_NOAVOID;
-            
+
             if (_connRef) {
                 _connRef->removeFromGraph();
                 delete _connRef;
@@ -117,7 +118,7 @@ SPConnEndPair::setAttr(unsigned const key, gchar const *const value)
         return;
 
     }
-    
+
     unsigned const handle_ix = key - SP_ATTR_CONNECTION_START;
     g_assert( handle_ix <= 1 );
     this->_connEnd[handle_ix]->setAttacherHref(value);
@@ -141,6 +142,20 @@ void
 SPConnEndPair::getAttachedItems(SPItem *h2attItem[2]) const {
     for (unsigned h = 0; h < 2; ++h) {
         h2attItem[h] = this->_connEnd[h]->ref.getObject();
+
+        // Deal with the case of the attached object being an empty group.
+        // A group containing no items does not have a valid bbox, so
+        // causes problems for the auto-routing code.  Also, since such a
+        // group no longer has an onscreen representation and can only be
+        // selected through the XML editor, it makes sense just to detach
+        // connectors from them.
+        if (SP_IS_GROUP(h2attItem[h])) {
+            if (SP_GROUP(h2attItem[h])->group->getItemCount() == 0) {
+                // This group is empty, so detach.
+                sp_conn_end_detach(_path, h);
+                h2attItem[h] = NULL;
+            }
+        }
     }
 }
 
@@ -149,19 +164,24 @@ SPConnEndPair::getEndpoints(NR::Point endPts[]) const {
     SPCurve *curve = _path->curve;
     SPItem *h2attItem[2];
     getAttachedItems(h2attItem);
-    
+
     for (unsigned h = 0; h < 2; ++h) {
         if ( h2attItem[h] ) {
-            NR::Rect const bbox = h2attItem[h]->invokeBbox(sp_item_i2doc_affine(h2attItem[h]));
-            endPts[h] = bbox.midpoint();
+            boost::optional<NR::Rect> bbox = h2attItem[h]->getBounds(sp_item_i2doc_affine(h2attItem[h]));
+            if (bbox) {
+                endPts[h] = bbox->midpoint();
+            } else {
+                // FIXME
+                endPts[h] = NR::Point(0, 0);
+            }
         }
-        else 
+        else
         {
             if (h == 0) {
-                endPts[h] = sp_curve_first_point(curve);
+                endPts[h] = *(curve->first_point());
             }
             else {
-                endPts[h] = sp_curve_last_point(curve);
+                endPts[h] = *(curve->last_point());
             }
         }
     }
@@ -180,7 +200,7 @@ static void emitPathInvalidationNotification(void *ptr)
     // then all connectors (that require it) will be rerouted.  Otherwise,
     // one connector could get rerouted several times as a result of
     // dragging a couple of shapes.
-   
+
     SPPath *path = SP_PATH(ptr);
     path->connEndPair._invalid_path_signal.emit(path);
 }
@@ -208,8 +228,8 @@ SPConnEndPair::update(void)
             NR::Point endPt[2];
             getEndpoints(endPt);
 
-            Avoid::Point src = { endPt[0][NR::X], endPt[0][NR::Y] };
-            Avoid::Point dst = { endPt[1][NR::X], endPt[1][NR::Y] };
+            Avoid::Point src(endPt[0][NR::X], endPt[0][NR::Y]);
+            Avoid::Point dst(endPt[1][NR::X], endPt[1][NR::Y]);
 
             _connRef->lateSetup(src, dst);
             _connRef->setCallback(&emitPathInvalidationNotification, _path);
@@ -251,7 +271,7 @@ SPConnEndPair::isAutoRoutingConn(void)
     }
     return false;
 }
-    
+
 void
 SPConnEndPair::makePathInvalid(void)
 {
@@ -271,9 +291,9 @@ SPConnEndPair::reroutePath(void)
     NR::Point endPt[2];
     getEndpoints(endPt);
 
-    Avoid::Point src = { endPt[0][NR::X], endPt[0][NR::Y] };
-    Avoid::Point dst = { endPt[1][NR::X], endPt[1][NR::Y] };
-    
+    Avoid::Point src(endPt[0][NR::X], endPt[0][NR::Y]);
+    Avoid::Point dst(endPt[1][NR::X], endPt[1][NR::Y]);
+
     _connRef->updateEndPoint(Avoid::VertID::src, src);
     _connRef->updateEndPoint(Avoid::VertID::tar, dst);
 
@@ -281,13 +301,13 @@ SPConnEndPair::reroutePath(void)
 
     Avoid::PolyLine route = _connRef->route();
     _connRef->calcRouteDist();
-    
-    sp_curve_reset(curve);
-    sp_curve_moveto(curve, endPt[0]);
+
+    curve->reset();
+    curve->moveto(endPt[0]);
 
     for (int i = 1; i < route.pn; ++i) {
         NR::Point p(route.ps[i].x, route.ps[i].y);
-        sp_curve_lineto(curve, p);
+        curve->lineto(p);
     }
 }