1 /* 2 SPDX-License-Identifier: GPL-2.0-or-later 3 SPDX-FileCopyrightText: 2004-2021 Umbrello UML Modeller Authors <umbrello-devel@kde.org> 4 */ 5 6 #ifndef WIDGETBASE_H 7 #define WIDGETBASE_H 8 9 #include "basictypes.h" 10 #include "icon_utils.h" 11 12 #include <QColor> 13 #include <QDomDocument> 14 #include <QFont> 15 #include <QGraphicsObject> 16 #include <QObject> 17 #include <QPainter> 18 #include <QPointer> 19 #include <QXmlStreamWriter> 20 21 // forward declarations 22 class QAction; 23 class ActivityWidget; 24 class ActorWidget; 25 class ArtifactWidget; 26 class AssociationWidget; 27 class BoxWidget; 28 class CategoryWidget; 29 class ClassifierWidget; 30 class CombinedFragmentWidget; 31 class ComponentWidget; 32 class DatatypeWidget; 33 class EntityWidget; 34 class EnumWidget; 35 class FloatingDashLineWidget; 36 class FloatingTextWidget; 37 class ForkJoinWidget; 38 class IDChangeLog; 39 class InterfaceWidget; 40 class MessageWidget; 41 class NodeWidget; 42 class NoteWidget; 43 class ObjectNodeWidget; 44 class ObjectWidget; 45 class PackageWidget; 46 class PinWidget; 47 class PortWidget; 48 class PinPortBase; 49 class PreconditionWidget; 50 class RegionWidget; 51 class SignalWidget; 52 class StateWidget; 53 //class TextWidget; 54 class UseCaseWidget; 55 class UMLDoc; 56 class UMLObject; 57 class UMLScene; 58 class UMLWidget; // required by function onWidget() 59 60 /** 61 * Provides a wrapper that bypasses the restriction that 62 * QGraphicsItem::setSelected() is not virtual 63 * 64 * The selection management of umbrello uses a virtual method 65 * setSelected() for selection to achieve the desired behavior 66 * in the different derivation levels regarding selection and 67 * deselection. 68 * 69 * Within QGraphicsScene, QGraphicsItem::setSelected() is called 70 * to manage the selection state, e.g. with clearSelection(), but 71 * unfortunately cannot be directly overwritten by umbrello because 72 * this method is not virtual (I consider this a design flaw). 73 * 74 * Fortunately there is a workaround for the problem by using 75 * QGraphicsItem::itemChange(), which is overridden in this class 76 * and calls the (now) virtual method setSelected() when the selection 77 * state changes. This calls derived implementations of this method 78 * and realizes the desired behavior. 79 * 80 * Within setSelected() you have to take care that 81 * QGraphicsObject::setSelected() is not called if the call came 82 * from itemChange() to avoid an endless loop. 83 * 84 * @author Ralf Habacker <ralf.habacker@freenet.de> 85 */ 86 class QGraphicsObjectWrapper: public QGraphicsObject 87 { 88 public: 89 virtual void setSelected(bool state); 90 protected: 91 bool m_calledFromItemChange{false}; 92 QVariant itemChange(GraphicsItemChange change, const QVariant &value); 93 }; 94 95 /** 96 * @short Common base class for UMLWidget and AssociationWidget 97 * @author Oliver Kellogg <okellogg@users.sourceforge.net> 98 * Bugs and comments to umbrello-devel@kde.org or https://bugs.kde.org 99 */ 100 class WidgetBase : public QGraphicsObjectWrapper 101 { 102 Q_OBJECT 103 Q_ENUMS(WidgetType) 104 105 public: 106 enum WidgetType 107 { 108 wt_Min = 299, // lower bounds check value 109 wt_UMLWidget, // does not have UMLObject representation 110 wt_Actor, // has UMLObject representation 111 wt_UseCase, // has UMLObject representation 112 wt_Class, // has UMLObject representation 113 wt_Interface, // has UMLObject representation 114 wt_Datatype, // has UMLObject representation 115 wt_Enum, // has UMLObject representation 116 wt_Entity, // has UMLObject representation 117 wt_Package, // has UMLObject representation 118 wt_Object, // has UMLObject representation 119 wt_Note, // does not have UMLObject representation 120 wt_Box, // does not have UMLObject representation 121 wt_Message, // does not have UMLObject representation 122 wt_Text, // does not have UMLObject representation 123 wt_State, // does not have UMLObject representation 124 wt_Activity, // does not have UMLObject representation 125 wt_Component, // has UMLObject representation 126 wt_Artifact, // has UMLObject representation 127 wt_Node, // has UMLObject representation 128 wt_Association, // has UMLObject representation 129 wt_ForkJoin, // does not have UMLObject representation 130 wt_Precondition, // does not have UMLObject representation 131 wt_CombinedFragment, // does not have UMLObject representation 132 wt_FloatingDashLine, // does not have UMLObject representation 133 wt_Signal, // does not have UMLObject representation 134 wt_Pin, 135 wt_ObjectNode, 136 wt_Region, 137 wt_Category, // has UMLObject representation 138 wt_Port, // has UMLObject representation 139 wt_Instance, // has UMLObject representation == wt_Object 140 wt_Max // upper bounds check value 141 }; 142 143 static QString toString(WidgetType wt); 144 static QString toI18nString(WidgetType wt); 145 static Icon_Utils::IconType toIcon(WidgetType wt); 146 147 explicit WidgetBase(UMLScene * scene, WidgetType type= wt_UMLWidget, Uml::ID::Type id = Uml::ID::None); 148 virtual ~WidgetBase(); 149 150 UMLObject* umlObject() const; 151 virtual void setUMLObject(UMLObject *obj); 152 153 Uml::ID::Type id() const; 154 void setID(Uml::ID::Type id); 155 156 void setLocalID(Uml::ID::Type id); 157 Uml::ID::Type localID() const; 158 159 virtual UMLWidget *widgetWithID(Uml::ID::Type id); 160 161 WidgetType baseType() const; 162 void setBaseType(const WidgetType& baseType); 163 QLatin1String baseTypeStr() const; 164 QString baseTypeStrWithoutPrefix() const; 165 166 virtual void setSelected(bool select); 167 168 UMLScene* umlScene() const; 169 UMLDoc* umlDoc() const; 170 171 QString documentation() const; 172 bool hasDocumentation(); 173 virtual void setDocumentation(const QString& doc); 174 175 QString name() const; 176 virtual void setName(const QString &strName); 177 178 QColor lineColor() const; 179 virtual void setLineColor(const QColor& color); 180 181 uint lineWidth() const; 182 virtual void setLineWidth(uint width); 183 184 QColor textColor() const; 185 virtual void setTextColor(const QColor& color); 186 187 QColor fillColor() const; 188 virtual void setFillColor(const QColor& color); 189 190 bool usesDiagramLineColor() const; 191 void setUsesDiagramLineColor(bool state); 192 193 bool usesDiagramLineWidth() const; 194 void setUsesDiagramLineWidth(bool state); 195 196 bool useFillColor(); 197 virtual void setUseFillColor(bool state); 198 199 bool usesDiagramTextColor() const; 200 void setUsesDiagramTextColor(bool state); 201 202 bool usesDiagramFillColor() const; 203 void setUsesDiagramFillColor(bool state); 204 205 bool usesDiagramUseFillColor() const; 206 void setUsesDiagramUseFillColor(bool state); 207 208 virtual QFont font() const; 209 virtual void setFont(const QFont& font); 210 211 bool autoResize(); 212 void setAutoResize(bool state); 213 214 bool changesShape(); 215 void setChangesShape(bool state); 216 217 virtual bool showPropertiesDialog(); 218 219 virtual bool loadFromXMI1(QDomElement &qElement); 220 virtual void saveToXMI1(QXmlStreamWriter& writer); 221 222 virtual void removeAssoc(AssociationWidget* pAssoc); 223 virtual void addAssoc(AssociationWidget* pAssoc); 224 225 WidgetBase& operator=(const WidgetBase& other); 226 227 QRectF rect() const; 228 void setRect(const QRectF& rect); 229 void setRect(qreal x, qreal y, qreal width, qreal height); 230 231 virtual QRectF boundingRect() const; 232 233 virtual UMLWidget* onWidget(const QPointF &p); 234 235 virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); 236 isActivityWidget()237 bool isActivityWidget() const { return baseType() == wt_Activity; } isActorWidget()238 bool isActorWidget() const { return baseType() == wt_Actor; } isArtifactWidget()239 bool isArtifactWidget() const { return baseType() == wt_Artifact; } isAssociationWidget()240 bool isAssociationWidget() const { return baseType() == wt_Association; } isBoxWidget()241 bool isBoxWidget() const { return baseType() == wt_Box; } isCategoryWidget()242 bool isCategoryWidget() const { return baseType() == wt_Category; } isClassWidget()243 bool isClassWidget() const { return baseType() == wt_Class; } isCombinedFragmentWidget()244 bool isCombinedFragmentWidget() const { return baseType() == wt_CombinedFragment; } isComponentWidget()245 bool isComponentWidget() const { return baseType() == wt_Component; } isDatatypeWidget()246 bool isDatatypeWidget() const { return baseType() == wt_Datatype; } isEntityWidget()247 bool isEntityWidget() const { return baseType() == wt_Entity; } isEnumWidget()248 bool isEnumWidget() const { return baseType() == wt_Enum; } isFloatingDashLineWidget()249 bool isFloatingDashLineWidget() const { return baseType() == wt_FloatingDashLine; } isForkJoinWidget()250 bool isForkJoinWidget() const { return baseType() == wt_ForkJoin; } isInterfaceWidget()251 bool isInterfaceWidget() const { return baseType() == wt_Interface; } isMessageWidget()252 bool isMessageWidget() const { return baseType() == wt_Message; } isNodeWidget()253 bool isNodeWidget() const { return baseType() == wt_Node; } isNoteWidget()254 bool isNoteWidget() const { return baseType() == wt_Note; } isObjectNodeWidget()255 bool isObjectNodeWidget() const { return baseType() == wt_ObjectNode; } isObjectWidget()256 bool isObjectWidget() const { return baseType() == wt_Object; } isPackageWidget()257 bool isPackageWidget() const { return baseType() == wt_Package; } isPinWidget()258 bool isPinWidget() const { return baseType() == wt_Pin; } isPortWidget()259 bool isPortWidget() const { return baseType() == wt_Port; } isPreconditionWidget()260 bool isPreconditionWidget() const { return baseType() == wt_Precondition; } isRegionWidget()261 bool isRegionWidget() const { return baseType() == wt_Region; } isSignalWidget()262 bool isSignalWidget() const { return baseType() == wt_Signal; } isStateWidget()263 bool isStateWidget() const { return baseType() == wt_State; } isTextWidget()264 bool isTextWidget() const { return baseType() == wt_Text; } isUseCaseWidget()265 bool isUseCaseWidget() const { return baseType() == wt_UseCase; } 266 267 ActivityWidget* asActivityWidget(); 268 ActorWidget* asActorWidget(); 269 ArtifactWidget* asArtifactWidget(); 270 AssociationWidget* asAssociationWidget(); 271 BoxWidget* asBoxWidget(); 272 CategoryWidget* asCategoryWidget(); 273 ClassifierWidget* asClassifierWidget(); 274 CombinedFragmentWidget* asCombinedFragmentWidget(); 275 ComponentWidget* asComponentWidget(); 276 DatatypeWidget* asDatatypeWidget(); 277 EntityWidget* asEntityWidget(); 278 EnumWidget* asEnumWidget(); 279 FloatingDashLineWidget* asFloatingDashLineWidget(); 280 ForkJoinWidget* asForkJoinWidget(); 281 InterfaceWidget* asInterfaceWidget(); 282 MessageWidget* asMessageWidget(); 283 NodeWidget* asNodeWidget(); 284 NoteWidget* asNoteWidget(); 285 ObjectNodeWidget* asObjectNodeWidget(); 286 ObjectWidget* asObjectWidget(); 287 PackageWidget* asPackageWidget(); 288 PinWidget* asPinWidget(); 289 PinPortBase* asPinPortBase(); 290 PortWidget* asPortWidget(); 291 PreconditionWidget* asPreconditionWidget(); 292 RegionWidget* asRegionWidget(); 293 SignalWidget* asSignalWidget(); 294 StateWidget* asStateWidget(); 295 FloatingTextWidget* asFloatingTextWidget(); 296 // TextWidget* asTextWidget(); 297 UseCaseWidget* asUseCaseWidget(); 298 UMLWidget* asUMLWidget(); 299 300 static bool widgetHasUMLObject(WidgetBase::WidgetType type); 301 virtual bool activate(IDChangeLog *changeLog = 0); 302 303 public Q_SLOTS: 304 virtual void slotMenuSelection(QAction *trigger); 305 306 protected: 307 virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); 308 309 private: 310 WidgetType m_baseType; ///< Type of widget. 311 protected: 312 UMLScene *m_scene; 313 QPointer<UMLObject> m_umlObject; 314 QString m_Doc; ///< Only used if m_umlObject is not set. 315 QString m_Text; 316 QRectF m_rect; ///< widget size 317 318 /** 319 * This ID is only used when the widget does not have a 320 * corresponding UMLObject (i.e. the m_umlObject pointer is NULL.) 321 * For UMLObjects, the ID from the UMLObject is used. 322 */ 323 Uml::ID::Type m_nId; 324 325 /** 326 * This ID is only used when a widget could be added more than once to a diagram 327 */ 328 Uml::ID::Type m_nLocalID; 329 330 QColor m_textColor; ///< Color of the text of the widget. Is saved to XMI. 331 QColor m_lineColor; ///< Color of the lines of the widget. Is saved to XMI. 332 QColor m_fillColor; ///< color of the background of the widget 333 QBrush m_brush; 334 QFont m_font; 335 uint m_lineWidth; ///< Width of the lines of the widget. Is saved to XMI. 336 bool m_useFillColor; ///< flag indicates if the UMLWidget uses the Diagram FillColour 337 338 /** 339 * true by default, false if the colors have 340 * been explicitly set for this widget. 341 * These are saved to XMI. 342 */ 343 bool m_usesDiagramFillColor; 344 bool m_usesDiagramLineColor; 345 bool m_usesDiagramLineWidth; 346 bool m_usesDiagramTextColor; 347 bool m_usesDiagramUseFillColor; 348 bool m_autoResize; 349 bool m_changesShape; ///< The widget changes its shape when the number of connections or their positions are changed 350 }; 351 352 #endif 353