[Uml-devel] branches/work/soc-umbrello/umbrello

Gopala Krishna A krishna.ggk at gmail.com
Mon Jul 13 09:37:00 UTC 2009


SVN commit 995737 by gopala:

* Added support for delayed initialization for WidgetBase and its subclasses.
* Added ability to react for associating a widget with UMLScene for firs time.
* Cleaned up WidgetBase header a bit.


 M  +2 -2      newlinepath.cpp  
 M  +47 -5     widgets/newassociationwidget.cpp  
 M  +1 -0      widgets/newassociationwidget.h  
 M  +83 -12    widgets/widgetbase.cpp  
 M  +30 -45    widgets/widgetbase.h  


--- branches/work/soc-umbrello/umbrello/newlinepath.cpp #995736:995737
@@ -953,7 +953,7 @@
 
         if (!widA || !widB) {
             uError() << "AssociationWidget is only partially constructed."
-                     << "One or both UMLWidget are null";
+                        "One or both UMLWidget are null";
             return RegionPair();
         }
 
@@ -1001,7 +1001,7 @@
 
         if (!aWid || !bWid) {
             uError() << "AssociationWidget is only partially constructed."
-                     << "One or both UMLWidget are null";
+                        "One or both UMLWidget are null";
             return;
         }
 
--- branches/work/soc-umbrello/umbrello/widgets/newassociationwidget.cpp #995736:995737
@@ -43,11 +43,21 @@
     }
 
 
+    AssociationWidget::AssociationWidget() : WidgetBase(0)
+    {
+        m_baseType = Uml::wt_Association;
+        m_associationType = Uml::at_Association;
+        m_associationLine = new New::AssociationLine(this);
+        m_nameWidget = 0;
+        setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable);
+    }
+
     AssociationWidget::AssociationWidget(UMLWidget *widgetA, Uml::Association_Type type,
                                          UMLWidget *widgetB, UMLObject *umlObj) :
         WidgetBase(umlObj),
         m_associationType(type)
     {
+        m_baseType = Uml::wt_Association;
         m_associationLine = new New::AssociationLine(this);
         m_nameWidget = 0;
 
@@ -68,6 +78,9 @@
 
         setWidgetForRole(widgetA, Uml::A);
         setWidgetForRole(widgetB, Uml::B);
+
+        setAssociationType(type);
+
         if (widgetA == widgetB) {
             widgetA->associationSpaceManager()->add(this,
                     RegionPair(Uml::reg_North, Uml::reg_North));
@@ -85,9 +98,15 @@
 
         if (isCollaboration()) {
             UMLScene *scene = widgetA->umlScene();
-            int collabID = scene->generateCollaborationId();
-            setName('m' + QString::number(collabID));
+            if (scene) {
+                int collabID = scene->generateCollaborationId();
+                setName('m' + QString::number(collabID));
+            } else {
+                uError() << "The UMLWidget's to be associated are not yet on a UMLScene";
+                uError() << "No collaboration id assigned";
+            }
         }
+
         setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable);
     }
 
@@ -496,10 +515,11 @@
 
     Uml::Association_Type AssociationWidget::associationType() const
     {
-        if (umlObject()) {
-            return static_cast<UMLAssociation*>(umlObject())->getAssocType();
+        if (!umlObject() || umlObject()->getBaseType() != Uml::ot_Association) {
+            return m_associationType;
         }
-        return m_associationType;
+
+        return static_cast<UMLAssociation*>(umlObject())->getAssocType();
     }
 
     void AssociationWidget::setAssociationType(Uml::Association_Type type)
@@ -509,6 +529,28 @@
             static_cast<UMLAssociation*>(umlObject())->setAssocType(type);
         }
 
+        WidgetRole &a = m_widgetRole[Uml::A];
+        WidgetRole &b = m_widgetRole[Uml::B];
+
+        if( a.umlWidget && !AssocRules::allowMultiplicity(type, a.umlWidget->baseType()) ) {
+            if (a.multiplicityWidget) {
+                a.multiplicityWidget->setName("");
+            }
+            if (b.multiplicityWidget) {
+                b.multiplicityWidget->setName("");
+            }
+        }
+
+        if (!AssocRules::allowRole(type)) {
+            if (a.roleWidget) {
+                a.roleWidget->setName("");
+            }
+            if (b.roleWidget) {
+                b.roleWidget->setName("");
+            }
+            //setRoleDocumentation("", Uml::A);
+            //setRoleDocumentation("", Uml::B);
+        }
     }
 
     bool AssociationWidget::isCollaboration() const
--- branches/work/soc-umbrello/umbrello/widgets/newassociationwidget.h #995736:995737
@@ -45,6 +45,7 @@
     {
         Q_OBJECT
     public:
+        AssociationWidget();
         AssociationWidget(UMLWidget *widgetA, Uml::Association_Type type,
                           UMLWidget *widgetB, UMLObject *obj = 0);
         virtual ~AssociationWidget();
--- branches/work/soc-umbrello/umbrello/widgets/widgetbase.cpp #995736:995737
@@ -114,6 +114,7 @@
     setFlags(ItemIsSelectable | ItemIsMovable);
     hide(); // Show up in slotInit
 
+    QTimer::singleShot(10, this, SLOT(slotInit()));
 
     // DEPRECATED INITIALIZATION
     {
@@ -132,6 +133,15 @@
 }
 
 /**
+ * @retval The UMLObject represented by this widget
+ * @retval null if no UMLObject representation.
+ */
+UMLObject* WidgetBase::umlObject() const
+{
+    return m_umlObject;
+}
+
+/**
  * Set the UMLObject for this widget to represent.
  *
  * @todo Either remove this method, or allow it to only allow specific
@@ -156,8 +166,8 @@
         m_widgetInterfaceData = new WidgetInterfaceData;
     }
 
-    //slotUMLObjectDataChanged();
     umlObjectChanged(oldObj);
+    QTimer::singleShot(10, this, SLOT(slotUMLObjectDataChanged()));
 }
 
 /**
@@ -202,6 +212,14 @@
 }
 
 /**
+ * @return The type used for rtti.
+ */
+Uml::Widget_Type WidgetBase::baseType() const
+{
+    return m_baseType;
+}
+
+/**
  * @return The UMLScene for this widget is returned, or 0 if the
  *         widget is not stored in a scene.
  *
@@ -299,6 +317,12 @@
     attributeChange(NameHasChanged, oldName);
 }
 
+/// @return The color used to draw lines of the widget.
+QColor WidgetBase::lineColor() const
+{
+    return m_lineColor;
+}
+
 /**
  * Set the linecolor to \a color and updates the widget.
  * @param color The color to be set
@@ -319,6 +343,12 @@
     attributeChange(LineColorHasChanged, oldColor);
 }
 
+/// @return The width of the lines drawn in the widget.
+uint WidgetBase::lineWidth() const
+{
+    return m_lineWidth;
+}
+
 /**
  * Sets the line width of widget lines to \a lw and calls
  * updateGeometry() method to let object calculate new bound rect
@@ -338,6 +368,12 @@
     attributeChange(LineWidthHasChanged, oldWidth);
 }
 
+/// @return Font color used to draw font.
+QColor WidgetBase::fontColor() const
+{
+    return m_fontColor;
+}
+
 /**
  * Sets the color of the font to \a color.
  * If \a color is invalid, line color is used for font color.
@@ -357,6 +393,12 @@
     attributeChange(FontColorHasChanged, oldColor);
 }
 
+/// @return The QBrush object used to fill this widget.
+QBrush WidgetBase::brush() const
+{
+    return m_brush;
+}
+
 /**
  * Sets the QBrush object of this widget to \a brush which is used to
  * fill this widget.
@@ -373,6 +415,12 @@
     attributeChange(BrushHasChanged, oldBrush);
 }
 
+/// @return The font used for displaying any text
+QFont WidgetBase::font() const
+{
+    return m_font;
+}
+
 /**
  * Set the font used to display text inside this widget.
  *
@@ -740,22 +788,25 @@
  */
 void WidgetBase::slotInit()
 {
+    // Call this virtual method to ensure the superclasses initialize themselves with
+    // various properties of m_umlObject.
     setUMLObject(m_umlObject);
-    // Ensure the texts of subclasses are properly initialized.
-    slotUMLObjectDataChanged();
-    // TODO: Move these to an explicit intializer method
+
+    // Now call attributeChange with various geometry parameters to ensure that proper
+    // initialization of sub objects' properties take place.
     QVariant v;
     attributeChange(LineColorHasChanged, v);
     attributeChange(LineWidthHasChanged, v);
     attributeChange(FontHasChanged, v);
     attributeChange(FontColorHasChanged, v);
     attributeChange(BrushHasChanged, v);
-    // TODO: or rather we can assign the umlScene's default properties
-    // for this widget as umlScene would have been created by now (see
-    // WidgetBase::itemChange where ItemSceneHasChanged is handled.)
 
-    show(); // Now show the item
-    updateGeometry(); // Now just update the geometry for the first ever time after it is shown.
+    // Now show the item
+    show();
+    // Now just update the geometry for the first ever time after it is shown.
+    updateGeometry();
+    // Now invoke the virtual delayedInitialize() for subclasses to do more initialization.
+    delayedInitialize();
 }
 
 /**
@@ -820,6 +871,8 @@
 
 /**
  * Do some initialization on first scene change.
+ * @note The virtual function call is legitimate here since scene->addItem() is always
+ *       invoked after item has been fully constructed.
  */
 QVariant WidgetBase::itemChange(GraphicsItemChange change, const QVariant& value)
 {
@@ -827,9 +880,8 @@
         UMLScene *uScene = umlScene();
         if (uScene && !m_isSceneSetBefore) {
             m_isSceneSetBefore = true;
-            // Use timer to disambiguate situation where virtual
-            // functions might not call be called appropriately.
-            QTimer::singleShot(10, this, SLOT(slotInit()));
+            // call this virtual method now.
+            sceneSetFirstTime();
         }
     }
     return QGraphicsItem::itemChange(change, value);
@@ -867,6 +919,25 @@
 }
 
 /**
+ * This virtual method is called very shortly after the object is constructed completely.
+ * A timer with small timeout is used for this purpose.
+ * @see WidgetBase::slotInit()
+ */
+void WidgetBase::delayedInitialize()
+{
+}
+
+/**
+ * This virtual method is called after this widget has been associated with a UMLScene
+ * for the first time.
+ * Initalization from UMLScene's properties like line color etc. can be done by
+ * reimplementing this method.
+ */
+void WidgetBase::sceneSetFirstTime()
+{
+}
+
+/**
  * This method sets the bounding rectangle of this widget to \a
  * rect. The bounding rect being set is cached locally for performance
  * reasons.
--- branches/work/soc-umbrello/umbrello/widgets/widgetbase.h #995736:995737
@@ -87,22 +87,13 @@
     explicit WidgetBase(UMLObject *object);
     virtual ~WidgetBase();
 
-    /**
-     * @retval The UMLObject represented by this widget
-     * @retval null if no UMLObject representation.
-     */
-    UMLObject* umlObject() const {
-        return m_umlObject;
-    }
+    UMLObject* umlObject() const;
     void setUMLObject(UMLObject *obj);
 
     Uml::IDType id() const;
     void setID(Uml::IDType id);
 
-    /// @return The base type rtti info.
-    Uml::Widget_Type baseType() const {
-        return m_baseType;
-    }
+    Uml::Widget_Type baseType() const;
 
     UMLScene* umlScene() const;
     UMLDoc* umlDoc() const;
@@ -113,50 +104,23 @@
     QString name() const;
     void setName(const QString& name);
 
-    /// @return The color used to draw lines of the widget.
-    QColor lineColor() const {
-        return m_lineColor;
-    }
+    QColor lineColor() const;
     void setLineColor(const QColor& color);
 
-    /// @return The width of the lines drawn in the widget.
-    uint lineWidth() const {
-        return m_lineWidth;
-    }
+    uint lineWidth() const;
     void setLineWidth(uint lw);
 
-    /// @return Font color used to draw font.
-    QColor fontColor() const {
-        return m_fontColor;
-    }
+    QColor fontColor() const;
     void setFontColor(const QColor& color);
 
-    /// @return The QBrush object used to fill this widget.
-    QBrush brush() const {
-        return m_brush;
-    }
+    QBrush brush() const;
     void setBrush(const QBrush& brush);
 
-    /// @return The font used for displaying any text
-    QFont font() const {
-        return m_font;
-    }
+    QFont font() const;
     void setFont(const QFont& font);
 
-    /**
-     * @return The bounding rectangle for this widget.
-     * @see setBoundingRect
-     */
-    QRectF boundingRect() const {
-        return m_boundingRect;
-    }
-    /**
-     * @return The shape of this widget.
-     * @see setShape
-     */
-    QPainterPath shape() const {
-        return m_shape;
-    }
+    QRectF boundingRect() const;
+    QPainterPath shape() const;
 
     virtual void showPropertiesDialog();
     virtual void setupContextMenuActions(ListPopupMenu &menu);
@@ -185,6 +149,9 @@
 
     virtual void umlObjectChanged(UMLObject *old);
 
+    virtual void delayedInitialize();
+    virtual void sceneSetFirstTime();
+
     void setBoundingRect(const QRectF &rect);
     void setShape(const QPainterPath& path);
 
@@ -280,4 +247,22 @@
 
 };
 
+/**
+ * @return The bounding rectangle for this widget.
+ * @see setBoundingRect
+ */
+inline QRectF WidgetBase::boundingRect() const
+{
+    return m_boundingRect;
+}
+
+/**
+ * @return The shape of this widget.
+ * @see setShape
+ */
+inline QPainterPath WidgetBase::shape() const
+{
+    return m_shape;
+}
+
 #endif




More information about the umbrello-devel mailing list