You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesdk/umbrello/umbrello/hierarchicalcodeblock.cpp

387 lines
11 KiB

/***************************************************************************
* *
* 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 parent 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.findRef(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.contains(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 parent 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"