Merge lp:~doctormo/inkscape/knot-visio into lp:~inkscape.dev/inkscape/trunk

Proposed by Martin Owens
Status: Merged
Merged at revision: 12015
Proposed branch: lp:~doctormo/inkscape/knot-visio
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 1888 lines (+91/-1110)
16 files modified
src/Makefile_insert (+0/-1)
src/attributes-test.h (+0/-1)
src/conn-avoid-ref.cpp (+5/-238)
src/conn-avoid-ref.h (+3/-13)
src/connection-points.cpp (+0/-37)
src/connection-points.h (+0/-70)
src/connector-context.cpp (+56/-545)
src/connector-context.h (+2/-18)
src/knot.cpp (+1/-0)
src/knot.h (+2/-0)
src/sp-conn-end-pair.cpp (+3/-14)
src/sp-conn-end.cpp (+16/-90)
src/sp-conn-end.h (+3/-10)
src/sp-item.cpp (+0/-3)
src/widgets/connector-toolbar.cpp (+0/-67)
src/widgets/toolbox.cpp (+0/-3)
To merge this branch: bzr merge lp:~doctormo/inkscape/knot-visio
Reviewer Review Type Date Requested Status
Inkscape Developers Pending
Review via email: mp+137472@code.launchpad.net

Description of the change

Clean up of connector code to remove disabled connector code while adding some functionality for custom anchor points to be developed further in the future.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Makefile_insert'
2--- src/Makefile_insert 2012-10-15 23:22:11 +0000
3+++ src/Makefile_insert 2012-12-03 04:59:19 +0000
4@@ -25,7 +25,6 @@
5 composite-undo-stack-observer.cpp \
6 composite-undo-stack-observer.h \
7 conditions.cpp conditions.h \
8- connection-points.cpp connection-points.h \
9 conn-avoid-ref.cpp conn-avoid-ref.h \
10 connection-pool.h \
11 connector-context.cpp connector-context.h \
12
13=== modified file 'src/attributes-test.h'
14--- src/attributes-test.h 2012-02-14 20:56:34 +0000
15+++ src/attributes-test.h 2012-12-03 04:59:19 +0000
16@@ -383,7 +383,6 @@
17 {"inkscape:connector-type", true},
18 {"inkscape:connection-start", true},
19 {"inkscape:connection-end", true},
20- {"inkscape:connection-points", true},
21 {"inkscape:connector-curvature", true},
22 {"inkscape:connector-avoid", true},
23 {"inkscape:connector-spacing", true},
24
25=== modified file 'src/conn-avoid-ref.cpp'
26--- src/conn-avoid-ref.cpp 2012-10-04 01:45:44 +0000
27+++ src/conn-avoid-ref.cpp 2012-12-03 04:59:19 +0000
28@@ -23,7 +23,6 @@
29 #include "helper/geom-curves.h"
30 #include "svg/stringstream.h"
31 #include "conn-avoid-ref.h"
32-#include "connection-points.h"
33 #include "sp-conn-end.h"
34 #include "sp-path.h"
35 #include "libavoid/router.h"
36@@ -86,206 +85,6 @@
37 }
38 }
39
40-static void print_connection_points(std::map<int, ConnectionPoint>& cp)
41-{
42- std::map<int, ConnectionPoint>::iterator i;
43- for (i=cp.begin(); i!=cp.end(); ++i)
44- {
45- const ConnectionPoint& p = i->second;
46- std::cout<<p.id<<" "<<p.type<<" "<<p.pos[Geom::X]<<" "<<p.pos[Geom::Y]<<std::endl;
47- }
48-}
49-
50-void SPAvoidRef::setConnectionPoints(gchar const *value)
51-{
52- std::set<int> updates;
53- std::set<int> deletes;
54- std::set<int> seen;
55-
56- if (value)
57- {
58- /* Rebuild the connection points list.
59- Update the connectors for which
60- the endpoint has changed.
61- */
62-
63- gchar ** strarray = g_strsplit(value, "|", 0);
64- gchar ** iter = strarray;
65-
66- while (*iter != NULL) {
67- ConnectionPoint cp;
68- Inkscape::SVGIStringStream is(*iter);
69- is>>cp;
70- cp.type = ConnPointUserDefined;
71-
72- /* Mark this connection point as seen, so we can delete
73- the other ones.
74- */
75- seen.insert(cp.id);
76- if ( connection_points.find(cp.id) != connection_points.end() )
77- {
78- /* An already existing connection point.
79- Check to see if changed, and, if it is
80- the case, trigger connector update for
81- the connector attached to this connection
82- point. This is done by adding the
83- connection point to a list of connection
84- points to be updated.
85- */
86- if ( connection_points[cp.id] != cp )
87- // The connection point got updated.
88- // Put it in the update list.
89- updates.insert(cp.id);
90- }
91- connection_points[cp.id] = cp;
92- ++iter;
93- }
94- /* Delete the connection points that didn't appear
95- in the new connection point list.
96- */
97- std::map<int, ConnectionPoint>::iterator it;
98-
99- for (it=connection_points.begin(); it!=connection_points.end(); ++it)
100- if ( seen.find(it->first) == seen.end())
101- deletes.insert(it->first);
102- g_strfreev(strarray);
103- }
104- else
105- {
106- /* Delete all the user-defined connection points
107- Actually we do this by adding them to the list
108- of connection points to be deleted.
109- */
110- std::map<int, ConnectionPoint>::iterator it;
111-
112- for (it=connection_points.begin(); it!=connection_points.end(); ++it)
113- deletes.insert(it->first);
114- }
115- /* Act upon updates and deletes.
116- */
117- if (deletes.empty() && updates.empty())
118- // Nothing to do, just return.
119- return;
120- // Get a list of attached connectors.
121- GSList* conns = getAttachedConnectors(Avoid::runningToAndFrom);
122- for (GSList *i = conns; i != NULL; i = i->next)
123- {
124- SPPath* path = SP_PATH(i->data);
125- SPConnEnd** connEnds = path->connEndPair.getConnEnds();
126- for (int ix=0; ix<2; ++ix) {
127- if (connEnds[ix]->type == ConnPointUserDefined) {
128- if (updates.find(connEnds[ix]->id) != updates.end()) {
129- if (path->connEndPair.isAutoRoutingConn()) {
130- path->connEndPair.tellLibavoidNewEndpoints();
131- } else {
132- }
133- }
134- else if (deletes.find(connEnds[ix]->id) != deletes.end()) {
135- sp_conn_end_detach(path, ix);
136- }
137- }
138- }
139- }
140- g_slist_free(conns);
141- // Remove all deleted connection points
142- if (deletes.size())
143- for (std::set<int>::iterator it = deletes.begin(); it != deletes.end(); ++it)
144- connection_points.erase(*it);
145-}
146-
147-void SPAvoidRef::setConnectionPointsAttrUndoable(const gchar* value, const gchar* action)
148-{
149- SPDocument* doc = item->document;
150-
151- item->setAttribute( "inkscape:connection-points", value, 0 );
152- item->updateRepr();
153- doc->ensureUpToDate();
154- DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, action);
155-}
156-
157-void SPAvoidRef::addConnectionPoint(ConnectionPoint &cp)
158-{
159- Inkscape::SVGOStringStream ostr;
160- bool first = true;
161- int newId = 1;
162- if ( connection_points.size() )
163- {
164- for (IdConnectionPointMap::iterator it = connection_points.begin(); ; )
165- {
166- if ( first )
167- {
168- first = false;
169- ostr<<it->second;
170- }
171- else
172- ostr<<'|'<<it->second;
173- IdConnectionPointMap::iterator prev_it = it;
174- ++it;
175- if ( it == connection_points.end() || prev_it->first + 1 != it->first )
176- {
177- newId = prev_it->first + 1;
178- break;
179- }
180- }
181- }
182- cp.id = newId;
183- if ( first )
184- {
185- first = false;
186- ostr<<cp;
187- }
188- else
189- ostr<<'|'<<cp;
190-
191- this->setConnectionPointsAttrUndoable( ostr.str().c_str(), _("Add a new connection point") );
192-}
193-
194-void SPAvoidRef::updateConnectionPoint(ConnectionPoint &cp)
195-{
196- Inkscape::SVGOStringStream ostr;
197- IdConnectionPointMap::iterator cp_pos = connection_points.find( cp.id );
198- if ( cp_pos != connection_points.end() )
199- {
200- bool first = true;
201- for (IdConnectionPointMap::iterator it = connection_points.begin(); it != connection_points.end(); ++it)
202- {
203- ConnectionPoint* to_write;
204- if ( it != cp_pos )
205- to_write = &it->second;
206- else
207- to_write = &cp;
208- if ( first )
209- {
210- first = false;
211- ostr<<*to_write;
212- }
213- else
214- ostr<<'|'<<*to_write;
215- }
216- this->setConnectionPointsAttrUndoable( ostr.str().c_str(), _("Move a connection point") );
217- }
218-}
219-
220-void SPAvoidRef::deleteConnectionPoint(ConnectionPoint &cp)
221-{
222- Inkscape::SVGOStringStream ostr;
223- IdConnectionPointMap::iterator cp_pos = connection_points.find( cp.id );
224- if ( cp_pos != connection_points.end() ) {
225- bool first = true;
226- for (IdConnectionPointMap::iterator it = connection_points.begin(); it != connection_points.end(); ++it) {
227- if ( it != cp_pos ) {
228- if ( first ) {
229- first = false;
230- ostr<<it->second;
231- } else {
232- ostr<<'|'<<it->second;
233- }
234- }
235- }
236- this->setConnectionPointsAttrUndoable( ostr.str().c_str(), _("Remove a connection point") );
237- }
238-}
239-
240 void SPAvoidRef::handleSettingChange(void)
241 {
242 SPDesktop *desktop = inkscape_active_desktop();
243@@ -387,45 +186,13 @@
244 return list;
245 }
246
247-Geom::Point SPAvoidRef::getConnectionPointPos(const int type, const int id)
248+Geom::Point SPAvoidRef::getConnectionPointPos()
249 {
250 g_assert(item);
251- Geom::Point pos;
252- const Geom::Affine& transform = item->i2doc_affine();
253-
254- if ( type == ConnPointDefault )
255- {
256- // For now, just default to the centre of the item
257- Geom::OptRect bbox = item->documentVisualBounds();
258- pos = (bbox) ? bbox->midpoint() : Geom::Point(0, 0);
259- }
260- else
261- {
262- // Get coordinates from the list of connection points
263- // that are attached to the item
264- pos = connection_points[id].pos * transform;
265- }
266-
267- return pos;
268-}
269-
270-bool SPAvoidRef::isValidConnPointId( const int type, const int id )
271-{
272- if ( type < 0 || type > 1 )
273- return false;
274- else
275- {
276- if ( type == ConnPointDefault )
277- if ( id < 0 || id > 8 )
278- return false;
279- else
280- {
281- }
282- else
283- return connection_points.find( id ) != connection_points.end();
284- }
285-
286- return true;
287+ // the center is all we are interested in now; we used to care
288+ // about non-center points, but that's moot.
289+ Geom::OptRect bbox = item->documentVisualBounds();
290+ return (bbox) ? bbox->midpoint() : Geom::Point(0, 0);
291 }
292
293 static std::vector<Geom::Point> approxCurveWithPoints(SPCurve *curve)
294
295=== modified file 'src/conn-avoid-ref.h'
296--- src/conn-avoid-ref.h 2012-02-15 15:03:26 +0000
297+++ src/conn-avoid-ref.h 2012-12-03 04:59:19 +0000
298@@ -13,14 +13,13 @@
299 * Released under GNU GPL, read the file 'COPYING' for more information
300 */
301
302+#include <2geom/point.h>
303 #include <glib.h>
304 #include <stddef.h>
305 #include <sigc++/connection.h>
306
307 class SPDesktop;
308 class SPItem;
309-struct ConnectionPoint;
310-typedef std::map<int, ConnectionPoint> IdConnectionPointMap;
311 namespace Avoid { class ShapeRef; }
312
313 class SPAvoidRef {
314@@ -31,16 +30,11 @@
315 // libavoid's internal representation of the item.
316 Avoid::ShapeRef *shapeRef;
317
318- // Used for holding connection points for item
319- IdConnectionPointMap connection_points;
320-
321 void setAvoid(char const *value);
322- void setConnectionPoints(gchar const *value);
323- void addConnectionPoint(ConnectionPoint &cp);
324- void updateConnectionPoint(ConnectionPoint &cp);
325- void deleteConnectionPoint(ConnectionPoint &cp);
326 void handleSettingChange(void);
327
328+ Geom::Point getConnectionPointPos(void);
329+
330 // Returns a list of SPItems of all connectors/shapes attached to
331 // this object. Pass one of the following for 'type':
332 // Avoid::runningTo
333@@ -48,9 +42,6 @@
334 // Avoid::runningToAndFrom
335 GSList *getAttachedShapes(const unsigned int type);
336 GSList *getAttachedConnectors(const unsigned int type);
337- Geom::Point getConnectionPointPos(const int type, const int id);
338-
339- bool isValidConnPointId( const int type, const int id );
340
341 private:
342 SPItem *item;
343@@ -61,7 +52,6 @@
344
345 // A sigc connection for transformed signal.
346 sigc::connection _transformed_connection;
347- void setConnectionPointsAttrUndoable(const gchar* value, const gchar* action);
348 };
349
350 extern GSList *get_avoided_items(GSList *list, SPObject *from,
351
352=== removed file 'src/connection-points.cpp'
353--- src/connection-points.cpp 2009-12-02 21:40:56 +0000
354+++ src/connection-points.cpp 1970-01-01 00:00:00 +0000
355@@ -1,37 +0,0 @@
356-#include "connection-points.h"
357-
358-
359-bool ConnectionPoint::operator!=(ConnectionPoint& cp)
360-{
361- return (id!=cp.id || type!=cp.type || dir!=cp.dir || pos!=cp.pos);
362-}
363-
364-bool ConnectionPoint::operator==(ConnectionPoint& cp)
365-{
366- return (id==cp.id && type==cp.type && dir==cp.dir && pos==cp.pos);
367-}
368-
369-
370-namespace Inkscape{
371-
372-SVGIStringStream&
373-operator>>(SVGIStringStream& istr, ConnectionPoint& cp)
374-{
375- istr>>cp.id>>cp.dir>>cp.pos[Geom::X]>>cp.pos[Geom::Y];
376-
377- return istr;
378-}
379-
380-SVGOStringStream&
381-operator<<(SVGOStringStream& ostr, const ConnectionPoint& cp)
382-{
383- ostr<<cp.id<<' '<<cp.dir<<' ';
384- ::operator<<( ostr, cp.pos[Geom::X] );
385- ostr<<' ';
386- ::operator<<( ostr, cp.pos[Geom::Y] );
387-
388- return ostr;
389-}
390-
391-
392-}
393
394=== removed file 'src/connection-points.h'
395--- src/connection-points.h 2009-12-02 21:40:56 +0000
396+++ src/connection-points.h 1970-01-01 00:00:00 +0000
397@@ -1,70 +0,0 @@
398-#ifndef INKSCAPE_CONNECTION_POINT_H
399-#define INKSCAPE_CONNECTION_POINT_H
400-
401-#include <2geom/point.h>
402-//#include <libavoid/vertices.h>
403-#include <libavoid/connector.h>
404-
405-#include "svg/stringstream.h"
406-
407-
408-enum ConnPointType {
409- ConnPointDefault = 0,
410- ConnPointUserDefined = 1
411-};
412-enum ConnPointDefaultPos{
413- ConnPointPosTL, // Top Left
414- ConnPointPosTC, // Top Centre
415- ConnPointPosTR, // Top Right
416- ConnPointPosCL, // Centre Left
417- ConnPointPosCC, // Centre Centre
418- ConnPointPosCR, // Centre Right
419- ConnPointPosBL, // Bottom Left
420- ConnPointPosBC, // Bottom Centre
421- ConnPointPosBR, // Bottom Right
422-};
423-
424-
425-struct ConnectionPoint
426-{
427- ConnectionPoint():
428- type(ConnPointDefault), // default to a default connection point
429- id(ConnPointPosCC), // default to the centre point
430- pos(),
431- dir(Avoid::ConnDirAll) // allow any direction
432- {
433- }
434- // type of the connection point
435- // default or user-defined
436- int type;
437-
438- /* id of the connection point
439- in the case of default
440- connection points it specifies
441- which of the 9 types the
442- connection point is.
443- */
444- int id;
445-
446- /* position related to parent item
447- in the case of default connection
448- points, these positions should be
449- computed by the item's avoidRef
450- */
451- Geom::Point pos;
452-
453- // directions from which connections can occur
454- Avoid::ConnDirFlags dir;
455-
456- bool operator!=(ConnectionPoint&);
457- bool operator==(ConnectionPoint&);
458-};
459-
460-namespace Inkscape{
461-
462-SVGIStringStream& operator>>(SVGIStringStream& istr, ConnectionPoint& cp);
463-SVGOStringStream& operator<<(SVGOStringStream& ostr, const ConnectionPoint& cp);
464-
465-}
466-
467-#endif
468\ No newline at end of file
469
470=== modified file 'src/connector-context.cpp'
471--- src/connector-context.cpp 2012-07-05 21:39:08 +0000
472+++ src/connector-context.cpp 2012-12-03 04:59:19 +0000
473@@ -5,10 +5,11 @@
474 * Michael Wybrow <mjwybrow@users.sourceforge.net>
475 * Abhishek Sharma
476 * Jon A. Cruz <jon@joncruz.org>
477+ * Martin Owens <doctormo@ubuntu.com>
478 *
479 * Copyright (C) 2005-2008 Michael Wybrow
480 * Copyright (C) 2009 Monash University
481- * Copyright (C) 2010 authors
482+ * Copyright (C) 2012 Authors
483 *
484 * Released under GNU GPL, read the file 'COPYING' for more information
485 *
486@@ -22,7 +23,6 @@
487 * in the connector tool. Perhaps have a way to convert between.
488 * o Only call libavoid's updateEndPoint as required. Currently we do it
489 * for both endpoints, even if only one is moving.
490- * o Allow user-placeable connection points.
491 * o Deal sanely with connectors with both endpoints attached to the
492 * same connection point, and drawing of connectors attaching
493 * overlapping shapes (currently tries to adjust connector to be
494@@ -41,30 +41,17 @@
495 * o Fix up libavoid's representation after undo actions. It doesn't see
496 * any transform signals and hence doesn't know shapes have moved back to
497 * there earlier positions.
498- * o Decide whether drawing/editing mode should be an Inkscape preference
499- * or the connector tool should always start in drawing mode.
500- * o Correct the problem with switching to the select tool when pressing
501- * space bar (there are moments when it refuses to do so).
502 *
503 * ----------------------------------------------------------------------------
504 *
505- * mjwybrow's observations on acracan's Summer of Code connector work:
506- *
507- * - GUI comments:
508- *
509- * - Buttons for adding and removing user-specified connection
510- * points should probably have "+" and "-" symbols on them so they
511- * are consistent with the similar buttons for the node tool.
512- * - Controls on the connector tool be should be reordered logically,
513- * possibly as follows:
514- *
515- * *Connector*: [Polyline-radio-button] [Orthgonal-radio-button]
516- * [Curvature-control] | *Shape*: [Avoid-button] [Dont-avoid-button]
517- * [Spacing-control] | *Connection pts*: [Edit-mode] [Add-pt] [Rm-pt]
518- *
519- * I think that the network layout controls be moved to the
520- * Align and Distribute dialog (there is already the layout button
521- * there, but no options are exposed).
522+ * Notes:
523+ *
524+ * Much of the way connectors work for user-defined points has been
525+ * changed so that it no longer defines special attributes to record
526+ * the points. Instead it uses single node paths to define points
527+ * who are then seperate objects that can be fixed on the canvas,
528+ * grouped into objects and take full advantage of all tranform, snap
529+ * and align functionality of all other objects.
530 *
531 * I think that the style change between polyline and orthogonal
532 * would be much clearer with two buttons (radio behaviour -- just
533@@ -74,80 +61,9 @@
534 * depending on whether an object is selected. We could consider
535 * this but there may not be space.
536 *
537- * The Add-pt and Rm-pt buttons should be greyed out (inactive) if
538- * we are not in connection point editing mode. And probably also
539- * if there is no shape selected, i.e. at the times they have no
540- * effect when clicked.
541- *
542 * Likewise for the avoid/ignore shapes buttons. These should be
543 * inactive when a shape is not selected in the connector context.
544 *
545- * - When creating/editing connection points:
546- *
547- * - Strange things can happen if you have connectors selected, or
548- * try rerouting connectors by dragging their endpoints when in
549- * connection point editing mode.
550- *
551- * - Possibly the selected shape's connection points should always
552- * be shown (i.e., have knots) when in editing mode.
553- *
554- * - It is a little strange to be able to place connection points
555- * competely outside shapes. Especially when you later can't draw
556- * connectors to them since the knots are only visible when you
557- * are over the shape. I think that you should only be able to
558- * place connection points inside or on the boundary of the shape
559- * itself.
560- *
561- * - The intended ability to place a new point at the current cursor
562- * position by pressing RETURN does not seem to work.
563- *
564- * - The Status bar tooltip should change to reflect editing mode
565- * and tell the user about RETURN and how to use the tool.
566- *
567- * - Connection points general:
568- *
569- * - Connection points that were inside the shape can end up outside
570- * after a rotation is applied to the shape in the select tool.
571- * It doesn't seem like the correct transform is being applied to
572- * these, or it is being applied at the wrong time. I'd expect
573- * connection points to rotate with the shape, and stay at the
574- * same position "on the shape"
575- *
576- * - I was able to make the connectors attached to a shape fall off
577- * the shape after scaling it. Not sure the exact cause, but may
578- * require more investigation/debugging.
579- *
580- * - The user-defined connection points should be either absolute
581- * (as the current ones are) or defined as a percentage of the
582- * shape. These would be based on a toggle setting on the
583- * toolbar, and they would be placed in exactly the same way by
584- * the user. The only difference would be that they would be
585- * store as percentage positions in the SVG connection-points
586- * property and that they would update/move automatically if the
587- * object was resized or scaled.
588- *
589- * - Thinking more, I think you always want to store and think about
590- * the positions of connection points to be pre-transform, but
591- * obviously the shape transform is applied to them. That way,
592- * they will rotate and scale automatically with the shape, when
593- * the shape transform is altered. The Percentage version would
594- * compute their position from the pre-transform dimensions and
595- * then have the transform applied to them, for example.
596- *
597- * - The connection points in the test_connection_points.svg file
598- * seem to follow the shape when it is moved, but connection
599- * points I add to new shapes, do not follow the shape, either
600- * when the shape is just moved or transformed. There is
601- * something wrong here. What exactly should the behaviour be
602- * currently?
603- *
604- * - I see that connection points are specified at absolute canvas
605- * positions. I really think that they should be specified in
606- * shape coordinated relative to the shapes. There may be
607- * transforms applied to layers and the canvas which would make
608- * specifying them quite difficult. I'd expect a position of 0, 0
609- * to be on the shape in question or very close to it, for example.
610- *
611 */
612
613
614@@ -158,7 +74,6 @@
615
616 #include "connector-context.h"
617 #include "pixmaps/cursor-connector.xpm"
618-#include "pixmaps/cursor-node.xpm"
619 #include "xml/node-event-vector.h"
620 #include "xml/repr.h"
621 #include "svg/svg.h"
622@@ -219,12 +134,13 @@
623 static gint connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent);
624 static gint connector_handle_key_press(SPConnectorContext *const cc, guint const keyval);
625
626-static void cc_active_shape_add_knot(SPDesktop* desktop, SPItem* item, ConnectionPointMap &cphandles, ConnectionPoint& cp);
627+static void cc_active_shape_add_knot(SPConnectorContext *cc, SPItem* item);
628 static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item);
629+static void cc_clear_active_knots(SPKnotList k);
630 static void cc_clear_active_shape(SPConnectorContext *cc);
631 static void cc_set_active_conn(SPConnectorContext *cc, SPItem *item);
632 static void cc_clear_active_conn(SPConnectorContext *cc);
633-static bool conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid);
634+static bool conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href);
635 static void cc_select_handle(SPKnot* knot);
636 static void cc_deselect_handle(SPKnot* knot);
637 static bool cc_item_is_shape(SPItem *item);
638@@ -238,10 +154,6 @@
639 gchar const *old_value, gchar const *new_value, bool is_interactive,
640 gpointer data);
641
642-
643-static char* cc_knot_tips[] = { _("<b>Connection point</b>: click or drag to create a new connector"),
644- _("<b>Connection point</b>: click to select, drag to move") };
645-
646 /*static Geom::Point connector_drag_origin_w(0, 0);
647 static bool connector_within_tolerance = false;*/
648 static SPEventContextClass *parent_class;
649@@ -316,9 +228,6 @@
650 ec->xp = 0;
651 ec->yp = 0;
652
653- cc->mode = SP_CONNECTOR_CONTEXT_DRAWING_MODE;
654- cc->knot_tip = 0;
655-
656 cc->red_color = 0xff00007f;
657
658 cc->newconn = NULL;
659@@ -341,16 +250,14 @@
660 cc->clickeditem = NULL;
661 cc->clickedhandle = NULL;
662
663- new (&cc->connpthandles) ConnectionPointMap();
664+ new (&cc->knots) SPKnotList();
665
666 for (int i = 0; i < 2; ++i) {
667 cc->endpt_handle[i] = NULL;
668 cc->endpt_handler_id[i] = 0;
669 }
670 cc->shref = NULL;
671- cc->scpid = NULL;
672 cc->ehref = NULL;
673- cc->ecpid = NULL;
674 cc->npoints = 0;
675 cc->state = SP_CONNECTOR_CONTEXT_IDLE;
676 }
677@@ -363,14 +270,6 @@
678
679 cc->sel_changed_connection.disconnect();
680
681- if (!cc->connpthandles.empty()) {
682- for (ConnectionPointMap::iterator it = cc->connpthandles.begin();
683- it != cc->connpthandles.end(); ++it) {
684- g_object_unref(it->first);
685- }
686- cc->connpthandles.clear();
687- }
688- cc->connpthandles.~ConnectionPointMap();
689 for (int i = 0; i < 2; ++i) {
690 if (cc->endpt_handle[1]) {
691 g_object_unref(cc->endpt_handle[i]);
692@@ -381,18 +280,10 @@
693 g_free(cc->shref);
694 cc->shref = NULL;
695 }
696- if (cc->scpid) {
697- g_free(cc->scpid);
698- cc->scpid = NULL;
699- }
700 if (cc->ehref) {
701 g_free(cc->shref);
702 cc->shref = NULL;
703 }
704- if (cc->ecpid) {
705- g_free(cc->scpid);
706- cc->scpid = NULL;
707- }
708 g_assert( cc->newConnRef == NULL );
709
710 G_OBJECT_CLASS(parent_class)->dispose(object);
711@@ -435,8 +326,6 @@
712
713 sp_event_context_read(ec, "curvature");
714 sp_event_context_read(ec, "orthogonal");
715- sp_event_context_read(ec, "mode");
716- cc->knot_tip = cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE ? cc_knot_tips[0] : cc_knot_tips[1];
717 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
718 if (prefs->getBool("/tools/connector/selcue", 0)) {
719 ec->enableSelectionCue();
720@@ -462,49 +351,7 @@
721 else if ( name == "orthogonal" ) {
722 cc->isOrthogonal = val->getBool();
723 }
724- else if ( name == "mode")
725- {
726- sp_connector_context_switch_mode(ec, val->getBool() ? SP_CONNECTOR_CONTEXT_EDITING_MODE : SP_CONNECTOR_CONTEXT_DRAWING_MODE);
727- }
728-}
729-
730-void sp_connector_context_switch_mode(SPEventContext* ec, unsigned int newMode)
731-{
732- SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec);
733-
734- cc->mode = newMode;
735- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
736- {
737- ec->cursor_shape = cursor_connector_xpm;
738- cc->knot_tip = cc_knot_tips[0];
739- if (cc->selected_handle)
740- cc_deselect_handle( cc->selected_handle );
741- cc->selected_handle = NULL;
742- // Show all default connection points
743-
744- }
745- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
746- {
747- ec->cursor_shape = cursor_node_xpm;
748- cc->knot_tip = cc_knot_tips[1];
749-/* if (cc->active_shape)
750- {
751- cc->selection->set( cc->active_shape );
752- }
753- else
754- {
755- SPItem* item = cc->selection->singleItem();
756- if ( item )
757- {
758- cc_set_active_shape(cc, item);
759- cc->selection->set( item );
760- }
761- }*/
762- }
763- sp_event_context_update_cursor(ec);
764-
765-}
766-
767+}
768
769 static void
770 sp_connector_context_finish(SPEventContext *ec)
771@@ -554,16 +401,20 @@
772 cc->active_shape_layer_repr = NULL;
773 }
774
775+ cc_clear_active_knots(cc->knots);
776+}
777+
778+static void
779+cc_clear_active_knots(SPKnotList k)
780+{
781 // Hide the connection points if they exist.
782- if (cc->connpthandles.size()) {
783- for (ConnectionPointMap::iterator it = cc->connpthandles.begin();
784- it != cc->connpthandles.end(); ++it) {
785+ if (k.size()) {
786+ for (SPKnotList::iterator it = k.begin(); it != k.end(); ++it) {
787 sp_knot_hide(it->first);
788 }
789 }
790 }
791
792-
793 static void
794 cc_clear_active_conn(SPConnectorContext *cc)
795 {
796@@ -590,21 +441,15 @@
797
798
799 static bool
800-conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href, gchar **cpid)
801+conn_pt_handle_test(SPConnectorContext *cc, Geom::Point& p, gchar **href)
802 {
803- // TODO: this will need to change when there are more connection
804- // points available for each shape.
805-
806- if (cc->active_handle && (cc->connpthandles.find(cc->active_handle) != cc->connpthandles.end()))
807+ if (cc->active_handle && (cc->knots.find(cc->active_handle) != cc->knots.end()))
808 {
809 p = cc->active_handle->pos;
810- const ConnectionPoint& cp = cc->connpthandles[cc->active_handle];
811- *href = g_strdup_printf("#%s", cc->active_shape->getId());
812- *cpid = g_strdup_printf("%c%d", cp.type == ConnPointDefault ? 'd' : 'u' , cp.id);
813+ *href = g_strdup_printf("#%s", cc->active_handle->owner->getId());
814 return true;
815 }
816 *href = NULL;
817- *cpid = NULL;
818 return false;
819 }
820
821@@ -660,14 +505,8 @@
822 cc->selection->toggle(item);
823 } else {
824 cc->selection->set(item);
825- if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE && cc->selected_handle )
826- {
827- cc_deselect_handle( cc->selected_handle );
828- cc->selected_handle = NULL;
829- }
830- /* When selecting a new item,
831- do not allow showing connection points
832- on connectors. (yet?)
833+ /* When selecting a new item, do not allow showing
834+ connection points on connectors. (yet?)
835 */
836 if ( item != cc->active_shape && !cc_item_is_connector( item ) )
837 cc_set_active_shape( cc, item );
838@@ -678,20 +517,9 @@
839 break;
840 case GDK_ENTER_NOTIFY:
841 {
842- if (cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE || (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE && !cc->selected_handle))
843+ if (!cc->selected_handle)
844 {
845 if (cc_item_is_shape(item)) {
846-
847- // I don't really understand what the above does,
848- // so I commented it.
849- // This is a shape, so show connection point(s).
850- /* if (!(cc->active_shape)
851- // Don't show handle for another handle.
852- // || (cc->connpthandles.find((SPKnot*) item) != cc->connpthandles.end())
853- )
854- {
855- cc_set_active_shape(cc, item);
856- }*/
857 cc_set_active_shape(cc, item);
858 }
859 ret = TRUE;
860@@ -754,8 +582,7 @@
861 SPEventContext *event_context = SP_EVENT_CONTEXT(cc);
862
863 gint ret = FALSE;
864- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
865- {
866+
867 if ( bevent.button == 1 && !event_context->space_panning ) {
868
869 SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
870@@ -766,7 +593,7 @@
871
872 Geom::Point const event_w(bevent.x,
873 bevent.y);
874-// connector_drag_origin_w = event_w;
875+
876 cc->xp = bevent.x;
877 cc->yp = bevent.y;
878 cc->within_tolerance = true;
879@@ -790,7 +617,7 @@
880 Geom::Point p = event_dt;
881
882 // Test whether we clicked on a connection point
883- bool found = conn_pt_handle_test(cc, p, &cc->shref, &cc->scpid);
884+ bool found = conn_pt_handle_test(cc, p, &cc->shref);
885
886 if (!found) {
887 // This is the first point, so just snap it to the grid
888@@ -815,8 +642,8 @@
889
890 spcc_connector_set_subsequent_point(cc, p);
891 spcc_connector_finish_segment(cc, p);
892- // Test whether we clicked on a connection point
893- /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
894+
895+ conn_pt_handle_test(cc, p, &cc->ehref);
896 if (cc->npoints != 0) {
897 spcc_connector_finish(cc);
898 }
899@@ -850,73 +677,9 @@
900 ret = TRUE;
901 }
902 }
903- }
904- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
905- {
906- if ( bevent.button == 1 && !event_context->space_panning )
907- {
908- // Initialize variables in case of dragging
909-
910- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
911-
912- if (Inkscape::have_viable_layer(desktop, cc->_message_context) == false) {
913- return TRUE;
914- }
915-
916- cc->xp = bevent.x;
917- cc->yp = bevent.y;
918- cc->within_tolerance = true;
919-
920- ConnectionPointMap::iterator const& active_knot_it = cc->connpthandles.find( cc->active_handle );
921-
922- switch (cc->state)
923- {
924- case SP_CONNECTOR_CONTEXT_IDLE:
925- if ( active_knot_it != cc->connpthandles.end() )
926- {
927- // We do not allow selecting and, thereby, moving default knots
928- if ( active_knot_it->second.type != ConnPointDefault)
929- {
930- if (cc->selected_handle != cc->active_handle)
931- {
932- if ( cc->selected_handle )
933- cc_deselect_handle( cc->selected_handle );
934- cc->selected_handle = cc->active_handle;
935- cc_select_handle( cc->selected_handle );
936- }
937- }
938- else
939- // Just ignore the default connection point
940- return FALSE;
941- }
942- else
943- if ( cc->selected_handle )
944- {
945- cc_deselect_handle( cc->selected_handle );
946- cc->selected_handle = NULL;
947- }
948-
949- if ( cc->selected_handle )
950- {
951- cc->state = SP_CONNECTOR_CONTEXT_DRAGGING;
952- cc->selection->set( cc->active_shape );
953- }
954-
955- ret = TRUE;
956- break;
957- // Dragging valid because of the way we create
958- // new connection points.
959- case SP_CONNECTOR_CONTEXT_DRAGGING:
960- // Do nothing.
961- ret = TRUE;
962- break;
963- }
964- }
965- }
966 return ret;
967 }
968
969-
970 static gint
971 connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion const &mevent)
972 {
973@@ -948,8 +711,6 @@
974 /* Find desktop coordinates */
975 Geom::Point p = dt->w2d(event_w);
976
977- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
978- {
979 SnapManager &m = dt->namedview->snap_manager;
980
981 switch (cc->state) {
982@@ -1010,26 +771,9 @@
983 }
984 break;
985 }
986- }
987- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
988- {
989- switch ( cc->state )
990- {
991- case SP_CONNECTOR_CONTEXT_DRAGGING:
992- sp_knot_set_position(cc->selected_handle, p, 0);
993- ret = TRUE;
994- break;
995- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
996- sp_knot_set_position(cc->selected_handle, p, 0);
997- ret = TRUE;
998- break;
999- }
1000- }
1001-
1002 return ret;
1003 }
1004
1005-
1006 static gint
1007 connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent)
1008 {
1009@@ -1046,8 +790,7 @@
1010
1011 /* Find desktop coordinates */
1012 Geom::Point p = cc->desktop->w2d(event_w);
1013- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
1014- {
1015+
1016 switch (cc->state) {
1017 //case SP_CONNECTOR_CONTEXT_POINT:
1018 case SP_CONNECTOR_CONTEXT_DRAGGING:
1019@@ -1065,7 +808,7 @@
1020 spcc_connector_set_subsequent_point(cc, p);
1021 spcc_connector_finish_segment(cc, p);
1022 // Test whether we clicked on a connection point
1023- /*bool found = */conn_pt_handle_test(cc, p, &cc->ehref, &cc->ecpid);
1024+ conn_pt_handle_test(cc, p, &cc->ehref);
1025 if (cc->npoints != 0) {
1026 spcc_connector_finish(cc);
1027 }
1028@@ -1093,68 +836,14 @@
1029 }
1030 ret = TRUE;
1031 }
1032- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
1033- {
1034- switch ( cc->state )
1035- {
1036- case SP_CONNECTOR_CONTEXT_DRAGGING:
1037-
1038- if (!cc->within_tolerance)
1039- {
1040- m.setup(desktop);
1041- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
1042- m.unSetup();
1043- sp_knot_set_position(cc->selected_handle, p, 0);
1044- ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
1045- cp.pos = p * (cc->active_shape)->dt2i_affine();
1046- cc->active_shape->avoidRef->updateConnectionPoint(cp);
1047- }
1048-
1049- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
1050- ret = TRUE;
1051- break;
1052-
1053-
1054- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
1055- m.setup(desktop);
1056- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
1057- m.unSetup();
1058-
1059- sp_knot_set_position(cc->selected_handle, p, 0);
1060-
1061- ConnectionPoint cp;
1062- cp.type = ConnPointUserDefined;
1063- cp.pos = p * (cc->active_shape)->dt2i_affine();
1064- cp.dir = Avoid::ConnDirAll;
1065- g_object_unref(cc->selected_handle);
1066- cc->active_shape->avoidRef->addConnectionPoint(cp);
1067- doc->ensureUpToDate();
1068- for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it)
1069- if (it->second.type == ConnPointUserDefined && it->second.id == cp.id)
1070- {
1071- cc->selected_handle = it->first;
1072- break;
1073- }
1074- cc_select_handle( cc->selected_handle );
1075- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
1076- ret = TRUE;
1077- break;
1078- }
1079- }
1080- }
1081-
1082-
1083 return ret;
1084 }
1085
1086-
1087 static gint
1088 connector_handle_key_press(SPConnectorContext *const cc, guint const keyval)
1089 {
1090 gint ret = FALSE;
1091- /* fixme: */
1092- if ( cc->mode == SP_CONNECTOR_CONTEXT_DRAWING_MODE )
1093- {
1094+
1095 switch (keyval) {
1096 case GDK_KEY_Return:
1097 case GDK_KEY_KP_Enter:
1098@@ -1189,100 +878,6 @@
1099 default:
1100 break;
1101 }
1102- }
1103- else if ( cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE )
1104- {
1105- switch ( cc->state )
1106- {
1107- case SP_CONNECTOR_CONTEXT_DRAGGING:
1108- if ( keyval == GDK_KEY_Escape )
1109- {
1110- // Cancel connection point dragging
1111-
1112- // Obtain original position
1113- ConnectionPoint const& cp = cc->connpthandles[cc->selected_handle];
1114- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
1115- const Geom::Affine& i2doc = (cc->active_shape)->i2doc_affine();
1116- sp_knot_set_position(cc->selected_handle, cp.pos * i2doc * desktop->doc2dt(), 0);
1117- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
1118- desktop->messageStack()->flash( Inkscape::NORMAL_MESSAGE,
1119- _("Connection point drag cancelled."));
1120- ret = TRUE;
1121- }
1122- else if ( keyval == GDK_KEY_Return || keyval == GDK_KEY_KP_Enter )
1123- {
1124- // Put connection point at current position
1125-
1126- Geom::Point p = cc->selected_handle->pos;
1127-
1128- if (!cc->within_tolerance)
1129- {
1130- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
1131- SnapManager &m = desktop->namedview->snap_manager;
1132- m.setup(desktop);
1133- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
1134- m.unSetup();
1135- sp_knot_set_position(cc->selected_handle, p, 0);
1136- ConnectionPoint& cp = cc->connpthandles[cc->selected_handle];
1137- cp.pos = p * (cc->active_shape)->dt2i_affine();
1138- cc->active_shape->avoidRef->updateConnectionPoint(cp);
1139- }
1140-
1141- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
1142- ret = TRUE;
1143- }
1144- break;
1145- case SP_CONNECTOR_CONTEXT_NEWCONNPOINT:
1146- if ( keyval == GDK_KEY_Escape )
1147- {
1148- // Just destroy the knot
1149- g_object_unref( cc->selected_handle );
1150- cc->selected_handle = NULL;
1151- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
1152- ret = TRUE;
1153- }
1154- else if ( keyval == GDK_KEY_Return || keyval == GDK_KEY_KP_Enter )
1155- {
1156- SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc);
1157- SPDocument *doc = sp_desktop_document(desktop);
1158- SnapManager &m = desktop->namedview->snap_manager;
1159- m.setup(desktop);
1160- Geom::Point p = cc->selected_handle->pos;
1161- m.freeSnapReturnByRef(p, Inkscape::SNAPSOURCE_OTHER_HANDLE);
1162- m.unSetup();
1163- sp_knot_set_position(cc->selected_handle, p, 0);
1164-
1165- ConnectionPoint cp;
1166- cp.type = ConnPointUserDefined;
1167- cp.pos = p * (cc->active_shape)->dt2i_affine();
1168- cp.dir = Avoid::ConnDirAll;
1169- g_object_unref(cc->selected_handle);
1170- cc->active_shape->avoidRef->addConnectionPoint(cp);
1171- doc->ensureUpToDate();
1172- for (ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end(); ++it)
1173- if (it->second.type == ConnPointUserDefined && it->second.id == cp.id)
1174- {
1175- cc->selected_handle = it->first;
1176- break;
1177- }
1178- cc_select_handle( cc->selected_handle );
1179- cc->state = SP_CONNECTOR_CONTEXT_IDLE;
1180- ret = TRUE;
1181- }
1182-
1183- break;
1184- case SP_CONNECTOR_CONTEXT_IDLE:
1185- if ( keyval == GDK_KEY_Delete && cc->selected_handle )
1186- {
1187- cc->active_shape->avoidRef->deleteConnectionPoint(cc->connpthandles[cc->selected_handle]);
1188- cc->selected_handle = NULL;
1189- ret = TRUE;
1190- }
1191-
1192- break;
1193- }
1194- }
1195-
1196 return ret;
1197 }
1198
1199@@ -1300,17 +895,15 @@
1200 if (p != NULL)
1201 {
1202 // Test whether we clicked on a connection point
1203- gchar *shape_label, *cpid;
1204- bool found = conn_pt_handle_test(cc, *p, &shape_label, &cpid);
1205+ gchar *shape_label;
1206+ bool found = conn_pt_handle_test(cc, *p, &shape_label);
1207
1208 if (found) {
1209 if (cc->clickedhandle == cc->endpt_handle[0]) {
1210 cc->clickeditem->setAttribute("inkscape:connection-start", shape_label, NULL);
1211- cc->clickeditem->setAttribute("inkscape:connection-start-point", cpid, NULL);
1212 }
1213 else {
1214 cc->clickeditem->setAttribute("inkscape:connection-end", shape_label, NULL);
1215- cc->clickeditem->setAttribute("inkscape:connection-end-point", cpid, NULL);
1216 }
1217 g_free(shape_label);
1218 }
1219@@ -1456,18 +1049,12 @@
1220 if (cc->shref)
1221 {
1222 cc->newconn->setAttribute( "inkscape:connection-start", cc->shref, NULL);
1223- if (cc->scpid) {
1224- cc->newconn->setAttribute( "inkscape:connection-start-point", cc->scpid, NULL);
1225- }
1226 connection = true;
1227 }
1228
1229 if (cc->ehref)
1230 {
1231 cc->newconn->setAttribute( "inkscape:connection-end", cc->ehref, NULL);
1232- if (cc->ecpid) {
1233- cc->newconn->setAttribute( "inkscape:connection-end-point", cc->ecpid, NULL);
1234- }
1235 connection = true;
1236 }
1237 // Process pending updates.
1238@@ -1540,7 +1127,7 @@
1239
1240 gboolean consumed = FALSE;
1241
1242- gchar* knot_tip = knot->tip ? knot->tip : cc->knot_tip;
1243+ gchar* knot_tip = "Click to join at this point";
1244 switch (event->type) {
1245 case GDK_ENTER_NOTIFY:
1246 sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE);
1247@@ -1624,10 +1211,12 @@
1248 return consumed;
1249 }
1250
1251-static void cc_active_shape_add_knot(SPDesktop* desktop, SPItem* item, ConnectionPointMap &cphandles, ConnectionPoint& cp)
1252+static void cc_active_shape_add_knot(SPConnectorContext *cc, SPItem* item)
1253 {
1254+ SPDesktop *desktop = cc->desktop;
1255 SPKnot *knot = sp_knot_new(desktop, 0);
1256
1257+ knot->owner = item;
1258 knot->setShape(SP_KNOT_SHAPE_SQUARE);
1259 knot->setSize(8);
1260 knot->setAnchor(SP_ANCHOR_CENTER);
1261@@ -1641,17 +1230,15 @@
1262
1263 g_signal_connect(G_OBJECT(knot->item), "event",
1264 G_CALLBACK(cc_generic_knot_handler), knot);
1265- sp_knot_set_position(knot, item->avoidRef->getConnectionPointPos(cp.type, cp.id) * desktop->doc2dt(), 0);
1266+ sp_knot_set_position(knot, item->avoidRef->getConnectionPointPos() * desktop->doc2dt(), 0);
1267 sp_knot_show(knot);
1268- cphandles[knot] = cp;
1269+ cc->knots[knot] = 1;
1270 }
1271
1272 static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item)
1273 {
1274 g_assert(item != NULL );
1275
1276- std::map<int, ConnectionPoint>* connpts = &item->avoidRef->connection_points;
1277-
1278 if (cc->active_shape != item)
1279 {
1280 // The active shape has changed
1281@@ -1677,84 +1264,23 @@
1282 sp_repr_add_listener(cc->active_shape_layer_repr, &layer_repr_events, cc);
1283 }
1284
1285-
1286- // Set the connection points.
1287- if ( cc->connpthandles.size() )
1288- // destroy the old list
1289- while (! cc->connpthandles.empty() )
1290- {
1291- g_object_unref(cc->connpthandles.begin()->first);
1292- cc->connpthandles.erase(cc->connpthandles.begin());
1293- }
1294- // build the new one
1295- if ( connpts->size() )
1296- for (std::map<int, ConnectionPoint>::iterator it = connpts->begin(); it != connpts->end(); ++it)
1297- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, it->second);
1298-
1299- // Also add default connection points
1300- // For now, only centre default connection point will
1301- // be available
1302- ConnectionPoint centre;
1303- centre.type = ConnPointDefault;
1304- centre.id = ConnPointPosCC;
1305- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, centre);
1306+ cc_clear_active_knots(cc->knots);
1307+
1308+ // The idea here is to try and add a group's children to solidify
1309+ // connection handling. We react to path objects with only one node.
1310+ for (SPObject *child = item->firstChild() ; child ; child = child->getNext() ) {
1311+ if (SP_IS_PATH(child) && SP_PATH(child)->nodesInPath() == 1) {
1312+ cc_active_shape_add_knot(cc, (SPItem *) child);
1313+ }
1314+ }
1315+ cc_active_shape_add_knot(cc, item);
1316+
1317 }
1318 else
1319 {
1320- // The active shape didn't change
1321- // Update only the connection point knots
1322-
1323 // Ensure the item's connection_points map
1324 // has been updated
1325 item->document->ensureUpToDate();
1326-
1327- std::set<int> seen;
1328- for ( ConnectionPointMap::iterator it = cc->connpthandles.begin(); it != cc->connpthandles.end() ;)
1329- {
1330- bool removed = false;
1331- if ( it->second.type == ConnPointUserDefined )
1332- {
1333- std::map<int, ConnectionPoint>::iterator p = connpts->find(it->second.id);
1334- if (p != connpts->end())
1335- {
1336- if ( it->second != p->second )
1337- // Connection point position has changed
1338- // Update knot position
1339- sp_knot_set_position(it->first,
1340- item->avoidRef->getConnectionPointPos(it->second.type, it->second.id) * cc->desktop->doc2dt(), 0);
1341- seen.insert(it->second.id);
1342- sp_knot_show(it->first);
1343- }
1344- else
1345- {
1346- // This connection point does no longer exist,
1347- // remove the knot
1348- ConnectionPointMap::iterator curr = it;
1349- ++it;
1350- g_object_unref( curr->first );
1351- cc->connpthandles.erase(curr);
1352- removed = true;
1353- }
1354- }
1355- else
1356- {
1357- // It's a default connection point
1358- // Just make sure it's position is correct
1359- sp_knot_set_position(it->first,
1360- item->avoidRef->getConnectionPointPos(it->second.type, it->second.id) * cc->desktop->doc2dt(), 0);
1361- sp_knot_show(it->first);
1362-
1363- }
1364- if ( !removed )
1365- ++it;
1366- }
1367- // Add knots for new connection points.
1368- if (connpts->size())
1369- for ( std::map<int, ConnectionPoint>::iterator it = connpts->begin(); it != connpts->end(); ++it )
1370- if ( seen.find(it->first) == seen.end() )
1371- // A new connection point has been added
1372- // to the shape. Add a knot for it.
1373- cc_active_shape_add_knot(cc->desktop, item, cc->connpthandles, it->second);
1374 }
1375 }
1376
1377@@ -1885,15 +1411,6 @@
1378 }
1379 }
1380
1381-void cc_remove_connection_point(SPConnectorContext* cc)
1382-{
1383- if (cc->selected_handle && cc->state == SP_CONNECTOR_CONTEXT_IDLE )
1384- {
1385- cc->active_shape->avoidRef->deleteConnectionPoint(cc->connpthandles[cc->selected_handle]);
1386- cc->selected_handle = NULL;
1387- }
1388-}
1389-
1390 static bool cc_item_is_shape(SPItem *item)
1391 {
1392 if (SP_IS_PATH(item)) {
1393@@ -2032,12 +1549,6 @@
1394 cc_set_active_conn(cc, cc->active_conn);
1395 }
1396 }
1397- else
1398- if ( !strcmp(name, "inkscape:connection-points") )
1399- if (repr == cc->active_shape_repr)
1400- // The connection points of the active shape
1401- // have changed. Update them.
1402- cc_set_active_shape(cc, cc->active_shape);
1403 }
1404
1405
1406
1407=== modified file 'src/connector-context.h'
1408--- src/connector-context.h 2011-10-05 07:06:08 +0000
1409+++ src/connector-context.h 2012-12-03 04:59:19 +0000
1410@@ -18,7 +18,6 @@
1411 #include "event-context.h"
1412 #include <2geom/point.h>
1413 #include "libavoid/connector.h"
1414-#include "connection-points.h"
1415 #include <glibmm/i18n.h>
1416
1417 #define SP_TYPE_CONNECTOR_CONTEXT (sp_connector_context_get_type())
1418@@ -44,12 +43,7 @@
1419 SP_CONNECTOR_CONTEXT_NEWCONNPOINT
1420 };
1421
1422-enum {
1423- SP_CONNECTOR_CONTEXT_DRAWING_MODE,
1424- SP_CONNECTOR_CONTEXT_EDITING_MODE
1425-};
1426-
1427-typedef std::map<SPKnot *, ConnectionPoint> ConnectionPointMap;
1428+typedef std::map<SPKnot *, int> SPKnotList;
1429
1430 struct SPConnectorContext : public SPEventContext {
1431 Inkscape::Selection *selection;
1432@@ -57,14 +51,8 @@
1433
1434 /** \invar npoints in {0, 2}. */
1435 gint npoints;
1436- /* The tool mode can be connector drawing or
1437- connection points editing.
1438- */
1439- unsigned int mode : 1;
1440 unsigned int state : 4;
1441
1442- gchar* knot_tip;
1443-
1444 // Red curve
1445 SPCanvasItem *red_bpath;
1446 SPCurve *red_curve;
1447@@ -89,7 +77,6 @@
1448 Inkscape::XML::Node *active_conn_repr;
1449 sigc::connection sel_changed_connection;
1450
1451-
1452 // The activehandle
1453 SPKnot *active_handle;
1454
1455@@ -99,13 +86,11 @@
1456 SPItem *clickeditem;
1457 SPKnot *clickedhandle;
1458
1459- ConnectionPointMap connpthandles;
1460+ SPKnotList knots;
1461 SPKnot *endpt_handle[2];
1462 guint endpt_handler_id[2];
1463 gchar *shref;
1464- gchar *scpid;
1465 gchar *ehref;
1466- gchar *ecpid;
1467 SPCanvasItem *c0, *c1, *cl0, *cl1;
1468 };
1469
1470@@ -113,7 +98,6 @@
1471
1472 GType sp_connector_context_get_type();
1473
1474-void sp_connector_context_switch_mode(SPEventContext* ec, unsigned int newMode);
1475 void cc_selection_set_avoid(bool const set_ignore);
1476 void cc_create_connection_point(SPConnectorContext* cc);
1477 void cc_remove_connection_point(SPConnectorContext* cc);
1478
1479=== modified file 'src/knot.cpp'
1480--- src/knot.cpp 2012-07-12 22:10:43 +0000
1481+++ src/knot.cpp 2012-12-03 04:59:19 +0000
1482@@ -184,6 +184,7 @@
1483 {
1484 knot->desktop = NULL;
1485 knot->item = NULL;
1486+ knot->owner = NULL;
1487 knot->flags = 0;
1488
1489 knot->size = 8;
1490
1491=== modified file 'src/knot.h'
1492--- src/knot.h 2012-04-10 10:38:21 +0000
1493+++ src/knot.h 2012-12-03 04:59:19 +0000
1494@@ -21,6 +21,7 @@
1495 #include <sigc++/sigc++.h>
1496 #include "enums.h"
1497 #include <gtk/gtk.h>
1498+#include "sp-item.h"
1499
1500 class SPDesktop;
1501 class SPKnot;
1502@@ -43,6 +44,7 @@
1503 struct SPKnot : GObject {
1504 SPDesktop *desktop; /**< Desktop we are on. */
1505 SPCanvasItem *item; /**< Our CanvasItem. */
1506+ SPItem *owner; /**< Optional Owner Item */
1507 guint flags;
1508
1509 guint size; /**< Always square. */
1510
1511=== modified file 'src/sp-conn-end-pair.cpp'
1512--- src/sp-conn-end-pair.cpp 2012-01-17 20:25:50 +0000
1513+++ src/sp-conn-end-pair.cpp 2012-12-03 04:59:19 +0000
1514@@ -82,9 +82,7 @@
1515 {
1516 object->readAttr( "inkscape:connector-type" );
1517 object->readAttr( "inkscape:connection-start" );
1518- object->readAttr( "inkscape:connection-start-point" );
1519 object->readAttr( "inkscape:connection-end" );
1520- object->readAttr( "inkscape:connection-end-point" );
1521 object->readAttr( "inkscape:connector-curvature" );
1522 }
1523
1524@@ -164,10 +162,6 @@
1525 case SP_ATTR_CONNECTION_END:
1526 this->_connEnd[(key == SP_ATTR_CONNECTION_START ? 0 : 1)]->setAttacherHref(value, _path);
1527 break;
1528- case SP_ATTR_CONNECTION_START_POINT:
1529- case SP_ATTR_CONNECTION_END_POINT:
1530- this->_connEnd[(key == SP_ATTR_CONNECTION_START_POINT ? 0 : 1)]->setAttacherEndpoint(value, _path);
1531- break;
1532 }
1533
1534 }
1535@@ -175,15 +169,10 @@
1536 void
1537 SPConnEndPair::writeRepr(Inkscape::XML::Node *const repr) const
1538 {
1539- char const * const attr_strs[] = {"inkscape:connection-start", "inkscape:connection-start-point",
1540- "inkscape:connection-end", "inkscape:connection-end-point"};
1541+ char const * const attr_strs[] = {"inkscape:connection-start", "inkscape:connection-end"};
1542 for (unsigned handle_ix = 0; handle_ix < 2; ++handle_ix) {
1543 if (this->_connEnd[handle_ix]->ref.getURI()) {
1544- repr->setAttribute(attr_strs[2*handle_ix], this->_connEnd[handle_ix]->ref.getURI()->toString());
1545- std::ostringstream ostr;
1546- ostr<<(this->_connEnd[handle_ix]->type == ConnPointDefault ? "d":"u") <<
1547- this->_connEnd[handle_ix]->id;
1548- repr->setAttribute(attr_strs[2*handle_ix+1], ostr.str().c_str());
1549+ repr->setAttribute(attr_strs[handle_ix], this->_connEnd[handle_ix]->ref.getURI()->toString());
1550 }
1551 }
1552 repr->setAttribute("inkscape:connector-curvature", Glib::Ascii::dtostr(_connCurvature).c_str());
1553@@ -222,7 +211,7 @@
1554 for (unsigned h = 0; h < 2; ++h) {
1555 if ( h2attItem[h] ) {
1556 g_assert(h2attItem[h]->avoidRef);
1557- endPts[h] = h2attItem[h]->avoidRef->getConnectionPointPos(_connEnd[h]->type, _connEnd[h]->id);
1558+ endPts[h] = h2attItem[h]->avoidRef->getConnectionPointPos();
1559 }
1560 else if (!curve->is_empty())
1561 {
1562
1563=== modified file 'src/sp-conn-end.cpp'
1564--- src/sp-conn-end.cpp 2012-10-27 11:46:53 +0000
1565+++ src/sp-conn-end.cpp 2012-12-03 04:59:19 +0000
1566@@ -21,11 +21,10 @@
1567 ref(owner),
1568 href(NULL),
1569 // Default to center connection endpoint
1570- type(ConnPointDefault),
1571- id(4),
1572 _changed_connection(),
1573 _delete_connection(),
1574- _transformed_connection()
1575+ _transformed_connection(),
1576+ _group_connection()
1577 {
1578 }
1579
1580@@ -154,9 +153,9 @@
1581 Geom::PathVector conn_pv = path->_curve->get_pathvector();
1582 double endPos[2] = { 0.0, static_cast<double>(conn_pv[0].size()) };
1583
1584- SPConnEnd** _connEnd = path->connEndPair.getConnEnds();
1585 for (unsigned h = 0; h < 2; ++h) {
1586- if (h2attItem[h] && _connEnd[h]->type == ConnPointDefault && _connEnd[h]->id == ConnPointPosCC) {
1587+ // Assume center point for all
1588+ if (h2attItem[h]) {
1589 Geom::Affine h2i2anc = i2anc_affine(h2attItem[h], ancestor);
1590 try_get_intersect_point_with_item(path, h2attItem[h], h2i2anc, path2anc,
1591 (h == 0), endPos[h]);
1592@@ -228,13 +227,9 @@
1593 static void
1594 sp_conn_end_deleted(SPObject *, SPObject *const owner, unsigned const handle_ix)
1595 {
1596- // todo: The first argument is the deleted object, or just NULL if
1597- // called by sp_conn_end_detach.
1598- g_return_if_fail(handle_ix < 2);
1599- char const * const attr_strs[] = {"inkscape:connection-start", "inkscape:connection-start-point",
1600- "inkscape:connection-end", "inkscape:connection-end-point"};
1601- owner->getRepr()->setAttribute(attr_strs[2*handle_ix], NULL);
1602- owner->getRepr()->setAttribute(attr_strs[2*handle_ix+1], NULL);
1603+ char const * const attrs[] = {
1604+ "inkscape:connection-start", "inkscape:connection-end"};
1605+ owner->getRepr()->setAttribute(attrs[handle_ix], NULL);
1606 /* I believe this will trigger sp_conn_end_href_changed. */
1607 }
1608
1609@@ -283,84 +278,6 @@
1610 }
1611 }
1612
1613-void
1614-SPConnEnd::setAttacherEndpoint(gchar const *value, SPPath* /*path*/)
1615-{
1616-
1617- /* References to the connection points have the following format
1618- <t><id>, where t is the type of the point, which
1619- can be either "d" for default or "u" for user-defined, and
1620- id is the local (inside the item) id of the connection point.
1621- In the case of default points id represents the position on the
1622- item (i.e. Top-Left, Center-Center, etc.).
1623- */
1624-
1625- bool changed = false;
1626- ConnPointType newtype = type;
1627-
1628- if (!value)
1629- {
1630- // Default to center endpoint
1631- type = ConnPointDefault;
1632- id = 4;
1633- }
1634- else
1635- {
1636- switch (value[0])
1637- {
1638- case 'd':
1639- if ( newtype != ConnPointDefault )
1640- {
1641- newtype = ConnPointDefault;
1642- changed = true;
1643- }
1644- break;
1645- case 'u':
1646- if ( newtype != ConnPointUserDefined)
1647- {
1648- newtype = ConnPointUserDefined;
1649- changed = true;
1650- }
1651- break;
1652- default:
1653- g_warning("Bad reference to a connection point.");
1654- }
1655-
1656- int newid = (int) g_ascii_strtod( value+1, 0 );
1657- if ( id != newid )
1658- {
1659- id = newid;
1660- changed = true;
1661- }
1662-
1663- // We have to verify that the reference to the
1664- // connection point is a valid one.
1665-
1666- if ( changed )
1667- {
1668-
1669- // Get the item the connector is attached to
1670- SPItem* item = ref.getObject();
1671- if ( item )
1672- {
1673- if (!item->avoidRef->isValidConnPointId( newtype, newid ) )
1674- {
1675- g_warning("Bad reference to a connection point.");
1676- }
1677- else
1678- {
1679- type = newtype;
1680- id = newid;
1681- }
1682- /* // Update the connector
1683- if (path->connEndPair.isAutoRoutingConn()) {
1684- path->connEndPair.tellLibavoidNewEndpoints();
1685- }
1686- */
1687- }
1688- }
1689- }
1690-}
1691
1692 void
1693 sp_conn_end_href_changed(SPObject */*old_ref*/, SPObject */*ref*/,
1694@@ -370,6 +287,7 @@
1695 SPConnEnd &connEnd = *connEndPtr;
1696 connEnd._delete_connection.disconnect();
1697 connEnd._transformed_connection.disconnect();
1698+ connEnd._group_connection.disconnect();
1699
1700 if (connEnd.href) {
1701 SPObject *refobj = connEnd.ref.getObject();
1702@@ -377,6 +295,14 @@
1703 connEnd._delete_connection
1704 = refobj->connectDelete(sigc::bind(sigc::ptr_fun(&sp_conn_end_deleted),
1705 path, handle_ix));
1706+ // This allows the connector tool to dive into a group's children
1707+ // And connect to their children's centers.
1708+ SPObject *parent = refobj->parent;
1709+ if (SP_IS_GROUP(parent) and ! SP_IS_LAYER(parent)) {
1710+ connEnd._group_connection
1711+ = SP_ITEM(parent)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_conn_end_shape_move),
1712+ path));
1713+ }
1714 connEnd._transformed_connection
1715 = SP_ITEM(refobj)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_conn_end_shape_move),
1716 path));
1717
1718=== modified file 'src/sp-conn-end.h'
1719--- src/sp-conn-end.h 2011-12-08 11:53:54 +0000
1720+++ src/sp-conn-end.h 2012-12-03 04:59:19 +0000
1721@@ -6,7 +6,6 @@
1722 #include <sigc++/connection.h>
1723
1724 #include "sp-use-reference.h"
1725-#include "connection-points.h"
1726 #include "conn-avoid-ref.h"
1727
1728 class SPPath;
1729@@ -18,15 +17,6 @@
1730 SPUseReference ref;
1731 gchar *href;
1732
1733- /* In the following, type refers to connection point type,
1734- i.e. default (one of the 9 combinations of right, centre,
1735- left, top, bottom) or user-defined. The id serves to identify
1736- the connection point in a list of connection points.
1737- */
1738-
1739- ConnPointType type;
1740- int id;
1741-
1742 /** Change of href string (not a modification of the attributes of the referrent). */
1743 sigc::connection _changed_connection;
1744
1745@@ -36,6 +26,9 @@
1746 /** A sigc connection for transformed signal, used to do move compensation. */
1747 sigc::connection _transformed_connection;
1748
1749+ /** A sigc connection for owning group transformed, used to do move compensation. */
1750+ sigc::connection _group_connection;
1751+
1752 void setAttacherHref(gchar const *, SPPath *);
1753 void setAttacherEndpoint(gchar const *, SPPath *);
1754
1755
1756=== modified file 'src/sp-item.cpp'
1757--- src/sp-item.cpp 2012-10-27 17:35:46 +0000
1758+++ src/sp-item.cpp 2012-12-03 04:59:19 +0000
1759@@ -511,9 +511,6 @@
1760 case SP_ATTR_CONNECTOR_AVOID:
1761 item->avoidRef->setAvoid(value);
1762 break;
1763- case SP_ATTR_CONNECTION_POINTS:
1764- item->avoidRef->setConnectionPoints(value);
1765- break;
1766 case SP_ATTR_TRANSFORM_CENTER_X:
1767 if (value) {
1768 item->transform_center_x = g_strtod(value, NULL);
1769
1770=== modified file 'src/widgets/connector-toolbar.cpp'
1771--- src/widgets/connector-toolbar.cpp 2012-11-11 12:46:25 +0000
1772+++ src/widgets/connector-toolbar.cpp 2012-12-03 04:59:19 +0000
1773@@ -78,13 +78,6 @@
1774 //## Connector ##
1775 //#########################
1776
1777-static void sp_connector_mode_toggled( GtkToggleAction* act, GObject * /*tbl*/ )
1778-{
1779- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1780- prefs->setBool("/tools/connector/mode",
1781- gtk_toggle_action_get_active( act ));
1782-}
1783-
1784 static void sp_connector_path_set_avoid(void)
1785 {
1786 cc_selection_set_avoid(true);
1787@@ -303,26 +296,6 @@
1788 }
1789 }
1790
1791-static void sp_connector_new_connection_point(GtkWidget *, GObject *tbl)
1792-{
1793- SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));
1794- SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context);
1795-
1796- if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) {
1797- cc_create_connection_point(cc);
1798- }
1799-}
1800-
1801-static void sp_connector_remove_connection_point(GtkWidget *, GObject *tbl)
1802-{
1803- SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));
1804- SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context);
1805-
1806- if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) {
1807- cc_remove_connection_point(cc);
1808- }
1809-}
1810-
1811 static Inkscape::XML::NodeEventVector connector_tb_repr_events = {
1812 NULL, /* child_added */
1813 NULL, /* child_removed */
1814@@ -351,22 +324,6 @@
1815 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1816 Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
1817
1818- // Editing mode toggle button
1819- {
1820- InkToggleAction* act = ink_toggle_action_new( "ConnectorEditModeAction",
1821- _("EditMode"),
1822- _("Switch between connection point editing and connector drawing mode"),
1823- INKSCAPE_ICON("connector-edit"),
1824- Inkscape::ICON_SIZE_DECORATION );
1825- gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
1826-
1827- bool tbuttonstate = prefs->getBool("/tools/connector/mode");
1828- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE ));
1829- g_object_set_data( holder, "mode", act );
1830- g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_mode_toggled), holder );
1831- }
1832-
1833-
1834 {
1835 InkAction* inky = ink_action_new( "ConnectorAvoidAction",
1836 _("Avoid"),
1837@@ -480,30 +437,6 @@
1838 }
1839
1840
1841- // New connection point button
1842- {
1843- InkAction* inky = ink_action_new( "ConnectorNewConnPointAction",
1844- _("New connection point"),
1845- _("Add a new connection point to the currently selected item"),
1846- INKSCAPE_ICON("connector-new-connpoint"),
1847- secondarySize );
1848- g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_new_connection_point), holder );
1849- gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
1850- }
1851-
1852- // Remove selected connection point button
1853-
1854- {
1855- InkAction* inky = ink_action_new( "ConnectorRemoveConnPointAction",
1856- _("Remove connection point"),
1857- _("Remove the currently selected connection point"),
1858- INKSCAPE_ICON("connector-remove-connpoint"),
1859- secondarySize );
1860- g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_remove_connection_point), holder );
1861- gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
1862- }
1863-
1864-
1865 // Code to watch for changes to the connector-spacing attribute in
1866 // the XML.
1867 Inkscape::XML::Node *repr = desktop->namedview->getRepr();
1868
1869=== modified file 'src/widgets/toolbox.cpp'
1870--- src/widgets/toolbox.cpp 2012-11-30 12:11:42 +0000
1871+++ src/widgets/toolbox.cpp 2012-12-03 04:59:19 +0000
1872@@ -527,7 +527,6 @@
1873 " </toolbar>"
1874
1875 " <toolbar name='ConnectorToolbar'>"
1876-// " <toolitem action='ConnectorEditModeAction' />"
1877 " <toolitem action='ConnectorAvoidAction' />"
1878 " <toolitem action='ConnectorIgnoreAction' />"
1879 " <toolitem action='ConnectorOrthogonalAction' />"
1880@@ -537,8 +536,6 @@
1881 " <toolitem action='ConnectorLengthAction' />"
1882 " <toolitem action='ConnectorDirectedAction' />"
1883 " <toolitem action='ConnectorOverlapAction' />"
1884-// " <toolitem action='ConnectorNewConnPointAction' />"
1885-// " <toolitem action='ConnectorRemoveConnPointAction' />"
1886 " </toolbar>"
1887
1888 "</ui>"