umbrello API Documentation

codedocument.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   copyright (C) 2004-2007                                               *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 /*  This code generated by:
00013  *      Author : thomas
00014  *      Date   : Wed Jun 18 2003
00015  */
00016 
00017 // own header
00018 #include "codedocument.h"
00019 
00020 // qt/kde includes
00021 #include <qregexp.h>
00022 #include <qdatetime.h>
00023 #include <kdebug.h>
00024 
00025 // local includes
00026 #include "codegenerator.h"
00027 #include "package.h"
00028 #include "umldoc.h"
00029 #include "uml.h"
00030 
00031 // Constructors/Destructors
00032 //
00033 
00034 CodeDocument::CodeDocument () : CodeGenObjectWithTextBlocks(this)
00035 {
00036     initDoc();
00037 }
00038 
00039 
00040 CodeDocument::~CodeDocument ( ) {
00041     // delete all the text blocks we have
00042     TextBlock *tb;
00043     for (TextBlockListIt it(m_textblockVector); (tb = it.current()) != NULL; ++it)
00044         delete tb;
00045     m_textblockVector.clear();
00046     delete m_header;
00047 }
00048 
00049 //
00050 // Methods
00051 //
00052 
00053 
00054 // Accessor methods
00055 //
00056 
00057 
00058 // Public attribute accessor methods
00059 //
00060 
00061 
00066 void CodeDocument::setFileName ( const QString &new_var ) {
00067     m_filename = new_var;
00068 }
00069 
00074 QString CodeDocument::getFileName ( ) const {
00075     return m_filename;
00076 }
00077 
00082 void CodeDocument::setFileExtension ( const QString &new_var ) {
00083     m_fileExtension = new_var;
00084     updateHeader(); // because we are using new heading file
00085 }
00086 
00091 QString CodeDocument::getFileExtension( ) const {
00092     return m_fileExtension;
00093 }
00094 
00099 void CodeDocument::setPackage ( UMLPackage *new_var ) {
00100     m_package = new_var;
00101 }
00102 
00107 QString CodeDocument::getPath ( ) {
00108 
00109     QString path = getPackage();
00110 
00111     // Replace all white spaces with blanks
00112     path.simplifyWhiteSpace();
00113 
00114     // Replace all blanks with underscore
00115     path.replace(QRegExp(" "), "_");
00116 
00117     // this allows multiple directory paths (ala Java, some other languages)
00118     // in from the package specification
00119     path.replace(QRegExp("\\."),"/"); // Simple hack!.. but this is more or less language
00120     // dependant and should probably be commented out.
00121     // Still, as a general default it may be useful -b.t.
00122     return path;
00123 }
00124 
00129 QString CodeDocument::getPackage ( ) const {
00130     if (m_package)
00131         return m_package->getName();
00132     return QString();
00133 }
00134 
00139 void CodeDocument::setID ( const QString &new_var ) {
00140     m_ID = new_var;
00141 }
00142 
00147 QString CodeDocument::getID ( ) const {
00148     return m_ID;
00149 }
00150 
00157 void CodeDocument::setWriteOutCode ( bool new_var ) {
00158     m_writeOutCode = new_var;
00159 }
00160 
00167 bool CodeDocument::getWriteOutCode ( ) {
00168     return m_writeOutCode;
00169 }
00170 
00174 void CodeDocument::setHeader ( CodeComment * header ) {
00175     m_header = header;
00176 }
00177 
00181 CodeComment * CodeDocument::getHeader ( ) {
00182     return m_header;
00183 }
00184 
00185 //
00186 // Other methods
00187 //
00188 
00189 QString CodeDocument::getUniqueTag ( QString prefix )
00190 {
00191 
00192     if(prefix.isEmpty())
00193         prefix = "tblock";
00194 
00195     QString tag = prefix + "_0";
00196     int number = lastTagIndex;
00197     for ( ; findTextBlockByTag(tag, true); number++) {
00198         tag = prefix + '_' + QString::number(number);
00199     }
00200     lastTagIndex = number;
00201     return tag;
00202 }
00203 
00208 bool CodeDocument::insertTextBlock(TextBlock * newBlock, TextBlock * existingBlock, bool after)
00209 {
00210 
00211     if(!newBlock || !existingBlock)
00212         return false;
00213 
00214     QString tag = existingBlock->getTag();
00215     if(!findTextBlockByTag(tag, true))
00216         return false;
00217 
00218     int index = m_textblockVector.findRef(existingBlock);
00219     if(index < 0)
00220     {
00221         // may be hiding in child hierarchical codeblock
00222         for(TextBlock * tb = m_textblockVector.first(); tb ; tb = m_textblockVector.next())
00223         {
00224             HierarchicalCodeBlock * hb = dynamic_cast<HierarchicalCodeBlock*>(tb);
00225             if(hb && hb->insertTextBlock(newBlock, existingBlock, after))
00226                 return true; // found, and inserted, otherwise keep going
00227         }
00228         // ugh. where is the child block?
00229         kWarning()<<" Warning: couldnt insert text block (tag:"<<newBlock->getTag()<<"). Reference text block (tag:"<<existingBlock->getTag()<<") not found."<<endl;
00230         return false;
00231     }
00232 
00233     // if we get here.. it was in this object so insert
00234 
00235     // check for tag FIRST
00236     QString new_tag = newBlock->getTag();
00237 
00238     // assign a tag if one doesn't already exist
00239     if(new_tag.isEmpty())
00240     {
00241         new_tag = getUniqueTag();
00242         newBlock->setTag(new_tag);
00243     }
00244 
00245     if(m_textBlockTagMap.contains(new_tag))
00246         return false; // return false, we already have some object with this tag in the list
00247     else
00248         m_textBlockTagMap.insert(new_tag, newBlock);
00249 
00250     if(after)
00251         index++;
00252 
00253     m_textblockVector.insert(index,newBlock);
00254 
00255     return true;
00256 }
00257 
00262 /*
00263 CodeDocumentDialog * CodeDocument::getDialog ( ) {
00264     return m_dialog;
00265 }
00266 */
00267 
00268 // Other methods
00269 //
00270 
00271 QString CodeDocument::cleanName ( const QString &name ) {
00272     return CodeGenerator::cleanName(name);
00273 }
00274 
00275 // update the text and status of the head comment
00276 void CodeDocument::updateHeader () {
00277 
00278     //try to find a heading file (license, coments, etc) then extract its text
00279     QString headingText = UMLApp::app()->getCommonPolicy()->getHeadingFile(getFileExtension());
00280 
00281     headingText.replace(QRegExp("%filename%"),getFileName()+getFileExtension());
00282     headingText.replace(QRegExp("%filepath%"),getPath());
00283     headingText.replace( QRegExp("%time%"), QTime::currentTime().toString());
00284     headingText.replace( QRegExp("%date%"), QDate::currentDate().toString());
00285 
00286     getHeader()->setText(headingText);
00287 
00288     // update the write out status of the header
00289     if(UMLApp::app()->getCommonPolicy()->getIncludeHeadings())
00290         getHeader()->setWriteOutText(true);
00291     else
00292         getHeader()->setWriteOutText(false);
00293 
00294 }
00295 
00300 QString CodeDocument::toString ( ) {
00301 
00302     // IF the whole document is turned "Off" then don't bother
00303     // checking individual code blocks, just send back empty string
00304     if(!getWriteOutCode())
00305         return QString("");
00306 
00307     QString content = getHeader()->toString();
00308 
00309     // update the time/date
00310 
00311     // comments, import, package codeblocks go next
00312     TextBlockList * items = getTextBlockList();
00313     for (TextBlock *c = items->first(); c; c = items->next())
00314     {
00315         if(c->getWriteOutText()) {
00316             QString str = c->toString();
00317             if(!str.isEmpty())
00318                 content.append(str);
00319         }
00320     }
00321     return content;
00322 }
00323 
00324 void CodeDocument::synchronize() {
00325     updateContent();
00326 }
00327 
00328 // need to overload method to beable to clear the childTextBlockMap
00329 void CodeDocument::resetTextBlocks() {
00330     CodeGenObjectWithTextBlocks::resetTextBlocks();
00331     m_childTextBlockTagMap.clear();
00332 }
00333 
00337 void CodeDocument::loadFromXMI ( QDomElement & root ) {
00338     setAttributesFromNode(root);
00339 }
00340 
00344 void CodeDocument::setAttributesOnNode ( QDomDocument & doc, QDomElement & docElement)
00345 {
00346 
00347     // superclass call
00348     CodeGenObjectWithTextBlocks::setAttributesOnNode(doc,docElement);
00349 
00350     // now set local attributes/fields
00351     docElement.setAttribute("fileName",getFileName());
00352     docElement.setAttribute("fileExt",getFileExtension());
00353     Uml::IDType pkgId = Uml::id_None;
00354     if (m_package)
00355         pkgId = m_package->getID();
00356     docElement.setAttribute("package", ID2STR(pkgId));
00357     docElement.setAttribute("writeOutCode",getWriteOutCode()?"true":"false");
00358     docElement.setAttribute("id",getID());
00359 
00360     // set the a header
00361     // which we will store in its own separate child node block
00362     QDomElement commElement = doc.createElement( "header" );
00363     getHeader()->saveToXMI(doc, commElement); // comment
00364     docElement.appendChild( commElement);
00365 
00366     // doc codePolicy?
00367     // FIX: store ONLY if different from the parent generator
00368     // policy.. something which is not possible right now. -b.t.
00369 
00370 }
00371 
00375 void CodeDocument::setAttributesFromNode ( QDomElement & root) {
00376 
00377     // now set local attributes
00378     setFileName(root.attribute("fileName",""));
00379     setFileExtension(root.attribute("fileExt",""));
00380     QString pkgStr = root.attribute("package","");
00381     if (!pkgStr.isEmpty() && pkgStr != "-1") {
00382         UMLDoc *umldoc = UMLApp::app()->getDocument();
00383         if (pkgStr.contains( QRegExp("\\D") )) {
00384             // suspecting pre-1.5.3 file format where the package name was
00385             // saved instead of the package ID.
00386             UMLObject *o = umldoc->findUMLObject(pkgStr);
00387             m_package = dynamic_cast<UMLPackage*>(o);
00388         }
00389         if (m_package == NULL) {
00390             UMLObject *o = umldoc->findObjectById(STR2ID(pkgStr));
00391             m_package = dynamic_cast<UMLPackage*>(o);
00392         }
00393     }
00394     setWriteOutCode(root.attribute("writeOutCode","true") == "true" ? true : false);
00395     setID(root.attribute("id",""));
00396 
00397     // load comment now
00398     // by looking for our particular child element
00399     QDomNode node = root.firstChild();
00400     QDomElement element = node.toElement();
00401     while( !element.isNull() ) {
00402         QString tag = element.tagName();
00403         if( tag == "header" ) {
00404             QDomNode cnode = element.firstChild();
00405             QDomElement celem = cnode.toElement();
00406             getHeader()->loadFromXMI(celem);
00407             break;
00408         }
00409         node = element.nextSibling();
00410         element = node.toElement();
00411     }
00412 
00413     // a rare case where the super-class load is AFTER local attributes
00414     CodeGenObjectWithTextBlocks::setAttributesFromNode(root);
00415 }
00416 
00420 void CodeDocument::saveToXMI ( QDomDocument & doc, QDomElement & root ) {
00421     QDomElement docElement = doc.createElement( "codedocument" );
00422 
00423     setAttributesOnNode(doc, docElement);
00424 
00425     root.appendChild( docElement );
00426 }
00427 
00428 // vanilla code documents don't have much
00429 // to do.. override this with a different
00430 // version for your own documents
00431 void CodeDocument::updateContent() {
00432     updateHeader(); // doing this insures time/date stamp is at the time of this call
00433 }
00434 
00439 CodeBlock * CodeDocument::newCodeBlock ( ) {
00440     return new CodeBlock(this);
00441 }
00442 
00447 CodeBlockWithComments * CodeDocument::newCodeBlockWithComments ( ) {
00448     return new CodeBlockWithComments(this);
00449 }
00450 
00451 HierarchicalCodeBlock * CodeDocument::newHierarchicalCodeBlock ( ) {
00452     HierarchicalCodeBlock *hb = new HierarchicalCodeBlock(this);
00453     //hb->update();
00454     return hb;
00455 }
00456 
00457 void CodeDocument::removeChildTagFromMap ( const QString &tag )
00458 {
00459     m_childTextBlockTagMap.erase(tag);
00460 }
00461 
00462 void CodeDocument::addChildTagToMap ( const QString &tag, TextBlock * tb)
00463 {
00464     m_childTextBlockTagMap.insert(tag, tb);
00465 }
00466 
00467 TextBlock * CodeDocument::findTextBlockByTag( const QString &tag , bool descendIntoChildren)
00468 {
00469     //if we already know to which file this class was written/should be written, just return it.
00470     if(m_textBlockTagMap.contains(tag))
00471         return m_textBlockTagMap[tag];
00472 
00473     if (descendIntoChildren)
00474         if(m_childTextBlockTagMap.contains(tag))
00475             return m_childTextBlockTagMap[tag];
00476 
00477     return (TextBlock*) NULL;
00478 }
00479 
00480 void CodeDocument::initDoc () {
00481 
00482     m_writeOutCode = true;
00483     m_package = NULL;
00484     m_fileExtension = QString("");
00485     m_ID = QString(""); // leave with NO ID as a default
00486 
00487     //m_textblockVector.setAutoDelete(false);
00488 
00489     setHeader(new CodeComment(this));
00490 
00491     lastTagIndex = 0;
00492 
00493     //  m_dialog = new CodeDocumentDialog( );
00494 
00495 }
00496 
00497 TextBlock * CodeDocument::findCodeClassFieldTextBlockByTag ( const QString &tag ) {
00498     kWarning()<<"Called findCodeClassFieldMethodByTag("<<tag<<") for a regular CodeDocument"<<endl;
00499     return (TextBlock *) NULL;
00500 }
00501 
00502 #include "codedocument.moc"
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:55 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003