Logo Search packages:      
Sourcecode: kdesdk version File versions

bool AssociationWidget::loadFromXMI ( QDomElement &  qElement,
const UMLWidgetList &  widgets,
const MessageWidgetList *  pMessages = NULL 
)

Same as above, but uses the supplied widgetList for resolving the role A and role B widgets. (The other loadFromXMI() queries the UMLView for these widgets.) Required for clipboard operations.

Definition at line 2870 of file associationwidget.cpp.

References UMLAssociation::assocTypeHasUMLRepresentation(), UMLDoc::findUMLObject(), findWidget(), getAssociation(), getAssocType(), UMLApp::getDocument(), LinePath::getPoint(), FloatingText::getText(), LinkWidget::getUMLObject(), FloatingText::isTextValid(), FloatingText::loadFromXMI(), LinePath::loadFromXMI(), m_LinePath, AssociationWidget::WidgetRole::m_nIndex, AssociationWidget::WidgetRole::m_nTotalCount, AssociationWidget::WidgetRole::m_OldCorner, AssociationWidget::WidgetRole::m_pChangeWidget, AssociationWidget::WidgetRole::m_pMulti, m_pName, AssociationWidget::WidgetRole::m_pRole, m_role, UMLAssociation::nrof_parent_widgets, UMLWidget::setActivated(), LinePath::setAssocType(), setAssocType(), setChangeability(), setDoc(), FloatingText::setLink(), setMulti(), setName(), setRoleDoc(), setRoleName(), setUMLAssociation(), setVisibility(), and setWidget().

{

      // load child widgets first
      QString widgetaid = qElement.attribute( "widgetaid", "-1" );
      QString widgetbid = qElement.attribute( "widgetbid", "-1" );
      int aId = widgetaid.toInt();
      int bId = widgetbid.toInt();
      UMLWidget *pWidgetA = findWidget( aId, widgets, pMessages );
      if (!pWidgetA) {
            kdError() << "AssociationWidget::loadFromXMI(): "
                    << "cannot find widget for roleA id " << aId << endl;
            return false;
      }
      UMLWidget *pWidgetB = findWidget( bId, widgets, pMessages );
      if (!pWidgetB) {
            kdError() << "AssociationWidget::loadFromXMI(): "
                    << "cannot find widget for roleB id " << bId << endl;
            return false;
      }
      setWidget(pWidgetA, A);
      setWidget(pWidgetB, B);

      QString id = qElement.attribute( "xmi.id", "-1" );
      bool oldStyleLoad = false;
      int nId = id.toInt();
      if (nId == -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.

            QString type = qElement.attribute( "type", "-1" );
            Uml::Association_Type aType = (Uml::Association_Type) type.toInt();
            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->getUMLObject();
                  UMLObject* umlRoleB = pWidgetB->getUMLObject();
                  if (!m_pObject && umlRoleA && umlRoleB)
                  {
                        oldStyleLoad = true; // flag for further special config below
                        if (aType == at_Aggregation || aType == at_Composition) {
                              kdWarning()<<" Old Style save file? swapping roles on association widget"<<this<<endl;
                              // 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->getUMLObject();
                              umlRoleB = pWidgetB->getUMLObject();
                        }

                        setUMLAssociation(UMLApp::app()->getDocument()->createUMLAssociation(umlRoleA, umlRoleB, aType));
                  }
            }

            setDoc( qElement.attribute("documentation", "") );
            setRoleDoc( qElement.attribute("roleAdoc", ""), A );
            setRoleDoc( qElement.attribute("roleBdoc", ""), B );

            setAssocType(aType);

            // visibilty defaults to Public if it cant set it here..
            QString visibilityA = qElement.attribute( "visibilityA", "0");
            if (visibilityA.toInt() > 0)
                  setVisibility( (Scope)visibilityA.toInt(), A);

            QString visibilityB = qElement.attribute( "visibilityB", "0");
            if (visibilityB.toInt() > 0)
                  setVisibility( (Scope)visibilityB.toInt(), B);

            // Changeability defaults to "Changeable" if it cant set it here..
            QString changeabilityA = qElement.attribute( "changeabilityA", "0");
            if (changeabilityA.toInt() > 0)
                  setChangeability( (Changeability_Type)changeabilityA.toInt(), A);

            QString changeabilityB = qElement.attribute( "changeabilityB", "0");
            if (changeabilityB.toInt() > 0)
                  setChangeability( (Changeability_Type)changeabilityB.toInt(), B);

      } else {

            // we should disconnect any prior association (can this happen??)
            if (m_pObject)
            {
                  UMLAssociation *umla = getAssociation();
                  umla->disconnect(this);
                  umla->nrof_parent_widgets--;
            }

            // New style: The xmi.id is a reference to the UMLAssociation.
            UMLDoc* umldoc = UMLApp::app()->getDocument();
            UMLAssociation * myAssoc = (UMLAssociation*)umldoc->findUMLObject(nId);
            if (myAssoc == NULL) {
                  kdError() << " AssociationWidget cannot find UML:Association " << nId << " for loadFromXMI"<< endl;
                  return false;
            } else
            {
                  setUMLAssociation(myAssoc);
            }

            m_LinePath.setAssocType( getAssociation()->getAssocType() );

      }

      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();

      //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();
                  FloatingText *ft = new FloatingText(m_pView, role, "", 0);
                  if( ! ft->loadFromXMI(element) ) {
                        // Most likely cause: The FloatingText 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->getText(), A);
                              break;

                        case Uml::tr_MultiB:
                              m_role[B].m_pMulti = ft;
                              if(oldStyleLoad)
                                    setMulti(m_role[B].m_pMulti->getText(), 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->getText());
                              break;

                        case Uml::tr_Coll_Message:
                              m_pName = ft;
                              ft->setLink(this);
                              ft->setActivated();
                              if(FloatingText::isTextValid(ft->getText()))
                                    ft -> show();
                              else
                                    ft -> hide();
                              break;

                        case Uml::tr_RoleAName:
                              m_role[A].m_pRole = ft;
                              setRoleName( ft->getText(), A );
                              break;
                        case Uml::tr_RoleBName:
                              m_role[B].m_pRole = ft;
                              setRoleName( ft->getText(), B );
                              break;
                        default:
                              kdDebug() << "AssociationWidget::loadFromXMI(): "
                                    << "unexpected FloatingText (textrole "
                                    << role << ")" << endl;
                              delete ft;
                              break;
                  }
            }
            node = element.nextSibling();
            element = node.toElement();
      }

      return true;
}


Generated by  Doxygen 1.6.0   Back to index