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

Gopala Krishna A krishna.ggk at gmail.com
Sat Aug 30 10:10:56 UTC 2008


SVN commit 854778 by gopala:

* Fixed a crash when an AssociationWidget line was drawn (had
  forgotten m_widgetInterfaceData = 0 after delete
  m_widgetInterfaceData)

* Implemented a better(robust ?) mechanism of delayed initialization
  (slotInit). From now on the delayed initialization happens on
  setting the first umlScene on a widget, which is again driven
  through timer to avoid "virtual function call in constructor"
  problem.

     This means the widgets show up with proper geometry when added to
  scene, unlike before where something like setFont was necessary to
  force size updation. This deprecates the "exclusive updation" i used
  in Test class.

* Improved context menu mechanism. Now submenu's actions are handled
  appropriately by their appropriate creators.



 M  +42 -9     newumlwidget.cpp  
 M  +7 -0      newumlwidget.h  


--- branches/work/soc-umbrello/umbrello/newumlwidget.cpp #854777:854778
@@ -94,6 +94,7 @@
     m_lineWidth(0),
     m_brush(awesomeBrush()),
     m_widgetInterfaceData(0),
+    m_isSceneSetBefore(false),
     firstTime(true)
 {
     if(!object) {
@@ -102,8 +103,6 @@
     setFlags(ItemIsSelectable | ItemIsMovable);
     hide(); // Show up in slotInit
 
-    // Call init this way so that virtual methods may be called.
-    QTimer::singleShot(0, this, SLOT(slotInit()));
 
     // DEPRECATED INITIALIZATION
     {
@@ -140,6 +139,7 @@
 
     if(m_umlObject) {
         delete m_widgetInterfaceData;
+        m_widgetInterfaceData = 0;
         connect(umlObject(), SIGNAL(modified()), this,
                 SLOT(slotUMLObjectDataChanged()));
     }
@@ -303,7 +303,7 @@
     const QColor oldColor = lineColor();
     m_lineColor = color;
     if(!m_lineColor.isValid()) {
-        uDebug() << "Invalid color";
+        uWarning() << "Invalid color";
         m_lineColor = Qt::black;
     }
 
@@ -741,7 +741,12 @@
     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
+    // NewUMLWidget::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.
 }
 
 /**
@@ -750,12 +755,25 @@
 void NewUMLWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
 {
     ListPopupMenu menu(0, this, false, false);
+    setupContextMenuActions(menu);
+
+    event->accept();
+
     QAction *triggered = menu.exec(event->screenPos());
     if(triggered) {
+        ListPopupMenu *parent = qobject_cast<ListPopupMenu*>(triggered->parent());
+        if (parent) {
+            NewUMLWidget *actionMenuOwner = parent->ownerWidget();
+            if (actionMenuOwner) {
+                actionMenuOwner->slotMenuSelection(triggered);
+                return;
+            }
+        }
+
+        // If owner fetching fails, then we force *menu* to be parent of triggered action.
         triggered->setParent(&menu);
-        slotMenuSelection(triggered);
+        this->slotMenuSelection(triggered);
     }
-    event->accept();
 }
 
 /**
@@ -792,6 +810,23 @@
 }
 
 /**
+ * Do some initialization on first scene change.
+ */
+QVariant NewUMLWidget::itemChange(GraphicsItemChange change, const QVariant& value)
+{
+    if (change == ItemSceneHasChanged) {
+        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()));
+        }
+    }
+    return QGraphicsItem::itemChange(change, value);
+}
+
+/**
  * This virtual method is called by this NewUMLWidget base class to
  * notify subclasses about the need to change its boundingRect
  * Example. When a new pen is set on a widget which paints
@@ -885,6 +920,7 @@
     m_lineWidth(0),
     m_brush(awesomeBrush()),
     m_widgetInterfaceData(0),
+    m_isSceneSetBefore(false),
     firstTime(true)
 {
     for(int i= FT_NORMAL; i < FT_INVALID; ++i) {
@@ -896,8 +932,6 @@
     }
     setFlags(ItemIsSelectable | ItemIsMovable);
     hide();
-    // Call init this way so that virtual methods may be called.
-    QTimer::singleShot(0, this, SLOT(slotInit()));
     if(scene) {
         scene->addItem(this);
     }
@@ -908,6 +942,7 @@
     m_lineColor(Qt::red),
     m_lineWidth(0),
     m_brush(awesomeBrush()),
+    m_isSceneSetBefore(false),
     firstTime(true)
 {
     for(int i= FT_NORMAL; i < FT_INVALID; ++i) {
@@ -926,8 +961,6 @@
     }
     hide();
     setFlags(ItemIsSelectable | ItemIsMovable);
-    // Call init this way so that virtual methods may be called.
-    QTimer::singleShot(0, this, SLOT(slotInit()));
 }
 
 void NewUMLWidget::setDefaultFontMetrics(NewUMLWidget::FontType fontType)
--- branches/work/soc-umbrello/umbrello/newumlwidget.h #854777:854778
@@ -171,6 +171,7 @@
     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
 
 	virtual QVariant attributeChange(WidgetAttributeChange change, const QVariant& oldValue);
+    virtual QVariant itemChange(GraphicsItemChange change, const QVariant& value);
 
     virtual void updateGeometry();
 
@@ -201,6 +202,12 @@
     // End of properties that will be saved.
 
     WidgetInterfaceData *m_widgetInterfaceData;
+
+    /**
+     * This is used to ensure that there is only one initialization when a
+     * new UMLScene is set for this widget for the first time.
+     */
+    bool m_isSceneSetBefore;
     /*
      * Disable the copy constructor and assignment operator.
      */




More information about the umbrello-devel mailing list