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); } } }
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); } } }
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(); }
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); ///////////////////////// }
// 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 CSharpWriter::writeClass(UMLClassifier *c) { if (!c) { kDebug()<<"Cannot write class of NULL concept!" << endl; return; } QString classname = cleanName(c->getName()); //find an appropriate name for our file QString fileName = findFileName(c, ".cs"); if (fileName.isEmpty()) { emit codeGenerated(c, false); return; } QFile filecs; if (!openFile(filecs, fileName)) { emit codeGenerated(c, false); return; } QTextStream cs(&filecs); ////////////////////////////// //Start generating the code!! ///////////////////////////// //try to find a heading file (license, coments, etc) QString str; str = getHeadingFile(".cs"); if (!str.isEmpty()) { str.replace(QRegExp("%filename%"),fileName); str.replace(QRegExp("%filepath%"),filecs.name()); cs<<str<<m_endl; } UMLDoc *umldoc = UMLApp::app()->getDocument(); UMLFolder *logicalView = umldoc->getRootFolder(Uml::mt_Logical); // write generic includes cs << "using System;" << m_endl; cs << "using System.Text;" << m_endl; cs << "using System.Collections;" << m_endl; cs << "using System.Collections.Generic;" << m_endl << m_endl; //write includes and namespace UMLPackage *container = c->getUMLPackage(); if (container == logicalView) container = NULL; UMLPackageList includes; findObjectsRelated(c, includes); m_seenIncludes.clear(); //m_seenIncludes.append(logicalView); if (includes.count()) { UMLPackage *p; for (UMLPackageListIt it(includes); (p = it.current()) != NULL; ++it) { UMLClassifier *cl = dynamic_cast<UMLClassifier*>(p); if (cl) p = cl->getUMLPackage(); if (p != logicalView && m_seenIncludes.findRef(p) == -1 && p != container) { cs << "using " << p->getFullyQualifiedName(".") << ";" << m_endl; m_seenIncludes.append(p); } } cs << m_endl; } m_container_indent = ""; if (container) { cs << "namespace " << container->getFullyQualifiedName(".") << m_endl; cs << "{" << m_endl << m_endl; m_container_indent = m_indentation; m_seenIncludes.append(container); } //Write class Documentation if there is somthing or if force option if (forceDoc() || !c->getDoc().isEmpty()) { cs << m_container_indent << "/// <summary>" << m_endl; cs << formatDoc(c->getDoc(), m_container_indent + "/// " ); cs << m_container_indent << "/// </summary>" << m_endl ; } UMLClassifierList superclasses = c->getSuperClasses(); UMLAssociationList aggregations = c->getAggregations(); UMLAssociationList compositions = c->getCompositions(); UMLAssociationList realizations = c->getRealizations(); bool isInterface = c->isInterface(); m_unnamedRoles = 1; cs << m_container_indent << "public "; //check if it is an interface or regular class if (isInterface) { cs << "interface " << classname; } else { //check if class is abstract and / or has abstract methods if (c->getAbstract() || c->hasAbstractOps()) cs << "abstract "; cs << "class " << classname << (superclasses.count() > 0 ? " : ":""); // write baseclass, ignore interfaces, write error on multiple inheritance if (superclasses.count() > 0) { UMLClassifier *obj; int supers = 0; for (obj = superclasses.first(); obj; obj = superclasses.next()) { if (!obj->isInterface()) { if (supers > 0) { cs << " // AND "; } cs << cleanName(obj->getName()); supers++; } } if (supers > 1) { cs << m_endl << "//WARNING: C# does not support multiple inheritance but there is more than 1 superclass defined in your UML model!" << m_endl; } } //check for realizations UMLAssociationList realizations = c->getRealizations(); UMLAssociation *a; if (!realizations.isEmpty()) { for (a = realizations.first(); a; a = realizations.next()) { UMLClassifier *real = (UMLClassifier*)a->getObject(Uml::B); if(real != c) { // write list of realizations cs << ", " << real->getName(); } } } } cs << m_endl << m_container_indent << '{' << m_endl; //associations if (forceSections() || !aggregations.isEmpty()) { cs << m_endl << m_container_indent << m_indentation << "#region Aggregations" << m_endl << m_endl; writeAssociatedAttributes(aggregations, c, cs); cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl; } //compositions if (forceSections() || !compositions.isEmpty()) { cs << m_endl << m_container_indent << m_indentation << "#region Compositions" << m_endl << m_endl; writeAssociatedAttributes(compositions, c, cs); cs << m_endl << m_container_indent << m_indentation << "#endregion" << m_endl; } //attributes // FIXME: C# allows Properties in interface! if (!isInterface) writeAttributes(c, cs); //operations writeOperations(c, cs); //finish file cs << m_endl << m_container_indent << "}" << m_endl << m_endl; // close class if (container) { cs << "} // end of namespace " << container->getFullyQualifiedName(".") << m_endl << m_endl; } //close files and notfiy we are done filecs.close(); emit codeGenerated(c, 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); }
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; }
// This method will cause the class to rebuild its text representation. // based on the parent classifier object. // For any situation in which this is called, we are either building the code // document up, or replacing/regenerating the existing auto-generated parts. As // such, we will want to insert everything we resonablely will want // during creation. We can set various parts of the document (esp. the // comments) to appear or not, as needed. void CPPHeaderCodeDocument::updateContent( ) { // Gather info on the various fields and parent objects of this class... UMLClassifier * c = getParentClassifier(); CodeGenPolicyExt *pe = UMLApp::app()->getPolicyExt(); CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe); // first, set the global flag on whether or not to show classfield info CodeClassFieldList * cfList = getCodeClassFieldList(); for(CodeClassField * field = cfList->first(); field; field = cfList->next()) field->setWriteOutMethods(policy->getAutoGenerateAccessors()); // attribute-based ClassFields // we do it this way to have the static fields sorted out from regular ones CodeClassFieldList staticPublicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Public ); CodeClassFieldList publicAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Public ); CodeClassFieldList staticProtectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Protected ); CodeClassFieldList protectedAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Protected ); CodeClassFieldList staticPrivateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true, Uml::Visibility::Private ); CodeClassFieldList privateAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, false, Uml::Visibility::Private); // association-based ClassFields // don't care if they are static or not..all are lumped together CodeClassFieldList publicPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Public); CodeClassFieldList publicAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Public); CodeClassFieldList publicCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Public ); CodeClassFieldList protPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Protected); CodeClassFieldList protAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Protected); CodeClassFieldList protCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Protected); CodeClassFieldList privPlainAssocClassFields = getSpecificClassFields ( CodeClassField::PlainAssociation , Uml::Visibility::Private); CodeClassFieldList privAggregationClassFields = getSpecificClassFields ( CodeClassField::Aggregation, Uml::Visibility::Private); CodeClassFieldList privCompositionClassFields = getSpecificClassFields ( CodeClassField::Composition, Uml::Visibility::Private); bool hasOperationMethods = c->getOpList().last() ? true : false; bool hasNamespace = false; bool isEnumeration = false; bool isInterface = parentIsInterface(); bool hasclassFields = hasClassFields(); bool forcedoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments(); QString endLine = UMLApp::app()->getCommonPolicy()->getNewLineEndingChars(); UMLClassifierList superclasses = c->findSuperClassConcepts(); // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT // // Write the hash define stuff to prevent multiple parsing/inclusion of header QString cppClassName = CodeGenerator::cleanName(c->getName()); QString hashDefine = CodeGenerator::cleanName(c->getName().upper().simplifyWhiteSpace()); QString defText = "#ifndef "+hashDefine + "_H"+ endLine + "#define "+ hashDefine + "_H"; addOrUpdateTaggedCodeBlockWithComments("hashDefBlock", defText, "", 0, false); // INCLUDE CODEBLOCK // // Q: Why all utils? Isnt just List and Vector the only classes we are using? // A: doesn't matter at all; its more readable to just include '*' and cpp compilers // don't slow down or anything. (TZ) QString includeStatement = ""; bool stringGlobal = policy->stringIncludeIsGlobal(); QString sStartBrak = stringGlobal ? "<" : "\""; QString sEndBrak = stringGlobal ? ">" : "\""; includeStatement.append("#include "+sStartBrak+policy->getStringClassNameInclude()+sEndBrak+endLine); if ( hasObjectVectorClassFields() ) { bool vecGlobal = policy->vectorIncludeIsGlobal(); QString vStartBrak = vecGlobal ? "<" : "\""; QString vEndBrak = vecGlobal ? ">" : "\""; QString value ="#include "+vStartBrak+policy->getVectorClassNameInclude()+vEndBrak; includeStatement.append(value+endLine); } //only include classes in a different package from this class UMLPackageList includes; QMap<UMLPackage *,QString> packageMap; // so we don't repeat packages CodeGenerator::findObjectsRelated(c,includes); for(UMLPackage *con = includes.first(); con ; con = includes.next()) if (con->getBaseType() != Uml::ot_Datatype && !packageMap.contains(con)) { packageMap.insert(con,con->getPackage()); if(con != getParentClassifier()) includeStatement.append("#include \""+CodeGenerator::cleanName(con->getName().lower())+".h\""+endLine); } // now, add/update the includes codeblock CodeBlockWithComments * inclBlock = addOrUpdateTaggedCodeBlockWithComments("includes", includeStatement, QString::null, 0, false); if(includeStatement.isEmpty() && inclBlock->getContentType() == CodeBlock::AutoGenerated) inclBlock->setWriteOutText(false); else inclBlock->setWriteOutText(true); // Using QString usingStatement; for(UMLClassifier *classifier = superclasses.first(); classifier ; classifier = superclasses.next()) { if(classifier->getPackage()!=c->getPackage() && !classifier->getPackage().isEmpty()) { usingStatement.append("using "+CodeGenerator::cleanName(c->getPackage())+"::"+cleanName(c->getName())+';'+endLine); } } CodeBlockWithComments * usingBlock = addOrUpdateTaggedCodeBlockWithComments("using", usingStatement, "", 0, false); if(usingStatement.isEmpty() && usingBlock->getContentType() == CodeBlock::AutoGenerated) usingBlock->setWriteOutText(false); else usingBlock->setWriteOutText(true); // namespace // This needs special treatment. We cant use "nowriteouttext" for this, as // that will prevent the class declaration from being written. Instead, we // check if "hasNamspace" is true or not, and then indent the remaining code // appropriately as well as set the start/end text of this namespace block. if (c->getUMLPackage() && policy->getPackageIsNamespace()) hasNamespace = true; else hasNamespace = false; // set start/end text of namespace block namespaceBlock = getHierarchicalCodeBlock("namespace", "Namespace", 0); if(hasNamespace) { UMLPackageList pkgList = c->getPackages(); QString pkgs; UMLPackage *pkg; for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) { pkgs += "namespace " + CodeGenerator::cleanName(pkg->getName()) + " { "; } namespaceBlock->setStartText(pkgs); QString closingBraces; for (pkg = pkgList.first(); pkg != NULL; pkg = pkgList.next()) { closingBraces += "} "; } namespaceBlock->setEndText(closingBraces); namespaceBlock->getComment()->setWriteOutText(true); } else { namespaceBlock->setStartText(""); namespaceBlock->setEndText(""); namespaceBlock->getComment()->setWriteOutText(false); } // Enum types for include if (!isInterface) { QString enumStatement; QString indent = UMLApp::app()->getCommonPolicy()->getIndentation(); UMLEnum* e = dynamic_cast<UMLEnum*>(c); if (e) { enumStatement.append(indent + "enum " + cppClassName + " {" + endLine); // populate UMLClassifierListItemList ell = e->getFilteredList(Uml::ot_EnumLiteral); for (UMLClassifierListItem *el=ell.first(); el ; ) { enumStatement.append(indent+indent); enumStatement.append(CodeGenerator::cleanName(el->getName())); if ((el=ell.next()) != 0) enumStatement.append(", "+endLine); else break; enumStatement.append(endLine); } enumStatement.append(indent+"};"); isEnumeration = true; } namespaceBlock->addOrUpdateTaggedCodeBlockWithComments("enums", enumStatement, "", 0, false); } // CLASS DECLARATION BLOCK // // add the class declaration block to the namespace block. CPPHeaderClassDeclarationBlock * myClassDeclCodeBlock = getClassDecl(); namespaceBlock->addTextBlock(myClassDeclCodeBlock); // note: wont add if already present // Is this really true?? hmm.. if(isEnumeration) myClassDeclCodeBlock->setWriteOutText(false); // not written out IF its an enumeration class else myClassDeclCodeBlock->setWriteOutText(true); // // Main Sub-Blocks // // declare public, protected and private methods, attributes (fields). // set the start text ONLY if this is the first time we created the objects. bool createdPublicBlock = publicBlock == 0 ? true : false; publicBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("publicBlock","Public stuff",0); if (createdPublicBlock) publicBlock->setStartText("public:"); bool createdProtBlock = protectedBlock == 0 ? true : false; protectedBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("protectedBlock","Protected stuff",0); if(createdProtBlock) protectedBlock->setStartText("protected:"); bool createdPrivBlock = privateBlock == 0 ? true : false; privateBlock = myClassDeclCodeBlock->getHierarchicalCodeBlock("privateBlock","Private stuff",0); if(createdPrivBlock) privateBlock->setStartText("private:"); // // * CLASS FIELD declaration section // // setup/get/create the field declaration code block // // public fields: Update the comment: we only set comment to appear under the following conditions HierarchicalCodeBlock * publicFieldDeclBlock = publicBlock->getHierarchicalCodeBlock("publicFieldsDecl", "Fields", 1); CodeComment * pubFcomment = publicFieldDeclBlock->getComment(); if (!forcedoc && !hasclassFields ) pubFcomment->setWriteOutText(false); else pubFcomment->setWriteOutText(true); // protected fields: Update the comment: we only set comment to appear under the following conditions HierarchicalCodeBlock * protectedFieldDeclBlock = protectedBlock->getHierarchicalCodeBlock("protectedFieldsDecl", "Fields", 1); CodeComment * protFcomment = protectedFieldDeclBlock->getComment(); if (!forcedoc && !hasclassFields ) protFcomment->setWriteOutText(false); else protFcomment->setWriteOutText(true); // private fields: Update the comment: we only set comment to appear under the following conditions HierarchicalCodeBlock * privateFieldDeclBlock = privateBlock->getHierarchicalCodeBlock("privateFieldsDecl", "Fields", 1); CodeComment * privFcomment = privateFieldDeclBlock->getComment(); if (!forcedoc && !hasclassFields ) privFcomment->setWriteOutText(false); else privFcomment->setWriteOutText(true); // now actually declare the fields within the appropriate HCodeBlock // // public declareClassFields(staticPublicAttribClassFields, publicFieldDeclBlock); declareClassFields(publicAttribClassFields, publicFieldDeclBlock); declareClassFields(publicPlainAssocClassFields, publicFieldDeclBlock); declareClassFields(publicAggregationClassFields, publicFieldDeclBlock); declareClassFields(publicCompositionClassFields, publicFieldDeclBlock); // protected declareClassFields(staticProtectedAttribClassFields, protectedFieldDeclBlock); declareClassFields(protectedAttribClassFields, protectedFieldDeclBlock); declareClassFields(protPlainAssocClassFields, protectedFieldDeclBlock); declareClassFields(protAggregationClassFields, protectedFieldDeclBlock); declareClassFields(protCompositionClassFields, protectedFieldDeclBlock); // private declareClassFields(staticPrivateAttribClassFields, privateFieldDeclBlock); declareClassFields(privateAttribClassFields, privateFieldDeclBlock); declareClassFields(privPlainAssocClassFields, privateFieldDeclBlock); declareClassFields(privAggregationClassFields, privateFieldDeclBlock); declareClassFields(privCompositionClassFields, privateFieldDeclBlock); // // METHODS section // // get/create the method codeblock // public methods HierarchicalCodeBlock * pubMethodsBlock = publicBlock->getHierarchicalCodeBlock("pubMethodsBlock", "", 1); CodeComment * pubMethodsComment = pubMethodsBlock->getComment(); // set conditions for showing this comment if (!forcedoc && !hasclassFields && !hasOperationMethods) pubMethodsComment->setWriteOutText(false); else pubMethodsComment->setWriteOutText(true); // protected methods HierarchicalCodeBlock * protMethodsBlock = protectedBlock->getHierarchicalCodeBlock("protMethodsBlock", "", 1); CodeComment * protMethodsComment = protMethodsBlock->getComment(); // set conditions for showing this comment if (!forcedoc && !hasclassFields && !hasOperationMethods) protMethodsComment->setWriteOutText(false); else protMethodsComment->setWriteOutText(true); // private methods HierarchicalCodeBlock * privMethodsBlock = privateBlock->getHierarchicalCodeBlock("privMethodsBlock", "", 1); CodeComment * privMethodsComment = privMethodsBlock->getComment(); // set conditions for showing this comment if (!forcedoc && !hasclassFields && !hasOperationMethods) privMethodsComment->setWriteOutText(false); else privMethodsComment->setWriteOutText(true); // METHODS sub-section : constructor methods // CodeGenerationPolicy *pol = UMLApp::app()->getCommonPolicy(); // setup/get/create the constructor codeblocks // public pubConstructorBlock = pubMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1); // special condiions for showing comment: only when autogenerateding empty constructors // Although, we *should* check for other constructor methods too CodeComment * pubConstComment = pubConstructorBlock->getComment(); if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors())) pubConstComment->setWriteOutText(false); else pubConstComment->setWriteOutText(true); // protected protConstructorBlock = protMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1); // special condiions for showing comment: only when autogenerateding empty constructors // Although, we *should* check for other constructor methods too CodeComment * protConstComment = protConstructorBlock->getComment(); if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors())) protConstComment->setWriteOutText(false); else protConstComment->setWriteOutText(true); // private privConstructorBlock = privMethodsBlock->getHierarchicalCodeBlock("constructionMethods", "Constructors", 1); // special condiions for showing comment: only when autogenerateding empty constructors // Although, we *should* check for other constructor methods too CodeComment * privConstComment = privConstructorBlock->getComment(); if (!forcedoc && (isInterface || !pol->getAutoGenerateConstructors())) privConstComment->setWriteOutText(false); else privConstComment->setWriteOutText(true); // add/get the empty constructor. I guess since there is no // meta-data to state what the scope of this method is, we will make it // "public" as a default. This might present problems if the user wants // to move the block into the "private" or "protected" blocks. QString emptyConstStatement = cppClassName + " ( ) { }"; // search for this first in the entire document. IF not present, put // it in the public constructor method block TextBlock * emptyConstTb = findTextBlockByTag("emptyconstructor", true); CodeBlockWithComments * emptyConstBlock = dynamic_cast<CodeBlockWithComments*>(emptyConstTb); if(!emptyConstBlock) emptyConstBlock = pubConstructorBlock->addOrUpdateTaggedCodeBlockWithComments("emptyconstructor", emptyConstStatement, "Empty Constructor", 1, false); // Now, as an additional condition we only show the empty constructor block // IF it was desired to be shown if(!isInterface && pol->getAutoGenerateConstructors()) emptyConstBlock->setWriteOutText(true); else emptyConstBlock->setWriteOutText(false); // METHODS subsection : ACCESSOR METHODS // // get/create the accessor codeblock // public HierarchicalCodeBlock * pubAccessorBlock = pubMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1); // set conditions for showing section comment CodeComment * pubAccessComment = pubAccessorBlock->getComment(); if (!forcedoc && !hasclassFields) pubAccessComment->setWriteOutText(false); else pubAccessComment->setWriteOutText(true); // protected HierarchicalCodeBlock * protAccessorBlock = protMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1); // set conditions for showing section comment CodeComment * protAccessComment = protAccessorBlock->getComment(); if (!forcedoc && !hasclassFields) protAccessComment->setWriteOutText(false); else protAccessComment->setWriteOutText(true); // private HierarchicalCodeBlock * privAccessorBlock = privMethodsBlock->getHierarchicalCodeBlock("accessorMethods", "Accessor Methods", 1); // set conditions for showing section comment CodeComment * privAccessComment = privAccessorBlock->getComment(); // We've to copy the private accessorMethods to the public block if (!forcedoc && !hasclassFields) privAccessComment->setWriteOutText(false); else privAccessComment->setWriteOutText(true); // now, 2 sub-sub sections in accessor block // add/update accessor methods for attributes HierarchicalCodeBlock * pubStaticAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubStaticAccessorMethods", "", 1); HierarchicalCodeBlock * pubRegularAccessors = pubAccessorBlock->getHierarchicalCodeBlock("pubRegularAccessorMethods", "", 1); pubStaticAccessors->getComment()->setWriteOutText(false); // never write block comment pubRegularAccessors->getComment()->setWriteOutText(false); // never write block comment HierarchicalCodeBlock * protStaticAccessors = protAccessorBlock->getHierarchicalCodeBlock("protStaticAccessorMethods", "", 1); HierarchicalCodeBlock * protRegularAccessors = protAccessorBlock->getHierarchicalCodeBlock("protRegularAccessorMethods", "", 1); protStaticAccessors->getComment()->setWriteOutText(false); // never write block comment protRegularAccessors->getComment()->setWriteOutText(false); // never write block comment HierarchicalCodeBlock * privStaticAccessors = privAccessorBlock->getHierarchicalCodeBlock("privStaticAccessorMethods", "", 1); HierarchicalCodeBlock * privRegularAccessors = privAccessorBlock->getHierarchicalCodeBlock("privRegularAccessorMethods", "", 1); privStaticAccessors->getComment()->setWriteOutText(false); // never write block comment privRegularAccessors->getComment()->setWriteOutText(false); // never write block comment // now add in accessors as appropriate // public stuff pubStaticAccessors->addCodeClassFieldMethods(staticPublicAttribClassFields); pubRegularAccessors->addCodeClassFieldMethods(publicAttribClassFields); // generate accessors as public if (policy && policy->getAccessorsArePublic()) { pubRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields); pubRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields); } pubRegularAccessors->addCodeClassFieldMethods(publicPlainAssocClassFields); pubRegularAccessors->addCodeClassFieldMethods(publicAggregationClassFields); pubRegularAccessors->addCodeClassFieldMethods(publicCompositionClassFields); // protected stuff protStaticAccessors->addCodeClassFieldMethods(staticProtectedAttribClassFields); // accessors are public so we don't have to create it here if (policy && !policy->getAccessorsArePublic()) protRegularAccessors->addCodeClassFieldMethods(protectedAttribClassFields); protRegularAccessors->addCodeClassFieldMethods(protPlainAssocClassFields); protRegularAccessors->addCodeClassFieldMethods(protAggregationClassFields); protRegularAccessors->addCodeClassFieldMethods(protCompositionClassFields); // private stuff privStaticAccessors->addCodeClassFieldMethods(staticPrivateAttribClassFields); // accessors are public so we don't have to create it here if (policy && !policy->getAccessorsArePublic()) privRegularAccessors->addCodeClassFieldMethods(privateAttribClassFields); privRegularAccessors->addCodeClassFieldMethods(privPlainAssocClassFields); privRegularAccessors->addCodeClassFieldMethods(privAggregationClassFields); privRegularAccessors->addCodeClassFieldMethods(privCompositionClassFields); // METHODS subsection : Operation methods (e.g. methods derive from operations but which arent constructors) // // setup/get/create the operations codeblock // public pubOperationsBlock = pubMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1); // set conditions for showing section comment CodeComment * pubOcomment = pubOperationsBlock->getComment(); if (!forcedoc && !hasOperationMethods ) pubOcomment->setWriteOutText(false); else pubOcomment->setWriteOutText(true); //protected protOperationsBlock = protMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1); // set conditions for showing section comment CodeComment * protOcomment = protOperationsBlock->getComment(); if (!forcedoc && !hasOperationMethods ) protOcomment->setWriteOutText(false); else protOcomment->setWriteOutText(true); //private privOperationsBlock = privMethodsBlock->getHierarchicalCodeBlock("operationMethods", "Operations", 1); // set conditions for showing section comment CodeComment * privOcomment = privOperationsBlock->getComment(); if (!forcedoc && !hasOperationMethods ) privOcomment->setWriteOutText(false); else privOcomment->setWriteOutText(true); // Operations // // nothing to do here.. "updateOperations" in parent class puts things // in the right place using the "addCodeOperation" method we defined in this class // FINISH up with hash def block close QString defTextEnd = "#endif //"+hashDefine + "_H"; addOrUpdateTaggedCodeBlockWithComments("hashDefBlockEnd", defTextEnd, "", 0, 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. 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); } }
/** * update the start and end text for this ownedhierarchicalcodeblock. */ void JavaClassDeclarationBlock::updateContent ( ) { JavaClassifierCodeDocument *parentDoc = dynamic_cast<JavaClassifierCodeDocument*>(getParentDocument()); UMLClassifier *c = parentDoc->getParentClassifier(); CodeGenerationPolicy *commonPolicy = UMLApp::app()->getCommonPolicy(); QString endLine = commonPolicy->getNewLineEndingChars(); bool isInterface = parentDoc->parentIsInterface(); // a little shortcut QString JavaClassName = parentDoc->getJavaClassName(c->getName()); // COMMENT if(isInterface) getComment()->setText("Interface "+JavaClassName+endLine+c->getDoc()); else getComment()->setText("Class "+JavaClassName+endLine+c->getDoc()); bool forceDoc = UMLApp::app()->getCommonPolicy()->getCodeVerboseDocumentComments(); if(forceDoc || !c->getDoc().isEmpty()) getComment()->setWriteOutText(true); else getComment()->setWriteOutText(false); // Now set START/ENDING Text QString startText = ""; // In Java, we need declare abstract only on classes if (c->getAbstract() && !isInterface) startText.append("abstract "); if (c->getVisibility() != Uml::Visibility::Public) { // We should probably emit a warning in here .. java doesn't like to allow // private/protected classes. The best we can do (I believe) // is to let these declarations default to "package visibility" // which is a level between traditional "private" and "protected" // scopes. To get this visibility level we just print nothing.. } else startText.append("public "); if(parentDoc->parentIsInterface()) startText.append("interface "); else startText.append("class "); startText.append(JavaClassName); // write inheritances out UMLClassifierList superclasses = c->findSuperClassConcepts(UMLClassifier::CLASS); UMLClassifierList superinterfaces = c->findSuperClassConcepts(UMLClassifier::INTERFACE); int nrof_superclasses = superclasses.count(); int nrof_superinterfaces = superinterfaces.count(); // write out inheritance int i = 0; if(nrof_superclasses >0) startText.append(" extends "); for (UMLClassifier * concept= superclasses.first(); concept; concept = superclasses.next()) { startText.append(parentDoc->cleanName(concept->getName())); if(i != (nrof_superclasses-1)) startText.append(", "); i++; } // write out what we 'implement' i = 0; if(nrof_superinterfaces >0) { // In Java interfaces "extend" other interfaces. Classes "implement" interfaces if(isInterface) startText.append(" extends "); else startText.append(" implements "); } for (UMLClassifier * concept= superinterfaces.first(); concept; concept = superinterfaces.next()) { startText.append(parentDoc->cleanName(concept->getName())); if(i != (nrof_superinterfaces-1)) startText.append(", "); i++; } // Set the header and end text for the hier.codeblock setStartText(startText+" {"); // setEndText("}"); // not needed }
void RefactoringAssistant::movableDropEvent (QListViewItem* parentItem, QListViewItem* afterme) { //when dropping on a class, we have to put the item in the appropriate folder! UMLObject *movingObject; UMLClassifier *newClassifier; QListViewItem *movingItem; for( movingItem = firstChild(); movingItem != 0; movingItem = movingItem->itemBelow() ) { if( movingItem->isSelected() ) break; } if( !movingItem || (movingItem == afterme) || !(movingObject = findUMLObject(movingItem)) ) { kWarning()<<"Moving item not found or dropping after itself or item not found in uml obj map. aborting. (drop had already been accepted)"<<endl; return; } Uml::Object_Type t = movingObject->getBaseType(); newClassifier = dynamic_cast<UMLClassifier*>( findUMLObject( parentItem ) ); if(!newClassifier) { if ((parentItem->text(1) == "operations" && t == Uml::ot_Operation) || (parentItem->text(1) == "attributes" && t == Uml::ot_Attribute)) { newClassifier = dynamic_cast<UMLClassifier*>( findUMLObject( parentItem->parent() ) ); } if(!newClassifier) { kWarning()<<"New parent of object is not a Classifier - Drop had already been accepted - check!"<<endl; return; } } if (t == Uml::ot_Operation) {kDebug()<<"moving operation"<<endl; UMLOperation *op = static_cast<UMLOperation*>(movingObject); if(newClassifier->checkOperationSignature(op->getName(), op->getParmList())) { QString msg = QString(i18n("An operation with that signature already exists in %1.\n")).arg(newClassifier->getName()) + QString(i18n("Choose a different name or parameter list." )); KMessageBox::error(this, msg, i18n("Operation Name Invalid"), false); return; } UMLClassifier *oldClassifier = dynamic_cast<UMLClassifier*>(op->parent()); if(oldClassifier) oldClassifier->removeOperation( op ); newClassifier->addOperation( op ); } else if (t == Uml::ot_Attribute) {kDebug()<<"moving attribute - not implemented"<<endl; // UMLAttribute *att = static_cast<UMLAttribute*>(movingObject); // if(!newClassifier->checkAttributeSignature(att)) // { // QString msg = QString(i18n("An attribute with that signature already exists in %1.\n")).arg(newClassifier->getName()) // + // QString(i18n("Choose a different name or parameter list." )); // KMessageBox::error(this, msg, i18n("Operation Name Invalid"), false); // return; // } // oldClassifier->removeAttribute( att ); // newClassifier->addAttribute( att ); } //emit moved(moving, afterFirst, afterme); emit moved(); }
void RefactoringAssistant::addClassifier( UMLClassifier *classifier, QListViewItem *parent, bool addSuper, bool addSub, bool recurse) { QListViewItem *classifierItem, *item; if( parent ) { classifierItem = parent; } else { classifierItem= new KListViewItem( this, classifier->getName() ); m_umlObjectMap[classifierItem] = classifier; } connect( classifier, SIGNAL( modified() ), this, SLOT( umlObjectModified() ) ); UMLClassifier *klass = dynamic_cast<UMLClassifier*>(classifier); if( klass ) {// only Classes have attributes... connect( classifier, SIGNAL(attributeAdded(UMLClassifierListItem*)), this, SLOT(attributeAdded(UMLClassifierListItem*))); connect( classifier, SIGNAL(attributeRemoved(UMLClassifierListItem*)), this, SLOT(attributeRemoved(UMLClassifierListItem*))); QListViewItem *attsFolder = new KListViewItem( classifierItem, i18n("Attributes"), "attributes" ); attsFolder->setPixmap(0,SmallIcon("folder_green_open")); attsFolder->setExpandable( true ); UMLAttributeList atts = klass->getAttributeList(); for( UMLAttribute *att = atts.first(); att; att = atts.next() ) { attributeAdded( att ); } } // add operations connect( classifier, SIGNAL(operationAdded(UMLClassifierListItem*)), this, SLOT(operationAdded(UMLClassifierListItem*))); connect( classifier, SIGNAL(operationRemoved(UMLClassifierListItem*)), this, SLOT(operationRemoved(UMLClassifierListItem*))); QListViewItem *opsFolder = new KListViewItem( classifierItem, i18n("Operations"), "operations" ); opsFolder->setPixmap(0,SmallIcon("folder_blue_open")); opsFolder->setExpandable( true ); UMLOperationList ops(classifier->getOpList()); for( UMLOperation *op = ops.first(); op ; op = ops.next() ) { operationAdded( op ); } //if add parents if(addSuper) { QListViewItem *superFolder = new KListViewItem( classifierItem, i18n("Base Classifiers") ); superFolder->setExpandable( true ); UMLClassifierList super = classifier->findSuperClassConcepts(); for( UMLClassifier *cl = super.first(); cl ; cl = super.next() ) { item = new KListViewItem( superFolder, cl->getName() ); item->setPixmap(0,m_pixmaps.Generalization); item->setExpandable( true ); m_umlObjectMap[item] = cl; if( recurse ) { addClassifier( cl, item, true, false, true); } } } if(addSub) { //add derived classifiers QListViewItem *derivedFolder = new KListViewItem( classifierItem, i18n("Derived Classifiers") ); derivedFolder->setExpandable( true ); UMLClassifierList derived = classifier->findSubClassConcepts(); for( UMLClassifier *d = derived.first(); d ; d = derived.next() ) { item = new KListViewItem( derivedFolder, d->getName() ); item->setPixmap(0,m_pixmaps.Subclass); item->setExpandable( true ); m_umlObjectMap[item] = d; if( recurse ) { addClassifier( d, item, false, true, true); } } } }