void CSharpWriter::writeRealizationsRecursive(UMLClassifier *currentClass, UMLAssociationList *realizations, QTextStream &cs) { UMLAssociation *a; for (a = realizations->first(); a; a = realizations->next()) { // we know its a classifier if its in the list UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B); //FIXME: Interfaces realize themselves without this condition!? if (real == currentClass) continue; // collect operations of one realization UMLOperationList opreal = real->getOpList(); // write realizations cs << m_endl << m_container_indent << m_indentation << "#region " << real->getName() << " members" << m_endl << m_endl; writeOperations(opreal,cs,false,false,true); cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl; // Recurse to parent realizations UMLAssociationList parentReal = real->getRealizations(); if (!parentReal.isEmpty()) { writeRealizationsRecursive(real, &parentReal, cs); } } }
/** * Get a unique id for this codedocument. * @return id for the codedocument */ QString CodeGenerator::getUniqueID(CodeDocument * codeDoc) { QString id = codeDoc->getID(); // does this document already exist? then just return its present id if (!id.isEmpty() && findCodeDocumentByID(id)) { return id; } // approach now differs by whether or not it is a classifier code document ClassifierCodeDocument * classDoc = dynamic_cast<ClassifierCodeDocument*>(codeDoc); if (classDoc) { UMLClassifier *c = classDoc->getParentClassifier(); id = ID2STR(c->id()); // this is supposed to be unique already.. } else { QString prefix = "doc"; QString id = prefix + "_0"; int number = lastIDIndex; for ( ; findCodeDocumentByID(id); ++number) { id = prefix + '_' + QString::number(number); } lastIDIndex = number; } return id; }
/** * Reimplemented from UMLWidget::saveToXMI to save * classifierwidget data either to 'interfacewidget' or 'classwidget' * XMI element. */ void ClassifierWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement) { QDomElement conceptElement; UMLClassifier *umlc = classifier(); QString tagName = umlc->isInterface() ? "interfacewidget" : "classwidget"; conceptElement = qDoc.createElement(tagName); UMLWidget::saveToXMI( qDoc, conceptElement ); conceptElement.setAttribute("showoperations", visualProperty(ShowOperations)); conceptElement.setAttribute("showpubliconly", visualProperty(ShowPublicOnly)); conceptElement.setAttribute("showopsigs", m_operationSignature); conceptElement.setAttribute("showpackage", visualProperty(ShowPackage)); conceptElement.setAttribute("showscope", visualProperty(ShowVisibility)); if (! umlc->isInterface()) { conceptElement.setAttribute("showattributes", visualProperty(ShowAttributes)); conceptElement.setAttribute("showattsigs", m_attributeSignature); } if (umlc->isInterface() || umlc->isAbstract()) { conceptElement.setAttribute("drawascircle", visualProperty(DrawAsCircle)); } qElement.appendChild(conceptElement); }
/** * Checks if changes are valid and applies them if they are, * else returns false */ bool UMLTemplateDialog::apply() { m_datatypeWidget->apply(); QString name = m_pNameLE->text(); if(name.length() == 0) { KMessageBox::error(this, i18n("You have entered an invalid template name."), i18n("Template Name Invalid"), 0); m_pNameLE->setText(m_pTemplate->name()); return false; } UMLClassifier * pClass = dynamic_cast<UMLClassifier *>(m_pTemplate->parent()); if (pClass) { UMLObject *o = pClass->findChildObject(name); if (o && o != m_pTemplate) { KMessageBox::error(this, i18n("The template parameter name you have chosen is already being used in this operation."), i18n("Template Name Not Unique"), 0); m_pNameLE->setText(m_pTemplate->name()); return false; } } m_pTemplate->setName(name); m_stereotypeWidget->apply(); m_docWidget->apply(); return true; }
bool UMLOperationDialog::apply() { QString name = m_pNameLE -> text(); if( name.length() == 0 ) { KMessageBox::error(this, i18n("You have entered an invalid operation name."), i18n("Operation Name Invalid"), false); m_pNameLE -> setText( m_pOperation -> getName() ); return false; } UMLClassifier *classifier = dynamic_cast<UMLClassifier*>( m_pOperation->parent() ); if( classifier != 0L && classifier->checkOperationSignature(name, m_pOperation->getParmList(), m_pOperation) ) { QString msg = QString(i18n("An operation with that signature already exists in %1.\n")).arg(classifier->getName()) + QString(i18n("Choose a different name or parameter list." )); KMessageBox::error(this, msg, i18n("Operation Name Invalid"), false); return false; } m_pOperation -> setName( name ); if( m_pPublicRB -> isChecked() ) m_pOperation -> setVisibility( Uml::Visibility::Public ); else if( m_pPrivateRB -> isChecked() ) m_pOperation -> setVisibility( Uml::Visibility::Private ); else if (m_pProtectedRB -> isChecked() ) m_pOperation -> setVisibility( Uml::Visibility::Protected ); else if (m_pImplementationRB -> isChecked() ) m_pOperation -> setVisibility( Uml::Visibility::Implementation ); QString typeName = m_pRtypeCB->currentText(); UMLTemplate *tmplParam = classifier->findTemplate(typeName); if (tmplParam) m_pOperation->setType(tmplParam); else m_pOperation->setTypeName(typeName); m_pOperation->setStereotype( m_pStereoTypeCB->currentText() ); bool isAbstract = m_pAbstractCB->isChecked(); m_pOperation -> setAbstract( isAbstract ); if (isAbstract) { /* If any operation is abstract then the owning class needs to be made abstract. The inverse is not true: The fact that no operation is abstract does not mean that the class must be non-abstract. */ classifier->setAbstract(true); } m_pOperation->setStatic( m_pStaticCB->isChecked() ); m_pOperation->setConst( m_pQueryCB->isChecked() ); return true; }
QSize EntityWidget::calculateSize() { if (!m_pObject) { return UMLWidget::calculateSize(); } int width, height; QFont font = UMLWidget::getFont(); font.setItalic(false); font.setUnderline(false); font.setBold(false); const QFontMetrics fm(font); const int fontHeight = fm.lineSpacing(); int lines = 1;//always have one line - for name if ( !m_pObject->getStereotype().isEmpty() ) { lines++; } const int numberOfEntityAttributes = ((UMLEntity*)m_pObject)->entityAttributes(); height = width = 0; //set the height of the entity lines += numberOfEntityAttributes; if (numberOfEntityAttributes == 0) { height += fontHeight / 2; //no entity literals, so just add a bit of space } height += lines * fontHeight; //now set the width of the concept //set width to name to start with // FIXME spaces to get round beastie with font width, // investigate UMLWidget::getFontMetrics() width = getFontMetrics(FT_BOLD_ITALIC).boundingRect(' ' + getName() + ' ').width(); const int w = getFontMetrics(FT_BOLD).boundingRect(m_pObject->getStereotype(true)).width(); width = w > width?w:width; UMLClassifier* classifier = (UMLClassifier*)m_pObject; UMLClassifierListItemList list = classifier->getFilteredList(Uml::ot_EntityAttribute); UMLClassifierListItem* listItem = 0; for (listItem = list.first(); listItem; listItem = list.next()) { int w = fm.width( listItem->getName() ); width = w > width?w:width; } //allow for width margin width += ENTITY_MARGIN * 2; return QSize(width, height); }
/** * Event handler for hover leave events. */ void ClassifierWidget::hoverLeaveEvent(UMLSceneHoverEvent * event) { Q_UNUSED(event); if (!visualProperty(DrawAsCircle)) { UMLClassifier* umlC = classifier(); if (umlC && !umlC->isInterface()) { m_attributeExpanderBox->setVisible(false); } m_operationExpanderBox->setVisible(false); } }
// we basically want to update the doc and start text of this method void RubyCodeOperation::updateMethodDeclaration() { CodeDocument * doc = getParentDocument(); RubyClassifierCodeDocument * rubydoc = dynamic_cast<RubyClassifierCodeDocument*>(doc); UMLClassifier *c = rubydoc->getParentClassifier(); UMLOperation * o = getParentOperation(); bool isInterface = rubydoc->getParentClassifier()->isInterface(); QString endLine = getNewLineEndingChars(); // now, the starting text. //:UNUSED: QString strVis = o->visibility().toString(); // no return type for constructors QString fixedReturn = RubyCodeGenerator::cppToRubyType(o->getTypeName()); QString returnType = o->isConstructorOperation() ? QString("") : (fixedReturn + QString(" ")); QString methodName = o->name(); QString RubyClassName = rubydoc->getRubyClassName(c->name()); // Skip destructors, and operator methods which // can't be defined in ruby if ( methodName.startsWith('~') || QRegExp("operator\\s*(=|--|\\+\\+|!=)$").exactMatch(methodName) ) { getComment()->setText(""); return; } if (RubyClassName == methodName) { methodName = "initialize"; } methodName.remove(QRegExp("operator\\s*")); methodName = methodName.mid(0, 1).toLower() + methodName.mid(1); QString paramStr = QString(""); QStringList commentedParams; // assemble parameters UMLAttributeList list = getParentOperation()->getParmList(); int nrofParam = list.count(); int paramNum = 0; foreach (UMLAttribute* parm, list) { QString paramName = RubyCodeGenerator::cppToRubyName(parm->name()); paramStr += paramName; if (! parm->getInitialValue().isEmpty()) { paramStr += QString(" = ") + RubyCodeGenerator::cppToRubyType(parm->getInitialValue()); } paramNum++; if (paramNum != nrofParam ) paramStr += ", "; }
void TEST_pythonwriter::test_writeClass() { PythonWriterTest* py = new PythonWriterTest(); UMLClassifier* c = new UMLClassifier("Customer", "12345678"); UMLAttribute* attr; attr = c->createAttribute("name_"); attr = c->createAttribute("address_"); py->writeClass(c); // does the just created file exist? QFile file(temporaryPath() + py->findFileName(c, QLatin1String(".py"))); QCOMPARE(file.exists(), true); }
void UMLOperationDialog::slotParameterProperties() { int result = 0; UMLAttribute* pAtt = 0, * pOldAtt = 0; pOldAtt = m_pOperation->findParm( m_pParmsLB->currentText() ); if( !pOldAtt ) { kDebug() << "THE impossible has occurred for:" << m_pParmsLB->currentText() << endl; return; }//should never occur ParmPropDlg dlg(this, m_doc, pOldAtt); result = dlg.exec(); QString name = dlg.getName(); pAtt = m_pOperation->findParm( name ); if( result ) { if( name.length() == 0 ) { KMessageBox::error(this, i18n("You have entered an invalid parameter name."), i18n("Parameter Name Invalid"), false); return; } if ( !pAtt || pOldAtt->getTypeName() != dlg.getTypeName() || pOldAtt->getDoc() != dlg.getDoc() || pOldAtt->getInitialValue() != dlg.getInitialValue() ) { pOldAtt->setName( name ); QString typeName = dlg.getTypeName(); if (pOldAtt->getTypeName() != typeName) { UMLClassifierList namesList( m_doc->getConcepts() ); UMLClassifier* obj = NULL; for (obj=namesList.first(); obj!=0; obj=namesList.next()) { if (typeName == obj->getFullyQualifiedName()) { pOldAtt->setType( obj ); break; } } if (obj == NULL) { // Nothing found: set type name directly. Bad. kDebug() << "UMLOperationDialog::slotParameterProperties: " << typeName << " not found." << endl; pOldAtt->setTypeName( typeName ); // Bad. } } m_pParmsLB->changeItem( dlg.getName(), m_pParmsLB -> currentItem() ); pOldAtt->setDoc( dlg.getDoc() ); pOldAtt->setInitialValue( dlg.getInitialValue() ); m_doc->setModified( true ); } else if( pAtt != pOldAtt ) { KMessageBox::error(this, i18n("The parameter name you have chosen is already being used in this operation."), i18n("Parameter Name Not Unique"), false); } } }
void RefactoringAssistant::createAttribute() { QListViewItem *item = selectedItem(); if(!item) { kWarning()<<"RefactoringAssistant::createAttribute() " <<"called with no item selected"<<endl; return; } UMLClassifier *c = dynamic_cast<UMLClassifier*>(findUMLObject( item )); if( !c ) return; c->createAttribute(); }
/** * Create new attribute. */ void RefactoringAssistant::createAttribute() { QTreeWidgetItem *item = currentItem(); if (!item) { uWarning() << "Called with no item selected."; return; } UMLClassifier *c = dynamic_cast<UMLClassifier*>(findUMLObject(item)); if (!c) { // find parent QTreeWidgetItem *parent = item->parent(); c = dynamic_cast<UMLClassifier*>(findUMLObject(parent)); if (!c) { uWarning() << "No classifier - cannot create!"; return; } } c->createAttribute(); }
void TEST_cppwriter::test_writeClass() { CppWriterTest* cpp = new CppWriterTest(); UMLClassifier* c = new UMLClassifier("Customer", "12345678"); UMLAttribute* attr; attr = c->createAttribute("name_"); attr = c->createAttribute("address_"); UMLOperation* op; op = c->createOperation("getName"); op = c->createOperation("getAddress"); cpp->writeClass(c); // does the just created file exist? QFile fileHeader(temporaryPath() + cpp->findFileName(c, QLatin1String(".h"))); QFile fileCPP(temporaryPath() + cpp->findFileName(c, QLatin1String(".cpp"))); QCOMPARE(fileHeader.exists(), true); QCOMPARE(fileCPP.exists(), true); }
/** * 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 = m_pEntityAttribute->umlParent()->asUMLClassifier(); UMLObject *o = pConcept ? pConcept->findChildObject(name) : 0; 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); } m_datatypeWidget->apply(); return true; }
// these exist for abstract classes only (which become xs:group nodes) QStringList XMLSchemaWriter::findAttributeGroups (UMLClassifier *c) { // we need to look for any class we inherit from. IF these // have attributes, then we need to notice QStringList list; UMLClassifierList superclasses = c->findSuperClassConcepts(); // list of what inherits from us for(UMLClassifier *classifier = superclasses.first(); classifier; classifier = superclasses.next()) { if(classifier->getAbstract()) { // only classes have attributes.. if (!classifier->isInterface()) { UMLAttributeList attribs = c->getAttributeList(); if (attribs.count() > 0) list.append(getElementName(classifier)+"AttribGroupType"); } } } return list; }
void PascalWriter::computeAssocTypeAndRole (UMLAssociation *a, QString& typeName, QString& roleName) { roleName = a->getRoleName(Uml::RoleType::A); if (roleName.isEmpty()) { if (a->getMultiplicity(Uml::RoleType::A).isEmpty()) { roleName = QLatin1String("M_"); roleName.append(typeName); } else { roleName = typeName; roleName.append(QLatin1String("_Vector")); } } UMLClassifier* c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::RoleType::A)); if (c == NULL) return; typeName = cleanName(c->name()); if (! a->getMultiplicity(Uml::RoleType::A).isEmpty()) typeName.append(QLatin1String("_Array_Access")); }
/** * Shows an operation dialog box. * * @param enableAutoIncrement Enable auto increment checkbox */ void FloatingTextWidget::showOperationDialog(bool enableAutoIncrement) { if (!m_linkWidget) { uError() << "m_linkWidget is NULL"; return; } QString seqNum = m_linkWidget->sequenceNumber(); UMLClassifier* c = m_linkWidget->lwClassifier(); QString opText = m_linkWidget->lwOperationText(); if (!c) { uError() << "m_linkWidget->lwClassifier() returns a NULL classifier"; return; } QPointer<SelectOperationDialog> selectDialog = new SelectOperationDialog(m_scene->activeView(), c, enableAutoIncrement); if (enableAutoIncrement && m_scene->autoIncrementSequence()) { seqNum = m_scene->autoIncrementSequenceValue(); selectDialog->setAutoIncrementSequence(true); } selectDialog->setSeqNumber(seqNum); if (m_linkWidget->operation() == 0) { selectDialog->setCustomOp(opText); } else { selectDialog->setClassOp(opText); } if (selectDialog->exec()) { seqNum = selectDialog->getSeqNumber(); opText = selectDialog->getOpText(); if (selectDialog->isClassOp()) { Model_Utils::OpDescriptor od; Model_Utils::Parse_Status st = Model_Utils::parseOperation(opText, od, c); if (st == Model_Utils::PS_OK) { UMLClassifierList selfAndAncestors = c->findSuperClassConcepts(); selfAndAncestors.prepend(c); UMLOperation *op = 0; foreach (UMLClassifier *cl, selfAndAncestors) { op = cl->findOperation(od.m_name, od.m_args); if (op) { break; } }
void RefactoringAssistant::addDerivedClassifier() { QListViewItem *item = selectedItem(); if(!item) { kWarning()<<"RefactoringAssistant::addDerivedClassifier() " <<"called with no item selected"<<endl; return; } UMLObject *obj = findUMLObject( item ); if( !dynamic_cast<UMLClassifier*>(obj) ) { kWarning()<<"RefactoringAssistant::addDerivedClassifier() " <<"called for a non-classifier object"<<endl; return; } //classes have classes and interfaces interfaces as super/derived classifiers Uml::Object_Type t = obj->getBaseType(); UMLClassifier *derived = static_cast<UMLClassifier*>(Object_Factory::createUMLObject(t)); if(!derived) return; m_doc->createUMLAssociation( derived, obj, Uml::at_Generalization ); ////////////////////// Manually add the classifier to the assitant - would be nicer to do it with ///////////////////// a signal, like operations and attributes QListViewItem *derivedFolder = item->firstChild(); while( derivedFolder->text(0) != i18n("Derived Classifiers") ) derivedFolder = derivedFolder->nextSibling(); if(!derivedFolder) { kWarning()<<"Cannot find Derived Folder"<<endl; return; } item = new KListViewItem( derivedFolder, derived->getName() ); item->setPixmap(0,m_pixmaps.Subclass); item->setExpandable( true ); m_umlObjectMap[item] = derived; addClassifier( derived, item, false, true, true); ///////////////////////// }
/** * Slot for adding a base classifier. */ void RefactoringAssistant::addBaseClassifier() { QTreeWidgetItem *item = currentItem(); if (!item) { uWarning() << "Called with no item selected"; return; } UMLObject *obj = findUMLObject(item); if (!dynamic_cast<UMLClassifier*>(obj)) { uWarning() << "Called for a non-classifier object."; return; } //classes have classes and interfaces interfaces as super/derived classifiers UMLObject::ObjectType t = obj->baseType(); UMLClassifier *super = static_cast<UMLClassifier*>(Object_Factory::createUMLObject(t)); if (!super) { return; } m_doc->createUMLAssociation(obj, super, Uml::AssociationType::Generalization); ////////////////////// Manually add the classifier to the assitant - would be nicer to do it with ///////////////////// a signal, like operations and attributes QTreeWidgetItem *baseFolder = 0; for (int i = 0; i < item->childCount(); ++i) { baseFolder = item->child(i); if (!baseFolder) { uWarning() << "Cannot find base folder!"; return; } if (baseFolder->text(0) == i18n("Base Classifiers")) { item = new QTreeWidgetItem(baseFolder, QStringList(super->name())); item->setIcon(0, Icon_Utils::SmallIcon(Icon_Utils::it_Generalisation)); item->setExpanded(true); m_umlObjectMap[item] = super; addClassifier(super, item, true, false, true); break; } } ///////////////////////// }
void CSharpWriter::writeOverridesRecursive(UMLClassifierList *superclasses, QTextStream &cs) { // oplist for implemented abstract operations UMLOperationList opabstract; opabstract.setAutoDelete(false); UMLClassifier *obj; for (obj = superclasses->first(); obj; obj = superclasses->next()) { if (!obj->isInterface() && obj->hasAbstractOps()) { // collect abstract ops UMLOperationList opl(obj->getOpList()); for (UMLOperation *op = opl.first(); op ; op = opl.next()) { if (op->getAbstract()) { opabstract.append(op); } } // write abstract implementations cs << m_endl << m_container_indent << m_indentation << "#region " << obj->getName() << " members" << m_endl << m_endl; writeOperations(opabstract,cs,false,true,true); cs << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl; opabstract.clear(); } // Recurse to parent superclasses UMLClassifierList superRecursive = obj->getSuperClasses(); UMLClassifierList *superRecursivePtr =& superRecursive; if (superRecursivePtr->count() > 0) { writeOverridesRecursive(superRecursivePtr, cs); } } }
/** * Checks if changes are valid and applies them if they are, * else returns false */ bool UMLTemplateDialog::apply() { QString typeName = m_pTypeCB->currentText(); UMLDoc *pDoc = UMLApp::app()->document(); UMLClassifierList namesList( pDoc->concepts() ); foreach (UMLClassifier* obj, namesList) { if (typeName == obj->name()) { m_pTemplate->setType(obj); } } if (namesList.isEmpty()) { // not found. // FIXME: This implementation is not good yet. m_pTemplate->setTypeName( typeName ); } QString name = m_pNameLE->text(); if( name.length() == 0 ) { KMessageBox::error(this, i18n("You have entered an invalid template name."), i18n("Template Name Invalid"), false); m_pNameLE->setText( m_pTemplate->name() ); return false; } UMLClassifier * pClass = dynamic_cast<UMLClassifier *>( m_pTemplate->parent() ); if (pClass) { UMLObject *o = pClass->findChildObject(name); if (o && o != m_pTemplate) { KMessageBox::error(this, i18n("The template parameter name you have chosen is already being used in this operation."), i18n("Template Name Not Unique"), false); m_pNameLE->setText( m_pTemplate->name() ); return false; } } m_pTemplate->setName(name); m_pTemplate->setStereotype( m_pStereoTypeLE->text() ); return true; }
/** * Delete an item from the tree. * @param item the tree widget item * @param obj the uml object */ void RefactoringAssistant::deleteItem(QTreeWidgetItem *item, UMLObject *obj) { UMLObject::ObjectType t = obj->baseType(); if (t == UMLObject::ot_Class || t == UMLObject::ot_Interface) { DEBUG(DBG_SRC) << "Delete class or interface - not yet implemented!"; //:TODO: } else if (t == UMLObject::ot_Operation) { QTreeWidgetItem *opNode = item->parent(); if (opNode) { QTreeWidgetItem *parent = opNode->parent(); UMLClassifier* c = static_cast<UMLClassifier*>(findUMLObject(parent)); if (!c) { uWarning() << "No classifier - cannot delete!"; return; } UMLOperation* op = static_cast<UMLOperation*>(obj); c->removeOperation(op); } } else if (t == UMLObject::ot_Attribute) { QTreeWidgetItem *attrNode = item->parent(); if (attrNode) { QTreeWidgetItem *parent = attrNode->parent(); UMLClassifier* c = static_cast<UMLClassifier*>(findUMLObject(parent)); if (!c) { uWarning() << "No classifier - cannot delete!"; return; } UMLAttribute* attr = static_cast<UMLAttribute*>(obj); c->removeAttribute(attr); } } else { uWarning() << "Called for unknown type " << typeid(*obj).name(); } }
QString UMLAttribute::getFullyQualifiedName( const QString& separator, bool includeRoot /* = false */) const { UMLOperation *op = NULL; UMLObject *owningObject = static_cast<UMLObject*>(parent()); if (owningObject->getBaseType() == Uml::ot_Operation) { op = static_cast<UMLOperation*>(owningObject); owningObject = static_cast<UMLObject*>(owningObject->parent()); } UMLClassifier *ownParent = dynamic_cast<UMLClassifier*>(owningObject); if (ownParent == NULL) { kError() << "UMLAttribute::getFullyQualifiedName(" << m_Name << "): parent " << owningObject->getName() << " is not a UMLClassifier" << endl; return ""; } QString tempSeparator = separator; if (tempSeparator.isEmpty()) tempSeparator = UMLApp::app()->activeLanguageScopeSeparator(); QString fqn = ownParent->getFullyQualifiedName(tempSeparator, includeRoot); if (op) fqn.append(tempSeparator + op->getName()); fqn.append(tempSeparator + m_Name); return fqn; }
QString UMLAttribute::toString(Uml::Signature_Type sig) { QString s; if(sig == Uml::st_ShowSig || sig == Uml::st_NoSig) { s = m_Vis.toString(true) + ' '; } if(sig == Uml::st_ShowSig || sig == Uml::st_SigNoVis) { // Determine whether the type name needs to be scoped. UMLObject *owningObject = static_cast<UMLObject*>(parent()); if (owningObject->getBaseType() == Uml::ot_Operation) { // The immediate parent() is the UMLOperation but we want // the UMLClassifier: owningObject = static_cast<UMLObject*>(owningObject->parent()); } UMLClassifier *ownParent = dynamic_cast<UMLClassifier*>(owningObject); if (ownParent == NULL) { kError() << "UMLAttribute::toString: parent " << owningObject->getName() << " is not a UMLClassifier" << endl; return ""; } QString typeName; UMLClassifier *type = UMLClassifierListItem::getType(); if (type) { UMLPackage *typeScope = type->getUMLPackage(); if (typeScope != ownParent && typeScope != ownParent->getUMLPackage()) typeName = type->getFullyQualifiedName(); else typeName = type->getName(); } // The default direction, "in", is not mentioned. // Perhaps we should include a pd_Unspecified in // Uml::Parameter_Direction to have better control over this. if (m_ParmKind == Uml::pd_InOut) s += "inout "; else if (m_ParmKind == Uml::pd_Out) s += "out "; // Construct the attribute text. QString string = s + getName() + " : " + typeName; if(m_InitialValue.length() > 0) string += " = " + m_InitialValue; return string; } return s + getName(); }
// we basically want to update the start text of this method void CPPSourceCodeAccessorMethod::updateMethodDeclaration() { CodeClassField * parentField = getParentClassField(); ClassifierCodeDocument * doc = parentField->getParentDocument(); CodeGenPolicyExt *pe = UMLApp::app()->policyExt(); CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe); // Check for dynamic casting failure! if (policy == NULL) { uError() << "policy: invalid dynamic cast"; return; } CPPCodeClassField * cppfield = dynamic_cast<CPPCodeClassField*>(parentField); // Check for dynamic casting failure! if (cppfield == NULL) { uError() << "cppfield: invalid dynamic cast"; return; } UMLClassifier * c = doc->getParentClassifier(); bool isInlineMethod = policy->getAccessorsAreInline(); QString tag = policy->getDocToolTag(); QString vectorClassName = policy->getVectorClassName(); QString fieldName = cppfield->getFieldName(); QString fieldType = cppfield->getTypeName(); QString objectType = cppfield->getListObjectType(); if(objectType.isEmpty()) objectType = fieldName; QString methodReturnType(QLatin1String("void")); QString methodName; // QLatin1String("get") + cppdoc->capitalizeFirstLetter(fieldName); QString methodParams = QChar(QLatin1Char(' ')); // QLatin1String("get") + cppdoc->capitalizeFirstLetter(fieldName); QString headerText; QString className = CodeGenerator::cleanName(c->name()); QString endLine = UMLApp::app()->commonPolicy()->getNewLineEndingChars(); switch(getType()) { case CodeAccessorMethod::ADD: methodName = QLatin1String("add_") + fieldType; methodReturnType = QLatin1String("void"); methodParams = objectType + QLatin1String(" value "); headerText = QLatin1String("Add a ") + fieldName + QLatin1String(" object to the ") + fieldName + QLatin1String("List") + endLine + getParentObject()->doc() + endLine + tag + QLatin1String("return void"); break; case CodeAccessorMethod::REMOVE: methodName = QLatin1String("remove_") + fieldType; methodParams = objectType + QLatin1String(" value "); methodReturnType = QLatin1String("void"); headerText = QLatin1String("Remove a ") + fieldName + QLatin1String(" object from the ") + fieldName + QLatin1String("List") + endLine + getParentObject()->doc() + endLine + tag + QLatin1String("return void"); break; case CodeAccessorMethod::LIST: methodName = QLatin1String("get_") + fieldType + QLatin1String("_list"); methodReturnType = vectorClassName; headerText = QLatin1String("Get the ") + fieldName + QLatin1String("List") + endLine + getParentObject()->doc() + endLine + tag + QLatin1String("return ") + vectorClassName + QLatin1String("with list of objects"); break; case CodeAccessorMethod::SET: methodName = QLatin1String("set_") + fieldName; methodParams = fieldType + QLatin1String(" value "); methodReturnType = QLatin1String("void"); headerText = QLatin1String("Set the value of ") + fieldName + endLine + getParentObject()->doc() + endLine + tag + QLatin1String("param value the value of ") + fieldName; break; case CodeAccessorMethod::GET: default: methodName = QLatin1String("get_") + fieldName; methodReturnType = fieldType; headerText = QLatin1String("Get the value of ") + fieldName + endLine + getParentObject()->doc() + endLine + tag + QLatin1String("return the value of ") + fieldName; break; } // set header CPPCodeDocumentation * header = new CPPCodeDocumentation(doc); if(!getParentObject()->doc().isEmpty()) header->setText(headerText); setComment(header); // set start method text (EndText never changes) setStartMethodText(methodReturnType + QLatin1Char(' ') + className + QLatin1String("::") + methodName + QLatin1String(" (") + methodParams + QLatin1Char(')') + QLatin1String(" {")); setOverallIndentationLevel(0); // these ONLY appear if they arent inline if(isInlineMethod) setWriteOutText(false); }
// we basically want to update the start text of this method void CPPSourceCodeAccessorMethod::updateMethodDeclaration() { CodeClassField * parentField = getParentClassField(); ClassifierCodeDocument * doc = parentField->getParentDocument(); CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt(); CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe); CPPCodeClassField * cppfield = dynamic_cast<CPPCodeClassField*>(parentField); UMLClassifier * c = doc->getParentClassifier(); bool isInlineMethod = policy->getAccessorsAreInline( ); QString vectorClassName = policy->getVectorClassName(); QString fieldName = cppfield->getFieldName(); QString fieldType = cppfield->getTypeName(); QString objectType = cppfield->getListObjectType(); if(objectType.isEmpty()) objectType = fieldName; QString methodReturnType = "void"; QString methodName; QString methodParams; QString headerText; QString className = CodeGenerator::cleanName(c->getName()); QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars(); switch(getType()) { case CodeAccessorMethod::ADD: methodName = "add_"+fieldType; methodReturnType = "void"; methodParams = objectType+" value "; headerText = "Add a "+fieldName+" object to the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return void"; break; case CodeAccessorMethod::REMOVE: methodName = "remove_"+fieldType; methodParams = objectType+" value "; methodReturnType = "void"; headerText = "Remove a "+fieldName+" object from the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return void"; break; case CodeAccessorMethod::LIST: methodName = "get_"+fieldType+"_list"; methodReturnType = vectorClassName; headerText = "Get the "+fieldName+"List"+endLine+getParentObject()->getDoc()+endLine+"@return "+vectorClassName+"with list of objects"; break; case CodeAccessorMethod::SET: methodName = "set_"+fieldName; methodParams = fieldType+" value "; methodReturnType = "void"; headerText = "Set the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@param value the value of "+fieldName; break; case CodeAccessorMethod::GET: default: methodName = "get_"+fieldName; methodReturnType = fieldType; headerText = "Get the value of "+fieldName+endLine+getParentObject()->getDoc()+endLine+"@return the value of "+fieldName; break; } // set header CPPCodeDocumentation * header = new CPPCodeDocumentation(doc); if(!getParentObject()->getDoc().isEmpty()) header->setText(headerText); setComment(header); // set start method text (EndText never changes) setStartMethodText(methodReturnType+' '+className+"::"+methodName+" ("+methodParams+')' + " {"); setOverallIndentationLevel(0); // these ONLY appear if they arent inline if(isInlineMethod) setWriteOutText(false); }
void CppTree2Uml::parseTypedef(TypedefAST* ast) { TypeSpecifierAST* typeSpec = ast->typeSpec(); InitDeclaratorListAST* declarators = ast->initDeclaratorList(); if (typeSpec && declarators){ QString typeId; if (typeSpec->name()) typeId = typeSpec->name()->text(); QList<InitDeclaratorAST*> l(declarators->initDeclaratorList()); InitDeclaratorAST* initDecl = 0; for (int i = 0; i < l.size(); ++i) { initDecl = l.at(i); if (initDecl==0) break; QString type, id; if (initDecl->declarator()){ type = typeOfDeclaration(typeSpec, initDecl->declarator()); DeclaratorAST* d = initDecl->declarator(); while (d->subDeclarator()){ d = d->subDeclarator(); } if (d->declaratorId()) id = d->declaratorId()->text(); } /* @todo Trace typedefs back to their root type for deciding whether to build a Datatype (for pointers.) */ /* check out if the ID type is a Datatype ex: typedef unsigned int uint; where unsigned int is a known datatype I'm not sure if setIsReference() should be run */ bool isDatatype = Import_Utils::isDatatype(typeId, m_currentNamespace[m_nsCnt]); if (type.contains(QLatin1Char('*')) || isDatatype) { UMLObject *inner = 0; if (m_currentNamespace[m_nsCnt] && m_currentNamespace[m_nsCnt]->baseType() == UMLObject::ot_Class && typeId == m_currentNamespace[m_nsCnt]->name()) inner = m_currentNamespace[m_nsCnt]; else inner = Import_Utils::createUMLObject(UMLObject::ot_Class, typeId, m_currentNamespace[m_nsCnt]); UMLObject *typedefObj = Import_Utils::createUMLObject(UMLObject::ot_Datatype, id, m_currentNamespace[m_nsCnt]); UMLClassifier *dt = static_cast<UMLClassifier*>(typedefObj); dt->setIsReference(); dt->setOriginType(static_cast<UMLClassifier*>(inner)); } else { Import_Utils::createUMLObject(UMLObject::ot_Class, id, m_currentNamespace[m_nsCnt], QString() /* doc */, QLatin1String("typedef") /* stereotype */); } } } }
/** * Reimplemented from UMLWidget::updateTextItemGroups to * calculate the Text strings, their properties and also hide/show * them based on the current state. */ void ClassifierWidget::updateTextItemGroups() { // Invalidate stuff and recalculate them. invalidateDummies(); TextItemGroup *headerGroup = textItemGroupAt(HeaderGroupIndex); TextItemGroup *attribOpGroup = textItemGroupAt(AttribOpGroupIndex); TextItemGroup *templateGroup = textItemGroupAt(TemplateGroupIndex); attribOpGroup->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); templateGroup->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); UMLClassifier *umlC = classifier(); UMLClassifierListItemList attribList = umlC->getFilteredList(UMLObject::ot_Attribute); UMLClassifierListItemList opList = umlC->getFilteredList(UMLObject::ot_Operation); // Set up template group and template text items. UMLTemplateList tlist = umlC->getTemplateList(); templateGroup->setTextItemCount(tlist.size()); bool templateHide = shouldDrawAsCircle(); // Hide if draw as circle. for(int i = 0; i < tlist.size(); ++i) { UMLTemplate *t = tlist[i]; templateGroup->textItemAt(i)->setText(t->toString()); templateGroup->textItemAt(i)->setExplicitVisibility(!templateHide); } // Stereo type and name. const int headerItemCount = 2; headerGroup->setTextItemCount(headerItemCount); const int cnt = attribList.count() + opList.count(); attribOpGroup->setTextItemCount(cnt); // Setup Stereo text item. TextItem *stereoItem = headerGroup->textItemAt(StereotypeItemIndex); stereoItem->setBold(true); stereoItem->setText(umlC->stereotype(true)); bool v = !shouldDrawAsCircle() && visualProperty(ShowStereotype) && !(umlC->stereotype(false).isEmpty()); stereoItem->setExplicitVisibility(v); // name item is always visible. TextItem *nameItem = headerGroup->textItemAt(NameItemIndex); nameItem->setBold(true); nameItem->setItalic(umlC->isAbstract()); nameItem->setUnderline(shouldDrawAsCircle()); QString nameText = name(); if (visualProperty(ShowPackage) == true) { nameText = umlC->fullyQualifiedName(); } bool showNameOnly = (!visualProperty(ShowAttributes) && !visualProperty(ShowOperations) && !visualProperty(ShowStereotype) && !shouldDrawAsCircle()); nameItem->setText(nameText); int attribStartIndex = 0; int opStartIndex = attribStartIndex + attribList.size(); // Now setup attribute texts. int visibleAttributes = 0; for (int i=0; i < attribList.size(); ++i) { UMLClassifierListItem *obj = attribList[i]; TextItem *item = attribOpGroup->textItemAt(attribStartIndex + i); item->setItalic(obj->isAbstract()); item->setUnderline(obj->isStatic()); item->setText(obj->toString(m_attributeSignature)); bool v = !shouldDrawAsCircle() && ( !visualProperty(ShowPublicOnly) || obj->visibility() == Uml::Visibility::Public) && visualProperty(ShowAttributes) == true; item->setExplicitVisibility(v); if (v) { ++visibleAttributes; } } // Update expander box to reflect current state and also visibility m_attributeExpanderBox->setExpanded(visualProperty(ShowAttributes)); const QString dummyText; // Setup line and dummies. if (!showNameOnly) { // Stuff in a dummy item as spacer if there are no attributes, if (!shouldDrawAsCircle() && (visibleAttributes == 0 || !visualProperty(ShowAttributes))) { m_dummyAttributeItem = new TextItem(dummyText); int index = attribStartIndex; if (visibleAttributes == 0 && !attribList.isEmpty()) { index = opStartIndex; } attribOpGroup->insertTextItemAt(index, m_dummyAttributeItem); m_lineItem2Index = index; ++opStartIndex; } else { // Now set the second index. m_lineItem2Index = opStartIndex - 1; } } int visibleOperations = 0; for (int i=0; i < opList.size(); ++i) { UMLClassifierListItem *obj = opList[i]; TextItem *item = attribOpGroup->textItemAt(opStartIndex + i); item->setItalic(obj->isAbstract()); item->setUnderline(obj->isStatic()); item->setText(obj->toString(m_operationSignature)); bool v = !shouldDrawAsCircle() && ( !visualProperty(ShowPublicOnly) || obj->visibility() == Uml::Visibility::Public) && visualProperty(ShowOperations); item->setExplicitVisibility(v); if (v) { ++visibleOperations; } } m_operationExpanderBox->setExpanded(visualProperty(ShowOperations)); if (!showNameOnly) { if (!shouldDrawAsCircle() && (visibleOperations == 0 || !visualProperty(ShowOperations))) { m_dummyOperationItem = new TextItem(dummyText); attribOpGroup->insertTextItemAt(opStartIndex+opList.size(), m_dummyOperationItem); } } UMLWidget::updateTextItemGroups(); }
void EntityWidget::draw(QPainter& p, int offsetX, int offsetY) { UMLWidget::setPen(p); if(UMLWidget::getUseFillColour()) p.setBrush(UMLWidget::getFillColour()); else p.setBrush(m_pView -> viewport() -> backgroundColor()); const int w = width(); const int h = height(); const QFontMetrics &fm = getFontMetrics(FT_NORMAL); int fontHeight = fm.lineSpacing(); const QString name = this->getName(); p.drawRect(offsetX, offsetY, w, h); p.setPen(QPen(Qt::black)); QFont font = UMLWidget::getFont(); font.setBold(true); p.setFont(font); int y = 0; if ( !m_pObject->getStereotype().isEmpty() ) { p.drawText(offsetX + ENTITY_MARGIN, offsetY, w - ENTITY_MARGIN * 2,fontHeight, Qt::AlignCenter, m_pObject->getStereotype(true)); font.setItalic( m_pObject -> getAbstract() ); p.setFont(font); p.drawText(offsetX + ENTITY_MARGIN, offsetY + fontHeight, w - ENTITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name); font.setBold(false); font.setItalic(false); p.setFont(font); y = fontHeight * 2; } else { font.setItalic( m_pObject -> getAbstract() ); p.setFont(font); p.drawText(offsetX + ENTITY_MARGIN, offsetY, w - ENTITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name); font.setBold(false); font.setItalic(false); p.setFont(font); y = fontHeight; } UMLWidget::setPen(p); p.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y); QFontMetrics fontMetrics(font); UMLClassifier *classifier = (UMLClassifier*)m_pObject; UMLClassifierListItem* entityattribute = 0; UMLClassifierListItemList list = classifier->getFilteredList(Uml::ot_EntityAttribute); for (entityattribute = list.first(); entityattribute; entityattribute = list.next()) { QString text = entityattribute->getName(); p.setPen( QPen(Qt::black) ); UMLEntityAttribute* casted = dynamic_cast<UMLEntityAttribute*>( entityattribute ); if( casted && casted->getIndexType() == Uml::Primary ) { font.setUnderline( true ); p.setFont( font ); font.setUnderline( false ); } p.drawText(offsetX + ENTITY_MARGIN, offsetY + y, fontMetrics.width(text), fontHeight, Qt::AlignVCenter, text); p.setFont( font ); y+=fontHeight; } if (m_bSelected) { drawSelected(&p, offsetX, offsetY); } }
/** * Draws the entity as a rectangle with a box underneith with a list of literals */ void EntityWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); setPenFromSettings(painter); if(UMLWidget::useFillColor()) painter->setBrush(UMLWidget::fillColor()); else painter->setBrush(m_scene->backgroundColor()); const int w = width(); const int h = height(); const QFontMetrics &fm = getFontMetrics(FT_NORMAL); int fontHeight = fm.lineSpacing(); const QString name = this->name(); painter->drawRect(0, 0, w, h); painter->setPen(textColor()); QFont font = UMLWidget::font(); font.setBold(true); painter->setFont(font); int y = 0; if (!m_umlObject->stereotype().isEmpty()) { painter->drawText(ENTITY_MARGIN, 0, w - ENTITY_MARGIN * 2, fontHeight, Qt::AlignCenter, m_umlObject->stereotype(true)); font.setItalic(m_umlObject->isAbstract()); painter->setFont(font); painter->drawText(ENTITY_MARGIN, fontHeight, w - ENTITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name); font.setBold(false); font.setItalic(false); painter->setFont(font); y = fontHeight * 2; } else { font.setItalic(m_umlObject->isAbstract()); painter->setFont(font); painter->drawText(ENTITY_MARGIN, 0, w - ENTITY_MARGIN * 2, fontHeight, Qt::AlignCenter, name); font.setBold(false); font.setItalic(false); painter->setFont(font); y = fontHeight; } setPenFromSettings(painter); painter->drawLine(0, y, w, y); QFontMetrics fontMetrics(font); UMLClassifier *classifier = (UMLClassifier*)m_umlObject; UMLClassifierListItem* entityattribute = 0; UMLClassifierListItemList list = classifier->getFilteredList(UMLObject::ot_EntityAttribute); foreach (entityattribute, list) { QString text = entityattribute->name(); painter->setPen(textColor()); UMLEntityAttribute* casted = dynamic_cast<UMLEntityAttribute*>(entityattribute); if(casted && casted->indexType() == UMLEntityAttribute::Primary) { font.setUnderline(true); painter->setFont(font); font.setUnderline(false); } painter->drawText(ENTITY_MARGIN, y, fontMetrics.width(text), fontHeight, Qt::AlignVCenter, text); painter->setFont(font); y+=fontHeight; }