void EnhancedPathHandle::saveOdf(KoShapeSavingContext &context) const
{
    if (!hasPosition()) {
        return;
    }
    context.xmlWriter().startElement("draw:handle");
    context.xmlWriter().addAttribute("draw:handle-position", m_positionX->toString() + ' ' + m_positionY->toString());
    if (isPolar()) {
        context.xmlWriter().addAttribute("draw:handle-polar", m_polarX->toString() + ' ' + m_polarY->toString());
        if (m_minRadius) {
            context.xmlWriter().addAttribute("draw:handle-radius-range-minimum", m_minRadius->toString());
        }
        if (m_maxRadius) {
            context.xmlWriter().addAttribute("draw:handle-radius-range-maximum", m_maxRadius->toString());
        }
    } else {
        if (m_minimumX) {
            context.xmlWriter().addAttribute("draw:handle-range-x-minimum", m_minimumX->toString());
        }
        if (m_maximumX) {
            context.xmlWriter().addAttribute("draw:handle-range-x-maximum", m_maximumX->toString());
        }
        if (m_minimumY) {
            context.xmlWriter().addAttribute("draw:handle-range-y-minimum", m_minimumY->toString());
        }
        if (m_maximumY) {
            context.xmlWriter().addAttribute("draw:handle-range-y-maximum", m_maximumY->toString());
        }
    }
    context.xmlWriter().endElement(); // draw:handle
}
void EnhancedPathHandle::changePosition(const QPointF &position)
{
    if (!hasPosition()) {
        return;
    }

    QPointF constrainedPosition(position);

    if (isPolar()) {
        // convert cartesian coordinates into polar coordinates
        QPointF polarCenter(m_polarX->evaluate(), m_polarY->evaluate());
        QPointF diff = constrainedPosition - polarCenter;
        // compute the polar radius
        qreal radius = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
        // compute the polar angle
        qreal angle = atan2(diff.y(), diff.x());
        if (angle < 0.0) {
            angle += 2 * M_PI;
        }

        // constrain the radius
        if (m_minRadius) {
            radius = qMax(m_minRadius->evaluate(), radius);
        }
        if (m_maxRadius) {
            radius = qMin(m_maxRadius->evaluate(), radius);
        }

        constrainedPosition.setX(angle * 180.0 / M_PI);
        constrainedPosition.setY(radius);
    } else {
        // constrain x coordinate
        if (m_minimumX) {
            constrainedPosition.setX(qMax(m_minimumX->evaluate(), constrainedPosition.x()));
        }
        if (m_maximumX) {
            constrainedPosition.setX(qMin(m_maximumX->evaluate(), constrainedPosition.x()));
        }

        // constrain y coordinate
        if (m_minimumY) {
            constrainedPosition.setY(qMax(m_minimumY->evaluate(), constrainedPosition.y()));
        }
        if (m_maximumY) {
            constrainedPosition.setY(qMin(m_maximumY->evaluate(), constrainedPosition.y()));
        }
    }

    m_positionX->modify(constrainedPosition.x());
    m_positionY->modify(constrainedPosition.y());
}
QPointF EnhancedPathHandle::position()
{
    if (!hasPosition())
        return QPointF();

    QPointF position(m_positionX->evaluate(), m_positionY->evaluate());
    if (isPolar()) {
        // convert polar coordinates into cartesian coordinates
        QPointF center(m_polarX->evaluate(), m_polarY->evaluate());
        qreal angleInRadian = position.x() * M_PI / 180.0;
        position = center + position.y() * QPointF(cos(angleInRadian), sin(angleInRadian));
    }

    return position;
}