1 /* 2 SPDX-License-Identifier: GPL-2.0-or-later 3 SPDX-FileCopyrightText: 2002-2021 Umbrello UML Modeller Authors <umbrello-devel@kde.org> 4 */ 5 6 #ifndef UMLWIDGET_H 7 #define UMLWIDGET_H 8 9 #include "associationwidgetlist.h" 10 #include "basictypes.h" 11 #include "optionstate.h" 12 #include "umlobject.h" 13 #include "umlwidgetlist.h" 14 #include "widgetbase.h" 15 #include "diagramproxywidget.h" 16 17 #include <QCursor> 18 #include <QFont> 19 20 class IDChangeLog; 21 class UMLDoc; 22 class UMLObject; 23 class UMLScene; 24 25 class QPainter; 26 class QFontMetrics; 27 28 /** 29 * This is the base class for nearly all graphical widgets. 30 * 31 * @short The base class for graphical UML objects. 32 * @author Paul Hensgen <phensgen@techie.com> 33 * Bugs and comments to umbrello-devel@kde.org or https://bugs.kde.org 34 */ 35 class UMLWidget : public WidgetBase, public DiagramProxyWidget 36 { 37 Q_OBJECT 38 public: 39 40 friend class ToolBarStateArrow; // for calling the mouse*Event handlers 41 42 static const QSizeF DefaultMinimumSize; 43 static const QSizeF DefaultMaximumSize; 44 static const int defaultMargin; 45 static const int selectionMarkerSize; 46 static const int resizeMarkerLineCount; 47 48 explicit UMLWidget(UMLScene *scene, WidgetType type = wt_UMLWidget, UMLObject *o = 0); 49 explicit UMLWidget(UMLScene *scene, WidgetType type = wt_UMLWidget, Uml::ID::Type id = Uml::ID::None); 50 virtual ~UMLWidget(); 51 52 // Copy constructor - not implemented. 53 // UMLWidget(const UMLWidget& other); 54 55 UMLWidget& operator=(const UMLWidget& other); 56 57 bool operator==(const UMLWidget& other) const; 58 59 virtual QSizeF minimumSize() const; 60 void setMinimumSize(const QSizeF &size); 61 62 virtual QSizeF maximumSize(); 63 void setMaximumSize(const QSizeF &size); 64 65 virtual void setUseFillColor(bool fc); 66 void setUseFillColorCmd(bool fc); 67 68 virtual void setTextColor(const QColor &color); 69 void setTextColorCmd(const QColor &color); 70 71 virtual void setLineColor(const QColor &color); 72 virtual void setLineColorCmd(const QColor &color); 73 74 virtual void setLineWidth(uint width); 75 void setLineWidthCmd(uint width); 76 77 virtual void setFillColor(const QColor &color); 78 void setFillColorCmd(const QColor &color); 79 80 void setSelectedFlag(bool _select); 81 virtual void setSelected(bool _select); 82 83 void setScene(UMLScene *scene); 84 85 virtual bool activate(IDChangeLog* changeLog = 0); 86 87 void setPenFromSettings(QPainter &p); 88 void setPenFromSettings(QPainter *p); 89 90 virtual void setFont(const QFont &font); 91 void setFontCmd(const QFont &font); 92 93 /** 94 * Returns whether we triggered the update of position movement. 95 * If so, you probably don't want to move it. 96 * 97 * @return The moving state. 98 */ getStartMove()99 bool getStartMove() const { 100 return m_startMove; 101 } 102 103 virtual qreal getX() const; 104 virtual qreal getY() const; 105 virtual QPointF getPos() const; 106 virtual void setX(qreal x); 107 virtual void setY(qreal y); 108 109 /** 110 * Returns the height of widget. 111 */ height()112 qreal height() const { 113 return rect().height(); 114 } 115 116 /** 117 * Returns the width of the widget. 118 */ width()119 qreal width() const { 120 return rect().width(); 121 } 122 123 void setSize(qreal width, qreal height); 124 void setSize(const QSizeF& size); 125 126 virtual void resizeWidget(qreal newW, qreal newH); 127 virtual void notifyParentResize(); 128 129 bool getIgnoreSnapToGrid() const; 130 void setIgnoreSnapToGrid(bool to); 131 132 void moveByLocal(qreal dx, qreal dy); 133 134 virtual void removeAssoc(AssociationWidget* pAssoc); 135 virtual void addAssoc(AssociationWidget* pAssoc); 136 137 AssociationWidgetList &associationWidgetList() const; 138 139 /** 140 * Read property of bool m_isInstance 141 */ isInstance()142 bool isInstance() const { 143 return m_isInstance; 144 } 145 146 /** 147 * Write property of bool m_isInstance 148 */ setIsInstance(bool isInstance)149 void setIsInstance(bool isInstance) { 150 m_isInstance = isInstance; 151 } 152 153 /** 154 * Write property of m_instanceName 155 */ setInstanceName(const QString & instanceName)156 void setInstanceName(const QString &instanceName) { 157 m_instanceName = instanceName; 158 } 159 160 /** 161 * Read property of m_instanceName 162 */ instanceName()163 QString instanceName() const { 164 return m_instanceName; 165 } 166 167 Uml::ShowStereoType::Enum showStereotype() const; 168 virtual void setShowStereotype(Uml::ShowStereoType::Enum flag); 169 QString tags() const; 170 171 virtual bool showPropertiesDialog(); 172 173 virtual void adjustAssocs(qreal dx, qreal dy); 174 virtual void adjustUnselectedAssocs(qreal dx, qreal dy); 175 176 bool isActivated() const; 177 void setActivated(bool active = true); 178 179 virtual void cleanup(); 180 181 void updateGeometry(bool withAssocs = true); 182 183 void clipSize(); 184 185 void forceUpdateFontMetrics(QPainter *painter); 186 void forceUpdateFontMetrics(QFont &font, QPainter *painter); 187 188 virtual bool loadFromXMI1(QDomElement &qElement); 189 virtual void saveToXMI1(QXmlStreamWriter& writer); 190 191 QPointF startMovePosition() const; 192 void setStartMovePosition(const QPointF &position); 193 194 QSizeF startResizeSize() const; 195 196 virtual QSizeF calculateSize(bool withExtensions = true) const; 197 void resize(); 198 fixedAspectRatio()199 bool fixedAspectRatio() const { 200 return m_fixedAspectRatio; 201 } 202 setFixedAspectRatio(bool state)203 void setFixedAspectRatio(bool state) { 204 m_fixedAspectRatio = state; 205 } 206 resizable()207 bool resizable() const { 208 return m_resizable; 209 } 210 setResizable(bool state)211 void setResizable(bool state) { 212 m_resizable = state; 213 } 214 215 typedef enum { 216 FT_NORMAL = 0, 217 FT_BOLD = 1, 218 FT_ITALIC = 2, 219 FT_UNDERLINE = 3, 220 FT_BOLD_ITALIC = 4, 221 FT_BOLD_UNDERLINE = 5, 222 FT_ITALIC_UNDERLINE = 6, 223 FT_BOLD_ITALIC_UNDERLINE = 7, 224 FT_INVALID = 8 225 } FontType; 226 227 virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType); 228 virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType, QPainter &painter); 229 230 QFontMetrics &getFontMetrics(UMLWidget::FontType fontType) const; 231 void setFontMetrics(UMLWidget::FontType fontType, QFontMetrics fm); 232 void setupFontType(QFont &font, UMLWidget::FontType fontType); 233 234 virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); 235 236 public Q_SLOTS: 237 virtual void updateWidget(); 238 virtual void slotMenuSelection(QAction* action); 239 virtual void slotWidgetMoved(Uml::ID::Type id); 240 virtual void slotFillColorChanged(Uml::ID::Type viewID); 241 virtual void slotLineColorChanged(Uml::ID::Type viewID); 242 virtual void slotTextColorChanged(Uml::ID::Type viewID); 243 virtual void slotLineWidthChanged(Uml::ID::Type viewID); 244 245 void slotSnapToGrid(); 246 247 signals: 248 /** 249 * Emit when the widget moves its' position. 250 * @param id The id of the object behind the widget. 251 */ 252 void sigWidgetMoved(Uml::ID::Type id); 253 254 protected: 255 virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); 256 virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); 257 virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); 258 virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); 259 virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); 260 261 virtual void moveEvent(QGraphicsSceneMouseEvent *event); 262 virtual void moveWidgetBy(qreal diffX, qreal diffY); 263 virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY); 264 virtual void constrain(qreal& width, qreal& height); 265 266 virtual bool isInResizeArea(QGraphicsSceneMouseEvent *me); 267 virtual QCursor resizeCursor() const; 268 269 void selectSingle(QGraphicsSceneMouseEvent *me); 270 void selectMultiple(QGraphicsSceneMouseEvent *me); 271 void deselect(QGraphicsSceneMouseEvent *me); 272 // void resetSelection(); 273 274 void setSelectionBounds(); 275 276 void resize(QGraphicsSceneMouseEvent *me); 277 278 bool wasSizeChanged(); 279 bool wasPositionChanged(); 280 281 virtual void toForeground(); 282 283 public: 284 enum AddWidgetOption { NoOption = 0, SetupSize = 1, SwitchDirection = 2, ShowProperties = 4, Default = SetupSize | ShowProperties }; 285 Q_DECLARE_FLAGS(AddWidgetOptions, AddWidgetOption) 286 287 protected: 288 void addConnectedWidget(UMLWidget *widget, Uml::AssociationType::Enum type = Uml::AssociationType::Association, AddWidgetOptions options = Default); 289 void addConnectedUMLObject(UMLObject::ObjectType otype, Uml::AssociationType::Enum type); 290 void addWidget(UMLWidget *widget, bool showProperties = true); 291 292 ///////////////// Data Loaded/Saved ///////////////////////////////// 293 294 QString m_instanceName; ///< instance name (used if on a deployment diagram) 295 bool m_isInstance; ///< holds whether this widget is a component instance (i.e. on a deployment diagram) 296 Uml::ShowStereoType::Enum m_showStereotype; ///< if and how the stereotype should be displayed 297 298 ///////////////// End of Data Loaded/Saved ////////////////////////// 299 300 bool m_startMove; 301 QPointF m_startMovePostion; 302 QSizeF m_startResizeSize; 303 int m_nPosX; 304 UMLDoc *m_doc; ///< shortcut for UMLApp::app()->document() 305 bool m_resizable; 306 QFontMetrics *m_pFontMetrics[FT_INVALID]; 307 QSizeF m_minimumSize; 308 QSizeF m_maximumSize; 309 310 /// true if the activate function has been called for this class instance 311 bool m_activated; 312 313 /** 314 * Change Widget Behaviour 315 */ 316 bool m_ignoreSnapToGrid; 317 bool m_ignoreSnapComponentSizeToGrid; 318 bool m_fixedAspectRatio; 319 320 /// The text in the status bar when the cursor was pressed. 321 QString m_oldStatusBarMsg; 322 323 /// The X/Y offset from the position of the cursor when it was pressed to the 324 /// upper left corner of the widget. 325 QPointF m_pressOffset; 326 327 /// The X/Y position the widget had when the movement started. 328 QPointF m_oldPos; 329 330 /// The width/height the widget had when the resize started. 331 qreal m_oldW, m_oldH; 332 333 /// If shift or control button were pressed in mouse press event. 334 bool m_shiftPressed; 335 336 /** 337 * If cursor was in move/resize area when left button was pressed (and no 338 * other widgets were selected). 339 */ 340 bool m_inMoveArea, m_inResizeArea; 341 342 /** 343 * If the widget was selected/moved/resized in the press and release cycle. 344 * Moved/resized is true if the widget was moved/resized even if the final 345 * position/size is the same as the starting one. 346 */ 347 bool m_moved, m_resized; 348 349 private: 350 void init(); 351 352 /// A list of AssociationWidgets between the UMLWidget and other UMLWidgets in the diagram 353 mutable AssociationWidgetList m_Assocs; 354 }; 355 Q_DECLARE_OPERATORS_FOR_FLAGS(UMLWidget::AddWidgetOptions) 356 #endif 357