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.
387 lines
11 KiB
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"
|