Commit 2d1468b2 authored by Oliver Kellogg's avatar Oliver Kellogg
Browse files

Fix misplacement of startpoint on associationline originating at port:

umbrello/umlwidgets/umlwidget.{h,cpp}
- Add virtual functions getX / getY returning qreal and getPos returning
  QPointF.  Default implementation calls QGraphicsObjectWrapper
  functions x() / y() / pos().

umbrello/umlwidgets/pinportbase.{h,cpp}
- Reimplement virtual functions getX / getY and getPos.
  They call the respective function of UMLWidget but add the respective
  component of parentItem() (i.e. x(), y(), pos() resp.)
  Reason: PinPortBase coordinates are relative to their ComponentWidget.

umbrello/toolbarstateassociation.cpp
- In function setSecondWidget, after creating the AssociationWidget
  check whether widgetA is a PortWidget. If it is then
  - store widgetA->getPos() to local variable lineStart;
  - set the startpoint of the association line to lineStart.

umbrello/umlwidgets/associationwidget.cpp
- Use new UMLWidget functions getX / getY / getPos in all code that is
  related to association line calculation and update:
  Function calculateEndingPoints, doUpdates, updateRegionLineCount.

CCBUG: 403692
parent 73942f3a
......@@ -4,7 +4,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2004-2020 *
* copyright (C) 2004-2021 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
......@@ -263,6 +263,11 @@ void ToolBarStateAssociation::setSecondWidget()
} */
}
AssociationWidget *temp = AssociationWidget::create(m_pUMLScene, widgetA, type, widgetB);
if (widgetA->baseType() == UMLWidget::wt_Port) {
QPointF lineStart = widgetA->getPos();
uDebug() << "ToolBarStateAssociation::setSecondWidget : lineStart = " << lineStart;
temp->associationLine()->setPoint(0, lineStart);
}
FloatingTextWidget *wt = temp->textWidgetByRole(Uml::TextRole::Coll_Message);
if (wt)
wt->showOperationDialog();
......
......@@ -1193,8 +1193,8 @@ bool AssociationWidget::linePathStartsAt(const UMLWidget* widget)
// QPointF lpStart = m_associationLine->point(0);
// int startX = lpStart.x();
// int startY = lpStart.y();
// int wX = widget->x();
// int wY = widget->y();
// int wX = widget->getX();
// int wY = widget->getY();
// int wWidth = widget->width();
// int wHeight = widget->height();
// bool result = (startX >= wX && startX <= wX + wWidth &&
......@@ -1649,8 +1649,8 @@ void AssociationWidget::calculateEndingPoints()
int size = m_associationLine->count();
if (size < 2) {
QPointF pA = pWidgetA->pos();
QPointF pB = pWidgetB->pos();
QPointF pA = pWidgetA->getPos();
QPointF pB = pWidgetB->getPos();
QPolygonF polyA = pWidgetA->shape().toFillPolygon().translated(pA);
QPolygonF polyB = pWidgetB->shape().toFillPolygon().translated(pB);
QLineF nearestPoints = Widget_Utils::closestPoints(polyA, polyB);
......@@ -1681,8 +1681,8 @@ void AssociationWidget::calculateEndingPoints()
// If the line has more than one segment change the values to calculate
// from widget to point 1.
qreal xB = pWidgetB->x() + pWidgetB->width() / 2;
qreal yB = pWidgetB->y() + pWidgetB->height() / 2;
qreal xB = pWidgetB->getX() + pWidgetB->width() / 2;
qreal yB = pWidgetB->getY() + pWidgetB->height() / 2;
if (size > 2) {
QPointF p = m_associationLine->point(1);
xB = p.x();
......@@ -1693,8 +1693,8 @@ void AssociationWidget::calculateEndingPoints()
// Now do the same for widgetB.
// If the line has more than one segment change the values to calculate
// from widgetB to the last point away from it.
qreal xA = pWidgetA->x() + pWidgetA->width() / 2;
qreal yA = pWidgetA->y() + pWidgetA->height() / 2;
qreal xA = pWidgetA->getX() + pWidgetA->width() / 2;
qreal yA = pWidgetA->getY() + pWidgetA->height() / 2;
if (size > 2 ) {
QPointF p = m_associationLine->point(size - 2);
xA = p.x();
......@@ -1713,7 +1713,7 @@ void AssociationWidget::doUpdates(const QPointF &otherP, RoleType::Enum role)
// Find widget region.
Uml::Region::Enum oldRegion = m_role[role].m_WidgetRegion;
UMLWidget *pWidget = m_role[role].umlWidget;
QRectF rc(pWidget->x(), pWidget->y(),
QRectF rc(pWidget->getX(), pWidget->getY(),
pWidget->width(), pWidget->height());
Uml::Region::Enum region = m_role[role].m_WidgetRegion; // alias for brevity
region = findPointRegion(rc, otherP);
......@@ -3633,7 +3633,7 @@ void AssociationWidget::updateRegionLineCount(int index, int totalCount,
polyA = polyA.united(polyListA.at(i));
}
}
polyA = polyA.translated(pWidgetA->pos());
polyA = polyA.translated(pWidgetA->getPos());
QList<QPolygonF> polyListB = pWidgetB->shape().toSubpathPolygons();
QPolygonF polyB = polyListB.at(0);
if (polyListB.size() > 1) {
......@@ -3641,7 +3641,7 @@ void AssociationWidget::updateRegionLineCount(int index, int totalCount,
polyB = polyB.united(polyListB.at(i));
}
}
polyB = polyB.translated(pWidgetB->pos());
polyB = polyB.translated(pWidgetB->getPos());
QLineF nearestPoints = Widget_Utils::closestPoints(polyA, polyB);
if (nearestPoints.isNull()) {
uError() << "Widget_Utils::closestPoints failed, falling back to simple widget positions";
......
......@@ -4,7 +4,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2014-2020 *
* copyright (C) 2014-2021 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
......@@ -94,6 +94,21 @@ void PinPortBase::setInitialPosition(const QPointF &scenePos)
m_childPlacement->setInitialPosition(scenePos);
}
qreal PinPortBase::getX() const
{
return parentItem()->x() + UMLWidget::getX();
}
qreal PinPortBase::getY() const
{
return parentItem()->y() + UMLWidget::getY();
}
QPointF PinPortBase::getPos() const
{
return parentItem()->pos() + UMLWidget::getPos();
}
/**
* Overrides method from UMLWidget in order to set a tooltip.
* The tooltip is set to the name().
......
......@@ -4,7 +4,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2014-2020 *
* copyright (C) 2014-2021 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
......@@ -39,6 +39,10 @@ public:
void setInitialPosition(const QPointF &scenePos);
qreal getX() const;
qreal getY() const;
QPointF getPos() const;
void updateWidget();
void setName(const QString &strName);
void moveWidgetBy(qreal diffX, qreal diffY);
......
......@@ -4,7 +4,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2002-2020 *
* copyright (C) 2002-2021 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
......@@ -1688,6 +1688,39 @@ void UMLWidget::setScene(UMLScene *scene)
connect(m_scene, SIGNAL(sigLineWidthChanged(Uml::ID::Type)), this, SLOT(slotLineWidthChanged(Uml::ID::Type)));
}
/**
* Gets the x-coordinate.
* Currently, the only class that reimplements this method is PinPortBase.
*
* @return The x-coordinate.
*/
qreal UMLWidget::getX() const
{
return QGraphicsObjectWrapper::x();
}
/**
* Gets the y-coordinate.
* Currently, the only class that reimplements this method is PinPortBase.
*
* @return The y-coordinate.
*/
qreal UMLWidget::getY() const
{
return QGraphicsObjectWrapper::y();
}
/**
* Gets the position.
* Currently, the only class that reimplements this method is PinPortBase.
*
* @return The QGraphicsObject position.
*/
QPointF UMLWidget::getPos() const
{
return QGraphicsObjectWrapper::pos();
}
/**
* Sets the x-coordinate.
* Currently, the only class that reimplements this method is
......
......@@ -105,6 +105,9 @@ public:
return m_startMove;
}
virtual qreal getX() const;
virtual qreal getY() const;
virtual QPointF getPos() const;
virtual void setX(qreal x);
virtual void setY(qreal y);
......
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