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 MESSAGEWIDGET_H
7 #define MESSAGEWIDGET_H
8 
9 #include "umlwidget.h"
10 #include "linkwidget.h"
11 
12 // forward declarations
13 class FloatingTextWidget;
14 class ObjectWidget;
15 class QResizeEvent;
16 class UMLOperation;
17 
18 /**
19  * Used to display a message on a sequence diagram.  The message
20  * could be between two objects or a message that calls itself on
21  * an object.  This class will only display the line that is
22  * required and the text will be setup by the @ref FloatingTextWidget
23  * widget that is passed in the constructor.  A message can be
24  * synchronous (calls a method and gains control back on return,
25  * as happens in most programming languages) or asynchronous
26  * (calls a method and gains back control immediately).
27  *
28  * @short Displays a message.
29  * @author Paul Hensgen
30  * @see UMLWidget
31  * @see ObjectWidget
32  * @see FloatingTextWidget
33  * Bugs and comments to umbrello-devel@kde.org or https://bugs.kde.org
34  */
35 class MessageWidget : public UMLWidget, public LinkWidget
36 {
37     Q_OBJECT
38 public:
39     MessageWidget(UMLScene * scene, ObjectWidget* a, ObjectWidget* b,
40                   int y, Uml::SequenceMessage::Enum sequenceMessageType,
41                   Uml::ID::Type id = Uml::ID::None);
42     MessageWidget(UMLScene * scene, Uml::SequenceMessage::Enum sequenceMessageType,
43                   Uml::ID::Type id = Uml::ID::None);
44     MessageWidget(UMLScene * scene, ObjectWidget* a, int xclick, int yclick,
45                   Uml::SequenceMessage::Enum sequenceMessageType,
46                   Uml::ID::Type id = Uml::ID::None);
47     virtual ~MessageWidget();
48 
49     virtual void setY(qreal y);
50 
51     //---------- LinkWidget Interface methods implementation from here on.
52 
53     virtual void lwSetFont (QFont font);
54     virtual UMLClassifier *operationOwner();
55 
56     virtual UMLOperation *operation();
57     virtual void setOperation(UMLOperation *op);
58 
59     virtual QString customOpText();
60     virtual void setCustomOpText(const QString &opText);
61 
62     virtual void setMessageText(FloatingTextWidget *ft);
63     virtual void setText(FloatingTextWidget *ft, const QString &newText);
64 
65     virtual QString lwOperationText();
66     virtual UMLClassifier *lwClassifier();
67     virtual void setOperationText(const QString &op);
68 
69     virtual void constrainTextPos(qreal &textX, qreal &textY, qreal textWidth, qreal textHeight,
70                                   Uml::TextRole::Enum tr);
71 
72     //---------- End LinkWidget Interface methods implementation.
73 
74     /// @return Whether the message is synchronous or asynchronous
sequenceMessageType()75     Uml::SequenceMessage::Enum sequenceMessageType() const {
76         return m_sequenceMessageType;
77     }
78 
79     bool hasObjectWidget(ObjectWidget * w);
80 
81     ObjectWidget* objectWidget(Uml::RoleType::Enum role);
82     void setObjectWidget(ObjectWidget * ow, Uml::RoleType::Enum role);
83 
84     bool isSelf() const;
85 
86     /**
87      * Returns the text widget it is related to.
88      *
89      * @return  The text widget we are related to.
90      */
floatingTextWidget()91     FloatingTextWidget * floatingTextWidget() {
92         return m_pFText;
93     }
94 
95     /**
96      * Sets the text widget it is related to.
97      *
98      * @param f The text widget we are related to.
99      */
setFloatingTextWidget(FloatingTextWidget * f)100     void setFloatingTextWidget(FloatingTextWidget * f) {
101         m_pFText = f;
102     }
103 
104     void calculateWidget();
105 
106     virtual bool activate(IDChangeLog * Log = 0);
107     void resolveObjectWidget(IDChangeLog* log);
108 
109     void calculateDimensions();
110     void calculateDimensionsSynchronous();
111     void calculateDimensionsAsynchronous();
112     void calculateDimensionsCreation();
113     void calculateDimensionsDestroy();
114     void calculateDimensionsLost();
115     void calculateDimensionsFound();
116 
117     virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
118 
119     void setTextPosition();
120 
121     void cleanup();
122 
123     void setSelected(bool _select);
124 
125     int getMinY();
126     int getMaxY();
127 
128     virtual QSizeF minimumSize() const;
129 
130     UMLWidget* onWidget(const QPointF& p);
131 
132     virtual void resizeWidget(qreal newW, qreal newH);
133 
134     virtual void saveToXMI1(QXmlStreamWriter& writer);
135     virtual bool loadFromXMI1(QDomElement & qElement);
136 
137     void setxclicked(int xclick);
138     void setyclicked(int yclick);
139 
140     /**
141      * Return the xclicked
142      */
getxclicked()143     int getxclicked() const {
144         return m_xclicked;
145     }
146 
147     virtual bool showPropertiesDialog();
148 
149 protected:
150     virtual void moveWidgetBy(qreal diffX, qreal diffY);
151     virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY);
152 
153     virtual bool isInResizeArea(QGraphicsSceneMouseEvent *me);
154 
155     void setLinkAndTextPos();
156 
157     int constrainX(int textX, int textWidth, Uml::TextRole::Enum tr);
158 
159     static void paintArrow(QPainter *p, int x, int y, int w,
160                            Qt::ArrowType direction, bool useDottedLine = false);
161     static void paintSolidArrowhead(QPainter *p, int x, int y, Qt::ArrowType direction);
162 
163     void updateResizability();
164 
165     void paintSynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option);
166     void paintAsynchronous(QPainter *painter, const QStyleOptionGraphicsItem *option);
167     void paintCreation(QPainter *painter, const QStyleOptionGraphicsItem *option);
168     void paintDestroy(QPainter *painter, const QStyleOptionGraphicsItem *option);
169     void paintLost(QPainter *painter, const QStyleOptionGraphicsItem *option);
170     void paintFound(QPainter *painter, const QStyleOptionGraphicsItem *option);
171 
172     // Data loaded/saved
173     QString m_CustomOp;
174     /**
175      * Whether the message is synchronous or asynchronous
176      */
177     Uml::SequenceMessage::Enum m_sequenceMessageType;
178 
179 private:
180     void resizeEvent(QResizeEvent *re);
181 
182     qreal constrainPositionY(qreal diffY);
183 
184     void init();
185 
186     QPointer<ObjectWidget> m_pOw[2];
187     FloatingTextWidget * m_pFText;
188 
189     int m_xclicked;
190     int m_yclicked;
191 
192     /**
193      * The following variables are used by loadFromXMI1() as an intermediate
194      * store. activate() resolves the IDs, i.e. after activate() the variables
195      * m_pOw[] and m_pFText can be used.
196      */
197     Uml::ID::Type m_widgetAId, m_widgetBId, m_textId;
198 
199 public slots:
200     void slotWidgetMoved(Uml::ID::Type id);
201     void slotMenuSelection(QAction* action);
202 
203 signals:
204     /**
205      * emitted when the message widget is moved up or down
206      * slots into ObjectWidget::slotMessageMoved()
207      */
208     void sigMessageMoved();
209 };
210 
211 #endif
212