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

Gopala Krishna A krishna.ggk at gmail.com
Wed Aug 12 16:33:57 UTC 2009


SVN commit 1010486 by gopala:

* FloatingTextWidget: Introduced hasValidText() method which returns validity of
                      its current text.

* AssociationWidget: Ported saveToXMI() method.

Now, only AssociationWidget::loadFromXMI() requires porting! Wow :)



 M  +309 -0    associationwidget.cpp  
 M  +15 -2     floatingtextwidget.cpp  
 M  +1 -0      floatingtextwidget.h  


--- branches/work/soc-umbrello/umbrello/widgets/associationwidget.cpp #1010485:1010486
@@ -974,6 +974,249 @@
 
 bool AssociationWidget::loadFromXMI(QDomElement& element)
 {
+#if 0
+    WidgetBase::loadFromXMI(qElement);
+
+    // load child widgets first
+    QString widgetaid = qElement.attribute("widgetaid", "-1");
+    QString widgetbid = qElement.attribute("widgetbid", "-1");
+    Uml::IDType aId = STR2ID(widgetaid);
+    Uml::IDType bId = STR2ID(widgetbid);
+    UMLWidget *pWidgetA = Widget_Utils::findWidget(aId, widgets, pMessages);
+    if (!pWidgetA) {
+        uError() << "cannot find widget for roleA id " << ID2STR(aId);
+        return false;
+    }
+    UMLWidget *pWidgetB = Widget_Utils::findWidget(bId, widgets, pMessages);
+    if (!pWidgetB) {
+        uError() << "cannot find widget for roleB id " << ID2STR(bId);
+        return false;
+    }
+    setWidget(pWidgetA, A);
+    setWidget(pWidgetB, B);
+
+    QString type = qElement.attribute("type", "-1");
+    Uml::Association_Type aType = (Uml::Association_Type) type.toInt();
+
+    QString id = qElement.attribute("xmi.id", "-1");
+    bool oldStyleLoad = false;
+    if (id == "-1") {
+        // xmi.id not present, ergo either a pure widget association,
+        // or old (pre-1.2) style:
+        // Everything is loaded from the AssociationWidget.
+        // UMLAssociation may or may not be saved - if it is, it's a dummy.
+        // Create the UMLAssociation if both roles are UML objects;
+        // else load the info locally.
+
+        if (UMLAssociation::assocTypeHasUMLRepresentation(aType)) {
+            // lack of an association in our widget AND presence of
+            // both uml objects for each role clearly identifies this
+            // as reading in an old-school file. Note it as such, and
+            // create, and add, the UMLAssociation for this widget.
+            // Remove this special code when backwards compatibility
+            // with older files isn't important anymore. -b.t.
+            UMLObject* umlRoleA = pWidgetA->umlObject();
+            UMLObject* umlRoleB = pWidgetB->umlObject();
+            if (!m_pObject && umlRoleA && umlRoleB)
+            {
+                oldStyleLoad = true; // flag for further special config below
+                if (aType == at_Aggregation || aType == at_Composition) {
+                    uWarning()<<" Old Style save file? swapping roles on association widget"<<this;
+                    // We have to swap the A and B widgets to compensate
+                    // for the long standing bug in LinePath of drawing
+                    // the diamond at the wrong end which was fixed
+                    // just before the 1.2 release.
+                    // The logic here is that the user has understood
+                    // that the diamond belongs at the SOURCE end of the
+                    // the association (i.e. at the container, not at the
+                    // contained), and has compensated for this anomaly
+                    // by drawing the aggregations/compositions from
+                    // target to source.
+                    UMLWidget *tmpWidget = pWidgetA;
+                    pWidgetA = pWidgetB;
+                    pWidgetB = tmpWidget;
+                    setWidget(pWidgetA, A);
+                    setWidget(pWidgetB, B);
+                    umlRoleA = pWidgetA->umlObject();
+                    umlRoleB = pWidgetB->umlObject();
+                }
+
+                setUMLAssociation(m_umldoc->createUMLAssociation(umlRoleA, umlRoleB, aType));
+            }
+        }
+
+        setDocumentation(qElement.attribute("documentation", ""));
+        setRoleDoc(qElement.attribute("roleAdoc", ""), A);
+        setRoleDoc(qElement.attribute("roleBdoc", ""), B);
+
+        // visibility defaults to Public if it cant set it here..
+        QString visibilityA = qElement.attribute("visibilityA", "0");
+        int vis = visibilityA.toInt();
+        if (vis >= 200)  // bkwd compat.
+            vis -= 200;
+        setVisibility((Uml::Visibility::Value)vis, A);
+
+        QString visibilityB = qElement.attribute("visibilityB", "0");
+        vis = visibilityB.toInt();
+        if (vis >= 200)  // bkwd compat.
+            vis -= 200;
+        setVisibility((Uml::Visibility::Value)vis, B);
+
+        // Changeability defaults to "Changeable" if it cant set it here..
+        QString changeabilityA = qElement.attribute("changeabilityA", "0");
+        if (changeabilityA.toInt() > 0)
+            setChangeability((Uml::Changeability_Type)changeabilityA.toInt(), A);
+
+        QString changeabilityB = qElement.attribute("changeabilityB", "0");
+        if (changeabilityB.toInt() > 0)
+            setChangeability((Uml::Changeability_Type)changeabilityB.toInt(), B);
+
+    } else {
+
+        // we should disconnect any prior association (can this happen??)
+        if (m_pObject && m_pObject->getBaseType() == ot_Association)
+        {
+            UMLAssociation *umla = getAssociation();
+            umla->disconnect(this);
+            umla->nrof_parent_widgets--;
+        }
+
+        // New style: The xmi.id is a reference to the UMLAssociation.
+        // If the UMLObject is not found right now, we try again later
+        // during the type resolution pass - see activate().
+        m_nId = STR2ID(id);
+        UMLObject *myObj = m_umldoc->findObjectById(m_nId);
+        if (myObj) {
+            const Uml::Object_Type ot = myObj->getBaseType();
+            if (ot != ot_Association) {
+                setUMLObject(myObj);
+            } else {
+                UMLAssociation * myAssoc = static_cast<UMLAssociation*>(myObj);
+                setUMLAssociation(myAssoc);
+                if (type == "-1")
+                    aType = myAssoc->getAssocType();
+            }
+        }
+    }
+
+    setAssocType(aType);
+
+    QString indexa = qElement.attribute("indexa", "0");
+    QString indexb = qElement.attribute("indexb", "0");
+    QString totalcounta = qElement.attribute("totalcounta", "0");
+    QString totalcountb = qElement.attribute("totalcountb", "0");
+    m_role[A].m_nIndex = indexa.toInt();
+    m_role[B].m_nIndex = indexb.toInt();
+    m_role[A].m_nTotalCount = totalcounta.toInt();
+    m_role[B].m_nTotalCount = totalcountb.toInt();
+
+    QString assocclassid = qElement.attribute("assocclass", "");
+    if (! assocclassid.isEmpty()) {
+        Uml::IDType acid = STR2ID(assocclassid);
+        UMLWidget *w = Widget_Utils::findWidget(acid, widgets);
+        if (w) {
+            m_pAssocClassWidget = static_cast<ClassifierWidget*>(w);
+            m_pAssocClassWidget->setClassAssocWidget(this);
+            // Preparation of the assoc class line is done in activate()
+            QString aclsegindex = qElement.attribute("aclsegindex", "0");
+            m_nLinePathSegmentIndex = aclsegindex.toInt();
+        } else {
+            uError() << "cannot find assocclass " << assocclassid;
+        }
+    }
+
+    //now load child elements
+    QDomNode node = qElement.firstChild();
+    QDomElement element = node.toElement();
+    while(!element.isNull()) {
+        QString tag = element.tagName();
+        if(tag == "linepath") {
+            if(!m_LinePath.loadFromXMI(element))
+                return false;
+            else {
+                // set up 'old' corner from first point in line
+                // as IF this ISNT done, then the subsequent call to
+                // widgetMoved will inadvertantly think we have made a
+                // big move in the position of the association when we haven't.
+                QPoint p = m_LinePath.getPoint(0);
+                m_role[A].m_OldCorner.setX(p.x());
+                m_role[A].m_OldCorner.setY(p.y());
+            }
+        } else if (tag == "floatingtext" ||
+                   tag == "UML:FloatingTextWidget") {  // for bkwd compatibility
+            QString r = element.attribute("role", "-1");
+            if(r == "-1")
+                return false;
+            Uml::Text_Role role = (Uml::Text_Role)r.toInt();
+            FloatingTextWidget *ft = new FloatingTextWidget(m_pView, role, "", Uml::id_Reserved);
+            if(! ft->loadFromXMI(element)) {
+                // Most likely cause: The FloatingTextWidget is empty.
+                delete ft;
+                node = element.nextSibling();
+                element = node.toElement();
+                continue;
+            }
+            // always need this
+            ft->setLink(this);
+
+            switch(role) {
+            case Uml::tr_MultiA:
+                m_role[A].m_pMulti = ft;
+                if(oldStyleLoad)
+                    setMulti(m_role[A].m_pMulti->text(), A);
+                break;
+
+            case Uml::tr_MultiB:
+                m_role[B].m_pMulti = ft;
+                if(oldStyleLoad)
+                    setMulti(m_role[B].m_pMulti->text(), B);
+                break;
+
+            case Uml::tr_ChangeA:
+                m_role[A].m_pChangeWidget = ft;
+                break;
+
+            case Uml::tr_ChangeB:
+                m_role[B].m_pChangeWidget = ft;
+                break;
+
+            case Uml::tr_Name:
+                m_pName = ft;
+                if(oldStyleLoad)
+                    setName(m_pName->text());
+                break;
+
+            case Uml::tr_Coll_Message:
+            case Uml::tr_Coll_Message_Self:
+                m_pName = ft;
+                ft->setLink(this);
+                ft->setActivated();
+                if(FloatingTextWidget::isTextValid(ft->text()))
+                    ft->show();
+                else
+                    ft->hide();
+                break;
+
+            case Uml::tr_RoleAName:
+                m_role[A].m_pRole = ft;
+                setRoleName(ft->text(), A);
+                break;
+            case Uml::tr_RoleBName:
+                m_role[B].m_pRole = ft;
+                setRoleName(ft->text(), B);
+                break;
+            default:
+                uDebug() << "unexpected FloatingTextWidget (textrole " << role << ")";
+                delete ft;
+                break;
+            }
+        }
+        node = element.nextSibling();
+        element = node.toElement();
+    }
+
+    return true;
+#endif
     //TODO: Port
     return false;
 }
@@ -986,7 +1229,73 @@
 
 void AssociationWidget::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
 {
+    QDomElement assocElement = qDoc.createElement("assocwidget");
+
+    WidgetBase::saveToXMI(qDoc, assocElement);
+    if (umlObject()) {
+        assocElement.setAttribute("xmi.id", ID2STR(umlObject()->getID()));
+    }
+    assocElement.setAttribute("type", associationType());
+    if (!association()) {
+        assocElement.setAttribute("visibilityA", visibility(Uml::A));
+        assocElement.setAttribute("visibilityB", visibility(Uml::B));
+        assocElement.setAttribute("changeabilityA", changeability(Uml::A));
+        assocElement.setAttribute("changeabilityB", changeability(Uml::B));
+        if (!umlObject()) {
+            assocElement.setAttribute("roleAdoc", roleDocumentation(Uml::A));
+            assocElement.setAttribute("roleBdoc", roleDocumentation(Uml::B));
+            assocElement.setAttribute("documentation", documentation());
+        }
+    }
+    assocElement.setAttribute("widgetaid", ID2STR(widgetIDForRole(Uml::A)));
+    assocElement.setAttribute("widgetbid", ID2STR(widgetIDForRole(Uml::B)));
     //TODO: Port
+#if 0
+    assocElement.setAttribute("indexa", m_role[A].m_nIndex);
+    assocElement.setAttribute("indexb", m_role[B].m_nIndex);
+    assocElement.setAttribute("totalcounta", m_role[A].m_nTotalCount);
+    assocElement.setAttribute("totalcountb", m_role[B].m_nTotalCount);
+#endif
+    m_associationLine->saveToXMI(qDoc, assocElement);
+
+    if(m_nameWidget->hasValidText()) {
+        m_nameWidget->saveToXMI(qDoc, assocElement);
+    }
+
+    if(multiplicityWidget(Uml::A)->hasValidText()) {
+        multiplicityWidget(Uml::A)->saveToXMI(qDoc, assocElement);
+    }
+
+    if(multiplicityWidget(Uml::B)->hasValidText()) {
+        multiplicityWidget(Uml::B)->saveToXMI(qDoc, assocElement);
+    }
+
+    if(roleWidget(Uml::A)->hasValidText()) {
+        roleWidget(Uml::A)->saveToXMI(qDoc, assocElement);
+    }
+
+    if(roleWidget(Uml::B)->hasValidText()) {
+        roleWidget(Uml::B)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (changeabilityWidget(Uml::A)->hasValidText()) {
+        changeabilityWidget(Uml::A)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (changeabilityWidget(Uml::B)->hasValidText()) {
+        changeabilityWidget(Uml::B)->saveToXMI(qDoc, assocElement);
+    }
+
+    if (m_associationClass) {
+        QString acid = ID2STR(m_associationClass->id());
+        assocElement.setAttribute("assocclass", acid);
+        //TODO: port
+#if 0
+        assocElement.setAttribute("aclsegindex", m_nLinePathSegmentIndex);
+#endif
+    }
+
+    qElement.appendChild(assocElement);
 }
 
 void AssociationWidget::slotMenuSelection(QAction *action)
--- branches/work/soc-umbrello/umbrello/widgets/floatingtextwidget.cpp #1010485:1010486
@@ -368,6 +368,17 @@
 }
 
 /**
+ * Checks and returns whether text represented by this FloatingTextWidget is valid
+ * or not.
+ *
+ * @see FloatingTextWidget::isTextValid()
+ */
+bool FloatingTextWidget::hasValidText() const
+{
+    return FloatingTextWidget::isTextValid(text());
+}
+
+/**
  * For a text to be valid it must be non-empty, i.e. have a length
  * larger that zero, and have at least one non whitespace character.
  *
@@ -379,9 +390,11 @@
     int length = text.length();
     if(length < 1)
         return false;
-    for(int i=0;i<length;i++)
-        if(!text.at(i).isSpace())
+    for(int i=0;i<length;i++) {
+        if(!text.at(i).isSpace()) {
             return true;
+        }
+    }
     return false;
 }
 
--- branches/work/soc-umbrello/umbrello/widgets/floatingtextwidget.h #1010485:1010486
@@ -85,6 +85,7 @@
     void handleRename();
     void changeName(const QString& newText);
 
+    bool hasValidText() const;
     static bool isTextValid(const QString &text);
 
     virtual void paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *);




More information about the umbrello-devel mailing list