From 3f971d74996c54b243e55e351dffe86213a5f246 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Krzysztof=20Kosi=C5=84ski?= Date: Wed, 10 Feb 2010 16:21:40 +0100 Subject: [PATCH] (Probably) fix a crash in the node tool and fix Ctrl+Alt dragging --- src/ui/tool/node.cpp | 34 +++++++++++++++++--------------- src/ui/tool/path-manipulator.cpp | 21 ++++++++++++++------ 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 09ca99c6e..865d65386 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -317,20 +317,20 @@ Glib::ustring Handle::_getTip(unsigned state) char const *more; bool can_shift_rotate = _parent->type() == NODE_CUSP && !other().isDegenerate(); if (can_shift_rotate) { - more = C_("Path handle tip", "more: Ctrl, Alt, Ctrl+Alt, Shift"); + more = C_("Path handle tip", "more: Shift, Ctrl, Alt"); } else { - more = C_("Path handle tip", "more: Ctrl, Alt, Ctrl+Alt"); + more = C_("Path handle tip", "more: Ctrl, Alt"); } if (state_held_alt(state)) { if (state_held_control(state)) { if (state_held_shift(state) && can_shift_rotate) { return format_tip(C_("Path handle tip", - "Shift+Ctrl+Alt: preserve length and snap rotation angle to %f° " + "Shift+Ctrl+Alt: preserve length and snap rotation angle to %g° " "increments while rotating both handles"), snap_increment_degrees()); } else { return format_tip(C_("Path handle tip", - "Ctrl+Alt: preserve length and snap rotation angle to %f° increments"), + "Ctrl+Alt: preserve length and snap rotation angle to %g° increments"), snap_increment_degrees()); } } else { @@ -346,11 +346,11 @@ Glib::ustring Handle::_getTip(unsigned state) if (state_held_control(state)) { if (state_held_shift(state) && can_shift_rotate) { return format_tip(C_("Path handle tip", - "Ctrl: snap rotation angle to %f° increments, click to retract"), + "Ctrl: snap rotation angle to %g° increments, click to retract"), snap_increment_degrees()); } else { return format_tip(C_("Path handle tip", - "Shift+Ctrl: snap rotation angle to %f° increments and rotate both handles"), + "Shift+Ctrl: snap rotation angle to %g° increments and rotate both handles"), snap_increment_degrees()); } } else if (state_held_shift(state) && can_shift_rotate) { @@ -381,7 +381,7 @@ Glib::ustring Handle::_getDragTip(GdkEventMotion */*event*/) GString *y = SP_PX_TO_METRIC_STRING(dist[Geom::Y], _desktop->namedview->getDefaultMetric()); GString *len = SP_PX_TO_METRIC_STRING(length(), _desktop->namedview->getDefaultMetric()); Glib::ustring ret = format_tip(C_("Path handle tip", - "Move by %s, %s; angle %.2f°, length %s"), x->str, y->str, angle, len->str); + "Move handle by %s, %s; angle %.2f°, length %s"), x->str, y->str, angle, len->str); g_string_free(x, TRUE); g_string_free(y, TRUE); g_string_free(len, TRUE); @@ -564,13 +564,15 @@ void Node::setType(NodeType type, bool update_handles) bool prev_line = _is_line_segment(_prev(), this); bool next_line = _is_line_segment(this, _next()); if (_type == NODE_SMOOTH) { - // for a node that is already smooth and at the end of a linear segment, + // for a node that is already smooth and has a degenerate handle, // drag out the second handle to 1/3 the length of the linear segment - if (next_line) { - _front.setRelativePos((_prev()->position() - position()) / 3); + if (_front.isDegenerate()) { + double dist = Geom::distance(_next()->position(), position()); + _front.setRelativePos(Geom::unit_vector(-_back.relativePos()) * dist / 3); } - if (prev_line) { - _back.setRelativePos((_next()->position() - position()) / 3); + if (_back.isDegenerate()) { + double dist = Geom::distance(_prev()->position(), position()); + _back.setRelativePos(Geom::unit_vector(-_front.relativePos()) * dist / 3); } } else if (isDegenerate()) { _updateAutoHandles(); @@ -1079,13 +1081,13 @@ Glib::ustring Node::_getTip(unsigned state) if (_selection.transformHandlesEnabled() && selected()) { if (_selection.size() == 1) { return format_tip(C_("Path node tip", - "%s: drag to shape the path (more: Shift, Ctrl, Ctrl+Alt)"), nodetype); + "%s: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype); } return format_tip(C_("Path node tip", - "%s: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Ctrl+Alt)"), nodetype); + "%s: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype); } return format_tip(C_("Path node tip", - "%s: drag to shape the path, click to select only this node (more: Shift, Ctrl, Ctrl+Alt)"), nodetype); + "%s: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"), nodetype); } Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/) @@ -1093,7 +1095,7 @@ Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/) Geom::Point dist = position() - _last_drag_origin(); GString *x = SP_PX_TO_METRIC_STRING(dist[Geom::X], _desktop->namedview->getDefaultMetric()); GString *y = SP_PX_TO_METRIC_STRING(dist[Geom::Y], _desktop->namedview->getDefaultMetric()); - Glib::ustring ret = format_tip(C_("Path node tip", "Move by %s, %s"), + Glib::ustring ret = format_tip(C_("Path node tip", "Move node by %s, %s"), x->str, y->str); g_string_free(x, TRUE); g_string_free(y, TRUE); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fd21970ee..d2f90bbca 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -58,8 +58,19 @@ enum PathChange { */ class PathManipulatorObserver : public Inkscape::XML::NodeObserver { public: - PathManipulatorObserver(PathManipulator *p) : _pm(p), _blocked(false) {} - virtual void notifyAttributeChanged(Inkscape::XML::Node &, GQuark attr, + PathManipulatorObserver(PathManipulator *p, Inkscape::XML::Node *node) + : _pm(p) + , _node(node) + , _blocked(false) + { + Inkscape::GC::anchor(_node); + _node->addObserver(*this); + } + ~PathManipulatorObserver() { + _node->removeObserver(*this); + Inkscape::GC::release(_node); + } + virtual void notifyAttributeChanged(Inkscape::XML::Node &node, GQuark attr, Util::ptr_shared, Util::ptr_shared) { // do nothing if blocked @@ -80,6 +91,7 @@ public: void unblock() { _blocked = false; } private: PathManipulator *_pm; + Inkscape::XML::Node *_node; bool _blocked; }; @@ -93,7 +105,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, , _path(path) , _spcurve(NULL) , _dragpoint(new CurveDragPoint(*this)) - , _observer(new PathManipulatorObserver(this)) + , _observer(new PathManipulatorObserver(this, SP_OBJECT(path)->repr)) , _edit_transform(et) , _num_selected(0) , _show_handles(true) @@ -127,14 +139,11 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - - _path->repr->addObserver(*_observer); } PathManipulator::~PathManipulator() { delete _dragpoint; - if (_path) _path->repr->removeObserver(*_observer); delete _observer; gtk_object_destroy(_outline); if (_spcurve) _spcurve->unref(); -- 2.30.2