summaryrefslogtreecommitdiffstats
path: root/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'umbrello/umbrello/codegenerators/cppheadercodedocument.cpp')
-rw-r--r--umbrello/umbrello/codegenerators/cppheadercodedocument.cpp813
1 files changed, 813 insertions, 0 deletions
diff --git a/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp b/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp
new file mode 100644
index 00000000..fe909c5d
--- /dev/null
+++ b/umbrello/umbrello/codegenerators/cppheadercodedocument.cpp
@@ -0,0 +1,813 @@
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * copyright (C) 2004-2007 *
+ * Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
+ ***************************************************************************/
+
+/* This code generated by:
+ * Author : thomas
+ * Date : Thu Aug 28 2003
+ */
+
+/**
+ We carve the CPP document up into 2 documents, "source" and "header".
+ This one represents the header portion.
+ The sections of each are as follows:
+
+ * header
+ * includes
+ * import statements
+ * class declaration
+ * guts of the class (e.g. field decl, accessor methods, operations, dependant classes)
+*/
+
+// own header
+#include "cppheadercodedocument.h"
+
+// qt/kde includes
+#include <qregexp.h>
+#include <kdebug.h>
+
+// local includes
+#include "cppcodegenerator.h"
+#include "cppcodegenerationpolicy.h"
+#include "cppcodedocumentation.h"
+#include "cppheadercodeaccessormethod.h"
+#include "cppheadercodeoperation.h"
+#include "cppheaderclassdeclarationblock.h"
+#include "cppheadercodeclassfielddeclarationblock.h"
+#include "../umlpackagelist.h"
+#include "../package.h"
+#include "../umlclassifierlistitemlist.h"
+#include "../classifierlistitem.h"
+#include "../enum.h"
+#include "../uml.h"
+
+// Constructors/Destructors
+//
+
+CPPHeaderCodeDocument::CPPHeaderCodeDocument ( UMLClassifier * concept )
+ : ClassifierCodeDocument (concept)
+{
+ setFileExtension(".h");
+
+ //initCodeClassFields(); // this is dubious because it calls down to
+ // CodeGenFactory::newCodeClassField(this)
+ // but "this" is still in construction at that time.
+
+ // needed? I doubt it, but it feels good to do it.
+ classDeclCodeBlock = 0;
+ publicBlock = 0;
+ protectedBlock = 0;
+ privateBlock = 0;
+ namespaceBlock = 0;
+ pubConstructorBlock = 0;
+ protConstructorBlock = 0;
+ privConstructorBlock = 0;
+ pubOperationsBlock = 0;
+ privOperationsBlock = 0;
+ protOperationsBlock = 0;
+
+ // this will call updateContent() as well as other things that sync our document.
+ //synchronize();
+
+}
+
+CPPHeaderCodeDocument::~CPPHeaderCodeDocument ( ) {
+ resetTextBlocks();
+}
+
+//
+// Methods
+//
+
+// Accessor methods
+//
+
+CPPHeaderClassDeclarationBlock * CPPHeaderCodeDocument::getClassDecl()
+{
+
+ if(!classDeclCodeBlock) {
+ classDeclCodeBlock = new CPPHeaderClassDeclarationBlock (this); // was deleted before our load
+ classDeclCodeBlock->setTag("classDeclarationBlock");
+ }
+ return classDeclCodeBlock;
+}
+
+// Other methods
+//
+
+// Sigh. NOT optimal. The only reason that we need to have this
+// is so we can create the CPPHeaderClassDeclarationBlock.
+// would be better if we could create a handler interface that each
+// codeblock used so all we have to do here is add the handler
+void CPPHeaderCodeDocument::loadChildTextBlocksFromNode ( QDomElement & root)
+{
+
+ QDomNode tnode = root.firstChild();
+ QDomElement telement = tnode.toElement();
+ bool loadCheckForChildrenOK = false;
+ while( !telement.isNull() ) {
+ QString nodeName = telement.tagName();
+
+ if( nodeName == "textblocks" ) {
+
+ QDomNode node = telement.firstChild();
+ QDomElement element = node.toElement();
+
+ // if there is nothing to begin with, then we don't worry about it
+ loadCheckForChildrenOK = element.isNull() ? true : false;
+
+ while( !element.isNull() ) {
+ QString name = element.tagName();
+
+ if( name == "codecomment" ) {
+ CodeComment * block = new CPPCodeDocumentation(this);
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeComment to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeaccessormethod" ||
+ name == "ccfdeclarationcodeblock"
+ ) {
+ QString acctag = element.attribute("tag","");
+ // search for our method in the
+ TextBlock * tb = findCodeClassFieldTextBlockByTag(acctag);
+ if(!tb || !addTextBlock(tb))
+ {
+ kError()<<"Unable to add codeclassfield child method to:"<<this<<endl;
+ // DON'T delete
+ } else
+ loadCheckForChildrenOK= true;
+
+ } else
+ if( name == "codeblock" ) {
+ CodeBlock * block = newCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeBlock to :"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeblockwithcomments" ) {
+ CodeBlockWithComments * block = newCodeBlockWithComments();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add codeBlockwithcomments to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "header" ) {
+ // do nothing.. this is treated elsewhere
+ } else
+ if( name == "hierarchicalcodeblock" ) {
+ HierarchicalCodeBlock * block = newHierarchicalCodeBlock();
+ block->loadFromXMI(element);
+ if(!addTextBlock(block))
+ {
+ kError()<<"Unable to add hierarchicalcodeBlock to:"<<this<<endl;
+ block->deleteLater();
+ } else
+ loadCheckForChildrenOK= true;
+ } else
+ if( name == "codeoperation" ) {
+ // find the code operation by id
+ QString id = element.attribute("parent_id","-1");
+ UMLObject * obj = UMLApp::app()->getDocument()->findObjectById(STR2ID(id));
+ UMLOperation * op = dynamic_cast<UMLOperation*>(obj);
+ if(op) {
+ CodeOperation * block = new CPPHeaderCodeOperation(this, op);
+ block->loadFromXMI(element);
+ if(addTextBlock(block))
+ loadCheckForChildrenOK= true;
+ else
+ {
+ kError()<<"Unable to add codeoperation to:"<<this<<endl;
+ block->deleteLater();
+ }
+ } else
+ kError()<<"Unable to find operation create codeoperation for:"<<this<<endl;
+ }
+ else
+ if( name == "cppheaderclassdeclarationblock" )
+ {
+ CPPHeaderClassDeclarationBlock * block = getClassDecl();
+ block->loadFromXMI(element);
+ // normally this would be populated by the following syncToparent
+ // call, but we cant wait for it, so lets just do it now.
+ namespaceBlock = getHierarchicalCodeBlock("namespace", "Namespace", 0);
+
+ if(!namespaceBlock || !namespaceBlock->addTextBlock(block))
+ {
+ kError()<<"Error:cant add class declaration codeblock"<<endl;
+ // DON'T delete/release block
+ // block->release();
+ } else
+ loadCheckForChildrenOK= true;
+
+ }
+ // only needed for extreme debugging conditions (E.g. making new codeclassdocument loader)
+ //else
+ //kDebug()<<" LoadFromXMI: Got strange tag in text block stack:"<<name<<", ignorning"<<endl;
+
+ node = element.nextSibling();
+ element = node.toElement();
+ }
+ break;
+ }
+
+ tnode = telement.nextSibling();
+ telement = tnode.toElement();
+ }
+
+ if(!loadCheckForChildrenOK)
+ {
+ CodeDocument * test = dynamic_cast<CodeDocument*>(this);
+ if(test)
+ {
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in doc: "<<test->getFileName()<<" "<<this<<endl;
+ } else {
+ HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(this);
+ if(hb)
+ kWarning()<<" loadChildBlocks : unable to initialize any child blocks in Hblock: "<<hb->getTag()<<" "<<this<<endl;
+ else
+ kDebug()<<" loadChildBlocks : unable to initialize any child blocks in UNKNOWN OBJ:"<<this<<endl;
+ }
+ }
+
+}
+
+void CPPHeaderCodeDocument::resetTextBlocks()
+{
+
+ // all special pointers need to be zero'd out.
+ classDeclCodeBlock = 0;
+ publicBlock = 0;
+ protectedBlock = 0;
+ privateBlock = 0;
+ namespaceBlock = 0;
+ pubConstructorBlock = 0;
+ protConstructorBlock = 0;
+ privConstructorBlock = 0;
+ pubOperationsBlock = 0;
+ privOperationsBlock = 0;
+ protOperationsBlock = 0;
+
+ // now do the traditional release of child text blocks
+ ClassifierCodeDocument::resetTextBlocks();
+
+}
+
+/**
+ * @param op
+ */
+// in the vannilla version, we just tack all operations on the end
+// of the document
+bool CPPHeaderCodeDocument::addCodeOperation (CodeOperation * op )
+{
+ Uml::Visibility scope = op->getParentOperation()->getVisibility();
+ if(!op->getParentOperation()->isLifeOperation())
+ {
+ switch (scope) {
+ default:
+ case Uml::Visibility::Public:
+ return pubOperationsBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Protected:
+ return protOperationsBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Private:
+ return privOperationsBlock->addTextBlock(op);
+ break;
+ }
+ } else {
+ switch (scope) {
+ default:
+ case Uml::Visibility::Public:
+ return pubConstructorBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Protected:
+ return protConstructorBlock->addTextBlock(op);
+ break;
+ case Uml::Visibility::Private:
+ return privConstructorBlock->addTextBlock(op);
+ break;
+ }
+ }
+}
+
+
+/**
+ * Save the XMI representation of this object
+ * @return bool status of save
+ */
+/*
+void CPPHeaderCodeDocument::saveToXMI ( QDomDocument & doc, QDomElement & root )
+{
+ QDomElement docElement = doc.createElement( "" );
+
+ setAttributesOnNode(doc, docElement);
+
+ root.appendChild( docElement );
+}
+*/
+
+// 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);
+
+}
+
+
+#include "cppheadercodedocument.moc"