Bug 129914

Summary: Cannot insert transition/association TO fork/join node in activity diagram
Product: [Applications] umbrello Reporter: Daniel Bausch <BarnieMan>
Component: generalAssignee: Umbrello Development Group <umbrello-devel>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: 1.5.2   
Target Milestone: ---   
Platform: Gentoo Packages   
OS: Linux   
Latest Commit: Version Fixed In:

Description Daniel Bausch 2006-06-27 17:15:46 UTC
Version:           1.5.2 (using KDE KDE 3.5.2)
Installed from:    Gentoo Packages
Compiler:          GCC 3.4.6 
OS:                Linux

Steps to reproduce:

1. Create a new activity diagram.
2. Place a starting node
3. Place a fork/join node
4. Try to draw an arrow from the starting node to the fork/join node

=> An error message pops up, saying this were an invalid association.

(An arrow from the fork to another node, in contrast, is possible.)

In earlier versions (KDE 3.4) this was possible.

PS: This arrow should be called a "transition". (I've got the german translation.)
Comment 1 Oliver Kellogg 2006-07-14 08:09:00 UTC
assocrules.cpp:190 illegal static_cast: widgetB is not ActivityWidget but ForkJoinWidget
Comment 2 Oliver Kellogg 2006-07-16 01:27:21 UTC
SVN commit 562841 by okellogg:

allowAssociation(Association_Type, UMLWidget*, UMLWidget*, bool)
case at_Activity: avoid illegal static_cast of widgetB to ActivityWidget
when it is really a ForkJoinWidget.
BUG:129914


 M  +1 -0      ChangeLog  
 M  +27 -26    umbrello/assocrules.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #562840:562841
@@ -3,6 +3,7 @@
 * Bugs/wishes from http://bugs.kde.org:
 * Fix crash when importing classes from a java file (129107, 130093)
 * Crash after single click on the "UML Model" tree window (126560/129252)
+* Cannot insert transition/association TO fork/join node in activity diagram (129914)
 * Importing java subinterface before superinterface results in superinterface
   not being treated as an interface (130793)
 
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/assocrules.cpp #562840:562841
@@ -186,32 +186,33 @@
         break;
 
     case at_Activity:
-        // no transitions to initial activity allowed
-        if( static_cast<ActivityWidget*>(widgetB)->getActivityType() ==
-                ActivityWidget::Initial )
-            return false;
-        // only from a normal, branch or fork activity to the end
-        if( static_cast<ActivityWidget*>(widgetB)->getActivityType() ==
-                ActivityWidget::End &&
-                static_cast<ActivityWidget*>(widgetA)->getActivityType() !=
-                ActivityWidget::Normal &&
-                static_cast<ActivityWidget*>(widgetA)->getActivityType() !=
-                ActivityWidget::Branch &&
-                static_cast<ActivityWidget*>(widgetA)->getActivityType() !=
-                ActivityWidget::Fork_DEPRECATED &&
-		dynamic_cast<ForkJoinWidget*>(widgetA) == NULL ) {
-            return false;
-        }
-        // only Forks and Branches can have more than one "outgoing" transition
-        if( static_cast<ActivityWidget*>(widgetA)->getActivityType() !=
-                ActivityWidget::Fork_DEPRECATED &&
-		dynamic_cast<ForkJoinWidget*>(widgetA) == NULL &&
-               static_cast<ActivityWidget*>(widgetA)->getActivityType() !=
-                ActivityWidget::Branch ) {
-            AssociationWidgetList list = widgetA->getAssocList();
-            for (AssociationWidget* assoc = list.first(); assoc; assoc = list.next()) {
-                if (assoc->getWidget(A) == widgetA) {
-                    return false;
+        {
+            ActivityWidget *actA = dynamic_cast<ActivityWidget*>(widgetA);
+            ActivityWidget *actB = dynamic_cast<ActivityWidget*>(widgetB);
+            // no transitions to initial activity allowed
+            if (actB && actB->getActivityType() == ActivityWidget::Initial)
+                return false;
+            // Fork_DEPRECATED here means "not applicable".
+            ActivityWidget::ActivityType actTypeA = ActivityWidget::Fork_DEPRECATED;
+            if (actA)
+                actTypeA = actA->getActivityType();
+            ActivityWidget::ActivityType actTypeB = ActivityWidget::Fork_DEPRECATED;
+            if (actB)
+                actTypeB = actB->getActivityType();
+            // only from a normal, branch or fork activity to the end
+            if (actTypeB == ActivityWidget::End &&
+                actTypeA != ActivityWidget::Normal &&
+                actTypeA != ActivityWidget::Branch &&
+                dynamic_cast<ForkJoinWidget*>(widgetA) == NULL) {
+                return false;
+            }
+            // only Forks and Branches can have more than one "outgoing" transition
+            if (actA != NULL && actTypeA != ActivityWidget::Branch) {
+                AssociationWidgetList list = widgetA->getAssocList();
+                for (AssociationWidget* assoc = list.first(); assoc; assoc = list.next()) {
+                    if (assoc->getWidget(A) == widgetA) {
+                        return false;
+                    }
                 }
             }
         }