示例#1
0
KWOutlineShape::KWOutlineShape(KWFrame *frame)
    : m_paintOutline(false)
{
    setShapeId(KoPathShapeId);
    setApplicationData(frame);

    class MyGroup : public KoShapeGroup
    {
    public:
        ~MyGroup() {
            setApplicationData(0); // make sure deleting this will not delete the parent frame.
        }
    };
    KoShapeGroup *group = new MyGroup();
    group->setSize(QSize(1, 1));
    group->setApplicationData(frame);

    KoShape *child = frame->shape();
    group->setTransformation(child->absoluteTransformation(0));
    QMatrix matrix;
    child->setTransformation(matrix);

    const QSizeF s = child->size();
    // init with a simple rect as the outline of the original.
    moveTo(QPointF(0, 0));
    lineTo(QPointF(s.width(), 0));
    lineTo(QPointF(s.width(), s.height()));
    lineTo(QPointF(0, s.height()));
    close();
    group->setZIndex(child->zIndex());

    group->addChild(this);
    group->addChild(child);
}
void ConnectionTool::paint(QPainter &painter, const KoViewConverter &converter)
{
    // get the correctly sized rect for painting handles
    QRectF handleRect = handlePaintRect(QPointF());

    painter.setRenderHint(QPainter::Antialiasing, true);

    if (m_currentStrategy) {
        painter.save();
        m_currentStrategy->paint(painter, converter);
        painter.restore();
    }

    QList<KoShape*> shapes = canvas()->shapeManager()->shapes();
    for (QList<KoShape*>::const_iterator end = shapes.constBegin(); end !=  shapes.constEnd(); ++end) {
        KoShape* shape = *end;
        if (!dynamic_cast<KoConnectionShape*>(shape)) {
            // only paint connection points of textShapes not inside a tos container and other shapes
            if (shape->shapeId() == TextShape_SHAPEID && dynamic_cast<KoTosContainer*>(shape->parent())) continue;

            painter.save();
            painter.setPen(Qt::black);
            QTransform transform = shape->absoluteTransformation(0);
            KoShape::applyConversion(painter, converter);
            // Draw all the connection points of the shape
            KoConnectionPoints connectionPoints = shape->connectionPoints();
            KoConnectionPoints::const_iterator cp = connectionPoints.constBegin();
            KoConnectionPoints::const_iterator lastCp = connectionPoints.constEnd();
            for(; cp != lastCp; ++cp) {
                if (shape == findNonConnectionShapeAtPosition(transform.map(cp.value().position)) ) {
                    handleRect.moveCenter(transform.map(cp.value().position));
                    painter.setBrush(cp.key() == m_activeHandle && shape == m_currentShape ?
                                     Qt::red : Qt::white);
                    painter.drawRect(handleRect);
                }
            }
            painter.restore();
        }
    }
    // paint connection points or connection handles depending
    // on the shape the mouse is currently
    if (m_currentShape && m_editMode == EditConnection) {
        KoConnectionShape *connectionShape = dynamic_cast<KoConnectionShape*>(m_currentShape);
        if (connectionShape) {
            int radius = handleRadius()+1;
            int handleCount = connectionShape->handleCount();
            for(int i = 0; i < handleCount; ++i) {
                painter.save();
                painter.setPen(Qt::blue);
                painter.setBrush(i == m_activeHandle ? Qt::red : Qt::white);
                painter.setTransform(connectionShape->absoluteTransformation(&converter) * painter.transform());
                connectionShape->paintHandle(painter, converter, i, radius);
                painter.restore();
            }
        }
    }
}
void KWCreateOutlineCommand::redo()
{
    QUndoCommand::redo();
    if (m_container == 0) {
        m_path = new KWOutlineShape(m_frame);
        m_container = m_path->parent();
    } else {
        KoShape *child = m_frame->shape();
        m_container->setTransformation(child->absoluteTransformation(0));
        QTransform matrix;
        child->setTransformation(matrix);
        m_container->addShape(child);
        m_container->setApplicationData(m_frame);
    }
    m_frame->setOutlineShape(m_path);
    m_controller->addShape(m_container);
    m_deleteOnExit = false;
}
示例#4
0
ShapeResizeStrategy::ShapeResizeStrategy(KoToolBase *tool,
        const QPointF &clicked, KoFlake::SelectionHandle direction )
    : KoInteractionStrategy(tool), m_lastScale(1.0,1.0)
{
    Q_ASSERT(tool->canvas()->shapeManager()->selection()->count() > 0);
    QList<KoShape*> selectedShapes = tool->canvas()->shapeManager()->selection()->selectedShapes(KoFlake::StrippedSelection);
    foreach(KoShape *shape, selectedShapes) {
        if ( ! shape->isEditable() )
            continue;
        m_selectedShapes << shape;
        m_startPositions << shape->position();
        m_oldTransforms << shape->transformation();
        m_transformations << QTransform();
        m_startSizes << shape->size();
    }
    m_start = clicked;

    KoShape *shp = 0;
    if (tool->canvas()->shapeManager()->selection()->count()>1)
       shp = tool->canvas()->shapeManager()->selection();
    if (tool->canvas()->shapeManager()->selection()->count()==1)
        shp = tool->canvas()->shapeManager()->selection()->firstSelectedShape();

    if ( shp )
    {
        m_windMatrix = shp->absoluteTransformation(0);
        m_unwindMatrix = m_windMatrix.inverted();
        m_initialSize = shp->size();
        m_initialPosition = m_windMatrix.map(QPointF());
    }

    switch(direction) {
        case KoFlake::TopMiddleHandle:
            m_start = 0.5 * (shp->absolutePosition(KoFlake::TopLeftCorner) + shp->absolutePosition(KoFlake::TopRightCorner) );
            m_top = true; m_bottom = false; m_left = false; m_right = false; break;
        case KoFlake::TopRightHandle:
            m_start = shp->absolutePosition(KoFlake::TopRightCorner);
            m_top = true; m_bottom = false; m_left = false; m_right = true; break;
        case KoFlake::RightMiddleHandle:
            m_start = 0.5 * ( shp->absolutePosition(KoFlake::TopRightCorner) + shp->absolutePosition(KoFlake::BottomRightCorner) );
            m_top = false; m_bottom = false; m_left = false; m_right = true; break;
        case KoFlake::BottomRightHandle:
            m_start = shp->absolutePosition(KoFlake::BottomRightCorner);
            m_top = false; m_bottom = true; m_left = false; m_right = true; break;
        case KoFlake::BottomMiddleHandle:
            m_start = 0.5 * ( shp->absolutePosition(KoFlake::BottomRightCorner) + shp->absolutePosition(KoFlake::BottomLeftCorner) );
            m_top = false; m_bottom = true; m_left = false; m_right = false; break;
        case KoFlake::BottomLeftHandle:
            m_start = shp->absolutePosition(KoFlake::BottomLeftCorner);
            m_top = false; m_bottom = true; m_left = true; m_right = false; break;
        case KoFlake::LeftMiddleHandle:
            m_start = 0.5 * ( shp->absolutePosition(KoFlake::BottomLeftCorner) + shp->absolutePosition(KoFlake::TopLeftCorner) );
            m_top = false; m_bottom = false; m_left = true; m_right = false; break;
        case KoFlake::TopLeftHandle:
            m_start = shp->absolutePosition(KoFlake::TopLeftCorner);
            m_top = true; m_bottom = false; m_left = true; m_right = false; break;
        default:
             Q_ASSERT(0); // illegal 'corner'
    }

    tool->setStatusText( i18n("Press CTRL to resize from center.") );
}
void KoPathConnectionPointStrategy::handleMouseMove(const QPointF &mouseLocation, Qt::KeyboardModifiers modifiers)
{
    Q_D(KoPathConnectionPointStrategy);

    const qreal MAX_DISTANCE = 20.0; // TODO make user definable
    const qreal MAX_DISTANCE_SQR = MAX_DISTANCE * MAX_DISTANCE;

    d->newConnectionShape = 0;
    d->newConnectionId = InvalidConnectionPointId;

    QRectF roi(mouseLocation - QPointF(MAX_DISTANCE, MAX_DISTANCE), QSizeF(2*MAX_DISTANCE, 2*MAX_DISTANCE));
    QList<KoShape*> shapes = d->tool->canvas()->shapeManager()->shapesAt(roi, true);
    if (shapes.count() < 2) {
        // we are not near any other shape, so remove the corresponding connection
        if (d->handleId == 0)
            d->connectionShape->connectFirst(0, InvalidConnectionPointId);
        else
            d->connectionShape->connectSecond(0, InvalidConnectionPointId);

        KoParameterChangeStrategy::handleMouseMove(mouseLocation, modifiers);
    } else {
        qreal minimalDistance = DBL_MAX;
        QPointF nearestPoint;
        KoShape *nearestShape = 0;
        int nearestPointId = InvalidConnectionPointId;

        Q_FOREACH (KoShape* shape, shapes) {
            // we do not want to connect to ourself
            if (shape == d->connectionShape)
                continue;

            KoConnectionPoints connectionPoints = shape->connectionPoints();
            if (! connectionPoints.count()) {
                QSizeF size = shape->size();
                connectionPoints[-1] = QPointF(0.0, 0.0);
                connectionPoints[-2] = QPointF(size.width(), 0.0);
                connectionPoints[-3] = QPointF(size.width(), size.height());
                connectionPoints[-4] = QPointF(0.0, size.height());
                connectionPoints[-5] = 0.5 * (connectionPoints[-1].position + connectionPoints[-2].position);
                connectionPoints[-6] = 0.5 * (connectionPoints[-2].position + connectionPoints[-3].position);
                connectionPoints[-7] = 0.5 * (connectionPoints[-3].position + connectionPoints[-4].position);
                connectionPoints[-8] = 0.5 * (connectionPoints[-4].position + connectionPoints[-1].position);
            }
            QPointF localMousePosition = shape->absoluteTransformation(0).inverted().map(mouseLocation);
            KoConnectionPoints::const_iterator cp = connectionPoints.constBegin();
            KoConnectionPoints::const_iterator lastCp = connectionPoints.constEnd();
            for(; cp != lastCp; ++cp) {
                QPointF difference = localMousePosition - cp.value().position;
                qreal distance = difference.x() * difference.x() + difference.y() * difference.y();
                if (distance > MAX_DISTANCE_SQR)
                    continue;
                if (distance < minimalDistance) {
                    nearestShape = shape;
                    nearestPoint = cp.value().position;
                    nearestPointId = cp.key();
                    minimalDistance = distance;
                }
            }
        }

        if (nearestShape) {
            nearestPoint = nearestShape->absoluteTransformation(0).map(nearestPoint);
        } else {
            nearestPoint = mouseLocation;
        }
        d->newConnectionShape = nearestShape;
        d->newConnectionId = nearestPointId;
        if (d->handleId == 0)
            d->connectionShape->connectFirst(nearestShape, nearestPointId);
        else
            d->connectionShape->connectSecond(nearestShape, nearestPointId);
        KoParameterChangeStrategy::handleMouseMove(nearestPoint, modifiers);
    }
}