Bug 141813 - unable to delete multiplicity information or lable from an aggregation
Summary: unable to delete multiplicity information or lable from an aggregation
Status: RESOLVED FIXED
Alias: None
Product: umbrello
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Fedora RPMs Linux
: NOR normal
Target Milestone: ---
Assignee: Umbrello Development Group
URL:
Keywords:
: 120699 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-02-17 02:04 UTC by Mark Gardinier
Modified: 2007-04-08 01:14 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
xml where I can't delete labels or multiplicity (4.97 KB, application/x-bzip2)
2007-02-17 02:08 UTC, Mark Gardinier
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Gardinier 2007-02-17 02:04:05 UTC
Version:            (using KDE KDE 3.5.5)
Installed from:    Fedora RPMs
Compiler:          N/A N/A
OS:                Linux

Follow these steps:

1.  Create a class
2.  Create another class
3.  Create an aggregation of the two.
4.  Right click on the aggregation, select properties and specify a name.
5.  Under roles, specify mulitplicity on both sides of the aggregation.  Don't name the role.
6.  Save the diagram.
7.  Right click on properties and try to delete the label or multiplicty.

I can't seem to.

I've attached my XML.

Thanks.
Comment 1 Mark Gardinier 2007-02-17 02:08:20 UTC
Created attachment 19712 [details]
xml where I can't delete labels or multiplicity
Comment 2 Oliver Kellogg 2007-02-17 07:32:43 UTC
SVN commit 634394 by okellogg:

setName(): Remove special-casing code for when m_pName is non-NULL but strName
 is empty. This is a sensitive spot so I put the offending code in a comment
 for documentation.
BUG:141813


 M  +1 -0      ChangeLog  
 M  +2 -0      umbrello/associationwidget.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #634393:634394
@@ -7,6 +7,7 @@
 * Javascript Code Generation creates bad format methods (135540)
 * Crash when deleting the link between a package and a class (141602)
 * Ada95 Code Generation Errors for Aggregation (141644)
+* Unable to delete multiplicity information or lable from an association (141813)
 
 Version 1.5.61
 
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/associationwidget.cpp #634393:634394
@@ -327,11 +327,13 @@
             m_pName->setUMLObject(m_role[B].m_pWidget->getUMLObject());
     } else {
         m_pName->setText(strName);
+        /**** This code leads to bug 141813 (unable to delete label or multi)
         if (strName.isEmpty()) {
             m_pName->hide();
             m_pName = NULL;
             return;
         }
+         ********************************************************************/
     }
 
     // set attribute of UMLAssociation associated with this associationwidget
Comment 3 Oliver Kellogg 2007-02-17 15:34:42 UTC
*** Bug 120699 has been marked as a duplicate of this bug. ***
Comment 4 Oliver Kellogg 2007-04-08 01:14:45 UTC
SVN commit 651498 by okellogg:

It turns out that I was too quick closing this PR, here are some changes that
hopefully clear out the problem in its entirety.

AssociationWidget::cleanup(): Make public. Invoke removeAssocClassLine().

AssociationWidget destructor: Remove call to cleanup(), this is much too late
 to do that.  It is the caller's responsibility to call cleanup() prior to
 physically destructing an AssociationWidget.

AssociationWidget::setFloatingText(): New method factors common processing
 from setRoleName() and setMulti().

CCBUG:141813


 M  +35 -61    associationwidget.cpp  
 M  +20 -7     associationwidget.h  
 M  +2 -1      floatingtextwidget.cpp  
 M  +1 -0      umlview.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/associationwidget.cpp #651497:651498
@@ -127,8 +127,6 @@
 }
 
 AssociationWidget::~AssociationWidget() {
-    cleanup();
-    removeAssocClassLine();
 }
 
 AssociationWidget& AssociationWidget::operator=(AssociationWidget & Other) {
@@ -354,48 +352,50 @@
 
 }
 
-void AssociationWidget::setMulti(const QString &strMulti, Role_Type role) {
-    bool newLabel = false;
-    Text_Role tr = (role == A ? tr_MultiA : tr_MultiB);
+void AssociationWidget::setFloatingText(Uml::Text_Role tr,
+                                        const QString &text,
+                                        FloatingTextWidget* &ft) {
+    if (! FloatingTextWidget::isTextValid(text)) {
+        if (ft) {
+            // Remove preexisting FloatingTextWidget
+            m_pView->removeWidget(ft);  // physically deletes ft
+            ft = NULL;
+        }
+        return;
+    }
 
-    if(!m_role[role].m_pMulti) {
-        // Don't construct the FloatingTextWidget if the string is empty.
-        if (strMulti.isEmpty())
-            return;
-
+    bool newLabel = false;
+    if (ft == NULL) {
+        ft = new FloatingTextWidget(m_pView, tr, text);
+        ft->setLink(this);
+        m_pView->addWidget(ft);
         newLabel = true;
-        m_role[role].m_pMulti = new FloatingTextWidget(m_pView, tr, strMulti);
-        m_role[role].m_pMulti->setLink(this);
-        m_pView->addWidget(m_role[role].m_pMulti);
     } else {
-        if (m_role[role].m_pMulti->getText().isEmpty()) {
+        if (ft->getText().isEmpty()) {
             newLabel = true;
         }
-        m_role[role].m_pMulti->setText(strMulti);
-        if (strMulti.isEmpty()) {
-            m_role[role].m_pMulti->hide();
-            m_role[role].m_pMulti = NULL;
-            return;
-        }
+        ft->setText(text);
     }
 
-    m_role[role].m_pMulti->setActivated();
+    ft->setActivated();
 
     if (newLabel) {
         setTextPosition( tr );
     }
 
-    if(FloatingTextWidget::isTextValid(m_role[role].m_pMulti->getText()))
-        m_role[role].m_pMulti -> show();
-    else
-        m_role[role].m_pMulti -> hide();
+    ft->show();
+}
 
+void AssociationWidget::setMulti(const QString &strMulti, Role_Type role) {
+    Text_Role tr = (role == A ? tr_MultiA : tr_MultiB);
+
+    setFloatingText(tr, strMulti, m_role[role].m_pMulti);
+
     if (m_pObject && m_pObject->getBaseType() == ot_Association)
         getAssociation()->setMulti(strMulti, role);
 }
 
 void AssociationWidget::setRoleName (const QString &strRole, Role_Type role) {
-    bool newLabel = false;
     Association_Type type = getAssocType();
     //if the association is not supposed to have a Role FloatingTextWidget
     if (!AssocRules::allowRole(type))  {
@@ -403,44 +403,21 @@
     }
 
     Text_Role tr = (role == A ? tr_RoleAName : tr_RoleBName);
-    if(!m_role[role].m_pRole) {
-        // Don't construct the FloatingTextWidget if the string is empty.
-        if (strRole.isEmpty())
-            return;
-
-        newLabel = true;
-        m_role[role].m_pRole = new FloatingTextWidget(m_pView, tr, strRole);
-        m_role[role].m_pRole->setLink(this);
-        m_pView->addWidget(m_role[role].m_pRole);
+    setFloatingText(tr, strRole, m_role[role].m_pRole);
+    if (m_role[role].m_pRole) {
         Uml::Visibility vis = getVisibility(role);
-        m_role[role].m_pRole->setPreText(vis.toString(true));
-    } else {
-        if (m_role[role].m_pRole->getText().isEmpty()) {
-            newLabel = true;
+        if (FloatingTextWidget::isTextValid(m_role[role].m_pRole->getText())) {
+            m_role[role].m_pRole->setPreText(vis.toString(true));
+            //m_role[role].m_pRole->show();
+        } else {
+            m_role[role].m_pRole->setPreText("");
+            //m_role[role].m_pRole->hide();
         }
-        m_role[role].m_pRole->setText(strRole);
-        if (strRole.isEmpty()) {
-            m_role[role].m_pRole->hide();
-            m_role[role].m_pRole = NULL;
-            return;
-        }
     }
 
     // set attribute of UMLAssociation associated with this associationwidget
     if (m_pObject && m_pObject->getBaseType() == ot_Association)
         getAssociation()->setRoleName(strRole, role);
-    m_role[role].m_RoleName = strRole;
-
-    m_role[role].m_pRole->setActivated();
-
-    if (newLabel) {
-        setTextPosition( tr );
-    }
-
-    if(FloatingTextWidget::isTextValid(m_role[role].m_pRole->getText()))
-        m_role[role].m_pRole -> show();
-    else
-        m_role[role].m_pRole -> hide();
 }
 
 void AssociationWidget::setRoleDoc (const QString &doc, Role_Type role) {
@@ -783,6 +760,7 @@
     }
 
     m_LinePath.cleanup();
+    removeAssocClassLine();
 }
 
 void AssociationWidget::setUMLAssociation (UMLAssociation * assoc)
@@ -3188,10 +3166,6 @@
 
     // Initialize local members.
     // These are only used if we don't have a UMLAssociation attached.
-    m_role[A].m_Visibility = Uml::Visibility::Public;
-    m_role[B].m_Visibility = Uml::Visibility::Public;
-    m_role[A].m_Changeability = chg_Changeable;
-    m_role[B].m_Changeability = chg_Changeable;
     m_AssocType = Uml::at_Association;
     m_umldoc = UMLApp::app()->getDocument();
     m_LinePath.setAssociation( this );
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/associationwidget.h #651497:651498
@@ -626,17 +626,17 @@
     bool loadFromXMI( QDomElement & qElement, const UMLWidgetList& widgets,
                       const MessageWidgetList* pMessages = NULL);
 
+    /**
+     * Cleans up all the association's data in the related widgets.
+     */
+    void cleanup();
+
 private:
 
     /** set our internal umlAssociation */
     void setUMLAssociation (UMLAssociation * assoc);
 
     /**
-     * Cleans up all the association's data in the related widgets.
-     */
-    void cleanup();
-
-    /**
      * Merges/syncs the association widget data into UML object
      * representation.
      * CHECK: Can we get rid of this.
@@ -847,12 +847,25 @@
         Uml::Visibility m_Visibility;
         Uml::Changeability_Type m_Changeability;
         QString m_RoleDoc;
-        QString m_RoleName;
-        QString m_Multi;
 
     } m_role[2];
 
     /**
+     * Change, create, or delete the FloatingTextWidget indicated by the given Text_Role.
+     *
+     * @param tr    Text_Role of the FloatingTextWidget to change or create.
+     * @param text  Text string that controls the action:
+     *              If empty and ft is NULL then setFloatingText() is a no-op.
+     *              If empty and ft is non-NULL then the existing ft is deleted.
+     *              If non-empty and ft is NULL then a new FloatingTextWidget is created
+     *              and returned in ft with the text set.
+     *              If non-empty and ft is non-NULL then the existing ft text is modified.
+     * @param ft    Reference to the pointer to FloatingTextWidget to change or create.
+     *              On creation/deletion, the pointer value will be changed.
+     */
+    void setFloatingText(Uml::Text_Role tr, const QString &text, FloatingTextWidget* &ft);
+
+    /**
      * Called to tell the association that another association has added
      * a line to the region of one of its widgets. The widget is identified
      * by its role (A or B).
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/floatingtextwidget.cpp #651497:651498
@@ -202,15 +202,16 @@
                 break;
               default:
                 assoc->setName(QString::null);
+                m_pView->removeWidget(this);
                 break;
             }
         } else {
             MessageWidget *msg = dynamic_cast<MessageWidget*>(m_pLink);
             if (msg) {
                 msg->setName(QString::null);
+                m_pView->removeWidget(this);
             }
         }
-        m_pView->removeWidget(this);
         return;
     }
     if (m_pLink && m_Role != Uml::tr_Seq_Message && m_Role != Uml::tr_Seq_Message_Self) {
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umlview.cpp #651497:651498
@@ -1749,6 +1749,7 @@
 
     emit sigAssociationRemoved(pAssoc);
 
+    pAssoc->cleanup();
     m_AssociationList.remove(pAssoc); // will delete our association
     m_pDoc->setModified();
 }