/*************************************************************************** * * * 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 * ***************************************************************************/ /* This code generated by: * Author : thomas * Date : Wed Jun 18 2003 */ // own header #include "codedocument.h" // qt/kde includes #include #include #include // local includes #include "codegenerator.h" #include "package.h" #include "umldoc.h" #include "uml.h" // Constructors/Destructors // CodeDocument::CodeDocument () : CodeGenObjectWithTextBlocks(this) { initDoc(); } CodeDocument::~CodeDocument ( ) { // delete all the text blocks we have TextBlock *tb; for (TextBlockListIt it(m_textblockVector); (tb = it.current()) != NULL; ++it) delete tb; m_textblockVector.clear(); delete m_header; } // // Methods // // Accessor methods // // Public attribute accessor methods // /** * Set the value of m_filename * @param new_var the new value of m_filename */ void CodeDocument::setFileName ( const TQString &new_var ) { m_filename = new_var; } /** * Get the value of m_filename * @return the value of m_filename */ TQString CodeDocument::getFileName ( ) const { return m_filename; } /** * Set the value of m_filename * @param new_var the new value of m_filename */ void CodeDocument::setFileExtension ( const TQString &new_var ) { m_fileExtension = new_var; updateHeader(); // because we are using new heading file } /** * Get the value of m_filename * @return the value of m_filename */ TQString CodeDocument::getFileExtension( ) const { return m_fileExtension; } /** * Set the value of the package. * @param new_var the new value of m_package */ void CodeDocument::setPackage ( UMLPackage *new_var ) { m_package = new_var; } /** * Get the value of path for this code document. * @return the value of the path */ TQString CodeDocument::getPath ( ) { TQString path = getPackage(); // Replace all white spaces with blanks path = path.simplifyWhiteSpace(); // Replace all blanks with underscore path.tqreplace(TQRegExp(" "), "_"); // this allows multiple directory paths (ala Java, some other languages) // in from the package specification path.tqreplace(TQRegExp("\\."),"/"); // Simple hack!.. but this is more or less language // dependant and should probably be commented out. // Still, as a general default it may be useful -b.t. return path; } /** * Get the value of package name. * @return the value of m_package->getName() */ TQString CodeDocument::getPackage ( ) const { if (m_package) return m_package->getName(); return TQString(); } /** * Set the value of m_ID * @param new_var the new value of m_ID */ void CodeDocument::setID ( const TQString &new_var ) { m_ID = new_var; } /** * Get the value of m_ID * @return the value of m_ID */ TQString CodeDocument::getID ( ) const { return m_ID; } /** * Set the value of m_writeOutCode * Whether or not to write out this code document and any codeblocks, etc that it * owns. * @param new_var the new value of m_writeOutCode */ void CodeDocument::setWriteOutCode ( bool new_var ) { m_writeOutCode = new_var; } /** * Get the value of m_writeOutCode * Whether or not to write out this code document and any codeblocks, etc that it * owns. * @return the value of m_writeOutCode */ bool CodeDocument::getWriteOutCode ( ) { return m_writeOutCode; } /** * Set the Header comment */ void CodeDocument::setHeader ( CodeComment * header ) { m_header = header; } /** * Get the Header comment */ CodeComment * CodeDocument::getHeader ( ) { return m_header; } // // Other methods // TQString CodeDocument::getUniqueTag ( const TQString& prefix ) { TQString tag = prefix ; if(tag.isEmpty()) tag += "tblock"; tag = tag + "_0"; int number = lastTagIndex; for ( ; findTextBlockByTag(tag, true); number++) { tag = prefix + '_' + TQString::number(number); } lastTagIndex = number; return tag; } /** * Insert a new text block before/after the existing text block. Returns * false if it cannot insert the textblock. */ bool CodeDocument::insertTextBlock(TextBlock * newBlock, TextBlock * existingBlock, bool after) { if(!newBlock || !existingBlock) return false; TQString tag = existingBlock->getTag(); if(!findTextBlockByTag(tag, true)) return false; int index = m_textblockVector.tqfindRef(existingBlock); if(index < 0) { // may be hiding in child hierarchical codeblock for(TextBlock * tb = m_textblockVector.first(); tb ; tb = m_textblockVector.next()) { HierarchicalCodeBlock * hb = dynamic_cast(tb); if(hb && hb->insertTextBlock(newBlock, existingBlock, after)) return true; // found, and inserted, otherwise keep going } // ugh. where is the child block? kWarning()<<" Warning: couldnt insert text block (tag:"<getTag()<<"). Reference text block (tag:"<getTag()<<") not found."<getTag(); // assign a tag if one doesn't already exist if(new_tag.isEmpty()) { new_tag = getUniqueTag(); newBlock->setTag(new_tag); } if(m_textBlockTagMap.tqcontains(new_tag)) return false; // return false, we already have some object with this tag in the list else m_textBlockTagMap.insert(new_tag, newBlock); if(after) index++; m_textblockVector.insert(index,newBlock); return true; } /** * Get the value of m_dialog * @return the value of m_dialog */ /* CodeDocumentDialog * CodeDocument::getDialog ( ) { return m_dialog; } */ // Other methods // TQString CodeDocument::cleanName ( const TQString &name ) { return CodeGenerator::cleanName(name); } // update the text and status of the head comment void CodeDocument::updateHeader () { //try to find a heading file (license, coments, etc) then extract its text TQString headingText = UMLApp::app()->getCommonPolicy()->getHeadingFile(getFileExtension()); headingText.tqreplace(TQRegExp("%filename%"),getFileName()+getFileExtension()); headingText.tqreplace(TQRegExp("%filepath%"),getPath()); headingText.tqreplace( TQRegExp("%time%"), TQTime::currentTime().toString()); headingText.tqreplace( TQRegExp("%date%"), TQDate::tqcurrentDate().toString()); getHeader()->setText(headingText); // update the write out status of the header if(UMLApp::app()->getCommonPolicy()->getIncludeHeadings()) getHeader()->setWriteOutText(true); else getHeader()->setWriteOutText(false); } /** * create the string representation of this object. * @return TQString */ TQString CodeDocument::toString ( ) { // IF the whole document is turned "Off" then don't bother // checking individual code blocks, just send back empty string if(!getWriteOutCode()) return TQString(""); TQString content = getHeader()->toString(); // update the time/date // comments, import, package codeblocks go next TextBlockList * items = getTextBlockList(); for (TextBlock *c = items->first(); c; c = items->next()) { if(c->getWriteOutText()) { TQString str = c->toString(); if(!str.isEmpty()) content.append(str); } } return content; } void CodeDocument::synchronize() { updateContent(); } // need to overload method to beable to clear the childTextBlockMap void CodeDocument::resetTextBlocks() { CodeGenObjectWithTextBlocks::resetTextBlocks(); m_childTextBlockTagMap.clear(); } /** * load params from the appropriate XMI element node. */ void CodeDocument::loadFromXMI ( TQDomElement & root ) { setAttributesFromNode(root); } /** set attributes of the node that represents this class * in the XMI document. */ void CodeDocument::setAttributesOnNode ( TQDomDocument & doc, TQDomElement & docElement) { // superclass call CodeGenObjectWithTextBlocks::setAttributesOnNode(doc,docElement); // now set local attributes/fields docElement.setAttribute("fileName",getFileName()); docElement.setAttribute("fileExt",getFileExtension()); Uml::IDType pkgId = Uml::id_None; if (m_package) pkgId = m_package->getID(); docElement.setAttribute("package", ID2STR(pkgId)); docElement.setAttribute("writeOutCode",getWriteOutCode()?"true":"false"); docElement.setAttribute("id",getID()); // set the a header // which we will store in its own separate child node block TQDomElement commElement = doc.createElement( "header" ); getHeader()->saveToXMI(doc, commElement); // comment docElement.appendChild( commElement); // doc codePolicy? // FIX: store ONLY if different from the tqparent generator // policy.. something which is not possible right now. -b.t. } /** set the class attributes of this object from * the passed element node. */ void CodeDocument::setAttributesFromNode ( TQDomElement & root) { // now set local attributes setFileName(root.attribute("fileName","")); setFileExtension(root.attribute("fileExt","")); TQString pkgStr = root.attribute("package",""); if (!pkgStr.isEmpty() && pkgStr != "-1") { UMLDoc *umldoc = UMLApp::app()->getDocument(); if (pkgStr.tqcontains( TQRegExp("\\D") )) { // suspecting pre-1.5.3 file format where the package name was // saved instead of the package ID. UMLObject *o = umldoc->findUMLObject(pkgStr); m_package = dynamic_cast(o); } if (m_package == NULL) { UMLObject *o = umldoc->findObjectById(STR2ID(pkgStr)); m_package = dynamic_cast(o); } } setWriteOutCode(root.attribute("writeOutCode","true") == "true" ? true : false); setID(root.attribute("id","")); // load comment now // by looking for our particular child element TQDomNode node = root.firstChild(); TQDomElement element = node.toElement(); while( !element.isNull() ) { TQString tag = element.tagName(); if( tag == "header" ) { TQDomNode cnode = element.firstChild(); TQDomElement celem = cnode.toElement(); getHeader()->loadFromXMI(celem); break; } node = element.nextSibling(); element = node.toElement(); } // a rare case where the super-class load is AFTER local attributes CodeGenObjectWithTextBlocks::setAttributesFromNode(root); } /** * Save the XMI representation of this object */ void CodeDocument::saveToXMI ( TQDomDocument & doc, TQDomElement & root ) { TQDomElement docElement = doc.createElement( "codedocument" ); setAttributesOnNode(doc, docElement); root.appendChild( docElement ); } // vanilla code documents don't have much // to do.. override this with a different // version for your own documents void CodeDocument::updateContent() { updateHeader(); // doing this insures time/date stamp is at the time of this call } /** * create a new CodeBlock object belonging to this CodeDocument. * @return CodeBlock */ CodeBlock * CodeDocument::newCodeBlock ( ) { return new CodeBlock(this); } /** * create a new CodeBlockWithComments object belonging to this CodeDocument. * @return CodeBlockWithComments */ CodeBlockWithComments * CodeDocument::newCodeBlockWithComments ( ) { return new CodeBlockWithComments(this); } HierarchicalCodeBlock * CodeDocument::newHierarchicalCodeBlock ( ) { HierarchicalCodeBlock *hb = new HierarchicalCodeBlock(this); //hb->update(); return hb; } void CodeDocument::removeChildTagFromMap ( const TQString &tag ) { m_childTextBlockTagMap.erase(tag); } void CodeDocument::addChildTagToMap ( const TQString &tag, TextBlock * tb) { m_childTextBlockTagMap.insert(tag, tb); } TextBlock * CodeDocument::findTextBlockByTag( const TQString &tag , bool descendIntoChildren) { //if we already know to which file this class was written/should be written, just return it. if(m_textBlockTagMap.tqcontains(tag)) return m_textBlockTagMap[tag]; if (descendIntoChildren) if(m_childTextBlockTagMap.tqcontains(tag)) return m_childTextBlockTagMap[tag]; return (TextBlock*) NULL; } void CodeDocument::initDoc () { m_writeOutCode = true; m_package = NULL; m_fileExtension = TQString(""); m_ID = TQString(""); // leave with NO ID as a default //m_textblockVector.setAutoDelete(false); setHeader(new CodeComment(this)); lastTagIndex = 0; // m_dialog = new CodeDocumentDialog( ); } TextBlock * CodeDocument::findCodeClassFieldTextBlockByTag ( const TQString &tag ) { kWarning()<<"Called findCodeClassFieldMethodByTag("<