diff --git a/umbrello/umlwidgets/statewidget.cpp b/umbrello/umlwidgets/statewidget.cpp index d3de60df0..59f2b2d83 100644 --- a/umbrello/umlwidgets/statewidget.cpp +++ b/umbrello/umlwidgets/statewidget.cpp @@ -1,663 +1,666 @@ /*************************************************************************** * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * copyright (C) 2002-2014 * * Umbrello UML Modeller Authors * ***************************************************************************/ // own header #include "statewidget.h" // app includes #include "cmds/cmdcreatediagram.h" #include "debug_utils.h" #include "dialog_utils.h" #include "docwindow.h" #include "listpopupmenu.h" #include "statedialog.h" #include "uml.h" #include "umldoc.h" #include "umlscene.h" #include "umlview.h" #include "umlwidget.h" // kde includes #include // qt includes #include #include /** * Creates a State widget. * * @param scene The parent of the widget. * @param stateType The type of state. * @param id The ID to assign (-1 will prompt a new ID.) */ StateWidget::StateWidget(UMLScene * scene, StateType stateType, Uml::ID::Type id) : UMLWidget(scene, WidgetBase::wt_State, id) { - m_stateType = stateType; + setStateType(stateType); m_drawVertical = true; - setAspectRatioMode(); m_Text = QLatin1String("State"); QSizeF size = minimumSize(); setSize(size.width(), size.height()); } /** * Destructor. */ StateWidget::~StateWidget() { } /** * Overrides the standard paint event. */ void StateWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); const qreal w = width(); const qreal h = height(); if (w == 0 || h == 0) return; setPenFromSettings(painter); switch (m_stateType) { case StateWidget::Normal: { if (UMLWidget::useFillColor()) { painter->setBrush(UMLWidget::fillColor()); } const QFontMetrics &fm = getFontMetrics(FT_NORMAL); const int fontHeight = fm.lineSpacing(); int textStartY = (h / 2) - (fontHeight / 2); const int count = m_Activities.count(); if (count == 0) { painter->drawRoundRect(0, 0, w, h, (h*40)/w, (w*40)/h); painter->setPen(textColor()); QFont font = UMLWidget::font(); font.setBold(false); painter->setFont(font); painter->drawText(STATE_MARGIN, textStartY, w - STATE_MARGIN * 2, fontHeight, Qt::AlignCenter, name()); setPenFromSettings(painter); } else { painter->drawRoundRect(0, 0, w, h, (h*40)/w, (w*40)/h); textStartY = STATE_MARGIN; painter->setPen(textColor()); QFont font = UMLWidget::font(); font.setBold(true); painter->setFont(font); painter->drawText(STATE_MARGIN, textStartY, w - STATE_MARGIN * 2, fontHeight, Qt::AlignCenter, name()); font.setBold(false); painter->setFont(font); setPenFromSettings(painter); int linePosY = textStartY + fontHeight; QStringList::Iterator end(m_Activities.end()); for(QStringList::Iterator it(m_Activities.begin()); it != end; ++it) { textStartY += fontHeight; painter->drawLine(0, linePosY, w, linePosY); painter->setPen(textColor()); painter->drawText(STATE_MARGIN, textStartY, w - STATE_MARGIN * 2, fontHeight, Qt::AlignCenter, *it); setPenFromSettings(painter); linePosY += fontHeight; }//end for }//end else } break; case StateWidget::Initial : painter->setBrush(WidgetBase::lineColor()); painter->drawEllipse(0, 0, w, h); break; case StateWidget::End : painter->setBrush(WidgetBase::lineColor()); painter->drawEllipse(0, 0, w, h); painter->setBrush(Qt::white); painter->drawEllipse(1, 1, w - 2, h - 2); painter->setBrush(WidgetBase::lineColor()); painter->drawEllipse(3, 3, w - 6, h - 6); break; case StateWidget::Fork: case StateWidget::Join: { painter->setPen(Qt::black); painter->setBrush(Qt::black); painter->drawRect(rect()); } break; case StateWidget::Junction: { painter->setPen(Qt::black); painter->setBrush(Qt::black); painter->drawEllipse(rect()); } break; case StateWidget::DeepHistory: { painter->setBrush(Qt::white); painter->drawEllipse(rect()); painter->setPen(Qt::black); painter->setFont(UMLWidget::font()); const QFontMetrics &fm = getFontMetrics(FT_NORMAL); const int fontHeight = fm.lineSpacing() / 2; const int xStar = fm.boundingRect(QLatin1String("H")).width(); const int yStar = fontHeight / 4; painter->drawText((w / 6), (h / 4) + fontHeight, QLatin1String("H")); painter->drawText((w / 6) + xStar, (h / 4) + fontHeight - yStar, QLatin1String("*")); } break; case StateWidget::ShallowHistory: { painter->setBrush(Qt::white); painter->drawEllipse(rect()); painter->setPen(Qt::black); painter->setFont(UMLWidget::font()); const QFontMetrics &fm = getFontMetrics(FT_NORMAL); const int fontHeight = fm.lineSpacing() / 2; painter->drawText((w / 6), (h / 4) + fontHeight, QLatin1String("H")); } break; case StateWidget::Choice: { const qreal x = w / 2; const qreal y = h / 2; QPolygonF polygon; polygon << QPointF(x, 0) << QPointF(w, y) << QPointF(x, h) << QPointF(0, y); painter->setBrush(UMLWidget::fillColor()); painter->drawPolygon(polygon); } break; case StateWidget::Combined: { const QFontMetrics &fm = getFontMetrics(FT_NORMAL); const int fontHeight = fm.lineSpacing(); painter->drawRoundedRect(rect(), STATE_MARGIN, STATE_MARGIN ); painter->drawLine(QPointF(0, fontHeight), QPointF(w, fontHeight)); painter->setPen(textColor()); QFont font = UMLWidget::font(); font.setBold(false); painter->setFont(font); painter->drawText(STATE_MARGIN, 0, w - STATE_MARGIN * 2, fontHeight, Qt::AlignCenter, name()); if (!m_linkedDiagram) { m_size = QSizeF(fm.width(name()) + STATE_MARGIN * 2, fm.lineSpacing() + STATE_MARGIN); } else { m_sceneRect = m_linkedDiagram->sceneRect(); m_clientRect = rect().adjusted(STATE_MARGIN, fontHeight + STATE_MARGIN, - STATE_MARGIN, -STATE_MARGIN); if (Tracer::instance()->isEnabled(QLatin1String(metaObject()->className()))) { painter->setPen(Qt::magenta); painter->drawRect(m_clientRect); } m_linkedDiagram->render(painter, m_clientRect); m_size = QSizeF(qMax(fm.width(m_linkedDiagram->name()), m_sceneRect.width()) + STATE_MARGIN * 2, fm.lineSpacing() + STATE_MARGIN + m_sceneRect.height()); setSize(m_size); } setPenFromSettings(painter); } break; default: uWarning() << "Unknown state type: " << stateTypeStr(); break; } UMLWidget::paint(painter, option, widget); } /** * Overrides method from UMLWidget */ QSizeF StateWidget::minimumSize() const { int width = 10, height = 10; switch (m_stateType) { case StateWidget::Normal: { const QFontMetrics &fm = getFontMetrics(FT_BOLD); const int fontHeight = fm.lineSpacing(); int textWidth = fm.width(name()); const int count = m_Activities.count(); height = fontHeight; if(count > 0) { height = fontHeight * (count + 1); QStringList::ConstIterator end(m_Activities.end()); for(QStringList::ConstIterator it(m_Activities.begin()); it != end; ++it) { int w = fm.width(*it); if(w > textWidth) textWidth = w; }//end for }//end if width = textWidth > STATE_WIDTH?textWidth:STATE_WIDTH; height = height > STATE_HEIGHT?height:STATE_HEIGHT; width += STATE_MARGIN * 2; height += STATE_MARGIN * 2; break; } case StateWidget::Fork: case StateWidget::Join: if (m_drawVertical) { width = 8; height = 60; } else { width = 60; height = 8; } break; case StateWidget::Junction: width = 18; height = 18; break; case StateWidget::DeepHistory: case StateWidget::ShallowHistory: { const QFontMetrics &fm = getFontMetrics(FT_NORMAL); width = height = fm.lineSpacing(); } break; case StateWidget::Choice: width = 25; height = 25; break; case StateWidget::Combined: return m_size; default: break; } return QSizeF(width, height); } /** * Overrides method from UMLWidget */ QSizeF StateWidget::maximumSize() { switch (m_stateType) { case StateWidget::Initial: case StateWidget::End: case StateWidget::Junction: case StateWidget::Choice: return QSizeF(35, 35); break; case StateWidget::DeepHistory: case StateWidget::ShallowHistory: { const QFontMetrics &fm = getFontMetrics(FT_NORMAL); const int fontHeight = fm.lineSpacing(); return QSizeF(fontHeight + 10, fontHeight + 10); } break; case StateWidget::Combined: return m_size; default: break; } return UMLWidget::maximumSize(); } /** * Set the aspect ratio mode. * Some state types have a fixed aspect ratio */ void StateWidget::setAspectRatioMode() { switch (m_stateType) { case StateWidget::Initial: case StateWidget::End: case StateWidget::Choice: case StateWidget::DeepHistory: case StateWidget::ShallowHistory: case StateWidget::Fork: case StateWidget::Join: case StateWidget::Junction: setFixedAspectRatio(true); break; default: setFixedAspectRatio(false); break; } } /** * Setup synthetizied graphics scene event * * @param e event to setup * @param event event source * @param pos position in item coordinates */ void StateWidget::setupEvent(QGraphicsSceneMouseEvent &e, QGraphicsSceneMouseEvent *event, const QPointF & pos) { QPointF p1 = pos - m_clientRect.topLeft(); qreal scaleW = m_sceneRect.width() / (m_clientRect.width() - STATE_MARGIN); qreal scaleH = m_sceneRect.height() / m_clientRect.height(); QPointF p2 = QPointF(p1.x() * scaleW, p1.y() * scaleH); QPointF p3 = p2 + m_sceneRect.topLeft(); e.setScenePos(p3); e.setPos(e.scenePos()); QPointF lastPos = mapFromScene(event->lastScenePos()); QPointF lp1 = lastPos - m_clientRect.topLeft(); QPointF lp2 = QPointF(lp1.x() * scaleW, lp1.y() * scaleH); QPointF lp3 = lp2 + m_sceneRect.topLeft(); e.setLastScenePos(lp3); e.setModifiers(event->modifiers()); e.setButtons(event->buttons()); e.setButton(event->button()); } void StateWidget::mousePressEvent(QGraphicsSceneMouseEvent *event) { QPointF pos = mapFromScene(event->scenePos()); if (m_stateType == Combined && m_linkedDiagram && m_clientRect.contains(pos)) { QGraphicsSceneMouseEvent e(event->type()); setupEvent(e, event, pos); m_linkedDiagram->mousePressEvent(&e); update(); } else UMLWidget::mousePressEvent(event); } void StateWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QPointF pos = mapFromScene(event->scenePos()); if (m_stateType == Combined && m_linkedDiagram && m_clientRect.contains(pos)) { QGraphicsSceneMouseEvent e(event->type()); setupEvent(e, event, pos); m_linkedDiagram->mouseMoveEvent(&e); update(); } else UMLWidget::mouseMoveEvent(event); } void StateWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { QPointF pos = mapFromScene(event->scenePos()); if (m_stateType == Combined && m_linkedDiagram && m_clientRect.contains(pos)) { QGraphicsSceneMouseEvent e(event->type()); setupEvent(e, event, pos); m_linkedDiagram->mouseReleaseEvent(&e); update(); } else UMLWidget::mouseReleaseEvent(event); } /** * Returns the type of state. * @return StateType */ StateWidget::StateType StateWidget::stateType() const { return m_stateType; } /** * Returns the type string of state. */ QString StateWidget::stateTypeStr() const { return QLatin1String(ENUM_NAME(StateWidget, StateType, m_stateType)); } /** * Sets the type of state. */ void StateWidget::setStateType(StateType stateType) { m_stateType = stateType; setAspectRatioMode(); + if (stateType == Combined) { + setAutoResize(false); + setResizable(false); + } } /** * Adds an activity to this widget. * @return true on success */ bool StateWidget::addActivity(const QString &activity) { m_Activities.append(activity); updateGeometry(); return true; } /** * Removes the given activity from the state. */ bool StateWidget::removeActivity(const QString &activity) { if(m_Activities.removeAll(activity) == 0) return false; updateGeometry(); return true; } /** * Renames the given activity. */ bool StateWidget::renameActivity(const QString &activity, const QString &newName) { int index = - 1; if((index = m_Activities.indexOf(activity)) == -1) return false; m_Activities[ index ] = newName; return true; } /** * Sets the states activities to the ones given. */ void StateWidget::setActivities(const QStringList &list) { m_Activities = list; updateGeometry(); } /** * Returns the list of activities. */ QStringList StateWidget::activities() const { return m_Activities; } /** * Get whether to draw a fork or join vertically. */ bool StateWidget::drawVertical() const { return m_drawVertical; } /** * Set whether to draw a fork or join vertically. */ void StateWidget::setDrawVertical(bool to) { m_drawVertical = to; setSize(height(), width()); updateGeometry(); UMLWidget::adjustAssocs(x(), y()); } /** * Show a properties dialog for a StateWidget. */ bool StateWidget::showPropertiesDialog() { bool result = false; UMLApp::app()->docWindow()->updateDocumentation(false); QPointer dialog = new StateDialog(m_scene->activeView(), this); if (dialog->exec() && dialog->getChangesMade()) { UMLApp::app()->docWindow()->showDocumentation(this, true); UMLApp::app()->document()->setModified(true); result = true; } delete dialog; return result; } Uml::ID::Type StateWidget::diagramLink() { return m_diagramLinkId; } bool StateWidget::setDiagramLink(const Uml::ID::Type &id) { UMLView *view = m_doc->findView(id); if (view) { m_diagramLinkId = id; m_linkedDiagram = view->umlScene(); } return view; } /** * Creates the "statewidget" XMI element. */ void StateWidget::saveToXMI1(QDomDocument & qDoc, QDomElement & qElement) { QDomElement stateElement = qDoc.createElement(QLatin1String("statewidget")); UMLWidget::saveToXMI1(qDoc, stateElement); stateElement.setAttribute(QLatin1String("statename"), m_Text); stateElement.setAttribute(QLatin1String("documentation"), m_Doc); stateElement.setAttribute(QLatin1String("statetype"), m_stateType); if (m_stateType == Fork || m_stateType == Join) stateElement.setAttribute(QLatin1String("drawvertical"), m_drawVertical); if (m_stateType == Combined) stateElement.setAttribute(QLatin1String("diagramlinkid"), Uml::ID::toString(m_diagramLinkId)); //save states activities QDomElement activitiesElement = qDoc.createElement(QLatin1String("Activities")); QStringList::Iterator end(m_Activities.end()); for(QStringList::Iterator it(m_Activities.begin()); it != end; ++it) { QDomElement tempElement = qDoc.createElement(QLatin1String("Activity")); tempElement.setAttribute(QLatin1String("name"), *it); activitiesElement.appendChild(tempElement); }//end for stateElement.appendChild(activitiesElement); qElement.appendChild(stateElement); } bool StateWidget::activate(IDChangeLog *changeLog) { if (stateType() == Combined) setDiagramLink(m_diagramLinkId); return UMLWidget::activate(changeLog); } /** * Loads a "statewidget" XMI element. */ bool StateWidget::loadFromXMI1(QDomElement & qElement) { if(!UMLWidget::loadFromXMI1(qElement)) return false; m_Text = qElement.attribute(QLatin1String("statename")); m_Doc = qElement.attribute(QLatin1String("documentation")); QString type = qElement.attribute(QLatin1String("statetype"), QLatin1String("1")); - m_stateType = (StateType)type.toInt(); + setStateType((StateType)type.toInt()); if (m_stateType == Combined) { QString linkID = qElement.attribute(QLatin1String("diagramlinkid")); m_diagramLinkId = Uml::ID::fromString(linkID); } setAspectRatioMode(); QString drawVertical = qElement.attribute(QLatin1String("drawvertical"), QLatin1String("1")); m_drawVertical = (bool)drawVertical.toInt(); //load states activities QDomNode node = qElement.firstChild(); QDomElement tempElement = node.toElement(); if(!tempElement.isNull() && tempElement.tagName() == QLatin1String("Activities")) { QDomNode node = tempElement.firstChild(); QDomElement activityElement = node.toElement(); while(!activityElement.isNull()) { if(activityElement.tagName() == QLatin1String("Activity")) { QString name = activityElement.attribute(QLatin1String("name")); if(!name.isEmpty()) m_Activities.append(name); }//end if node = node.nextSibling(); activityElement = node.toElement(); }//end while }//end if return true; } /** * Captures any popup menu signals for menus it created. */ void StateWidget::slotMenuSelection(QAction* action) { bool ok = false; QString nameNew = name(); ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action); switch(sel) { case ListPopupMenu::mt_Rename: nameNew = name(); ok = Dialog_Utils::askNewName(WidgetBase::WidgetType::wt_State, nameNew); if (ok && nameNew.length() > 0) { setName(nameNew); } break; case ListPopupMenu::mt_Properties: showPropertiesDialog(); break; case ListPopupMenu::mt_New_Activity: nameNew = i18n("new activity"); ok = Dialog_Utils::askName(i18n("Enter Activity"), i18n("Enter the name of the new activity:"), nameNew); if (ok && nameNew.length() > 0) { addActivity(nameNew); } break; case ListPopupMenu::mt_FlipHorizontal: setDrawVertical(false); break; case ListPopupMenu::mt_FlipVertical: setDrawVertical(true); break; case ListPopupMenu::mt_CombinedState: { QString diagramName = m_doc->createDiagramName(Uml::DiagramType::State); Uml::CmdCreateDiagram* d = new Uml::CmdCreateDiagram(m_doc, Uml::DiagramType::State, diagramName); UMLApp::app()->executeCommand(d); m_diagramLinkId = d->view()->umlScene()->ID(); setStateType(Combined); } break; case ListPopupMenu::mt_EditCombinedState: if (!m_linkedDiagram) { uError() << "no diagram id defined at widget '" << Uml::ID::toString(id()) << "'"; break; } m_linkedDiagram->setWidgetLink(this); UMLApp::app()->document()->changeCurrentView(m_diagramLinkId); break; default: UMLWidget::slotMenuSelection(action); break; } } diff --git a/umbrello/umlwidgets/umlwidget.h b/umbrello/umlwidgets/umlwidget.h index 96ec367ff..cd5a0511c 100644 --- a/umbrello/umlwidgets/umlwidget.h +++ b/umbrello/umlwidgets/umlwidget.h @@ -1,356 +1,364 @@ /*************************************************************************** * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * copyright (C) 2002-2014 * * Umbrello UML Modeller Authors * ***************************************************************************/ #ifndef UMLWIDGET_H #define UMLWIDGET_H #include "associationwidgetlist.h" #include "basictypes.h" #include "optionstate.h" #include "umlobject.h" #include "umlwidgetlist.h" #include "widgetbase.h" #include #include class IDChangeLog; class UMLDoc; class UMLObject; class UMLScene; class QPainter; class QFontMetrics; /** * This is the base class for nearly all graphical widgets. * * @short The base class for graphical UML objects. * @author Paul Hensgen * Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org */ class UMLWidget : public WidgetBase { Q_OBJECT public: friend class ToolBarStateArrow; // for calling the mouse*Event handlers static const QSizeF DefaultMinimumSize; static const QSizeF DefaultMaximumSize; static const int defaultMargin; static const int selectionMarkerSize; static const int resizeMarkerLineCount; explicit UMLWidget(UMLScene *scene, WidgetType type = wt_UMLWidget, UMLObject *o = 0); explicit UMLWidget(UMLScene *scene, WidgetType type = wt_UMLWidget, Uml::ID::Type id = Uml::ID::None); virtual ~UMLWidget(); // Copy constructor - not implemented. // UMLWidget(const UMLWidget& other); UMLWidget& operator=(const UMLWidget& other); bool operator==(const UMLWidget& other) const; void setLocalID(Uml::ID::Type id); Uml::ID::Type localID() const; virtual UMLWidget* widgetWithID(Uml::ID::Type id); virtual QSizeF minimumSize() const; void setMinimumSize(const QSizeF &size); virtual QSizeF maximumSize(); void setMaximumSize(const QSizeF &size); virtual void setUseFillColor(bool fc); void setUseFillColorCmd(bool fc); virtual void setTextColor(const QColor &color); void setTextColorCmd(const QColor &color); virtual void setLineColor(const QColor &color); virtual void setLineColorCmd(const QColor &color); virtual void setLineWidth(uint width); void setLineWidthCmd(uint width); virtual void setFillColor(const QColor &color); void setFillColorCmd(const QColor &color); void setSelectedFlag(bool _select); virtual void setSelected(bool _select); void setScene(UMLScene *scene); virtual bool activate(IDChangeLog* ChangeLog = 0); void setPenFromSettings(QPainter &p); void setPenFromSettings(QPainter *p); virtual void setFont(const QFont &font); void setFontCmd(const QFont &font); /** * Returns whether we triggered the update of position movement. * If so, you probably don't want to move it. * * @return The moving state. */ bool getStartMove() const { return m_startMove; } virtual void setX(qreal x); virtual void setY(qreal y); /** * Returns the height of widget. */ qreal height() const { return rect().height(); } /** * Returns the width of the widget. */ qreal width() const { return rect().width(); } void setSize(qreal width, qreal height); void setSize(const QSizeF& size); virtual void resizeWidget(qreal newW, qreal newH); virtual void notifyParentResize(); bool getIgnoreSnapToGrid() const; void setIgnoreSnapToGrid(bool to); void moveByLocal(qreal dx, qreal dy); void removeAssoc(AssociationWidget* pAssoc); void addAssoc(AssociationWidget* pAssoc); AssociationWidgetList &associationWidgetList() const; /** * Read property of bool m_isInstance */ bool isInstance() const { return m_isInstance; } /** * Write property of bool m_isInstance */ void setIsInstance(bool isInstance) { m_isInstance = isInstance; } /** * Write property of m_instanceName */ void setInstanceName(const QString &instanceName) { m_instanceName = instanceName; } /** * Read property of m_instanceName */ QString instanceName() const { return m_instanceName; } bool showStereotype() const; virtual void setShowStereotype(bool flag); virtual bool showPropertiesDialog(); virtual void adjustAssocs(qreal dx, qreal dy); virtual void adjustUnselectedAssocs(qreal dx, qreal dy); bool isActivated() const; void setActivated(bool active = true); virtual void cleanup(); static bool widgetHasUMLObject(WidgetBase::WidgetType type); void updateGeometry(bool withAssocs = true); void clipSize(); void forceUpdateFontMetrics(QPainter *painter); void forceUpdateFontMetrics(QFont &font, QPainter *painter); virtual bool loadFromXMI1(QDomElement &qElement); virtual void saveToXMI1(QDomDocument &qDoc, QDomElement &qElement); QPointF startMovePosition() const; void setStartMovePosition(const QPointF &position); QSizeF startResizeSize() const; virtual QSizeF calculateSize(bool withExtensions = true) const; void resize(); bool fixedAspectRatio() const { return m_fixedAspectRatio; } void setFixedAspectRatio(bool state) { m_fixedAspectRatio = state; } + bool resizable() const { + return m_resizable; + } + + void setResizable(bool state) { + m_resizable = state; + } + typedef enum { FT_NORMAL = 0, FT_BOLD = 1, FT_ITALIC = 2, FT_UNDERLINE = 3, FT_BOLD_ITALIC = 4, FT_BOLD_UNDERLINE = 5, FT_ITALIC_UNDERLINE = 6, FT_BOLD_ITALIC_UNDERLINE = 7, FT_INVALID = 8 } FontType; virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType); virtual void setDefaultFontMetrics(QFont &font, UMLWidget::FontType fontType, QPainter &painter); QFontMetrics &getFontMetrics(UMLWidget::FontType fontType) const; void setFontMetrics(UMLWidget::FontType fontType, QFontMetrics fm); void setupFontType(QFont &font, UMLWidget::FontType fontType); virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); public Q_SLOTS: virtual void updateWidget(); virtual void slotMenuSelection(QAction* action); virtual void slotWidgetMoved(Uml::ID::Type id); virtual void slotFillColorChanged(Uml::ID::Type viewID); virtual void slotLineColorChanged(Uml::ID::Type viewID); virtual void slotTextColorChanged(Uml::ID::Type viewID); virtual void slotLineWidthChanged(Uml::ID::Type viewID); void slotSnapToGrid(); signals: /** * Emit when the widget moves its' position. * @param id The id of the object behind the widget. */ void sigWidgetMoved(Uml::ID::Type id); protected: virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); virtual void moveEvent(QGraphicsSceneMouseEvent *event); virtual void moveWidgetBy(qreal diffX, qreal diffY); virtual void constrainMovementForAllWidgets(qreal &diffX, qreal &diffY); virtual void constrain(qreal& width, qreal& height); virtual bool isInResizeArea(QGraphicsSceneMouseEvent *me); virtual QCursor resizeCursor() const; void selectSingle(QGraphicsSceneMouseEvent *me); void selectMultiple(QGraphicsSceneMouseEvent *me); void deselect(QGraphicsSceneMouseEvent *me); // void resetSelection(); void setSelectionBounds(); void resize(QGraphicsSceneMouseEvent *me); bool wasSizeChanged(); bool wasPositionChanged(); virtual void toForeground(); public: enum AddWidgetOption { NoOption = 0, SetupSize = 1, SwitchDirection = 2, ShowProperties = 4, Default = SetupSize | ShowProperties }; Q_DECLARE_FLAGS(AddWidgetOptions, AddWidgetOption) protected: void addConnectedWidget(UMLWidget *widget, Uml::AssociationType::Enum type = Uml::AssociationType::Association, AddWidgetOptions options = Default); void addConnectedUMLObject(UMLObject::ObjectType otype, Uml::AssociationType::Enum type); void addWidget(UMLWidget *widget, bool showProperties = true); ///////////////// Data Loaded/Saved ///////////////////////////////// QString m_instanceName; ///< instance name (used if on a deployment diagram) bool m_isInstance; ///< holds whether this widget is a component instance (i.e. on a deployment diagram) bool m_showStereotype; ///< should the stereotype be displayed ///////////////// End of Data Loaded/Saved ////////////////////////// Uml::ID::Type m_nLocalID; bool m_startMove; QPointF m_startMovePostion; QSizeF m_startResizeSize; int m_nPosX; UMLDoc *m_doc; ///< shortcut for UMLApp::app()->getDocument() bool m_resizable; QFontMetrics *m_pFontMetrics[FT_INVALID]; QSizeF m_minimumSize; QSizeF m_maximumSize; /// true if the activate function has been called for this class instance bool m_activated; /** * Change Widget Behaviour */ bool m_ignoreSnapToGrid; bool m_ignoreSnapComponentSizeToGrid; bool m_fixedAspectRatio; /// The text in the status bar when the cursor was pressed. QString m_oldStatusBarMsg; /// The X/Y offset from the position of the cursor when it was pressed to the /// upper left corner of the widget. QPointF m_pressOffset; /// The X/Y position the widget had when the movement started. QPointF m_oldPos; /// The width/height the widget had when the resize started. qreal m_oldW, m_oldH; /// If shift or control button were pressed in mouse press event. bool m_shiftPressed; /** * If cursor was in move/resize area when left button was pressed (and no * other widgets were selected). */ bool m_inMoveArea, m_inResizeArea; /** * If the widget was selected/moved/resized in the press and release cycle. * Moved/resized is true if the widget was moved/resized even if the final * position/size is the same as the starting one. */ bool m_moved, m_resized; private: void init(); /// A list of AssociationWidgets between the UMLWidget and other UMLWidgets in the diagram mutable AssociationWidgetList m_Assocs; }; Q_DECLARE_OPERATORS_FOR_FLAGS(UMLWidget::AddWidgetOptions) #endif