Esempio n. 1
0
void UMLAttribute::setTemplateParams(const QString& templateParam, UMLClassifierList &templateParamList) {
    if (templateParam.isEmpty())
        return;
    QString type = templateParam.simplifyWhiteSpace();

    int start = type.find(QChar('<'));
    if (start >= 0 ) {
        int end = start;
        int count = 1;
        int len = type.length();
        while (count != 0 && ++end < len) {
            QChar c = type.at(end);
            if (c == QChar('<')) {
                count++;
            }
            if (c == QChar('>')) {
                count--;
            }
        }
        if (count != 0) {
            //The template is ill-formated, let's quit
            return;
        }
        setTemplateParams(type.mid(start + 1, end - start - 1), templateParamList);
        setTemplateParams(type.left(start) + type.right(len - end - 1), templateParamList);
    } else {
        QStringList paramsList = QStringList::split(QChar(','), type);
        for ( QStringList::Iterator it = paramsList.begin(); it != paramsList.end(); ++it ) {
            QString param = *it;
            if (!param.isEmpty()) {
                UMLDoc *pDoc = UMLApp::app()->getDocument();
                UMLObject* obj = pDoc->findUMLObject(param);
                if (obj == NULL ) {
                    obj = pDoc->findUMLObject(param.remove(QChar(' ')));
                }
                if (obj != NULL ) {
                    //We want to list only the params that already exist in this document
                    //If the param doesnt't already exist, we couldn't draw an association anyway
                    UMLClassifier* tmpClassifier = static_cast<UMLClassifier*>(obj);
                    if (templateParamList.findRef(tmpClassifier) == -1) {
                        templateParamList.append(tmpClassifier);
                    }
                }
            }
        }
    }
}
Esempio n. 2
0
/**
 * Sets the classes Package.
 * DEPRECATED - use SetUMLPackage instead.
 *
 * @param _name   The classes Package name.
 */
void UMLObject::setPackage(const QString &_name)
{
    UMLObject *pkgObj = NULL;
    if (!_name.isEmpty()) {
        UMLDoc* umldoc = UMLApp::app()->document();
        pkgObj = umldoc->findUMLObject(_name);
        if (pkgObj == NULL) {
            uDebug() << "creating UMLPackage " << _name << " for " << m_name;
            pkgObj = Import_Utils::createUMLObject(ot_Package, _name);
        } else {
            const ObjectType ot = pkgObj->baseType();
            if (ot != ot_Package && ot != ot_Folder && ot != ot_Component) {
                uError() << m_name << ": " << "existing " << _name << " is not a container";
                // This should not happen - if it does, there may be further problems.
                // A container name should not overlap with another name in the same scope.
                pkgObj = Import_Utils::createUMLObject(ot_Package, _name);
            }
        }
    }
    setUMLPackage(static_cast<UMLPackage *>(pkgObj));
}
Esempio n. 3
0
/**
 * Resolve referenced objects (if any.)
 * Needs to be called after all UML objects are loaded from file.
 * This needs to be done after all model objects are loaded because
 * some of the xmi.id's might be forward references, i.e. they may
 * identify model objects which were not yet loaded at the point of
 * reference.
 * The default implementation attempts resolution of the m_SecondaryId.
 *
 * @return   True for success.
 */
bool UMLObject::resolveRef()
{
    if (m_pSecondary || (m_SecondaryId.isEmpty() && m_SecondaryFallback.isEmpty())) {
        maybeSignalObjectCreated();
        return true;
    }
#ifdef VERBOSE_DEBUGGING
    uDebug() << m_name << ": m_SecondaryId is " << m_SecondaryId;
#endif
    UMLDoc *pDoc = UMLApp::app()->document();
    // In the new, XMI standard compliant save format,
    // the type is the xmi.id of a UMLClassifier.
    if (! m_SecondaryId.isEmpty()) {
        m_pSecondary = pDoc->findObjectById(Uml::ID::fromString(m_SecondaryId));
        if (m_pSecondary != NULL) {
            if (m_pSecondary->baseType() == ot_Stereotype) {
                m_pStereotype = dynamic_cast<UMLStereotype*>(m_pSecondary.data());
                m_pStereotype->incrRefCount();
                m_pSecondary = NULL;
            }
            m_SecondaryId = QString();
            maybeSignalObjectCreated();
            return true;
        }
        if (m_SecondaryFallback.isEmpty()) {
            uDebug() << "object with xmi.id=" << m_SecondaryId << " not found, setting to undef";
            UMLFolder *datatypes = pDoc->datatypeFolder();
            m_pSecondary = Object_Factory::createUMLObject(ot_Datatype, QLatin1String("undef"), datatypes, false);
            return true;
        }
    }
    if (m_SecondaryFallback.isEmpty()) {
        uError() << m_name << ": cannot find type with id " << m_SecondaryId;
        return false;
    }
#ifdef VERBOSE_DEBUGGING
    uDebug() << m_name << ": could not resolve secondary ID " << m_SecondaryId
             << ", using secondary fallback " << m_SecondaryFallback;
#endif
    m_SecondaryId = m_SecondaryFallback;
    // Assume we're dealing with the older Umbrello format where
    // the type name was saved in the "type" attribute rather
    // than the xmi.id of the model object of the attribute type.
    m_pSecondary = pDoc->findUMLObject(m_SecondaryId, ot_UMLObject, this);
    if (m_pSecondary) {
        m_SecondaryId = QString();
        maybeSignalObjectCreated();
        return true;
    }
    // Work around Object_Factory::createUMLObject()'s incapability
    // of on-the-fly scope creation:
    if (m_SecondaryId.contains(QLatin1String("::"))) {
        // TODO: Merge Import_Utils::createUMLObject() into Object_Factory::createUMLObject()
        m_pSecondary = Import_Utils::createUMLObject(ot_UMLObject, m_SecondaryId, m_pUMLPackage);
        if (m_pSecondary) {
            if (Import_Utils::newUMLObjectWasCreated()) {
                maybeSignalObjectCreated();
                qApp->processEvents();
                uDebug() << "Import_Utils::createUMLObject() created a new type for "
                         << m_SecondaryId;
            } else {
                uDebug() << "Import_Utils::createUMLObject() returned an existing type for "
                         << m_SecondaryId;
            }
            m_SecondaryId = QString();
            return true;
        }
        uError() << "Import_Utils::createUMLObject() failed to create a new type for "
                 << m_SecondaryId;
        return false;
    }
    uDebug() << "Creating new type for " << m_SecondaryId;
    // This is very C++ specific - we rely on  some '*' or
    // '&' to decide it's a ref type. Plus, we don't recognize
    // typedefs of ref types.
    bool isReferenceType = (m_SecondaryId.contains(QLatin1Char('*')) ||
                            m_SecondaryId.contains(QLatin1Char('&')));
    ObjectType ot = ot_Class;
    if (isReferenceType) {
        ot = ot_Datatype;
    } else {
        if (Model_Utils::isCommonDataType(m_SecondaryId))
            ot = ot_Datatype;
    }
    m_pSecondary = Object_Factory::createUMLObject(ot, m_SecondaryId, NULL);
    if (m_pSecondary == NULL)
        return false;
    m_SecondaryId = QString();
    maybeSignalObjectCreated();
    //qApp->processEvents();
    return true;
}
Esempio n. 4
0
/**
 * Implement abstract operation from NativeImportBase.
 */
bool AdaImport::parseStmt()
{
    const int srcLength = m_source.count();
    QString keyword = m_source[m_srcIndex];
    UMLDoc *umldoc = UMLApp::app()->document();
    //uDebug() << '"' << keyword << '"';
    if (keyword == QLatin1String("with")) {
        if (m_inGenericFormalPart) {
            // mapping of generic formal subprograms or packages is not yet implemented
            return false;
        }
        while (++m_srcIndex < srcLength && m_source[m_srcIndex] != QLatin1String(";")) {
            QStringList components = m_source[m_srcIndex].toLower().split(QLatin1Char('.'));
            const QString& prefix = components.first();
            if (prefix == QLatin1String("system")
                || prefix == QLatin1String("ada")
                || prefix == QLatin1String("gnat")
                || prefix == QLatin1String("interfaces")
                || prefix == QLatin1String("text_io")
                || prefix == QLatin1String("unchecked_conversion")
                || prefix == QLatin1String("unchecked_deallocation")) {
                if (advance() != QLatin1String(","))
                    break;
                continue;
            }
            parseStems(components);
            if (advance() != QLatin1String(","))
                break;
        }
        return true;
    }
    if (keyword == QLatin1String("generic")) {
        m_inGenericFormalPart = true;
        return true;
    }
    if (keyword == QLatin1String("package")) {
        const QString& name = advance();
        QStringList parentPkgs = name.toLower().split(QLatin1Char('.'));
        parentPkgs.pop_back();  // exclude the current package
        parseStems(parentPkgs);
        UMLObject *ns = NULL;
        if (advance() == QLatin1String("is")) {
            ns = Import_Utils::createUMLObject(UMLObject::ot_Package, name,
                                               currentScope(), m_comment);
            if (m_source[m_srcIndex + 1] == QLatin1String("new")) {
                m_srcIndex++;
                QString pkgName = advance();
                UMLObject *gp = Import_Utils::createUMLObject(UMLObject::ot_Package, pkgName,
                                                              currentScope());
                gp->setStereotype(QLatin1String("generic"));
                // Add binding from instantiator to instantiatee
                UMLAssociation *assoc = new UMLAssociation(Uml::AssociationType::Dependency, ns, gp);
                assoc->setUMLPackage(umldoc->rootFolder(Uml::ModelType::Logical));
                assoc->setStereotype(QLatin1String("bind"));
                // Work around missing display of stereotype in AssociationWidget:
                assoc->setName(assoc->stereotype(true));
                umldoc->addAssociation(assoc);
                skipStmt();
            } else {
                pushScope(static_cast<UMLPackage*>(ns));
            }
        } else if (m_source[m_srcIndex] == QLatin1String("renames")) {
            m_renaming[name] = advance();
        } else {
            uError() << "unexpected: " << m_source[m_srcIndex];
            skipStmt(QLatin1String("is"));
        }
        if (m_inGenericFormalPart) {
            if (ns)
                ns->setStereotype(QLatin1String("generic"));
            m_inGenericFormalPart = false;
        }
        return true;
    }
    if (m_inGenericFormalPart)
        return false;  // skip generic formal parameter (not yet implemented)
    if (keyword == QLatin1String("subtype")) {
        QString name = advance();
        advance();  // "is"
        QString base = expand(advance());
        base.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
        UMLObject *type = umldoc->findUMLObject(base, UMLObject::ot_UMLObject, currentScope());
        if (type == NULL) {
            type = Import_Utils::createUMLObject(UMLObject::ot_Datatype, base, currentScope());
        }
        UMLObject *subtype = Import_Utils::createUMLObject(type->baseType(), name,
                                                           currentScope(), m_comment);
        UMLAssociation *assoc = new UMLAssociation(Uml::AssociationType::Dependency, subtype, type);
        assoc->setUMLPackage(umldoc->rootFolder(Uml::ModelType::Logical));
        assoc->setStereotype(QLatin1String("subtype"));
        // Work around missing display of stereotype in AssociationWidget:
        assoc->setName(assoc->stereotype(true));
        umldoc->addAssociation(assoc);
        skipStmt();
        return true;
    }
    if (keyword == QLatin1String("type")) {
        QString name = advance();
        QString next = advance();
        if (next == QLatin1String("(")) {
            uDebug() << name << ": discriminant handling is not yet implemented";
            // @todo Find out how to map discriminated record to UML.
            //       For now, we just create a pro forma empty record.
            Import_Utils::createUMLObject(UMLObject::ot_Class, name, currentScope(),
                                          m_comment, QLatin1String("record"));
            skipStmt(QLatin1String("end"));
            if ((next = advance()) == QLatin1String("case"))
                m_srcIndex += 2;  // skip "case" ";"
            skipStmt();
            return true;
        }
        if (next == QLatin1String(";")) {
            // forward declaration
            Import_Utils::createUMLObject(UMLObject::ot_Class, name, currentScope(),
                                          m_comment);
            return true;
        }
        if (next != QLatin1String("is")) {
            uError() << "expecting \"is\"";
            return false;
        }
        next = advance();
        if (next == QLatin1String("(")) {
            // enum type
            UMLObject *ns = Import_Utils::createUMLObject(UMLObject::ot_Enum,
                            name, currentScope(), m_comment);
            UMLEnum *enumType = static_cast<UMLEnum*>(ns);
            while ((next = advance()) != QLatin1String(")")) {
                Import_Utils::addEnumLiteral(enumType, next, m_comment);
                m_comment.clear();
                if (advance() != QLatin1String(","))
                    break;
            }
            skipStmt();
            return true;
        }
        bool isTaggedType = false;
        if (next == QLatin1String("abstract")) {
            m_isAbstract = true;
            next = advance();
        }
        if (next == QLatin1String("tagged")) {
            isTaggedType = true;
            next = advance();
        }
        if (next == QLatin1String("limited") ||
            next == QLatin1String("task") ||
            next == QLatin1String("protected") ||
            next == QLatin1String("synchronized")) {
            next = advance();  // we can't (yet?) represent that
        }
        if (next == QLatin1String("private") ||
            next == QLatin1String("interface") ||
            next == QLatin1String("record") ||
            (next == QLatin1String("null") &&
             m_source[m_srcIndex+1] == QLatin1String("record"))) {
            UMLObject::ObjectType t = (next == QLatin1String("interface") ? UMLObject::ot_Interface
                                                                          : UMLObject::ot_Class);
            UMLObject *ns = Import_Utils::createUMLObject(t, name, currentScope(), m_comment);
            if (t == UMLObject::ot_Interface) {
                while ((next = advance()) == QLatin1String("and")) {
                    UMLClassifier *klass = static_cast<UMLClassifier*>(ns);
                    QString base = expand(advance());
                    UMLObject *p = Import_Utils::createUMLObject(UMLObject::ot_Interface, base, currentScope());
                    UMLClassifier *parent = static_cast<UMLClassifier*>(p);
                    Import_Utils::createGeneralization(klass, parent);
                }
            } else {
                ns->setAbstract(m_isAbstract);
            }
            m_isAbstract = false;
            if (isTaggedType) {
                if (! m_classesDefinedInThisScope.contains(ns))
                    m_classesDefinedInThisScope.append(ns);
            } else {
                ns->setStereotype(QLatin1String("record"));
            }
            if (next == QLatin1String("record"))
                m_klass = static_cast<UMLClassifier*>(ns);
            else
                skipStmt();
            return true;
        }
        if (next == QLatin1String("new")) {
            QString base = expand(advance());
            QStringList baseInterfaces;
            while ((next = advance()) == QLatin1String("and")) {
                baseInterfaces.append(expand(advance()));
            }
            const bool isExtension = (next == QLatin1String("with"));
            UMLObject::ObjectType t;
            if (isExtension || m_isAbstract) {
                t = UMLObject::ot_Class;
            } else {
                base.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
                UMLObject *known = umldoc->findUMLObject(base, UMLObject::ot_UMLObject, currentScope());
                t = (known ? known->baseType() : UMLObject::ot_Datatype);
            }
            UMLObject *ns = Import_Utils::createUMLObject(t, base, NULL);
            UMLClassifier *parent = static_cast<UMLClassifier*>(ns);
            ns = Import_Utils::createUMLObject(t, name, currentScope(), m_comment);
            if (isExtension) {
                next = advance();
                if (next == QLatin1String("null") || next == QLatin1String("record")) {
                    UMLClassifier *klass = static_cast<UMLClassifier*>(ns);
                    Import_Utils::createGeneralization(klass, parent);
                    if (next == QLatin1String("record")) {
                        // Set the m_klass for attributes.
                        m_klass = klass;
                    }
                    if (baseInterfaces.count()) {
                        t = UMLObject::ot_Interface;
                        QStringList::Iterator end(baseInterfaces.end());
                        for (QStringList::Iterator bi(baseInterfaces.begin()); bi != end; ++bi) {
                             ns = Import_Utils::createUMLObject(t, *bi, currentScope());
                             parent = static_cast<UMLClassifier*>(ns);
                             Import_Utils::createGeneralization(klass, parent);
                        }
                    }
                }
            }
            skipStmt();
            return true;
        }
        // Datatypes: TO BE DONE
        return false;
    }
    if (keyword == QLatin1String("private")) {
        m_currentAccess = Uml::Visibility::Private;
        return true;
    }
    if (keyword == QLatin1String("end")) {
        if (m_klass) {
            if (advance() != QLatin1String("record")) {
                uError() << "end: expecting \"record\" at "
                          << m_source[m_srcIndex];
            }
            m_klass = NULL;
        } else if (scopeIndex()) {
            if (advance() != QLatin1String(";")) {
                QString scopeName = currentScope()->fullyQualifiedName();
                if (scopeName.toLower() != m_source[m_srcIndex].toLower())
                    uError() << "end: expecting " << scopeName << ", found "
                              << m_source[m_srcIndex];
            }
            popScope();
            m_currentAccess = Uml::Visibility::Public;   // @todo make a stack for this
        } else {
            uError() << "importAda: too many \"end\"";
        }
        skipStmt();
        return true;
    }
    // subprogram
    if (keyword == QLatin1String("not"))
        keyword = advance();
    if (keyword == QLatin1String("overriding"))
        keyword = advance();
    if (keyword == QLatin1String("function") || keyword == QLatin1String("procedure")) {
        const QString& name = advance();
        QString returnType;
        if (advance() != QLatin1String("(")) {
            // Unlike an Ada package, a UML package does not support
            // subprograms.
            // In order to map those, we would need to create a UML
            // class with stereotype <<utility>> for the Ada package.
            uDebug() << "ignoring parameterless " << keyword << " " << name;
            skipStmt();
            return true;
        }
        UMLClassifier *klass = NULL;
        UMLOperation *op = NULL;
        const uint MAX_PARNAMES = 16;
        while (m_srcIndex < srcLength && m_source[m_srcIndex] != QLatin1String(")")) {
            QString parName[MAX_PARNAMES];
            uint parNameCount = 0;
            do {
                if (parNameCount >= MAX_PARNAMES) {
                    uError() << "MAX_PARNAMES is exceeded at " << name;
                    break;
                }
                parName[parNameCount++] = advance();
            } while (advance() == QLatin1String(","));
            if (m_source[m_srcIndex] != QLatin1String(":")) {
                uError() << "importAda: expecting ':'";
                skipStmt();
                break;
            }
            const QString &direction = advance();
            QString typeName;
            Uml::ParameterDirection::Enum dir = Uml::ParameterDirection::In;
            if (direction == QLatin1String("access")) {
                // Oops, we have to improvise here because there
                // is no such thing as "access" in UML.
                // So we use the next best thing, "inout".
                // Better ideas, anyone?
                dir = Uml::ParameterDirection::InOut;
                typeName = advance();
            } else if (direction == QLatin1String("in")) {
                if (m_source[m_srcIndex + 1] == QLatin1String("out")) {
                    dir = Uml::ParameterDirection::InOut;
                    m_srcIndex++;
                }
                typeName = advance();
            } else if (direction == QLatin1String("out")) {
                dir = Uml::ParameterDirection::Out;
                typeName = advance();
            } else {
                typeName = direction;  // In Ada, the default direction is "in"
            }
            typeName.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
            typeName = expand(typeName);
            if (op == NULL) {
                // In Ada, the first parameter indicates the class.
                UMLObject *type = Import_Utils::createUMLObject(UMLObject::ot_Class, typeName, currentScope());
                UMLObject::ObjectType t = type->baseType();
                if ((t != UMLObject::ot_Interface &&
                     (t != UMLObject::ot_Class || type->stereotype() == QLatin1String("record"))) ||
                    !m_classesDefinedInThisScope.contains(type)) {
                    // Not an instance bound method - we cannot represent it.
                    skipStmt(QLatin1String(")"));
                    break;
                }
                klass = static_cast<UMLClassifier*>(type);
                op = Import_Utils::makeOperation(klass, name);
                // The controlling parameter is suppressed.
                parNameCount--;
                if (parNameCount) {
                    for (uint i = 0; i < parNameCount; ++i) {
                        parName[i] = parName[i + 1];
                    }
                }
            }
            for (uint i = 0; i < parNameCount; ++i) {
                UMLAttribute *att = Import_Utils::addMethodParameter(op, typeName, parName[i]);
                att->setParmKind(dir);
            }
            if (advance() != QLatin1String(";"))
                break;
        }
        if (keyword == QLatin1String("function")) {
            if (advance() != QLatin1String("return")) {
                if (klass)
                    uError() << "importAda: expecting \"return\" at function "
                        << name;
                return false;
            }
            returnType = expand(advance());
            returnType.remove(QLatin1String("Standard."), Qt::CaseInsensitive);
        }
        bool isAbstract = false;
        if (advance() == QLatin1String("is") && advance() == QLatin1String("abstract"))
            isAbstract = true;
        if (klass != NULL && op != NULL)
            Import_Utils::insertMethod(klass, op, m_currentAccess, returnType,
                                       false, isAbstract, false, false, m_comment);
        skipStmt();
        return true;
    }
    if (keyword == QLatin1String("task") || keyword == QLatin1String("protected")) {
        // Can task and protected objects/types be mapped to UML?
        QString name = advance();
        if (name == QLatin1String("type")) {
            name = advance();
        }
        QString next = advance();
        if (next == QLatin1String("(")) {
            skipStmt(QLatin1String(")"));  // skip discriminant
            next = advance();
        }
        if (next == QLatin1String("is"))
            skipStmt(QLatin1String("end"));
        skipStmt();
        return true;
    }
    if (keyword == QLatin1String("for")) {    // rep spec
        QString typeName = advance();
        QString next = advance();
        if (next == QLatin1String("'")) {
            advance();  // skip qualifier
            next = advance();
        }
        if (next == QLatin1String("use")) {
            if (advance() == QLatin1String("record"))
                skipStmt(QLatin1String("end"));
        } else {
            uError() << "importAda: expecting \"use\" at rep spec of "
                      << typeName;
        }
        skipStmt();
        return true;
    }
    // At this point we're only interested in attribute declarations.
    if (m_klass == NULL || keyword == QLatin1String("null")) {
        skipStmt();
        return true;
    }
    const QString& name = keyword;
    if (advance() != QLatin1String(":")) {
        uError() << "adaImport: expecting \":\" at " << name << " "
                  << m_source[m_srcIndex];
        skipStmt();
        return true;
    }
    QString nextToken = advance();
    if (nextToken == QLatin1String("aliased"))
        nextToken = advance();
    QString typeName = expand(nextToken);
    QString initialValue;
    if (advance() == QLatin1String(":=")) {
        initialValue = advance();
        QString token;
        while ((token = advance()) != QLatin1String(";")) {
            initialValue.append(QLatin1Char(' ') + token);
        }
    }
    UMLObject *o = Import_Utils::insertAttribute(m_klass, m_currentAccess, name,
                                                 typeName, m_comment);
    if (o) {
        UMLAttribute *attr = static_cast<UMLAttribute*>(o);
        attr->setInitialValue(initialValue);
    }
    skipStmt();
    return true;
}
Esempio n. 5
0
/**
 * Returns the UML Object if found, or null otherwise.
 * @param name        name of the uml object
 * @param parentPkg   parent package
 * @return null or the uml objecct
 */
UMLObject* JavaImport::findObject(const QString& name, UMLPackage *parentPkg)
{
    UMLDoc *umldoc = UMLApp::app()->document();
    UMLObject * o = umldoc->findUMLObject(name, UMLObject::ot_UMLObject , parentPkg);
    return o;
}
/**
 * Checks if changes are valid and applies them if they are,
 * else returns false
 */
bool UMLEntityAttributeDialog::apply()
{
    QString name = m_pNameLE->text();
    if (name.isEmpty()) {
        KMessageBox::error(this, i18n("You have entered an invalid entity attribute name."),
                           i18n("Entity Attribute Name Invalid"), 0);
        m_pNameLE->setText(m_pEntityAttribute->name());
        return false;
    }
    UMLClassifier * pConcept = dynamic_cast<UMLClassifier *>(m_pEntityAttribute->parent());
    UMLObject *o = pConcept->findChildObject(name);
    if (o && o != m_pEntityAttribute) {
        KMessageBox::error(this, i18n("The entity attribute name you have chosen is already being used in this operation."),
                           i18n("Entity Attribute Name Not Unique"), 0);
        m_pNameLE->setText(m_pEntityAttribute->name());
        return false;
    }
    m_pEntityAttribute->setName(name);
    m_pEntityAttribute->setInitialValue(m_pInitialLE->text());
    m_stereotypeWidget->apply();
    m_pEntityAttribute->setValues(m_pValuesLE->text());
    m_pEntityAttribute->setAttributes(m_pAttributesCB->currentText());
    m_pEntityAttribute->setAutoIncrement(m_pAutoIncrementCB->isChecked());
    m_pEntityAttribute->setNull(m_pNullCB->isChecked());

    /*
    if (m_pPublicRB->isChecked()) {
        m_pEntityAttribute->setIndexType(UMLEntityAttribute::Primary);
    } else if (m_pProtectedRB->isChecked()) {
        m_pEntityAttribute->setIndexType(UMLEntityAttribute::Unique);
    } else
    */

    if (m_pPrivateRB->isChecked()) {
        m_pEntityAttribute->setIndexType(UMLEntityAttribute::Index);
    } else {
        m_pEntityAttribute->setIndexType(UMLEntityAttribute::None);
    }

    QString typeName = m_pTypeCB->currentText();
    UMLDoc *pDoc = UMLApp::app()->document();
    UMLClassifierList dataTypes = pDoc->datatypes();
    foreach (UMLClassifier* dat, dataTypes) {
        if (typeName == dat->name()) {
            m_pEntityAttribute->setType(dat);
            return true;
        }
    }
    UMLObject *obj = pDoc->findUMLObject(typeName);
    UMLClassifier *classifier = dynamic_cast<UMLClassifier*>(obj);
    if (classifier == NULL) {
        // If it's obviously a pointer type (C++) then create a datatype.
        // Else we don't know what it is so as a compromise create a class.
        UMLObject::ObjectType ot =
            (typeName.contains(QChar::fromLatin1('*')) ? UMLObject::ot_Datatype
                                                      : UMLObject::ot_Class);
        obj = Object_Factory::createUMLObject(ot, typeName);
        if (obj == NULL)
            return false;
        classifier = static_cast<UMLClassifier*>(obj);
    }
    m_pEntityAttribute->setType(classifier);
    return true;
}