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; }
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); } }