void RefactoringAssistant::attributeAdded( UMLClassifierListItem *a ) { UMLAttribute *att = static_cast<UMLAttribute*>(a); UMLClassifier *c = dynamic_cast<UMLClassifier*>(att->parent()); if(!c) { kWarning() << "RefactoringAssistant::attributeAdded(" << att->getName() << ") - Parent is not a class!" << endl; return; } QListViewItem *item = findListViewItem( c ); if( !item ) { return; } for( QListViewItem *folder = item->firstChild(); folder; folder = folder->nextSibling() ) { if( folder->text(1) == "attributes" ) { item = new KListViewItem( folder, att->getName() ); m_umlObjectMap[item] = att; connect( att, SIGNAL( modified() ), this, SLOT( umlObjectModified() ) ); setVisibilityIcon( item, att ); break; } } }
QString CPPCodeClassField::getInitialValue() { if (parentIsAttribute()) { UMLAttribute * at = dynamic_cast<UMLAttribute*>( getParentObject() ); if (at) { return fixInitialStringDeclValue(at->getInitialValue(), getTypeName()); } else { kError() << "CPPCodeClassField::getInitialValue: parent object is not a UMLAttribute" << endl; return ""; } } else { if(fieldIsSingleValue()) { // FIX : IF the multiplicity is "1" then we should init a new object here, if its 0 or 1, // then we can just return 'empty' string (minor problem). return ""; } else { return " new "+getListFieldClassName()+"( )"; } } }
/** * Returns the signature of items that are operations. * @return signature of an operation item, else an empty string */ QString UMLListViewItem::toolTip() { UMLObject *obj = umlObject(); if (obj) { switch (obj->baseType()) { case UMLObject::ot_Class: return obj->doc(); case UMLObject::ot_Operation: { UMLOperation *op = static_cast<UMLOperation*>(obj); return op->toString(Uml::SignatureType::ShowSig); } case UMLObject::ot_Attribute: { UMLAttribute *at = static_cast<UMLAttribute*>(obj); return at->toString(Uml::SignatureType::ShowSig); } default: return QString(); } } else { return QString(); } }
/** * Parse assignments in the form <identifier> '=' <value> * Instance variables are identified by a prefixed 'self.'. * @return success status of parsing */ bool PythonImport::parseAssignmentStmt(const QString keyword) { QString variable = keyword; advance(); QString value = advance(); if (value == QLatin1String("-")) value.append(advance()); bool isStatic = true; if (variable.startsWith(QLatin1String("self."))) { variable.remove(0,5); isStatic = false; } Uml::Visibility::Enum visibility = Uml::Visibility::Public; if (variable.startsWith(QLatin1String("__"))) { visibility = Uml::Visibility::Private; variable.remove(0, 2); } else if (variable.startsWith(QLatin1String("_"))) { visibility = Uml::Visibility::Protected; variable.remove(0, 1); } QString type; if (value == QLatin1String("[")) { if (lookAhead() == QLatin1String("]")) { advance(); type = QLatin1String("list"); value = QLatin1String(""); } } else if (value == QLatin1String("{")) { if (lookAhead() == QLatin1String("}")) { advance(); type = QLatin1String("dict"); value = QLatin1String(""); } } else if (value.startsWith(QLatin1String("\""))) { type = QLatin1String("string"); } else if (value == QLatin1String("True") || value == QLatin1String("False")) { type = QLatin1String("bool"); } else if (value.contains(QRegExp(QLatin1String("-?\\d+\\.\\d*")))) { type = QLatin1String("float"); } else if (value.contains(QRegExp(QLatin1String("-?\\d+")))) { type = QLatin1String("int"); } else if (!value.isEmpty()) { type = QLatin1String("object"); } UMLObject* o = Import_Utils::insertAttribute(m_klass, visibility, variable, type, m_comment, false); UMLAttribute* a = o->asUMLAttribute(); a->setInitialValue(value); a->setStatic(isStatic); return true; }
void CSharpWriter::writeAttributes(UMLClassifier *c, QTextStream &cs) { UMLAttributeList atpub, atprot, atpriv, atdefval; atpub.setAutoDelete(false); atprot.setAutoDelete(false); atpriv.setAutoDelete(false); atdefval.setAutoDelete(false); //sort attributes by scope and see if they have a default value UMLAttributeList atl = c->getAttributeList(); UMLAttribute *at; for (at = atl.first(); at ; at = atl.next()) { if (!at->getInitialValue().isEmpty()) atdefval.append(at); switch (at->getVisibility()) { case Uml::Visibility::Public: atpub.append(at); break; case Uml::Visibility::Protected: atprot.append(at); break; case Uml::Visibility::Private: atpriv.append(at); break; default: break; } } if (forceSections() || atl.count()) cs << m_endl << m_container_indent << m_indentation << "#region Attributes" << m_endl << m_endl; // write public attributes if (forceSections() || atpub.count()) { writeAttributes(atpub,cs); } // write protected attributes if (forceSections() || atprot.count()) { writeAttributes(atprot,cs); } // write private attributes if (forceSections() || atpriv.count()) { writeAttributes(atpriv,cs); } if (forceSections() || atl.count()) cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl << m_endl; }
/** * Slot for removing an attribute from the tree. * @param listItem the attribute to be removed */ void RefactoringAssistant::attributeRemoved(UMLClassifierListItem *listItem) { UMLAttribute *att = static_cast<UMLAttribute*>(listItem); DEBUG(DBG_SRC) << "attribute = " << att->name(); //:TODO: QTreeWidgetItem *item = findListViewItem(att); if (!item) { uWarning() << "Attribute is not in tree!"; return; } disconnect(att, SIGNAL(modified()), this, SLOT(objectModified())); m_umlObjectMap.remove(item); delete item; DEBUG(DBG_SRC) << "attribute = " << att->name() << " deleted!"; //:TODO: }
void UMLAttributeList::copyInto(UMLAttributeList *rhs) const { // Don't copy yourself. if (rhs == this) return; rhs->clear(); // Suffering from const; we shall not modify our object. UMLAttributeList *tmp = new UMLAttributeList(*this); UMLAttribute *item; for (item = tmp->first(); item; item = tmp->next() ) { rhs->append((UMLAttribute*)item->clone()); } delete tmp; }
QString CPPCodeClassField::getFieldName() { if (parentIsAttribute()) { UMLAttribute * at = (UMLAttribute*) getParentObject(); return cleanName(at->getName()); } else { UMLRole * role = (UMLRole*) getParentObject(); QString roleName = role->getName(); if(fieldIsSingleValue()) { return roleName.replace(0, 1, roleName.left(1).lower()); } else { return roleName.lower() + "Vector"; } } }
QString RubyCodeClassField::getFieldName() { if (parentIsAttribute()) { UMLAttribute * at = (UMLAttribute*) getParentObject(); return cleanName(at->name()); } else { UMLRole * role = (UMLRole*) getParentObject(); QString roleName = role->name(); if(fieldIsSingleValue()) { return roleName.replace(0, 1, roleName.left(1).toLower()); } else { return roleName.toLower() + QLatin1String("Array"); } } }
/** * Slot for adding an attribute to the tree. * @param listItem the new attribute to add */ void RefactoringAssistant::attributeAdded(UMLClassifierListItem *listItem) { UMLAttribute *att = static_cast<UMLAttribute*>(listItem); DEBUG(DBG_SRC) << "attribute = " << att->name(); //:TODO: UMLClassifier *parent = dynamic_cast<UMLClassifier*>(att->parent()); if (!parent) { uWarning() << att->name() << " - Parent of attribute is not a classifier!"; return; } QTreeWidgetItem *item = findListViewItem(parent); if (!item) { uWarning() << "Parent is not in tree!"; return; } for (int i = 0; i < item->childCount(); ++i) { QTreeWidgetItem *folder = item->child(i); if (folder->text(1) == QLatin1String("attributes")) { item = new QTreeWidgetItem(folder, QStringList(att->name())); m_umlObjectMap[item] = att; connect(att, SIGNAL(modified()), this, SLOT(objectModified())); setVisibilityIcon(item, att); DEBUG(DBG_SRC) << "attribute = " << att->name() << " added!"; //:TODO: break; } } }
QString JavaCodeClassField::getInitialValue() { if (parentIsAttribute()) { UMLAttribute * at = dynamic_cast<UMLAttribute*>(getParentObject()); if (at) { return fixInitialStringDeclValue(at->getInitialValue(), getTypeName()); } else { uError() << "parent object is not a UMLAttribute"; return QString(); } } else { if(fieldIsSingleValue()) { // FIX : IF the multiplicity is "1" then we should init a new object here, if its 0 or 1, // then we can just return 'empty' string (minor problem). return QString(); } else { return QLatin1String(" new ") + JavaCodeGenerator::getListFieldClassName() + QLatin1String("()"); } } }
/** * update the start and end text for this ownedhierarchicalcodeblock. */ void XMLElementCodeBlock::updateContent ( ) { QString endLine = getNewLineEndingChars(); QString nodeName = getNodeName(); // Now update START/ENDING Text QString startText = '<' + nodeName; QString endText = ""; UMLAttributeList * alist = getAttributeList(); for (UMLAttribute *at = alist->first(); at; at=alist->next()) { if(at->getInitialValue().isEmpty()) kWarning()<<" XMLElementCodeBlock : cant print out attribute that lacks an initial value"<<endl; else { startText.append(" " +at->getName()+"=\""); startText.append(at->getInitialValue()+"\""); } } // now set close of starting/ending node, the style depending on whether we have child text or not if(getTextBlockList()->count()) { startText.append(">"); endText = "</" + nodeName + '>'; } else { startText.append("/>"); endText = ""; } setStartText(startText); setEndText(endText); }
void CSharpWriter::writeAttributes(UMLAttributeList &atList, QTextStream &cs) { for (UMLAttribute *at = atList.first(); at ; at = atList.next()) { bool asProperty = true; if (at->getVisibility() == Uml::Visibility::Private) { asProperty = false; } writeAttribute(at->getDoc(), at->getVisibility(), at->getStatic(), makeLocalTypeName(at), at->getName(), at->getInitialValue(), asProperty, cs); cs << m_endl; } // end for return; }
void JSWriter::writeOperations(QString classname, UMLOperationList *opList, QTextStream &js) { UMLOperation *op; UMLAttribute *at; for(op = opList->first(); op; op = opList->next()) { UMLAttributeList atl = op->getParmList(); //write method doc if we have doc || if at least one of the params has doc bool writeDoc = forceDoc() || !op->getDoc().isEmpty(); for (at = atl.first(); at; at = atl.next()) writeDoc |= !at->getDoc().isEmpty(); if( writeDoc ) //write method documentation { js << "/**" << m_endl << formatDoc(op->getDoc()," * "); for (at = atl.first(); at; at = atl.next()) //write parameter documentation { if(forceDoc() || !at->getDoc().isEmpty()) { js << " * @param " + cleanName(at->getName())<<m_endl; js << formatDoc(at->getDoc()," * "); } }//end for : write parameter documentation js << " */" << m_endl; }//end if : write method documentation js << classname << ".prototype." << cleanName(op->getName()) << " = function " << "("; int i = atl.count(); int j=0; for (at = atl.first(); at ;at = atl.next(),j++) { js << cleanName(at->getName()) << (!(at->getInitialValue().isEmpty()) ? (QString(" = ")+at->getInitialValue()) : QString("")) << ((j < i-1)?", ":""); } js << ")" << m_endl << "{" << m_endl << m_indentation << m_endl << "}" << m_endl; js << m_endl << m_endl; }//end for }
void UMLOperationDialog::slotNewParameter() { int result = 0; UMLAttribute* pAtt = 0; QString currentName = m_pOperation->getUniqueParameterName(); UMLAttribute* newAttribute = new UMLAttribute(m_pOperation, currentName, Uml::id_Reserved); ParmPropDlg dlg(this, m_doc, newAttribute); 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); delete newAttribute; return; } if( !pAtt ) { newAttribute->setID( UniqueID::gen() ); newAttribute->setName( name ); newAttribute->setTypeName( dlg.getTypeName() ); newAttribute->setInitialValue( dlg.getInitialValue() ); newAttribute->setDoc( dlg.getDoc() ); newAttribute->setParmKind( dlg.getParmKind() ); m_pOperation->addParm( newAttribute ); m_pParmsLB -> insertItem( name ); m_doc -> setModified( true ); } else { KMessageBox::sorry(this, i18n("The parameter name you have chosen\nis already being used in this operation."), i18n("Parameter Name Not Unique"), false); delete newAttribute; } } else { delete newAttribute; } }
void SQLWriter::printAttributes(QTextStream& sql, UMLAttributeList attributeList, bool first) { QString attrDoc = ""; UMLAttribute* at; for (at=attributeList.first();at;at=attributeList.next()) { // print , after attribute if (first == false) { sql <<","; } else { first = false; } // print documentation/comment of last attribute at end of line if (attrDoc.isEmpty() == false) { sql << " -- " << attrDoc << m_endl; } else { sql << m_endl; } // write the attribute sql << m_indentation << cleanName(at->getName()) << " " << at->getTypeName() << " " << (at->getInitialValue().isEmpty()?QString(""):QString(" DEFAULT ")+at->getInitialValue()); // now get documentation/comment of current attribute attrDoc = at->getDoc(); } // print documentation/comment at end of line if (attrDoc.isEmpty() == false) { sql << " -- " << attrDoc << m_endl; } else { sql << m_endl; } return; }
/** * 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; }
// 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. QString strVis = rubydoc->scopeToRubyDecl(o->getVisibility()); // no return type for constructors QString fixedReturn = RubyCodeGenerator::cppToRubyType(o->getTypeName()); QString returnType = o->isConstructorOperation() ? QString("") : (fixedReturn + QString(" ")); QString methodName = o->getName(); QString RubyClassName = rubydoc->getRubyClassName(c->getName()); // 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.replace(QRegExp("operator\\s*"), ""); methodName = methodName.mid(0, 1).lower() + methodName.mid(1); QString paramStr = QString(""); QStringList commentedParams; // assemble parameters UMLAttributeList list = getParentOperation()->getParmList(); int nrofParam = list.count(); int paramNum = 0; for(UMLAttribute* parm = list.first(); parm; parm = list.next()) { QString paramName = RubyCodeGenerator::cppToRubyName(parm->getName()); paramStr += paramName; if (! parm->getInitialValue().isEmpty()) { paramStr += QString(" = ") + RubyCodeGenerator::cppToRubyType(parm->getInitialValue()); } paramNum++; if (paramNum != nrofParam ) paramStr += ", "; } QString startText; if (isInterface) { // Assume 'isInterface' means a module in Ruby, so // generate module methods startText = "def "+ RubyClassName + '.' + methodName + '(' + paramStr +')'; } else { startText = "def "+ methodName + '(' + paramStr +')'; } startText += ""; setEndMethodText("end"); setStartMethodText(startText); // Lastly, for text content generation, we fix the comment on the // operation, IF the codeop is autogenerated & currently empty QString comment = o->getDoc(); if (comment.isEmpty()) { if (getContentType() == CodeBlock::AutoGenerated) { UMLAttributeList parameters = o->getParmList(); for(UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) { comment += endLine + "* _" + iterator.current()->getName() + "_ "; comment += (' ' + iterator.current()->getDoc().replace( QRegExp("[\\n\\r]+[\\t ]*"), endLine + " " ) ); } // add a returns statement too if(!returnType.isEmpty() && !QRegExp("^void\\s*$").exactMatch(returnType)) comment += endLine + "* _returns_ " + returnType + ' '; getComment()->setText(comment); } } else { comment.replace(QRegExp("[\\n\\r]+ *"), endLine); comment.replace(QRegExp("[\\n\\r]+\\t*"), endLine); comment.replace(" m_", " "); comment.replace(QRegExp("\\s[npb](?=[A-Z])"), " "); QRegExp re_params("@param (\\w)(\\w*)"); int pos = re_params.search(comment); while (pos != -1) { comment.replace( re_params.cap(0), QString("@param _") + re_params.cap(1).lower() + re_params.cap(2) + '_' ); commentedParams.append(re_params.cap(1).lower() + re_params.cap(2)); pos += re_params.matchedLength() + 3; pos = re_params.search(comment, pos); } UMLAttributeList parameters = o->getParmList(); for (UMLAttributeListIt iterator(parameters); iterator.current(); ++iterator) { // Only write an individual @param entry if one hasn't been found already // in the main doc comment if (commentedParams.contains(RubyCodeGenerator::cppToRubyName(iterator.current()->getName())) == 0) { comment += (endLine + "@param _" + RubyCodeGenerator::cppToRubyName(iterator.current()->getName()) + '_'); if (iterator.current()->getDoc().isEmpty()) { comment += (' ' + RubyCodeGenerator::cppToRubyType(iterator.current()->getTypeName())); } else { comment += (' ' + iterator.current()->getDoc().replace(QRegExp("[\\n\\r]+[\\t ]*"), endLine + " ")); } } } comment.replace("@ref ", ""); comment.replace("@param", "*"); comment.replace("@return", "* _returns_"); // All lines after the first one starting with '*' in the doc comment // must be indented correctly. If they aren't a list // item starting with '*', then indent the text with // two spaces, ' ', to line up with the list item. pos = comment.find(endLine + '*'); if (pos != -1) { pos += endLine.length() + 1; pos = comment.find(endLine, pos); } while (pos > 0) { pos += endLine.length(); if (comment[pos] != '*') { comment.insert(pos, " "); pos += 2; } pos = comment.find(endLine, pos); } QString typeStr = RubyCodeGenerator::cppToRubyType(o->getTypeName()); if ( !typeStr.isEmpty() && !QRegExp("^void\\s*$").exactMatch(typeStr) && comment.contains("_returns_") == 0 ) { comment += endLine + "* _returns_ " + typeStr; } getComment()->setText(comment); } // In Java, for interfaces..we DONT write out non-public // method declarations. And for Ruby modules? if (isInterface) { UMLOperation * o = getParentOperation(); if(o->getVisibility() != Uml::Visibility::Public) setWriteOutText(false); } }
/** * Implement abstract operation from NativeImportBase. * @return success status of operation */ bool PascalImport::parseStmt() { const int srcLength = m_source.count(); QString keyword = m_source[m_srcIndex].toLower(); //uDebug() << '"' << keyword << '"'; if (keyword == "uses") { while (m_srcIndex < srcLength - 1) { QString unit = advance(); const QString& prefix = unit.toLower(); if (prefix == "sysutils" || prefix == "types" || prefix == "classes" || prefix == "graphics" || prefix == "controls" || prefix == "strings" || prefix == "forms" || prefix == "windows" || prefix == "messages" || prefix == "variants" || prefix == "stdctrls" || prefix == "extctrls" || prefix == "activex" || prefix == "comobj" || prefix == "registry" || prefix == "classes" || prefix == "dialogs") { if (advance() != ",") break; continue; } QString filename = unit + ".pas"; if (! m_parsedFiles.contains(unit)) { // Save current m_source and m_srcIndex. QStringList source(m_source); uint srcIndex = m_srcIndex; m_source.clear(); parseFile(filename); // Restore m_source and m_srcIndex. m_source = source; m_srcIndex = srcIndex; // Also reset m_currentAccess. // CHECK: need to reset more stuff? m_currentAccess = Uml::Visibility::Public; } if (advance() != ",") break; } return true; } if (keyword == "unit") { const QString& name = advance(); UMLObject *ns = Import_Utils::createUMLObject(Uml::ot_Package, name, m_scope[m_scopeIndex], m_comment); m_scope[++m_scopeIndex] = static_cast<UMLPackage*>(ns); skipStmt(); return true; } if (keyword == "interface") { m_inInterface = true; return true; } if (keyword == "initialization" || keyword == "implementation") { m_inInterface = false; return true; } if (! m_inInterface) { // @todo parseStmt() should support a notion for "quit parsing, close file immediately" return false; } if (keyword == "label") { m_section = sect_LABEL; return true; } if (keyword == "const") { m_section = sect_CONST; return true; } if (keyword == "resourcestring") { m_section = sect_RESOURCESTRING; return true; } if (keyword == "type") { m_section = sect_TYPE; return true; } if (keyword == "var") { m_section = sect_VAR; return true; } if (keyword == "threadvar") { m_section = sect_THREADVAR; return true; } if (keyword == "automated" || keyword == "published" // no concept in UML || keyword == "public") { m_currentAccess = Uml::Visibility::Public; return true; } if (keyword == "protected") { m_currentAccess = Uml::Visibility::Protected; return true; } if (keyword == "private") { m_currentAccess = Uml::Visibility::Private; return true; } if (keyword == "packed") { return true; // TBC: perhaps this could be stored in a TaggedValue } if (keyword == "[") { skipStmt("]"); return true; } if (keyword == "end") { if (m_klass) { m_klass = NULL; } else if (m_scopeIndex) { m_scopeIndex--; m_currentAccess = Uml::Visibility::Public; } else { uError() << "importPascal: too many \"end\""; } skipStmt(); return true; } if (keyword == "function" || keyword == "procedure" || keyword == "constructor" || keyword == "destructor") { if (m_klass == NULL) { // Unlike a Pascal unit, 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 unit, http://bugs.kde.org/89167 bool dummyVirtual = false; bool dummyAbstract = false; checkModifiers(dummyVirtual, dummyAbstract); return true; } const QString& name = advance(); UMLOperation *op = Import_Utils::makeOperation(m_klass, name); if (m_source[m_srcIndex + 1] == "(") { advance(); const uint MAX_PARNAMES = 16; while (m_srcIndex < srcLength && m_source[m_srcIndex] != ")") { QString nextToken = m_source[m_srcIndex + 1].toLower(); Uml::Parameter_Direction dir = Uml::pd_In; if (nextToken == "var") { dir = Uml::pd_InOut; advance(); } else if (nextToken == "const") { advance(); } else if (nextToken == "out") { dir = Uml::pd_Out; advance(); } 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() == ","); if (m_source[m_srcIndex] != ":") { uError() << "importPascal: expecting ':' at " << m_source[m_srcIndex]; skipStmt(); break; } nextToken = advance(); if (nextToken.toLower() == "array") { nextToken = advance().toLower(); if (nextToken != "of") { uError() << "importPascal(" << name << "): expecting 'array OF' at " << nextToken; skipStmt(); return false; } nextToken = advance(); } for (uint i = 0; i < parNameCount; ++i) { UMLAttribute *att = Import_Utils::addMethodParameter(op, nextToken, parName[i]); att->setParmKind(dir); } if (advance() != ";") break; } } QString returnType; if (keyword == "function") { if (advance() != ":") { uError() << "importPascal: expecting \":\" at function " << name; return false; } returnType = advance(); } else if (keyword == "constructor" || keyword == "destructor") { op->setStereotype(keyword); } skipStmt(); bool isVirtual = false; bool isAbstract = false; checkModifiers(isVirtual, isAbstract); Import_Utils::insertMethod(m_klass, op, m_currentAccess, returnType, !isVirtual, isAbstract, false, false, m_comment); return true; } if (m_section != sect_TYPE) { skipStmt(); return true; } if (m_klass == NULL) { const QString& name = m_source[m_srcIndex]; QString nextToken = advance(); if (nextToken != "=") { uDebug() << name << ": expecting '=' at " << nextToken; return false; } keyword = advance().toLower(); if (keyword == "(") { // enum type UMLObject *ns = Import_Utils::createUMLObject(Uml::ot_Enum, name, m_scope[m_scopeIndex], m_comment); UMLEnum *enumType = static_cast<UMLEnum*>(ns); while (++m_srcIndex < srcLength && m_source[m_srcIndex] != ")") { Import_Utils::addEnumLiteral(enumType, m_source[m_srcIndex]); if (advance() != ",") break; } skipStmt(); return true; } if (keyword == "set") { // @todo implement Pascal set types skipStmt(); return true; } if (keyword == "array") { // @todo implement Pascal array types skipStmt(); return true; } if (keyword == "file") { // @todo implement Pascal file types skipStmt(); return true; } if (keyword == "^") { // @todo implement Pascal pointer types skipStmt(); return true; } if (keyword == "class" || keyword == "interface") { Uml::Object_Type t = (keyword == "class" ? Uml::ot_Class : Uml::ot_Interface); UMLObject *ns = Import_Utils::createUMLObject(t, name, m_scope[m_scopeIndex], m_comment); UMLClassifier *klass = static_cast<UMLClassifier*>(ns); m_comment.clear(); QString lookAhead = m_source[m_srcIndex + 1]; if (lookAhead == "(") { advance(); do { QString base = advance(); UMLObject *ns = Import_Utils::createUMLObject(Uml::ot_Class, base, NULL); UMLClassifier *parent = static_cast<UMLClassifier*>(ns); m_comment.clear(); Import_Utils::createGeneralization(klass, parent); } while (advance() == ","); if (m_source[m_srcIndex] != ")") { uError() << "PascalImport: expecting \")\" at " << m_source[m_srcIndex]; return false; } lookAhead = m_source[m_srcIndex + 1]; } if (lookAhead == ";") { skipStmt(); return true; } if (lookAhead == "of") { // @todo implement class-reference type return false; } m_klass = klass; m_currentAccess = Uml::Visibility::Public; return true; } if (keyword == "record") { UMLObject *ns = Import_Utils::createUMLObject(Uml::ot_Class, name, m_scope[m_scopeIndex], m_comment); ns->setStereotype("record"); m_klass = static_cast<UMLClassifier*>(ns); return true; } if (keyword == "function" || keyword == "procedure") { /*UMLObject *ns =*/ Import_Utils::createUMLObject(Uml::ot_Datatype, name, m_scope[m_scopeIndex], m_comment); if (m_source[m_srcIndex + 1] == "(") skipToClosing('('); skipStmt(); return true; } // Datatypes: TO BE DONE return false; } // At this point we need a class because we're expecting its member attributes. if (m_klass == NULL) { uDebug() << "importPascal: skipping " << m_source[m_srcIndex]; skipStmt(); return true; } QString name, stereotype; if (keyword == "property") { stereotype = keyword; name = advance(); } else { name = m_source[m_srcIndex]; } if (advance() != ":") { uError() << "PascalImport: expecting \":\" at " << name << " " << m_source[m_srcIndex]; skipStmt(); return true; } QString typeName = advance(); QString initialValue; if (advance() == "=") { initialValue = advance(); QString token; while ((token = advance()) != ";") { initialValue.append(' ' + token); } } UMLObject *o = Import_Utils::insertAttribute(m_klass, m_currentAccess, name, typeName, m_comment); UMLAttribute *attr = static_cast<UMLAttribute*>(o); attr->setStereotype(stereotype); attr->setInitialValue(initialValue); skipStmt(); return true; }
void CSharpWriter::writeOperations(UMLOperationList opList, QTextStream &cs, bool isInterface /* = false */, bool isOverride /* = false */, bool generateErrorStub /* = false */) { for (UMLOperation *op=opList.first(); op ; op=opList.next()) { UMLAttributeList atl = op->getParmList(); UMLAttribute *at; //write method doc if we have doc || if at least one of the params has doc bool writeDoc = forceDoc() || !op->getDoc().isEmpty(); for (at = atl.first(); at; at = atl.next()) { writeDoc |= !at->getDoc().isEmpty(); } //write method documentation if (writeDoc && !isOverride) { cs << m_container_indent << m_indentation << "/// <summary>" << m_endl; cs << formatDoc(op->getDoc(), m_container_indent + m_indentation + "/// "); cs << m_container_indent << m_indentation << "/// </summary>" << m_endl; //write parameter documentation for (at = atl.first(); at; at = atl.next()) { if (forceDoc() || !at->getDoc().isEmpty()) { cs << m_container_indent << m_indentation << "/// <param name=\"" << cleanName(at->getName()) << "\">"; //removing newlines from parameter doc cs << formatDoc(at->getDoc(), "").replace("\n", " ").remove('\r').replace(QRegExp(" $"), ""); cs << "</param>" << m_endl; } } // FIXME: "returns" should contain documentation, not type. cs << m_container_indent << m_indentation << "/// <returns>"; if (! op->getTypeName().isEmpty()) { cs << makeLocalTypeName(op); } cs << "</returns>" << m_endl; } // method visibility cs << m_container_indent << m_indentation; if (!isInterface) { if (!isOverride) { if (op->getAbstract()) cs << "abstract "; cs << op->getVisibility().toString() << " "; if (op->getStatic()) cs << "static "; } else { // method overriding an abstract parent cs << op->getVisibility().toString() << " override "; if (op->getStatic()) cs << "static "; } } // return type (unless constructor, destructor) if (!op->isLifeOperation()) { if (op->getTypeName().isEmpty()) { cs << "void "; } else { cs << makeLocalTypeName(op) << " "; } } // method name cs << cleanName(op->getName()) << "("; // method parameters int i= atl.count(); int j=0; for (at = atl.first(); at; at = atl.next(), j++) { cs << makeLocalTypeName(at) << " " << cleanName(at->getName()); // no initial values in C# //<< (!(at->getInitialValue().isEmpty()) ? // (QString(" = ")+at->getInitialValue()) : // QString("")) cs << ((j < i-1)?", ":""); } cs << ")"; //FIXME: how to control generation of error stub? if (!isInterface && (!op->getAbstract() || isOverride)) { cs << m_endl << m_container_indent << m_indentation << "{" << m_endl; if (generateErrorStub) { cs << m_container_indent << m_indentation << m_indentation; cs << "throw new Exception(\"The method or operation is not implemented.\");" << m_endl; } cs << m_container_indent << m_indentation << "}" << m_endl; } else { cs << ';' << m_endl; } cs << m_endl; } }
/** * This slot is called to finish item editing */ void UMLListViewItem::slotEditFinished(const QString &newText) { m_label = text(0); DEBUG(DBG_LVI) << this << "text=" << newText; UMLListView* listView = static_cast<UMLListView*>(treeWidget()); UMLDoc* doc = listView->document(); if (newText == m_label) { return; } if (newText.isEmpty()) { cancelRenameWithMsg(); return; } switch (m_type) { case lvt_UseCase: case lvt_Actor: case lvt_Class: case lvt_Package: case lvt_UseCase_Folder: case lvt_Logical_Folder: case lvt_Component_Folder: case lvt_Deployment_Folder: case lvt_EntityRelationship_Folder: case lvt_Interface: case lvt_Datatype: case lvt_Enum: case lvt_EnumLiteral: case lvt_Subsystem: case lvt_Component: case lvt_Port: case lvt_Node: case lvt_Category: if (m_object == 0 || !doc->isUnique(newText)) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, newText)); doc->setModified(true); m_label = newText; break; case lvt_Operation: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLOperation *op = static_cast<UMLOperation*>(m_object); UMLClassifier *parent = static_cast<UMLClassifier *>(op->parent()); Model_Utils::OpDescriptor od; Model_Utils::Parse_Status st = Model_Utils::parseOperation(newText, od, parent); if (st == Model_Utils::PS_OK) { // TODO: Check that no operation with the exact same profile exists. UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(op, od.m_name)); op->setType(od.m_pReturnType); UMLAttributeList parmList = op->getParmList(); const int newParmListCount = parmList.count(); if (newParmListCount > od.m_args.count()) { // Remove parameters at end of of list that no longer exist. for (int i = od.m_args.count(); i < newParmListCount; i++) { UMLAttribute *a = parmList.at(i); op->removeParm(a, false); } } Model_Utils::NameAndType_ListIt lit = od.m_args.begin(); for (int i = 0; lit != od.m_args.end(); ++lit, ++i) { const Model_Utils::NameAndType& nm_tp = *lit; UMLAttribute *a; if (i < newParmListCount) { a = parmList.at(i); } else { a = new UMLAttribute(op); a->setID(UniqueID::gen()); } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(a, nm_tp.m_name)); a->setType(nm_tp.m_type); a->setParmKind(nm_tp.m_direction); a->setInitialValue(nm_tp.m_initialValue); if (i >= newParmListCount) { op->addParm(a); } } m_label = op->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_Attribute: case lvt_EntityAttribute: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLClassifier *parent = static_cast<UMLClassifier*>(m_object->parent()); Model_Utils::NameAndType nt; Uml::Visibility::Enum vis; Model_Utils::Parse_Status st; st = Model_Utils::parseAttribute(newText, nt, parent, &vis); if (st == Model_Utils::PS_OK) { UMLObject *exists = parent->findChildObject(newText); if (exists) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, nt.m_name)); UMLAttribute *pAtt = static_cast<UMLAttribute*>(m_object); pAtt->setType(nt.m_type); pAtt->setVisibility(vis); pAtt->setParmKind(nt.m_direction); pAtt->setInitialValue(nt.m_initialValue); m_label = pAtt->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_PrimaryKeyConstraint: case lvt_UniqueConstraint: case lvt_ForeignKeyConstraint: case lvt_CheckConstraint: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLEntity *parent = static_cast<UMLEntity*>(m_object->parent()); QString name; Model_Utils::Parse_Status st; st = Model_Utils::parseConstraint(newText, name, parent); if (st == Model_Utils::PS_OK) { UMLObject *exists = parent->findChildObject(name); if (exists) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, name)); UMLEntityConstraint* uec = static_cast<UMLEntityConstraint*>(m_object); m_label = uec->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_Template: { if (m_object == 0) { cancelRenameWithMsg(); return; } UMLClassifier *parent = static_cast<UMLClassifier*>(m_object->parent()); Model_Utils::NameAndType nt; Model_Utils::Parse_Status st = Model_Utils::parseTemplate(newText, nt, parent); if (st == Model_Utils::PS_OK) { UMLObject *exists = parent->findChildObject(newText); if (exists) { cancelRenameWithMsg(); return; } UMLApp::app()->executeCommand(new Uml::CmdRenameUMLObject(m_object, nt.m_name)); UMLTemplate *tmpl = static_cast<UMLTemplate*>(m_object); tmpl->setType(nt.m_type); m_label = tmpl->toString(Uml::SignatureType::SigNoVis); } else { KMessageBox::error(0, Model_Utils::psText(st), i18n("Rename canceled")); } setText(m_label); break; } case lvt_UseCase_Diagram: case lvt_Class_Diagram: case lvt_Sequence_Diagram: case lvt_Collaboration_Diagram: case lvt_State_Diagram: case lvt_Activity_Diagram: case lvt_Component_Diagram: case lvt_Deployment_Diagram: { UMLView *view = doc->findView(ID()); if (view == 0) { cancelRenameWithMsg(); return; } UMLView *anotherView = doc->findView(view->umlScene()->type(), newText); if (anotherView && anotherView->umlScene()->ID() == ID()) { anotherView = 0; } if (anotherView) { cancelRenameWithMsg(); return; } view->umlScene()->setName(newText); setText(newText); doc->signalDiagramRenamed(view); break; } default: KMessageBox::error(0, i18n("Renaming an item of listview type %1 is not yet implemented.", m_type), i18n("Function Not Implemented")); setText(m_label); break; } doc->setModified(true); }
/** If clipboard has mime type application/x-uml-clip5, Pastes the data from the clipboard into the current Doc */ bool UMLClipboard::pasteClip5(QMimeSource* data) { UMLDoc *doc = UMLApp::app()->getDocument(); UMLListView *listView = UMLApp::app()->getListView(); UMLListViewItem* lvitem = dynamic_cast<UMLListViewItem *>( listView->currentItem() ); if (!lvitem || (lvitem->getType() != Uml::lvt_Class && lvitem->getType() != Uml::lvt_Interface)) { return false; } UMLClassifier *parent = dynamic_cast<UMLClassifier *>(lvitem->getUMLObject()); if (parent == NULL) { kError() << "UMLClipboard::pasteClip5: parent is not a UMLClassifier" << endl; return false; } UMLObjectList objects; objects.setAutoDelete(false); IDChangeLog* idchanges = 0; bool result = UMLDrag::decodeClip5(data, objects, parent); if(!result) { return false; } UMLObject *obj = 0; doc->setModified(true); idchanges = doc->getChangeLog(); // Assume success if at least one child object could be pasted if (objects.count()) result = false; for (UMLObjectListIt it(objects); (obj = it.current()) != NULL; ++it) { obj->setID(doc->assignNewID(obj->getID())); switch(obj->getBaseType()) { case Uml::ot_Attribute : { UMLObject *exist = parent->findChildObject(obj->getName(), Uml::ot_Attribute); if (exist) { QString newName = parent->uniqChildName(Uml::ot_Attribute, obj->getName()); obj->setName(newName); } UMLAttribute *att = static_cast<UMLAttribute*>(obj); if (parent->addAttribute(att, idchanges)) { result = true; } else { kError() << "UMLClipboard::pasteClip5: " << parent->getName() << "->addAttribute(" << att->getName() << ") failed" << endl; } break; } case Uml::ot_Operation : { UMLOperation *op = static_cast<UMLOperation*>(obj); UMLOperation *exist = parent->checkOperationSignature(op->getName(), op->getParmList()); if (exist) { QString newName = parent->uniqChildName(Uml::ot_Operation, obj->getName()); op->setName(newName); } if (parent->addOperation(op, idchanges)) { result = true; } else { kError() << "UMLClipboard::pasteClip5: " << parent->getName() << "->addOperation(" << op->getName() << ") failed" << endl; } break; } default : kWarning() << "pasting unknown children type in clip type 5" << endl; return false; } } return result; }
void JSWriter::writeClass(UMLClassifier *c) { if(!c) { kDebug()<<"Cannot write class of NULL concept!" << endl; return; } QString classname = cleanName(c->getName()); QString fileName = c->getName().lower(); //find an appropriate name for our file fileName = findFileName(c,".js"); if (fileName.isEmpty()) { emit codeGenerated(c, false); return; } QFile filejs; if(!openFile(filejs, fileName)) { emit codeGenerated(c, false); return; } QTextStream js(&filejs); ////////////////////////////// //Start generating the code!! ///////////////////////////// //try to find a heading file (license, coments, etc) QString str; str = getHeadingFile(".js"); if(!str.isEmpty()) { str.replace(QRegExp("%filename%"),fileName); str.replace(QRegExp("%filepath%"),filejs.name()); js << str << m_endl; } //write includes UMLPackageList includes; findObjectsRelated(c,includes); for (UMLPackage *conc = includes.first(); conc; conc = includes.next()) { QString headerName = findFileName(conc, ".js"); if ( !headerName.isEmpty() ) { js << "#include \"" << headerName << "\"" << m_endl; } } js << m_endl; //Write class Documentation if there is somthing or if force option if(forceDoc() || !c->getDoc().isEmpty()) { js << m_endl << "/**" << m_endl; js << " * class " << classname << m_endl; js << formatDoc(c->getDoc()," * "); js << " */" << m_endl << m_endl; } //check if class is abstract and / or has abstract methods if(c->getAbstract() && !hasAbstractOps(c)) js << "/******************************* Abstract Class ****************************" << m_endl << " " << classname << " does not have any pure virtual methods, but its author" << m_endl << " defined it as an abstract class, so you should not use it directly." << m_endl << " Inherit from it instead and create only objects from the derived classes" << m_endl << "*****************************************************************************/" << m_endl << m_endl; js << classname << " = function ()" << m_endl; js << "{" << m_endl; js << m_indentation << "this._init ();" << m_endl; js << "}" << m_endl; js << m_endl; UMLClassifierList superclasses = c->getSuperClasses(); for (UMLClassifier *obj = superclasses.first(); obj; obj = superclasses.next()) { js << classname << ".prototype = new " << cleanName(obj->getName()) << " ();" << m_endl; } js << m_endl; if (! c->isInterface()) { UMLAttributeList atl = c->getAttributeList(); js << "/**" << m_endl; QString temp = "_init sets all " + classname + " attributes to their default value." " Make sure to call this method within your class constructor"; js << formatDoc(temp, " * "); js << " */" << m_endl; js << classname << ".prototype._init = function ()" << m_endl; js << "{" << m_endl; for(UMLAttribute *at = atl.first(); at ; at = atl.next()) { if (forceDoc() || !at->getDoc().isEmpty()) { js << m_indentation << "/**" << m_endl << formatDoc(at->getDoc(), m_indentation + " * ") << m_indentation << " */" << m_endl; } if(!at->getInitialValue().isEmpty()) { js << m_indentation << "this.m_" << cleanName(at->getName()) << " = " << at->getInitialValue() << ";" << m_endl; } else { js << m_indentation << "this.m_" << cleanName(at->getName()) << " = \"\";" << m_endl; } } } //associations UMLAssociationList aggregations = c->getAggregations(); if (forceSections() || !aggregations.isEmpty ()) { js << m_endl << m_indentation << "/**Aggregations: */" << m_endl; writeAssociation(classname, aggregations , js ); } UMLAssociationList compositions = c->getCompositions(); if( forceSections() || !compositions.isEmpty()) { js << m_endl << m_indentation << "/**Compositions: */" << m_endl; writeAssociation(classname, compositions , js ); } js << m_endl; js << "}" << m_endl; js << m_endl; //operations UMLOperationList ops(c->getOpList()); writeOperations(classname, &ops, js); js << m_endl; //finish file //close files and notfiy we are done filejs.close(); emit codeGenerated(c, true); }
/** * Utility method to get the value of parent object type. * the typeName of this parameters (e.g. boolean, int, etc or perhaps Class name of * an object) * @return the value of type */ QString CodeParameter::getTypeName ( ) { UMLAttribute * at = (UMLAttribute*) m_parentObject; return at->getTypeName(); }
void UMLOperationDialog::setupDialog() { int margin = fontMetrics().height(); QVBoxLayout * topLayout = new QVBoxLayout( plainPage() ); m_pGenGB = new QGroupBox(i18n("General Properties"), plainPage() ); QGridLayout * genLayout = new QGridLayout(m_pGenGB, 3, 4 ); genLayout -> setColStretch(1, 1); genLayout -> setColStretch(3, 1); genLayout -> addColSpacing(1, 200); genLayout -> addColSpacing(3, 200); genLayout -> setMargin(margin); genLayout -> setSpacing(10); Dialog_Utils::makeLabeledEditField( m_pGenGB, genLayout, 0, m_pNameL, i18n("&Name:"), m_pNameLE, m_pOperation->getName() ); m_pRtypeL = new QLabel(i18n("&Type:"), m_pGenGB ); genLayout -> addWidget(m_pRtypeL, 0, 2); m_pRtypeCB = new KComboBox(true, m_pGenGB ); genLayout -> addWidget(m_pRtypeCB, 0, 3); m_pRtypeL->setBuddy(m_pRtypeCB); m_pStereoTypeL = new QLabel( i18n("Stereotype name:"), m_pGenGB ); genLayout -> addWidget(m_pStereoTypeL, 1, 0); m_pStereoTypeCB = new KComboBox(true, m_pGenGB ); genLayout -> addWidget(m_pStereoTypeCB, 1, 1); m_pAbstractCB = new QCheckBox( i18n("&Abstract operation"), m_pGenGB ); m_pAbstractCB -> setChecked( m_pOperation->getAbstract() ); genLayout -> addWidget( m_pAbstractCB, 2, 0 ); m_pStaticCB = new QCheckBox( i18n("Classifier &scope (\"static\")"), m_pGenGB ); m_pStaticCB -> setChecked( m_pOperation->getStatic() ); genLayout -> addWidget( m_pStaticCB, 2, 1 ); m_pQueryCB = new QCheckBox( i18n("&Query (\"const\")"), m_pGenGB ); m_pQueryCB -> setChecked( m_pOperation->getConst() ); genLayout -> addWidget( m_pQueryCB, 2, 2 ); topLayout -> addWidget( m_pGenGB ); m_pScopeBG = new QButtonGroup(i18n("Visibility"), plainPage() ); QHBoxLayout * scopeLayout = new QHBoxLayout(m_pScopeBG); scopeLayout -> setMargin(margin); m_pPublicRB = new QRadioButton(i18n("P&ublic"), m_pScopeBG); scopeLayout -> addWidget(m_pPublicRB); m_pPrivateRB = new QRadioButton(i18n("P&rivate"), m_pScopeBG); scopeLayout -> addWidget(m_pPrivateRB); m_pProtectedRB = new QRadioButton(i18n("Prot&ected"), m_pScopeBG); scopeLayout -> addWidget(m_pProtectedRB); m_pImplementationRB = new QRadioButton(i18n("I&mplementation"), m_pScopeBG); scopeLayout -> addWidget(m_pImplementationRB); topLayout -> addWidget(m_pScopeBG); m_pParmsGB = new QGroupBox(i18n("Parameters"), plainPage() ); QVBoxLayout* parmsLayout = new QVBoxLayout(m_pParmsGB); parmsLayout->setMargin(margin); parmsLayout->setSpacing(10); //horizontal box contains the list box and the move up/down buttons QHBoxLayout* parmsHBoxLayout = new QHBoxLayout(parmsLayout); m_pParmsLB = new QListBox(m_pParmsGB); parmsHBoxLayout->addWidget(m_pParmsLB); //the move up/down buttons (another vertical box) QVBoxLayout* buttonLayout = new QVBoxLayout( parmsHBoxLayout ); m_pUpButton = new KArrowButton( m_pParmsGB ); m_pUpButton->setEnabled( false ); buttonLayout->addWidget( m_pUpButton ); m_pDownButton = new KArrowButton( m_pParmsGB, Qt::DownArrow ); m_pDownButton->setEnabled( false ); buttonLayout->addWidget( m_pDownButton ); KButtonBox* buttonBox = new KButtonBox(m_pParmsGB); buttonBox->addButton( i18n("Ne&w Parameter..."), this, SLOT(slotNewParameter()) ); m_pDeleteButton = buttonBox->addButton( i18n("&Delete"), this, SLOT(slotDeleteParameter()) ); m_pPropertiesButton = buttonBox->addButton( i18n("&Properties"), this, SLOT(slotParameterProperties()) ); parmsLayout->addWidget(buttonBox); topLayout -> addWidget(m_pParmsGB); m_pDeleteButton->setEnabled(false); m_pPropertiesButton->setEnabled(false); m_pUpButton->setEnabled(false); m_pDownButton->setEnabled(false); // Add "void". We use this for denoting "no return type" independent // of the programming language. // For example, the Ada generator would interpret the return type // "void" as an instruction to generate a procedure instead of a // function. insertType( "void" ); m_pRtypeCB->setDuplicatesEnabled(false);//only allow one of each type in box m_pRtypeCB->setCompletionMode( KGlobalSettings::CompletionPopup ); // add template parameters UMLClassifier *classifier = dynamic_cast<UMLClassifier*>(m_pOperation->parent()); if (classifier) { UMLClassifierListItemList tmplParams( classifier->getFilteredList(Uml::ot_Template) ); for (UMLClassifierListItem *li = tmplParams.first(); li; li = tmplParams.next()) insertType( li->getName() ); } //now add the Classes and Interfaces (both are Concepts) UMLClassifierList namesList( m_doc->getConcepts() ); UMLClassifier* pConcept = 0; for(pConcept=namesList.first(); pConcept!=0 ;pConcept=namesList.next()) { insertType( pConcept->getFullyQualifiedName() ); } //work out which one to select int returnBoxCount = 0; bool foundReturnType = false; while (returnBoxCount < m_pRtypeCB->count() && foundReturnType == false) { QString returnBoxString = m_pRtypeCB->text(returnBoxCount); if ( returnBoxString == m_pOperation->getTypeName() ) { foundReturnType = true; m_pRtypeCB->setCurrentItem(returnBoxCount); break; } returnBoxCount++; } if (!foundReturnType) { insertType( m_pOperation->getTypeName(), 0 ); m_pRtypeCB->setCurrentItem(0); } //fill in parm list box UMLAttributeList list = m_pOperation->getParmList(); UMLAttribute * pAtt = 0; for (pAtt = list.first(); pAtt; pAtt = list.next()) m_pParmsLB->insertItem( pAtt->getName() ); //set scope Uml::Visibility scope = m_pOperation -> getVisibility(); if( scope == Uml::Visibility::Public ) m_pPublicRB -> setChecked( true ); else if( scope == Uml::Visibility::Private ) m_pPrivateRB -> setChecked( true ); else if( scope == Uml::Visibility::Protected ) m_pProtectedRB -> setChecked( true ); else if( scope == Uml::Visibility::Implementation ) m_pImplementationRB -> setChecked( true ); // manage stereotypes m_pStereoTypeCB -> setDuplicatesEnabled(false);//only allow one of each type in box m_pStereoTypeCB->setCompletionMode( KGlobalSettings::CompletionPopup ); insertStereotype (QString("")); // an empty stereotype is the default int defaultStereotype=0; bool foundDefaultStereotype = false; for (UMLStereotypeListIt it(m_doc->getStereotypes()); it.current(); ++it) { if (!foundDefaultStereotype) { if ( m_pOperation->getStereotype() == it.current()->getName()) { foundDefaultStereotype = true; } defaultStereotype++; } insertStereotype (it.current()->getName()); } // lookup for a default stereotype, if the operation doesn't have one if (foundDefaultStereotype) m_pStereoTypeCB->setCurrentItem(defaultStereotype); else m_pStereoTypeCB->setCurrentItem(-1); //setup parm list box signals connect( m_pUpButton, SIGNAL( clicked() ), this, SLOT( slotParameterUp() ) ); connect( m_pDownButton, SIGNAL( clicked() ), this, SLOT( slotParameterDown() ) ); connect(m_pParmsLB, SIGNAL(clicked(QListBoxItem*)), this, SLOT(slotParamsBoxClicked(QListBoxItem*))); connect(m_pParmsLB, SIGNAL(rightButtonPressed(QListBoxItem *, const QPoint &)), this, SLOT(slotParmRightButtonPressed(QListBoxItem *, const QPoint &))); connect(m_pParmsLB, SIGNAL(rightButtonClicked(QListBoxItem *, const QPoint &)), this, SLOT(slotParmRightButtonClicked(QListBoxItem *, const QPoint &))); connect(m_pParmsLB, SIGNAL(doubleClicked(QListBoxItem *)), this, SLOT(slotParmDoubleClick(QListBoxItem *))); m_pNameLE->setFocus(); connect( m_pNameLE, SIGNAL( textChanged ( const QString & ) ), SLOT( slotNameChanged( const QString & ) ) ); slotNameChanged(m_pNameLE->text() ); }