Commit 96503cae authored by Jan Hambrecht's avatar Jan Hambrecht

restrict conection point positions to bounding box of shape

this seems to finally fix bug 251529
parent 4e0f8950
......@@ -219,6 +219,15 @@ QPointF KoShapePrivate::defaultConnectionPoint(KoFlake::ConnectionPointId connec
return QPointF();
}
}
void KoShapePrivate::setConnectionPoint(int id, const QPointF &position)
{
// restrict position of connection point to bounding box
const qreal x = qBound<qreal>(0.0, position.x(), 1.0);
const qreal y = qBound<qreal>(0.0, position.y(), 1.0);
connectors[id] = QPointF(x, y);
}
// static
QString KoShapePrivate::getStyleProperty(const char *property, KoShapeLoadingContext &context)
{
......@@ -747,14 +756,14 @@ int KoShape::addConnectionPoint(const QPointF &point)
{
Q_D(KoShape);
QSizeF s = size();
// convert glue point from shape coordinates to factors of size
QPointF connectionPoint(point.x() / s.width(), point.y() / s.height());
// get next glue point id
int nextConnectionPointId = KoFlake::FirstCustomConnectionPoint;
if (d->connectors.size())
nextConnectionPointId = qMax(nextConnectionPointId, (--d->connectors.end()).key()+1);
d->connectors[nextConnectionPointId] = connectionPoint;
// convert glue point from shape coordinates to factors of size
d->setConnectionPoint(nextConnectionPointId, QPointF(point.x()/s.width(), point.y()/s.height()));
return nextConnectionPointId;
}
......@@ -765,10 +774,7 @@ bool KoShape::insertConnectionPoint(const QPointF &point, int connectionPointId)
if (connectionPointId < 0 || d->connectors.contains(connectionPointId))
return false;
QSizeF s = size();
// convert glue point from shape coordinates to factors of size
QPointF connectionPoint(point.x() / s.width(), point.y() / s.height());
QPointF connectionPoint;
switch(connectionPointId) {
case KoFlake::TopConnectionPoint:
case KoFlake::RightConnectionPoint:
......@@ -777,11 +783,16 @@ bool KoShape::insertConnectionPoint(const QPointF &point, int connectionPointId)
connectionPoint = d->defaultConnectionPoint(static_cast<KoFlake::ConnectionPointId>(connectionPointId));
break;
default:
// do nothing for all other cases
{
QSizeF s = size();
// convert glue point from shape coordinates to factors of size
connectionPoint.rx() = point.x() / s.width();
connectionPoint.ry() = point.y() / s.height();
break;
}
}
d->connectors[connectionPointId] = connectionPoint;
d->setConnectionPoint(connectionPointId, connectionPoint);
return true;
}
......@@ -809,15 +820,14 @@ bool KoShape::setConnectionPointPosition(int connectionPointId, const QPointF &n
return false;
Q_D(KoShape);
KoConnectionPoints::iterator cp = d->connectors.find(connectionPointId);
// check if connection point exists
if(cp == d->connectors.end())
if (!d->connectors.contains(connectionPointId))
return false;
QSizeF s = size();
cp->rx() = newPosition.x() / s.width();
cp->ry() = newPosition.y() / s.height();
// convert glue point from shape coordinates to factors of size
const qreal x = newPosition.x() / s.width();
const qreal y = newPosition.y() / s.height();
d->setConnectionPoint(connectionPointId, QPointF(x, y));
d->shapeChanged(ConnectionPointChanged);
return true;
......@@ -1416,10 +1426,11 @@ bool KoShape::loadOdfAttributes(const KoXmlElement &element, KoShapeLoadingConte
// convert position to be relative to top-left corner
connectorPos += QPointF(0.5, 0.5);
}
d->connectors[index] = connectorPos;
d->setConnectionPoint(index, connectorPos);
kDebug(30006) << "loaded glue-point" << index << "at position" << connectorPos;
}
}
kDebug(30006) << "shape has now" << d->connectors.count() << "glue-points";
}
return true;
......
......@@ -315,12 +315,13 @@ public:
/**
* @brief Add a connector point to the shape
*
* A connector is a place on the shape that allows a graphical connection to be made
* using a line, for example.
*
* @param point the position where to place the connector. The points coordinate system
* are based around the zero-pos which is the top-left of the shape
* The point does not have to be inside the boundings rectangle. The point is in pt,
* are based around the zero-pos which is the top-left of the shape. The position of
* the connector is restricted to the bounding rectangle of the shape. The point is in pt,
* just like the rest of the KoShape class uses.
* @return the id of the new connection point
*/
......@@ -328,6 +329,9 @@ public:
/**
* Tries to insert connection point with specified id.
*
* The position of the connector is restricted to the bounding rectangle of the shape.
*
* @param point the position of the connector in shape coordinates
* @param connectionPointId the id of the connection point to insert
* @return true if inserting connection point was successful;
......@@ -343,6 +347,9 @@ public:
/**
* Sets new position for specified custom connection point
*
* The position of the connector is restricted to the bounding rectangle of the shape.
*
* @param connectionPointId the id of the custom connection point to change
* @param newPosition the new position of the custom connection point in shape coordinates
* @return true if position could be changed, else false
......
......@@ -145,6 +145,9 @@ public:
/// Returns the specified default connection point
QPointF defaultConnectionPoint(KoFlake::ConnectionPointId connectionPointId);
/// Sets the specified connection point
void setConnectionPoint(int id, const QPointF &position);
Q_DECLARE_PUBLIC(KoShape)
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment