[Uml-devel] KDE/kdesdk/umbrello
Oliver Kellogg
okellogg at users.sourceforge.net
Sun Feb 26 20:11:55 UTC 2012
SVN commit 1282402 by okellogg:
(In reply to comment #1)
> [...]
> you have an inheritance in the opposite direction.
> The mutual inheritance throws Umbrello off the handle and so I've removed
> the first one. (Actually I wonder why Umbrello did not disallow its
> creation.)
It turns out that
AssocRules::allowAssociation(Uml::AssociationType,
UMLWidget *, UMLWidget *)
was being called twice: First in ToolBarStateAssociation::setSecondWidget()
(toolbarstateassociation.cpp:226) and again via ToolBarStateAssociation::
addAssociationInViewAndDoc() in UMLView::addAssociation().
At the time of the second call, the AssociationWidget was already created
and inserted at its role widgets.
Fixed as follows:
- In UMLView::addAssociation(), remove the call to
AssocRules::allowAssociation()
- At ToolBarStateAssociation::addAssociationInViewAndDoc(), change return
type to bool (true for success) and test the success at
ToolBarStateAssociation::setSecondWidget()
- Revert the "#if 0" at the extendedCheck code at assocrules.cpp:170 ff.
thus re-enabling the check for illegal mutual associations.
BUG:235703
M +1 -0 ChangeLog
M +0 -33 umbrello/assocrules.cpp
M +9 -6 umbrello/toolbarstateassociation.cpp
M +1 -1 umbrello/toolbarstateassociation.h
M +0 -7 umbrello/umlview.cpp
M +25 -6 umbrello/widgets/associationwidget.cpp
--- trunk/KDE/kdesdk/umbrello/ChangeLog #1282401:1282402
@@ -8,6 +8,7 @@
* Generation of classes from files in folder in umbrello (197137)
* Crash when Clicking on / Trying to Move Datatype on Simple Diagram (202410)
* Segfault importing Java code - related to variable length parameters (230770)
+* Segmentation fault when trying to generate code (235703)
* Can't uncheck "Show Public Only" (242545)
* Umbrello crashed after copy/paste (243392)
* Crash when opening file (251094)
--- trunk/KDE/kdesdk/umbrello/umbrello/assocrules.cpp #1282401:1282402
@@ -165,38 +165,6 @@
}
}
- return bValid;
-
-/* TODO:
- - Check the below code
- - Check its callers - example: On making a Containment from a Package to a Class,
- the assoc is already inserted in widgetB->associationWidgetList()
- when we get here. The assoc SHOULD NOT already be there - therefore the
- precondition of the below tests is not met, thus they fail, and
- toolbarstateassociation.cpp:311 says "delete assoc" - but that's too late
- because the assoc is already being referenced. Valgrind report:
-Invalid read of size 4
- at 0x82EA890: AssociationWidget::getTextWidgetByRole(Uml::TextRole) (associationwidget.cpp:819)
- by 0x82EE799: AssociationWidget::calculateTextPosition(Uml::TextRole) (associationwidget.cpp:2411)
- by 0x82EEC23: AssociationWidget::saveIdealTextPositions() (associationwidget.cpp:1833)
- by 0x832E676: UMLWidget::adjustAssocs(int, int) (umlwidget.cpp:782)
- by 0x832CDF8: UMLWidget::updateComponentSize() (umlwidget.cpp:1240)
- by 0x832CEC1: UMLWidget::updateWidget() (umlwidget.cpp:230)
- by 0x832DAC2: UMLWidget::qt_metacall(QMetaObject::Call, int, void**) (umlwidget.moc:86)
- by 0x598D863: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/libQtCore.so.4.5.3)
- by 0x598E584: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib/libQtCore.so.4.5.3)
- by 0x83F6168: UMLObject::modified() (umlobject.moc:122)
- by 0x83F61FD: UMLObject::setUMLPackage(UMLPackage*) (umlobject.cpp:552)
- by 0x83E2341: UMLListView::moveObject(std::string, UMLListViewItem::ListViewType, UMLListViewItem*) (umllistview.cpp:1772)
- Address 0x68e6e24 is 92 bytes inside a block of size 708 free'd
- at 0x40265BD: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
- by 0x83A6BE4: ToolBarStateAssociation::addAssociationInViewAndDoc(AssociationWidget*) (toolbarstateassociation.cpp:311)
- by 0x83A6DA1: ToolBarStateAssociation::setSecondWidget() (toolbarstateassociation.cpp:230)
- by 0x83A70DF: ToolBarStateAssociation::mouseReleaseWidget() (toolbarstateassociation.cpp:149)
- by 0x83A5255: ToolBarState::mouseRelease(UMLSceneMouseEvent*) (toolbarstate.cpp:123)
- */
-
-#if 0
if (!bValid) {
return false;
}
@@ -328,7 +296,6 @@
break;
}
return false;
-#endif
}
/**
--- trunk/KDE/kdesdk/umbrello/umbrello/toolbarstateassociation.cpp #1282401:1282402
@@ -227,7 +227,7 @@
}
if (valid) {
AssociationWidget *temp = AssociationWidget::create(m_pUMLScene, widgetA, type, widgetB);
- addAssociationInViewAndDoc(temp);
+ if (addAssociationInViewAndDoc(temp)) {
if (type == Uml::AssociationType::Containment) {
UMLListView *lv = UMLApp::app()->listView();
UMLObject *newContainer = widgetA->umlObject();
@@ -240,6 +240,7 @@
}
}
UMLApp::app()->document()->setModified();
+ }
} else {
//TODO improve error feedback: tell the user what are the valid type of associations for
//the second widget using the first widget
@@ -291,24 +292,26 @@
* If the association can't be added, is deleted.
*
* @param assoc The AssociationWidget to add.
+ * @return True on success
*/
-void ToolBarStateAssociation::addAssociationInViewAndDoc(AssociationWidget* assoc)
+bool ToolBarStateAssociation::addAssociationInViewAndDoc(AssociationWidget* assoc)
{
// append in view
if (m_pUMLScene->addAssociation(assoc, false)) {
// if view went ok, then append in document
UMLAssociation *umla = assoc->getAssociation();
- if (umla == NULL) {
- // association without model representation in UMLDoc
- return;
- }
+ if (umla) {
+ // association with model representation in UMLDoc
Uml::ModelType m = Model_Utils::convert_DT_MT(m_pUMLScene->type());
UMLDoc *umldoc = UMLApp::app()->document();
umla->setUMLPackage(umldoc->rootFolder(m));
UMLApp::app()->document()->addAssociation(umla);
+ }
+ return true;
} else {
uError() << "cannot addAssocInViewAndDoc(), deleting";
delete assoc;
+ return false;
}
}
--- trunk/KDE/kdesdk/umbrello/umbrello/toolbarstateassociation.h #1282401:1282402
@@ -64,7 +64,7 @@
Uml::AssociationType getAssociationType();
- void addAssociationInViewAndDoc(AssociationWidget* assoc);
+ bool addAssociationInViewAndDoc(AssociationWidget* assoc);
void cleanAssociation();
--- trunk/KDE/kdesdk/umbrello/umbrello/umlview.cpp #1282401:1282402
@@ -1832,13 +1832,6 @@
return false;
}
- //make sure valid
- if (!isPasteOperation && !m_doc->loading() &&
- !AssocRules::allowAssociation(assocType, pWidgetA, pWidgetB)) {
- uWarning() << "allowAssociation returns false " << "for AssocType " << assocType;
- return false;
- }
-
//make sure there isn't already the same assoc
foreach(AssociationWidget* assocwidget, m_AssociationList) {
--- trunk/KDE/kdesdk/umbrello/umbrello/widgets/associationwidget.cpp #1282401:1282402
@@ -112,17 +112,36 @@
UMLDoc *doc = UMLApp::app()->document();
UMLAssociation *myAssoc = doc->findAssociation( assocType, umlRoleA, umlRoleB, &swap );
if (myAssoc != NULL) {
- if (assocType == Uml::AssociationType::Generalization) {
- uDebug() << " Ignoring second construction of same generalization";
- } else {
- uDebug() << " constructing a similar or exact same assoc " <<
- "as an already existing assoc (swap=" << swap << ")";
+ switch (assocType) {
+ case Uml::AssociationType::Generalization:
+ case Uml::AssociationType::Dependency:
+ case Uml::AssociationType::Association_Self:
+ case Uml::AssociationType::Coll_Message_Self:
+ case Uml::AssociationType::Seq_Message_Self:
+ case Uml::AssociationType::Containment:
+ case Uml::AssociationType::Realization:
+ uDebug() << "Ignoring second construction of same assoctype "
+ << assocType << " between " << umlRoleA->name()
+ << " and " << umlRoleB->name();
+ break;
+ default:
+ uDebug() << "constructing a similar or exact same assoctype "
+ << assocType << " between " << umlRoleA->name() << " and "
+ << umlRoleB->name() << "as an already existing assoc (swap="
+ << swap << ")";
// now, just create a new association anyways
myAssoc = NULL;
+ break;
}
}
- if (myAssoc == NULL)
+ if (myAssoc == NULL) {
myAssoc = new UMLAssociation( assocType, umlRoleA, umlRoleB );
+ // CHECK: myAssoc is not yet inserted at any parent UMLPackage -
+ // need to check carefully that all callers do this, lest it be
+ // orphaned.
+ // ToolBarStateAssociation::addAssociationInViewAndDoc() is
+ // okay in this regard.
+ }
instance->setUMLAssociation(myAssoc);
}
}
More information about the umbrello-devel
mailing list