Index: app/connectionpoint_ops.c =================================================================== RCS file: /cvs/gnome/dia/app/connectionpoint_ops.c,v retrieving revision 1.9 diff -u -r1.9 connectionpoint_ops.c --- app/connectionpoint_ops.c 23 Mar 2001 14:29:48 -0000 1.9 +++ app/connectionpoint_ops.c 21 May 2002 20:29:22 -0000 @@ -107,7 +107,13 @@ if (connected_obj->handles[j]->connected_to == cp) handle = connected_obj->handles[j]; } - assert(handle!=NULL); + if (handle == NULL) + { + /* the connection point might have been altered by calling + move_handle below */ + list = g_list_next(list); + continue; + } object_add_updates(connected_obj, dia); connected_obj->ops->move_handle(connected_obj, handle , Index: lib/connection.c =================================================================== RCS file: /cvs/gnome/dia/lib/connection.c,v retrieving revision 1.9 diff -u -r1.9 connection.c --- lib/connection.c 26 May 2001 01:11:48 -0000 1.9 +++ lib/connection.c 21 May 2002 20:29:23 -0000 @@ -24,6 +24,95 @@ #include "connection.h" #include "message.h" +static coord +square_distance_point_point (Point p1, Point p2) +{ + const coord dx = p2.x - p1.x; + const coord dy = p2.y - p1.y; + return dx*dx+dy*dy; +} + + +static void +optimize_connection (Connection* conn) +{ + ConnectionPoint* first_connpoint = conn->endpoint_handles[0].connected_to; + ConnectionPoint* second_connpoint = conn->endpoint_handles[1].connected_to; + ConnectionPoint* new_first_connpoint = first_connpoint; + ConnectionPoint* new_second_connpoint = second_connpoint; + + Object* first_object; + Object* second_object; + + ConnectionPoint** first_connections; + ConnectionPoint** second_connections; + + coord min_distance; + + int first_connection_num; + + /* for now we only handle full connections */ + if ( (first_connpoint == 0L) + || (second_connpoint == 0L)) + return; + + min_distance = square_distance_point_point ( + first_connpoint->pos, second_connpoint->pos); + + first_object = first_connpoint->object; + second_object = second_connpoint->object; + + first_connections = first_object->connections; + second_connections = second_object->connections; + + /* Now figure out the connections with the smallest distance. + This is O(n*m) - not optimal but we're only proofing a concept */ + for (first_connection_num = 0; first_connection_num < first_object->num_connections; first_connection_num++) + { + int second_connection_num; + + for (second_connection_num = 0; second_connection_num < second_object->num_connections; second_connection_num++) + { + const coord distance = square_distance_point_point ( + first_connections[first_connection_num]->pos, + second_connections[second_connection_num]->pos); + + if (distance < min_distance) + { + min_distance = distance; + new_first_connpoint = first_connections[first_connection_num]; + new_second_connpoint = second_connections[second_connection_num]; + } + + } + + } + + if (new_first_connpoint != first_connpoint) + { + conn->endpoint_handles[0].connected_to = new_first_connpoint; + + first_connpoint->connected = g_list_remove (first_connpoint->connected, conn); + + new_first_connpoint->connected = g_list_prepend (new_first_connpoint->connected, conn); + + conn->endpoints[0] = new_first_connpoint->pos; + } + + if (new_second_connpoint != second_connpoint) + { + conn->endpoint_handles[1].connected_to = new_second_connpoint; + + second_connpoint->connected = g_list_remove (second_connpoint->connected, conn); + + new_second_connpoint->connected = g_list_prepend (new_second_connpoint->connected, conn); + + conn->endpoints[1] = new_second_connpoint->pos; + } + +} + + void connection_move_handle(Connection *conn, HandleId id, Point *to, HandleMoveReason reason) @@ -39,11 +128,15 @@ message_error("Internal error in connection_move_handle.\n"); break; } + + optimize_connection (conn); } void connection_update_handles(Connection *conn) { + assert(conn != NULL); + conn->endpoint_handles[0].id = HANDLE_MOVE_STARTPOINT; conn->endpoint_handles[0].pos = conn->endpoints[0];