X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fsp-conn-end-pair.cpp;h=7c85277768d7e87581e4d118f01b00091f030ec2;hb=a73d81e9f12725b2c9c23cb4080ff4403d3a1406;hp=bb5d89107f521b617b9f4034e093b450a2dede71;hpb=e800991baacdaf989464de712ef462863d379687;p=inkscape.git diff --git a/src/sp-conn-end-pair.cpp b/src/sp-conn-end-pair.cpp index bb5d89107..7c8527776 100644 --- a/src/sp-conn-end-pair.cpp +++ b/src/sp-conn-end-pair.cpp @@ -17,6 +17,9 @@ #include "xml/repr.h" #include "sp-path.h" #include "libavoid/vertices.h" +#include "libavoid/router.h" +#include "document.h" +#include "sp-item-group.h" SPConnEndPair::SPConnEndPair(SPPath *const owner) @@ -46,7 +49,7 @@ SPConnEndPair::~SPConnEndPair() delete _connRef; _connRef = NULL; } - + _invalid_path_connection.disconnect(); _transformed_connection.disconnect(); } @@ -73,12 +76,9 @@ sp_conn_end_pair_build(SPObject *object) } -static void +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(); @@ -92,9 +92,10 @@ 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(itemID); + _connRef = new Avoid::ConnRef(router, itemID); _invalid_path_connection = connectInvalidPath( sigc::ptr_fun(&sp_conn_adjust_invalid_path)); _transformed_connection = _path->connectTransformed( @@ -102,7 +103,7 @@ SPConnEndPair::setAttr(unsigned const key, gchar const *const value) } else { _connType = SP_CONNECTOR_NOAVOID; - + if (_connRef) { _connRef->removeFromGraph(); delete _connRef; @@ -114,7 +115,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); @@ -138,6 +139,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; + } + } } } @@ -146,13 +161,18 @@ 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(); + NR::Maybe 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); @@ -177,7 +197,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); } @@ -205,8 +225,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); @@ -220,14 +240,18 @@ SPConnEndPair::update(void) void SPConnEndPair::storeIds(void) { if (_connEnd[0]->href) { - GQuark itemId = g_quark_from_string(_connEnd[0]->href); + // href begins with a '#' which we don't want. + const char *startId = _connEnd[0]->href + 1; + GQuark itemId = g_quark_from_string(startId); _connRef->setEndPointId(Avoid::VertID::src, itemId); } else { _connRef->setEndPointId(Avoid::VertID::src, 0); } if (_connEnd[1]->href) { - GQuark itemId = g_quark_from_string(_connEnd[1]->href); + // href begins with a '#' which we don't want. + const char *endId = _connEnd[1]->href + 1; + GQuark itemId = g_quark_from_string(endId); _connRef->setEndPointId(Avoid::VertID::tar, itemId); } else { @@ -244,7 +268,7 @@ SPConnEndPair::isAutoRoutingConn(void) } return false; } - + void SPConnEndPair::makePathInvalid(void) { @@ -264,9 +288,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); @@ -274,7 +298,7 @@ SPConnEndPair::reroutePath(void) Avoid::PolyLine route = _connRef->route(); _connRef->calcRouteDist(); - + sp_curve_reset(curve); sp_curve_moveto(curve, endPt[0]);