void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
    NodeList::iterator second = first.next();

    // special cancel handling - retract handles when if the segment was degenerate
    if (_is_drag_cancelled(event) && _segment_was_degenerate) {
        first->front()->retract();
        second->back()->retract();
        _pm.update();
        return;
    }

    if (_drag_initiated && !(event->state & GDK_SHIFT_MASK)) {
        SnapManager &m = _desktop->namedview->snap_manager;
        SPItem *path = static_cast<SPItem *>(_pm._path);
        m.setup(_desktop, true, path); // We will not try to snap to "path" itself
        Inkscape::SnapCandidatePoint scp(new_pos, Inkscape::SNAPSOURCE_OTHER_HANDLE);
        Inkscape::SnappedPoint sp = m.freeSnap(scp, Geom::OptRect(), false);
        new_pos = sp.getPoint();
        m.unSetup();
    }

    // Magic Bezier Drag Equations follow!
    // "weight" describes how the influence of the drag should be distributed
    // among the handles; 0 = front handle only, 1 = back handle only.
    double weight, t = _t;
    if (t <= 1.0 / 6.0) weight = 0;
    else if (t <= 0.5) weight = (pow((6 * t - 1) / 2.0, 3)) / 2;
    else if (t <= 5.0 / 6.0) weight = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5;
    else weight = 1;

    Geom::Point delta = new_pos - position();
    Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta;
    Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta;

    //modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed
    if(!_pm._isBSpline()){
        first->front()->move(first->front()->position() + offset0);
        second->back()->move(second->back()->position() + offset1);
    }else if(weight>=0.8){
        if(held_shift(*event)){
            second->back()->move(new_pos);
        } else {
            second->move(second->position() + delta);
        }
    }else if(weight<=0.2){
        if(held_shift(*event)){
            first->back()->move(new_pos);
        } else {
            first->move(first->position() + delta);
        }
    }else{
        first->move(first->position() + delta);
        second->move(second->position() + delta);
    }
    _pm.update();
}
bool CurveDragPoint::grabbed(GdkEventMotion */*event*/)
{
    _pm._selection.hideTransformHandles();
    NodeList::iterator second = first.next();

    // move the handles to 1/3 the length of the segment for line segments
    if (first->front()->isDegenerate() && second->back()->isDegenerate()) {
        _segment_was_degenerate = true;

        // delta is a vector equal 1/3 of distance from first to second
        Geom::Point delta = (second->position() - first->position()) / 3.0;
        // only update the nodes if the mode is bspline
        if(!_pm._isBSpline()){
            first->front()->move(first->front()->position() + delta);
            second->back()->move(second->back()->position() - delta);
        }
        _pm.update();
    } else {
        _segment_was_degenerate = false;
    }
    return false;
}