1 /* 2 SPDX-License-Identifier: GPL-2.0-or-later 3 SPDX-FileCopyrightText: 2002-2020 Umbrello UML Modeller Authors <umbrello-devel@kde.org> 4 */ 5 6 #ifndef ASSOCIATIONWIDGET_H 7 #define ASSOCIATIONWIDGET_H 8 9 #include "associationwidgetlist.h" 10 #include "associationwidgetrole.h" 11 #include "linkwidget.h" 12 #include "messagewidgetlist.h" 13 #include "umlwidgetlist.h" 14 #include "widgetbase.h" 15 16 class AssociationLine; 17 class ClassifierWidget; 18 class UMLScene; 19 class UMLAssociation; 20 class UMLAttribute; 21 class UMLClassifierListItem; 22 class UMLOperation; 23 24 /** 25 * This class represents an association inside a diagram. 26 * 27 * Constructor is made non accessible: 28 * Users shall use the static create() methods for constructing AssociationWidgets. 29 * 30 * Associations exist not only between UML objects. For example, when a Note is 31 * attached to a UML object, the Note itself is not a UML object. 32 * This class supports both kinds of associations. An association where one or 33 * both roles are not a UML object is called a "pure widget association". 34 * 35 * An AssociationWidget where both roles are UML objects has a corresponding 36 * UMLAssociation. The UMLAssociation can be retrieved using the getAssociation 37 * method. 38 * A pure widget association does not have a corresponding UMLAssociation. 39 * The getAssociation method returns NULL in this case. 40 * 41 * @author Gustavo Madrigal 42 * @author Gopala Krishna 43 * @short This class represents an association inside a diagram. 44 * Bugs and comments to umbrello-devel@kde.org or https://bugs.kde.org 45 */ 46 class AssociationWidget : public WidgetBase, public LinkWidget 47 { 48 Q_OBJECT 49 public: 50 static AssociationWidget* create(UMLScene *scene); 51 static AssociationWidget* create 52 (UMLScene *scene, UMLWidget* WidgetA, 53 Uml::AssociationType::Enum assocType, UMLWidget* WidgetB, 54 UMLObject *umlobject = 0); 55 56 virtual ~AssociationWidget(); 57 58 virtual void setUMLObject(UMLObject *obj); 59 60 //---------- LinkWidget Interface methods implementation from now on. 61 62 virtual void lwSetFont(QFont font); 63 virtual UMLClassifier *operationOwner(); 64 65 virtual UMLOperation *operation(); 66 virtual void setOperation(UMLOperation *op); 67 68 virtual QString customOpText(); 69 virtual void setCustomOpText(const QString &opText); 70 71 virtual void resetTextPositions(); 72 73 virtual void setMessageText(FloatingTextWidget *ft); 74 virtual void setText(FloatingTextWidget *ft, const QString &newText); 75 76 virtual bool showPropertiesDialog(); 77 78 virtual QString lwOperationText(); 79 virtual UMLClassifier *lwClassifier(); 80 virtual void setOperationText(const QString &op); 81 82 virtual void constrainTextPos(qreal &textX, qreal &textY, 83 qreal textWidth, qreal textHeight, 84 Uml::TextRole::Enum tr); 85 86 virtual void calculateNameTextSegment(); 87 88 //---------- End LinkWidget Interface methods implementation. 89 90 UMLAssociation* association() const; 91 UMLAttribute* attribute() const; 92 93 // AssociationWidget& operator=(const AssociationWidget& other); 94 bool operator==(const AssociationWidget& other) const; 95 bool operator!=(AssociationWidget& other) const; 96 97 FloatingTextWidget* textWidgetByRole(Uml::TextRole::Enum tr) const; 98 99 FloatingTextWidget* nameWidget() const; 100 QString name() const; 101 void setName(const QString &strRole); 102 void setStereotype(const QString &stereo); 103 104 FloatingTextWidget* roleWidget(Uml::RoleType::Enum role) const; 105 QString roleName(Uml::RoleType::Enum role) const; 106 void setRoleName(const QString &strRole, Uml::RoleType::Enum role); 107 108 QString roleDocumentation(Uml::RoleType::Enum role) const; 109 void setRoleDocumentation(const QString& doc, Uml::RoleType::Enum role); 110 111 FloatingTextWidget* multiplicityWidget(Uml::RoleType::Enum role) const; 112 QString multiplicity(Uml::RoleType::Enum role) const; 113 void setMultiplicity(const QString& text, Uml::RoleType::Enum role); 114 115 Uml::Visibility::Enum visibility(Uml::RoleType::Enum role) const; 116 void setVisibility(Uml::Visibility::Enum value, Uml::RoleType::Enum role); 117 118 FloatingTextWidget* changeabilityWidget(Uml::RoleType::Enum role) const; 119 Uml::Changeability::Enum changeability(Uml::RoleType::Enum role) const; 120 void setChangeability(Uml::Changeability::Enum value, Uml::RoleType::Enum role); 121 122 Uml::ID::Type widgetIDForRole(Uml::RoleType::Enum role) const; 123 Uml::ID::Type widgetLocalIDForRole(Uml::RoleType::Enum role) const; 124 UMLWidget* widgetForRole(Uml::RoleType::Enum role) const; 125 void setWidgetForRole(UMLWidget* widget, Uml::RoleType::Enum role); 126 127 bool containsAsEndpoint(UMLWidget* widget); 128 129 Uml::AssociationType::Enum associationType() const; 130 void setAssociationType(Uml::AssociationType::Enum type); 131 132 bool isCollaboration() const; 133 bool isSelf() const; 134 135 QString toString() const; 136 137 bool isActivated() const; 138 void setActivated(bool active); 139 140 AssociationLine* associationLine() const; 141 142 virtual bool activate(IDChangeLog *changeLog = 0); 143 virtual QRectF boundingRect() const; 144 virtual QPainterPath shape() const; 145 146 void widgetMoved(UMLWidget* widget, qreal x, qreal y); 147 148 void saveIdealTextPositions(); 149 150 UMLWidget* onWidget(const QPointF &p); 151 bool onAssociation(const QPointF& point); 152 bool onAssocClassLine(const QPointF& point); 153 154 void createAssocClassLine(); 155 void createAssocClassLine(ClassifierWidget* classifierWidget, 156 int linePathSegmentIndex); 157 158 void selectAssocClassLine(bool sel = true); 159 void removeAssocClassLine(); 160 void computeAssocClassLine(); 161 162 void setXEntireAssoc(qreal x); 163 void setYEntireAssoc(qreal y); 164 165 void moveMidPointsBy(qreal x, qreal y); 166 void moveEntireAssoc(qreal x, qreal y); 167 168 QFont font() const; 169 170 virtual void setTextColor(const QColor &color); 171 virtual void setLineColor(const QColor &color); 172 virtual void setLineWidth(uint width); 173 174 void calculateEndingPoints(); 175 176 void clipSize(); 177 178 bool loadFromXMI1(QDomElement& qElement, const UMLWidgetList& widgets, 179 const MessageWidgetList* messages); 180 virtual bool loadFromXMI1(QDomElement& qElement); 181 virtual void saveToXMI1(QXmlStreamWriter& writer); 182 183 void cleanup(); 184 185 bool isPointAddable(); 186 bool isPointRemovable(); 187 bool isAutoLayouted(); 188 bool isLayoutChangeable(); 189 190 virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); 191 virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); 192 virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); 193 virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); 194 195 virtual void setSelected(bool _select); 196 197 public Q_SLOTS: //:TODO: all virtual? 198 virtual void slotMenuSelection(QAction* action); 199 void slotClassifierListItemRemoved(UMLClassifierListItem* obj); 200 void slotAttributeChanged(); 201 202 void syncToModel(); 203 204 protected: 205 virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); 206 207 virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); 208 virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); 209 virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); 210 211 private: 212 QPointF calculateTextPosition(Uml::TextRole::Enum role); 213 void setTextPosition(Uml::TextRole::Enum role); 214 void setTextPositionRelatively(Uml::TextRole::Enum role, const QPointF &oldPosition); 215 void setFloatingText(Uml::TextRole::Enum role, const QString& text, FloatingTextWidget* &ft); 216 217 AssociationWidget(UMLScene *scene); 218 219 void setUMLAssociation(UMLAssociation * assoc); 220 221 void mergeAssociationDataIntoUMLRepresentation(); 222 223 static Uml::Region::Enum findPointRegion(const QRectF& rect, const QPointF& pos); 224 static qreal findInterceptOnEdge(const QRectF &rect, Uml::Region::Enum region, const QPointF &point); 225 static QLineF::IntersectType intersect(const QRectF &rect, const QLineF &line, 226 QPointF* intersectionPoint); 227 228 void moveEvent(QGraphicsSceneMouseEvent *me); 229 230 Uml::TextRole::Enum calculateNameType(Uml::TextRole::Enum defaultRoleType); 231 232 static QPointF swapXY(const QPointF &p); 233 234 // not used at the moment 235 // static QPointF calculatePointAtDistance(const QPointF &P1, const QPointF &P2, float Distance); 236 // static QPointF calculatePointAtDistanceOnPerpendicular(const QPointF &P1, const QPointF &P2, float Distance); 237 // static float perpendicularProjection(const QPointF& P1, const QPointF& P2, const QPointF& P3, QPointF& ResultingPoint); 238 239 static QPointF midPoint(const QPointF& p0, const QPointF& p1); 240 241 void createPointsSelfAssociation(); 242 void updatePointsSelfAssociation(); 243 void createPointsException(); 244 void updatePointsException(); 245 246 void updateRegionLineCount(int index, int totalCount, 247 Uml::Region::Enum region, Uml::RoleType::Enum role); 248 249 void updateAssociations(int totalCount, Uml::Region::Enum region, Uml::RoleType::Enum role); 250 251 int getRegionCount(Uml::Region::Enum region, Uml::RoleType::Enum role); 252 253 void doUpdates(const QPointF &otherP, Uml::RoleType::Enum role); 254 255 void setChangeWidget(const QString &strChangeWidget, Uml::RoleType::Enum role); 256 257 bool checkAddPoint(const QPointF &scenePos); 258 bool checkRemovePoint(const QPointF &scenePos); 259 bool checkAutoLayoutSpline(); 260 261 bool linePathStartsAt(const UMLWidget* widget); 262 263 void insertIntoLists(qreal position, const AssociationWidget* assoc); 264 265 qreal m_positions[100]; ///< auxiliary variable for updateAssociations() 266 int m_positions_len; ///< auxiliary variable for updateAssociations() 267 AssociationWidgetList m_ordered; ///< auxiliary variable for updateAssociations() 268 269 bool m_activated; ///< flag which is true if the activate method has been called for this class instance 270 271 /** 272 * When the association has a Role Floating Text this text should move 273 * when the AssociationLine moves but only if the closest segment to the 274 * role text moves. 275 * This segment is: 276 * m_associationLine[m_unNameLineSegment] -- m_associationLine[m_unNameLineSegment+1] 277 */ 278 int m_unNameLineSegment; 279 280 QPointF m_oldNamePoint; ///< Position of name floatingtext saved by saveIdealTextPositions() 281 QPointF m_oldMultiAPoint; ///< Position of role A multiplicity floatingtext saved by saveIdealTextPositions() 282 QPointF m_oldMultiBPoint; ///< Position of role B multiplicity floatingtext saved by saveIdealTextPositions() 283 QPointF m_oldChangeAPoint; ///< Position of role A changeability floatingtext saved by saveIdealTextPositions() 284 QPointF m_oldChangeBPoint; ///< Position of role B changeability floatingtext saved by saveIdealTextPositions() 285 QPointF m_oldRoleAPoint; ///< Position of role A name floatingtext saved by saveIdealTextPositions() 286 QPointF m_oldRoleBPoint; ///< Position of role B name floatingtext saved by saveIdealTextPositions() 287 288 int m_nLinePathSegmentIndex; ///< anchor for m_pAssocClassLine 289 QGraphicsLineItem *m_pAssocClassLine; ///< used for connecting assoc. class 290 QGraphicsRectItem *m_pAssocClassLineSel0; ///< selection decoration for the start point of the assoc. class line 291 QGraphicsRectItem *m_pAssocClassLineSel1; ///< selection decoration for the end point of the assoc. class line 292 293 AssociationLine *m_associationLine; ///< the definition points for the association line 294 ClassifierWidget *m_associationClass; ///< used if we have an assoc. class 295 Uml::AssociationType::Enum m_associationType; ///< is only used if m_pObject is not set 296 AssociationWidgetRole m_role[2]; 297 FloatingTextWidget* m_nameWidget; ///< displays the name of this association 298 QPointF m_eventScenePos; ///< holds scene pos of contextMenuEvent() 299 300 }; 301 302 #endif 303