Logo Search packages:      
Sourcecode: kdesdk-kde4 version File versions  Download package

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 3447 of file associationwidget.cpp.

References UMLAssociation::assocTypeHasUMLRepresentation(), UMLDoc::createUMLAssociation(), UMLDoc::findObjectById(), Widget_Utils::findWidget(), getAssociation(), UMLAssociation::getAssocType(), UMLObject::getBaseType(), LinePath::getPoint(), FloatingTextWidget::getText(), WidgetBase::getUMLObject(), FloatingTextWidget::isTextValid(), FloatingTextWidget::loadFromXMI(), LinePath::loadFromXMI(), loadFromXMI(), m_LinePath, WidgetBase::m_nId, AssociationWidget::WidgetRole::m_nIndex, m_nLinePathSegmentIndex, AssociationWidget::WidgetRole::m_nTotalCount, AssociationWidget::WidgetRole::m_OldCorner, m_pAssocClassWidget, AssociationWidget::WidgetRole::m_pChangeWidget, AssociationWidget::WidgetRole::m_pMulti, m_pName, AssociationWidget::WidgetRole::m_pRole, m_role, m_umldoc, UMLAssociation::nrof_parent_widgets, UMLWidget::setActivated(), setAssocType(), setChangeability(), ClassifierWidget::setClassAssocWidget(), WidgetBase::setDoc(), FloatingTextWidget::setLink(), setMulti(), setName(), setRoleDoc(), setRoleName(), setUMLAssociation(), setUMLObject(), setVisibility(), and setWidget().

{
    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) << endl;
        return false;
    }
    UMLWidget *pWidgetB = Widget_Utils::findWidget( bId, widgets, pMessages );
    if (!pWidgetB) {
        uError() << "cannot find widget for roleB id " << ID2STR(bId) << endl;
        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->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) {
                    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->getUMLObject();
                    umlRoleB = pWidgetB->getUMLObject();
                }

                setUMLAssociation(m_umldoc->createUMLAssociation(umlRoleA, umlRoleB, aType));
            }
        }

        setDoc( 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 << endl;
        }
    }

    //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->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:
            case Uml::tr_Coll_Message_Self:
                m_pName = ft;
                ft->setLink(this);
                ft->setActivated();
                if(FloatingTextWidget::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:
                uDebug() << "unexpected FloatingTextWidget (textrole "
                    << role << ")" << endl;
                delete ft;
                break;
            }
        }
        node = element.nextSibling();
        element = node.toElement();
    }

    return true;
}


Generated by  Doxygen 1.6.0   Back to index