/***************************************************************************
* *
* 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 : Wed Jun 18 2003
*/
// own header
# include "hierarchicalcodeblock.h"
// qt/kde includes
# include <kdebug.h>
// local includes
# include "codedocument.h"
# include "classifiercodedocument.h"
# include "codeclassfield.h"
# include "codegenerationpolicy.h"
# include "codegenerators/codegenfactory.h"
# include "uml.h"
// Constructors/Destructors
//
HierarchicalCodeBlock : : HierarchicalCodeBlock ( CodeDocument * doc , const TQString & start , const TQString & endString , const TQString & comment )
: CodeBlockWithComments ( doc , start , comment ) , CodeGenObjectWithTextBlocks ( doc )
{
setEndText ( endString ) ;
initAttributes ( ) ;
}
HierarchicalCodeBlock : : ~ HierarchicalCodeBlock ( ) { }
//
// Methods
//
// Accessor methods
//
/**
* Set the value of m_endText
* @ param new_var the new value of m_endText
*/
void HierarchicalCodeBlock : : setEndText ( const TQString & new_var ) {
m_endText = new_var ;
}
/**
* Get the value of m_endText
* @ return the value of m_endText
*/
TQString HierarchicalCodeBlock : : getEndText ( ) {
return m_endText ;
}
TQString HierarchicalCodeBlock : : getUniqueTag ( )
{
return getUniqueTag ( " hblock_tag " ) ;
}
TQString HierarchicalCodeBlock : : getUniqueTag ( const TQString & prefix )
{
return getParentDocument ( ) - > getUniqueTag ( prefix ) ;
}
// other methods
CodeBlock * HierarchicalCodeBlock : : newCodeBlock ( ) {
return getParentDocument ( ) - > newCodeBlock ( ) ;
}
CodeBlockWithComments * HierarchicalCodeBlock : : newCodeBlockWithComments ( ) {
return getParentDocument ( ) - > newCodeBlockWithComments ( ) ;
}
HierarchicalCodeBlock * HierarchicalCodeBlock : : newHierarchicalCodeBlock ( ) {
HierarchicalCodeBlock * hb = new HierarchicalCodeBlock ( getParentDocument ( ) ) ;
//hb->update();
return hb ;
}
/**
* Add a CodeBlock object to the m_textblockVector List
*/
bool HierarchicalCodeBlock : : addTextBlock ( TextBlock * add_object )
{
if ( CodeGenObjectWithTextBlocks : : addTextBlock ( add_object ) )
{
getParentDocument ( ) - > addChildTagToMap ( add_object - > getTag ( ) , add_object ) ;
return true ;
}
return false ;
}
/**
* Insert a new text block before the existing text block . Returns
* false if it cannot insert the textblock .
*/
bool HierarchicalCodeBlock : : insertTextBlock ( TextBlock * newBlock , TextBlock * existingBlock , bool after )
{
if ( ! newBlock | | ! existingBlock )
return false ;
TQString tag = existingBlock - > getTag ( ) ;
// FIX: just do a quick check if the tqparent DOCUMENT has this.
// IF it does, then the lack of an index will force us into
// a search of any child hierarchical codeblocks we may have
// Its not efficient, but works. I don't think speed is a problem
// right now for the current implementation, but in the future
// when code import/roundtripping is done, it *may* be. -b.t.
if ( ! getParentDocument ( ) - > 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 < HierarchicalCodeBlock * > ( tb ) ;
if ( hb & & hb - > insertTextBlock ( newBlock , existingBlock , after ) )
return true ; // found, and inserted, otherwise keep going
}
kWarning ( ) < < " Warning: couldnt insert text block (tag: " < < newBlock - > getTag ( ) < < " ). Reference text block (tag: " < < existingBlock - > getTag ( ) < < " ) not found. " < < endl ;
return false ;
}
// if we get here.. it was in this object so insert
// check for tag FIRST
TQString new_tag = newBlock - > 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 ) ;
getParentDocument ( ) - > addChildTagToMap ( new_tag , newBlock ) ;
}
if ( after )
index + + ;
m_textblockVector . insert ( index , newBlock ) ;
return true ;
}
/**
* Remove a CodeBlock object from m_textblockVector List
*/
bool HierarchicalCodeBlock : : removeTextBlock ( TextBlock * remove_object ) {
// try to remove from the list in this object
if ( ! m_textblockVector . removeRef ( remove_object ) )
{
// may be hiding in child hierarchical codeblock
for ( TextBlock * tb = m_textblockVector . first ( ) ; tb ; tb = m_textblockVector . next ( ) )
{
HierarchicalCodeBlock * hb = dynamic_cast < HierarchicalCodeBlock * > ( tb ) ;
if ( hb & & hb - > removeTextBlock ( remove_object ) )
return true ; // because we got in child hb;
}
return false ;
}
// IF we get here, the text block was in THIS object (and not a child)..
TQString tag = remove_object - > getTag ( ) ;
if ( ! ( tag . isEmpty ( ) ) )
{
m_textBlockTagMap . erase ( tag ) ;
getParentDocument ( ) - > removeChildTagFromMap ( tag ) ;
}
return true ;
}
/**
* @ param text
*/
void HierarchicalCodeBlock : : setStartText ( const TQString & text ) {
m_startText = text ;
}
/**
* @ return TQString
*/
TQString HierarchicalCodeBlock : : getStartText ( ) {
return m_startText ;
}
// Other methods
//
void HierarchicalCodeBlock : : addCodeClassFieldMethods ( CodeClassFieldList & list )
{
for ( CodeClassFieldListIt ccflit ( list ) ; ccflit . current ( ) ; + + ccflit )
{
CodeClassField * field = ccflit . current ( ) ;
CodeAccessorMethodList list = field - > getMethodList ( ) ;
CodeAccessorMethod * method ;
for ( CodeAccessorMethodListIt it ( list ) ; ( method = it . current ( ) ) ! = NULL ; + + it )
{
TQString tag = method - > getTag ( ) ;
if ( tag . isEmpty ( ) )
{
tag = getUniqueTag ( ) ;
method - > setTag ( tag ) ;
}
addTextBlock ( method ) ; // wont add if already exists in object;
}
}
}
/**
* Save the XMI representation of this object
*/
void HierarchicalCodeBlock : : saveToXMI ( TQDomDocument & doc , TQDomElement & root ) {
TQDomElement blockElement = doc . createElement ( " hierarchicalcodeblock " ) ;
setAttributesOnNode ( doc , blockElement ) ;
root . appendChild ( blockElement ) ;
}
void HierarchicalCodeBlock : : setAttributesOnNode ( TQDomDocument & doc , TQDomElement & elem ) {
// set super-class attributes
CodeBlockWithComments : : setAttributesOnNode ( doc , elem ) ;
CodeGenObjectWithTextBlocks : : setAttributesOnNode ( doc , elem ) ;
// set local class attributes
if ( getContentType ( ) ! = CodeBlock : : AutoGenerated )
{
TQString endLine = UMLApp : : app ( ) - > getCommonPolicy ( ) - > getNewLineEndingChars ( ) ;
elem . setAttribute ( " startText " , encodeText ( getStartText ( ) , endLine ) ) ;
elem . setAttribute ( " endText " , encodeText ( getEndText ( ) , endLine ) ) ;
}
}
/**
* load params from the appropriate XMI element node .
*/
void HierarchicalCodeBlock : : loadFromXMI ( TQDomElement & root ) {
setAttributesFromNode ( root ) ;
}
/** set the class attributes of this object from
* the passed element node .
*/
void HierarchicalCodeBlock : : setAttributesFromNode ( TQDomElement & root )
{
// set attributes from the XMI
CodeBlockWithComments : : setAttributesFromNode ( root ) ; // superclass load
if ( getContentType ( ) ! = CodeBlock : : AutoGenerated )
{
TQString endLine = UMLApp : : app ( ) - > getCommonPolicy ( ) - > getNewLineEndingChars ( ) ;
setStartText ( decodeText ( root . attribute ( " startText " , " " ) , endLine ) ) ;
setEndText ( decodeText ( root . attribute ( " endText " , " " ) , endLine ) ) ;
}
// do this *after* all other attributes saved
CodeGenObjectWithTextBlocks : : setAttributesFromNode ( root ) ;
}
/** set the class attributes from a passed object
*/
void HierarchicalCodeBlock : : setAttributesFromObject ( TextBlock * obj ) {
CodeBlockWithComments : : setAttributesFromObject ( obj ) ;
HierarchicalCodeBlock * hb = dynamic_cast < HierarchicalCodeBlock * > ( obj ) ;
if ( hb )
{
setStartText ( hb - > getStartText ( ) ) ;
setEndText ( hb - > getEndText ( ) ) ;
CodeGenObjectWithTextBlocks * cgowtb = dynamic_cast < CodeGenObjectWithTextBlocks * > ( obj ) ;
CodeGenObjectWithTextBlocks : : setAttributesFromObject ( cgowtb ) ;
}
}
/**
* @ return TQString
*/
TQString HierarchicalCodeBlock : : toString ( ) {
TQString string = TQString ( ) ;
if ( getWriteOutText ( ) ) {
TQString indent = getIndentationString ( ) ;
TQString endLine = UMLApp : : app ( ) - > getCommonPolicy ( ) - > getNewLineEndingChars ( ) ;
TQString startText = " " ;
TQString endText = " " ;
if ( ! getStartText ( ) . isEmpty ( ) )
startText = formatMultiLineText ( getStartText ( ) , indent , endLine ) ;
if ( ! getEndText ( ) . isEmpty ( ) )
endText = formatMultiLineText ( getEndText ( ) , indent , endLine ) ;
TQString body = childTextBlocksToString ( ) ;
TQString comment = getComment ( ) - > toString ( ) ;
// tack in text, if there is something there..
if ( ! comment . isEmpty ( ) & & getComment ( ) - > getWriteOutText ( ) )
string . append ( comment ) ;
if ( ! startText . isEmpty ( ) )
string . append ( startText ) ;
if ( ! body . isEmpty ( ) )
string . append ( body ) ;
if ( ! endText . isEmpty ( ) )
string . append ( endText ) ;
}
return string ;
}
TQString HierarchicalCodeBlock : : childTextBlocksToString ( ) {
TextBlockList * list = getTextBlockList ( ) ;
TQString retString = " " ;
for ( TextBlock * block = list - > first ( ) ; block ; block = list - > next ( ) )
{
TQString blockValue = block - > toString ( ) ;
if ( ! blockValue . isEmpty ( ) )
retString . append ( blockValue ) ;
}
return retString ;
}
TextBlock * HierarchicalCodeBlock : : findCodeClassFieldTextBlockByTag ( const TQString & tag )
{
ClassifierCodeDocument * cdoc = dynamic_cast < ClassifierCodeDocument * > ( getParentDocument ( ) ) ;
if ( cdoc )
return cdoc - > findCodeClassFieldTextBlockByTag ( tag ) ;
else
kError ( ) < < " HierarchicalCodeBlock: findCodeClassFieldTextBlockByTag() finds NO tqparent document! Badly constructed textblock?!? " < < endl ;
// if we get here, we failed.
return ( TextBlock * ) NULL ;
}
void HierarchicalCodeBlock : : initAttributes ( ) {
m_canDelete = false ;
m_startText = " " ;
m_endText = " " ;
}
void HierarchicalCodeBlock : : release ( ) {
resetTextBlocks ( ) ;
TextBlock : : release ( ) ;
}
# include "hierarchicalcodeblock.moc"