rev 6864 - in trunk/packages/kdesdk/debian: . patches
Sune Vuorela
pusling-guest at alioth.debian.org
Fri Jul 27 09:20:59 UTC 2007
Author: pusling-guest
Date: 2007-07-27 09:20:59 +0000 (Fri, 27 Jul 2007)
New Revision: 6864
Added:
trunk/packages/kdesdk/debian/patches/01_branches_umbrello_update_1.5.71.diff
Modified:
trunk/packages/kdesdk/debian/changelog
Log:
update umbrello from upstream
Modified: trunk/packages/kdesdk/debian/changelog
===================================================================
--- trunk/packages/kdesdk/debian/changelog 2007-07-26 16:07:24 UTC (rev 6863)
+++ trunk/packages/kdesdk/debian/changelog 2007-07-27 09:20:59 UTC (rev 6864)
@@ -1,6 +1,10 @@
kdesdk (4:3.5.7-3) unstable; urgency=low
+ +++ Changes by Sune Vuorela:
+
* Implement the use of uploaders.mk and update uploaders.
+ * Pull newer umbrello release in. (Closes: 428059). Thanks to Eric Valette
+ for his friendly attitude.
-- Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org> Mon, 23 Jul 2007 23:27:56 +0200
Added: trunk/packages/kdesdk/debian/patches/01_branches_umbrello_update_1.5.71.diff
===================================================================
--- trunk/packages/kdesdk/debian/patches/01_branches_umbrello_update_1.5.71.diff (rev 0)
+++ trunk/packages/kdesdk/debian/patches/01_branches_umbrello_update_1.5.71.diff 2007-07-27 09:20:59 UTC (rev 6864)
@@ -0,0 +1,2435 @@
+diff -pruN kdesdk-3.5.7/umbrello/ChangeLog kdesdk/umbrello/ChangeLog
+--- kdesdk-3.5.7/umbrello/ChangeLog 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/ChangeLog 2007-06-06 00:33:30.000000000 +0200
+@@ -1,3 +1,17 @@
++Version 1.5.71
++
++* Bugs/wishes from http://bugs.kde.org:
++* Preprocessor keywords ignored which causes endless loop in code import (119125)
++* Code generator for D language (124805)
++* Unstable saves and loads, class names become dirty (145709)
++* Crash on deleting class in list view (145762)
++* Class attribute documentation not generated for python (145916)
++* Python code generator does not wrap lines properly (145918)
++* Attribute documentation not generated for 'Export to XHTML' (145972)
++* Crash when moving a class in a Java UML diagram (146058)
++* Arrowheads are not shown (146064)
++* Crash when creating a class that refers to more than one other classes/datatypes (146367)
++
+ Version 1.5.7
+
+ * Bugs/wishes from http://bugs.kde.org:
+diff -pruN kdesdk-3.5.7/umbrello/THANKS kdesdk/umbrello/THANKS
+--- kdesdk-3.5.7/umbrello/THANKS 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/THANKS 2007-06-05 07:04:45.000000000 +0200
+@@ -49,6 +49,7 @@ Tobias Koenig <tokoe @kde.org>
+ Piotr Kolaczkowski <P.Kolaczkowski @elka.pw.edu.pl>
+ Matthias Kretz <kretz @kde.org>
+ Thorsten Kunz <tk @bytecrash.net>
++Jari-Matti Mäkelä <jmjm @iki.fi>
+ Gustavo Madrigal <gmadrigal @nextphere.com>
+ martin <mv123q3 @hotmail.com>
+ Rene Meyer <Rene.Meyer @sturmit.de>
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/associationwidget.cpp kdesdk/umbrello/umbrello/associationwidget.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/associationwidget.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/associationwidget.cpp 2007-06-07 10:51:43.000000000 +0200
+@@ -5,8 +5,8 @@
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+- * copyright (C) 2002-2006 *
+- * Umbrello UML Modeller Authors <uml-devel at uml.sf.net> *
++ * copyright (C) 2002-2007 *
++ * Umbrello UML Modeller Authors <uml-devel at uml.sf.net> *
+ ***************************************************************************/
+
+ // own header
+@@ -350,23 +350,17 @@ void AssociationWidget::setFloatingText(
+ return;
+ }
+
+- bool newLabel = false;
+ if (ft == NULL) {
+ ft = new FloatingTextWidget(m_pView, tr, text);
+ ft->setLink(this);
++ ft->activate();
++ setTextPosition(tr);
+ m_pView->addWidget(ft);
+- newLabel = true;
+ } else {
+- if (ft->getText().isEmpty()) {
+- newLabel = true;
+- }
++ bool newLabel = ft->getText().isEmpty();
+ ft->setText(text);
+- }
+-
+- ft->setActivated();
+-
+- if (newLabel) {
+- setTextPosition( tr );
++ if (newLabel)
++ setTextPosition(tr);
+ }
+
+ ft->show();
+@@ -3437,7 +3431,21 @@ bool AssociationWidget::loadFromXMI( QDo
+ }
+
+ // New style: The xmi.id is a reference to the UMLAssociation.
++ // If the UMLObject is not found right now, we try again later
++ // during the type resolution pass - see activate().
+ m_nId = STR2ID(id);
++ UMLObject *myObj = m_umldoc->findObjectById(m_nId);
++ if (myObj) {
++ const Uml::Object_Type ot = myObj->getBaseType();
++ if (ot != ot_Association) {
++ setUMLObject(myObj);
++ } else {
++ UMLAssociation * myAssoc = static_cast<UMLAssociation*>(myObj);
++ setUMLAssociation(myAssoc);
++ if (type == "-1")
++ aType = myAssoc->getAssocType();
++ }
++ }
+ }
+
+ setAssocType(aType);
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/attribute.cpp kdesdk/umbrello/umbrello/attribute.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/attribute.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/attribute.cpp 2007-06-07 11:26:13.000000000 +0200
+@@ -26,22 +26,18 @@
+ UMLAttribute::UMLAttribute( const UMLObject *parent,
+ const QString& name, Uml::IDType id,
+ Uml::Visibility s,
+- const QString& type, const QString& iv )
++ UMLObject *type, const QString& iv )
+ : UMLClassifierListItem(parent, name, id) {
+ m_InitialValue = iv;
+ m_BaseType = Uml::ot_Attribute;
+ m_Vis = s;
+ m_ParmKind = Uml::pd_In;
+- if (!type.isEmpty()) {
+- UMLDoc *pDoc = UMLApp::app()->getDocument();
+- m_pSecondary = pDoc->findUMLObject(type);
+- if (m_pSecondary == NULL) {
+- if (type.contains( QRegExp("[\\*\\&]") ))
+- m_pSecondary = Object_Factory::createUMLObject(Uml::ot_Datatype, type);
+- else
+- m_pSecondary = Object_Factory::createUMLObject(Uml::ot_Class, type);
+- }
++ /* CHECK: Do we need this:
++ if (type == NULL) {
++ type = Object_Factory::createUMLObject(Uml::ot_Datatype, "undef");
+ }
++ */
++ m_pSecondary = type;
+ }
+
+ UMLAttribute::UMLAttribute(const UMLObject *parent) : UMLClassifierListItem(parent) {
+@@ -299,8 +295,9 @@ UMLClassifierList UMLAttribute::getTempl
+ UMLClassifierList templateParamList;
+ QString type = getType()->getName();
+ QString templateParam;
+- //template and generic only in C++ and Java ?
+- if (UMLApp::app()->getActiveLanguage() == Uml::pl_Cpp || UMLApp::app()->getActiveLanguage() == Uml::pl_Java) {
++ // Handle C++/D/Java template/generic parameters
++ const Uml::Programming_Language pl = UMLApp::app()->getActiveLanguage();
++ if (pl == Uml::pl_Cpp || pl == Uml::pl_Java || pl == Uml::pl_D) {
+ int start = type.find(QChar('<'));
+ if (start >= 0 ) {
+ int end = type.findRev(QChar('>'));
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/attribute.h kdesdk/umbrello/umbrello/attribute.h
+--- kdesdk-3.5.7/umbrello/umbrello/attribute.h 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/attribute.h 2007-06-07 11:22:51.000000000 +0200
+@@ -40,7 +40,7 @@ public:
+ UMLAttribute(const UMLObject *parent, const QString& name,
+ Uml::IDType id = Uml::id_None,
+ Uml::Visibility s = Uml::Visibility::Private,
+- const QString& type = "int", const QString& iv = 0);
++ UMLObject *type = 0, const QString& iv = 0);
+
+ /**
+ * Sets up an attribute.
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/classifier.cpp kdesdk/umbrello/umbrello/classifier.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/classifier.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/classifier.cpp 2007-06-07 11:49:57.000000000 +0200
+@@ -182,10 +182,9 @@ UMLOperation* UMLClassifier::createOpera
+ if (params) {
+ for (Model_Utils::NameAndType_ListIt it = params->begin(); it != params->end(); ++it ) {
+ const Model_Utils::NameAndType &nt = *it;
+- UMLAttribute *par = new UMLAttribute(op, nt.m_name);
+- par->setType(nt.m_type);
++ UMLAttribute *par = new UMLAttribute(op, nt.m_name, Uml::id_None, Uml::Visibility::Private,
++ nt.m_type, nt.m_initialValue);
+ par->setParmKind(nt.m_direction);
+- par->setInitialValue(nt.m_initialValue);
+ op->addParm(par);
+ }
+ }
+@@ -243,8 +242,8 @@ bool UMLClassifier::addOperation(UMLOper
+ kDebug() << " UMLClassifier::addOperation list after change: " << buf << endl;
+ } else
+ m_List.append( op );
+- UMLObject::emitModified();
+ emit operationAdded(op);
++ UMLObject::emitModified();
+ connect(op,SIGNAL(modified()),this,SIGNAL(modified()));
+ return true;
+ }
+@@ -272,8 +271,8 @@ int UMLClassifier::removeOperation(UMLOp
+ // disconnection needed.
+ // note that we don't delete the operation, just remove it from the Classifier
+ disconnect(op,SIGNAL(modified()),this,SIGNAL(modified()));
+- UMLObject::emitModified();
+ emit operationRemoved(op);
++ UMLObject::emitModified();
+ return m_List.count();
+ }
+
+@@ -496,7 +495,10 @@ bool UMLClassifier::acceptAssociationTyp
+ return false; //shutup compiler warning
+ }
+
+-UMLAttribute* UMLClassifier::createAttribute(const QString &name /*=null*/) {
++UMLAttribute* UMLClassifier::createAttribute(const QString &name /*=null*/,
++ UMLObject *type,
++ Uml::Visibility vis,
++ const QString &init) {
+ Uml::IDType id = UniqueID::gen();
+ QString currentName;
+ if (name.isNull()) {
+@@ -504,9 +506,7 @@ UMLAttribute* UMLClassifier::createAttri
+ } else {
+ currentName = name;
+ }
+- const Settings::OptionState optionState = Settings::getOptionState();
+- Uml::Visibility scope = optionState.classState.defaultAttributeScope;
+- UMLAttribute* newAttribute = new UMLAttribute(this, currentName, id, scope);
++ UMLAttribute* newAttribute = new UMLAttribute(this, currentName, id, vis, type, init);
+
+ int button = QDialog::Accepted;
+ bool goodName = false;
+@@ -528,6 +528,7 @@ UMLAttribute* UMLClassifier::createAttri
+ }
+
+ if (button != QDialog::Accepted) {
++ delete newAttribute;
+ return NULL;
+ }
+
+@@ -547,8 +548,8 @@ UMLAttribute* UMLClassifier::addAttribut
+ Uml::Visibility scope = Settings::getOptionState().classState.defaultAttributeScope;
+ UMLAttribute *a = new UMLAttribute(this, name, id, scope);
+ m_List.append(a);
+- UMLObject::emitModified();
+ emit attributeAdded(a);
++ UMLObject::emitModified();
+ connect(a,SIGNAL(modified()),this,SIGNAL(modified()));
+ return a;
+ }
+@@ -561,8 +562,8 @@ UMLAttribute* UMLClassifier::addAttribut
+ if (type)
+ a->setType(type);
+ m_List.append(a);
+- UMLObject::emitModified();
+ emit attributeAdded(a);
++ UMLObject::emitModified();
+ connect(a,SIGNAL(modified()),this,SIGNAL(modified()));
+ return a;
+ }
+@@ -576,8 +577,8 @@ bool UMLClassifier::addAttribute(UMLAttr
+ m_List.insert(position, att);
+ else
+ m_List.append(att);
+- UMLObject::emitModified();
+ emit attributeAdded(att);
++ UMLObject::emitModified();
+ connect(att, SIGNAL(modified()), this, SIGNAL(modified()));
+ return true;
+ } else if (Log) {
+@@ -592,8 +593,8 @@ int UMLClassifier::removeAttribute(UMLAt
+ kDebug() << "can't find att given in list" << endl;
+ return -1;
+ }
+- UMLObject::emitModified();
+ emit attributeRemoved(a);
++ UMLObject::emitModified();
+ // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
+ // for us by QObject. -b.t.
+ // disconnect(a,SIGNAL(modified()),this,SIGNAL(modified()));
+@@ -674,8 +675,8 @@ UMLTemplate* UMLClassifier::addTemplate(
+ return t;
+ t = new UMLTemplate(this, name, id);
+ m_List.append(t);
+- UMLObject::emitModified();
+ emit templateAdded(t);
++ UMLObject::emitModified();
+ connect(t, SIGNAL(modified()), this, SIGNAL(modified()));
+ return t;
+ }
+@@ -686,8 +687,8 @@ bool UMLClassifier::addTemplate(UMLTempl
+ newTemplate->parent()->removeChild(newTemplate);
+ this->insertChild(newTemplate);
+ m_List.append(newTemplate);
+- UMLObject::emitModified();
+ emit templateAdded(newTemplate);
++ UMLObject::emitModified();
+ connect(newTemplate,SIGNAL(modified()),this,SIGNAL(modified()));
+ return true;
+ } else if (log) {
+@@ -707,8 +708,8 @@ bool UMLClassifier::addTemplate(UMLTempl
+ m_List.insert(position,Template);
+ else
+ m_List.append(Template);
+- UMLObject::emitModified();
+ emit templateAdded(Template);
++ UMLObject::emitModified();
+ connect(Template,SIGNAL(modified()),this,SIGNAL(modified()));
+ return true;
+ }
+@@ -721,8 +722,8 @@ int UMLClassifier::removeTemplate(UMLTem
+ kWarning() << "can't find att given in list" << endl;
+ return -1;
+ }
+- UMLObject::emitModified();
+ emit templateRemoved(umltemplate);
++ UMLObject::emitModified();
+ disconnect(umltemplate,SIGNAL(modified()),this,SIGNAL(modified()));
+ return m_List.count();
+ }
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/classifier.h kdesdk/umbrello/umbrello/classifier.h
+--- kdesdk-3.5.7/umbrello/umbrello/classifier.h 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/classifier.h 2007-06-07 11:48:19.000000000 +0200
+@@ -78,9 +78,15 @@ public:
+ * Creates an attribute for the class.
+ *
+ * @param name An optional name, used by when creating through UMLListView
++ * @param type An optional type, used by when creating through UMLListView
++ * @param vis An optional visibility, used by when creating through UMLListView
++ * @param init An optional initial value, used by when creating through UMLListView
+ * @return The UMLAttribute created
+ */
+- virtual UMLAttribute* createAttribute(const QString &name = QString::null);
++ virtual UMLAttribute* createAttribute(const QString &name = QString::null,
++ UMLObject *type = 0,
++ Uml::Visibility vis = Uml::Visibility::Private,
++ const QString &init = QString::null);
+
+ /**
+ * Adds an attribute to the class.
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/codegenerators/codegenfactory.cpp kdesdk/umbrello/umbrello/codegenerators/codegenfactory.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/codegenerators/codegenfactory.cpp 2007-05-14 09:40:28.000000000 +0200
++++ kdesdk/umbrello/umbrello/codegenerators/codegenfactory.cpp 2007-06-05 07:24:23.000000000 +0200
+@@ -34,6 +34,7 @@
+ #include "adawriter.h"
+ #include "cppwriter.h"
+ #include "csharpwriter.h"
++#include "dwriter.h"
+ #include "idlwriter.h"
+ #include "javawriter.h"
+ #include "pascalwriter.h"
+@@ -116,6 +117,9 @@ CodeGenerator* createObject(Uml::Program
+ case Uml::pl_CSharp:
+ obj = new CSharpWriter();
+ break;
++ case Uml::pl_D:
++ obj = new DWriter();
++ break;
+ case Uml::pl_IDL:
+ obj = new IDLWriter();
+ break;
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/codegenerators/dwriter.cpp kdesdk/umbrello/umbrello/codegenerators/dwriter.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/codegenerators/dwriter.cpp 1970-01-01 01:00:00.000000000 +0100
++++ kdesdk/umbrello/umbrello/codegenerators/dwriter.cpp 2007-06-05 07:55:38.000000000 +0200
+@@ -0,0 +1,975 @@
++
++/***************************************************************************
++ * *
++ * 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) 2007 Jari-Matti Mäkelä <jmjm at iki.fi> *
++ * Umbrello UML Modeller Authors <uml-devel at uml.sf.net> *
++ ***************************************************************************/
++
++/***************************************************************************
++ This is the "old" code generator that does not support code editing
++ in the Modeller but uses significantly less file space because the
++ source code is not replicated in the XMI file.
++ ***************************************************************************/
++
++// own header
++#include "dwriter.h"
++// qt includes
++#include <qfile.h>
++#include <qstringlist.h>
++#include <qtextstream.h>
++#include <qregexp.h>
++// kde includes
++#include <kdebug.h>
++// app includes
++#include "../umldoc.h"
++#include "../classifier.h"
++#include "../operation.h"
++#include "../attribute.h"
++#include "../association.h"
++#include "../template.h"
++#include "../umltemplatelist.h"
++
++DWriter::DWriter() {
++ startline = m_endl + m_indentation;
++}
++
++DWriter::~DWriter() {}
++
++Uml::Programming_Language DWriter::getLanguage() {
++ return Uml::pl_D;
++}
++
++// FIXME: doesn't work yet
++void DWriter::writeModuleDecl(UMLClassifier *c, QTextStream &d) {
++ if(!c->getPackage().isEmpty())
++ d << "module " << c->getPackage() << ";" << m_endl;
++
++ writeBlankLine(d);
++}
++
++void DWriter::writeModuleImports(UMLClassifier *c, QTextStream &d) {
++ // another preparation, determine what we have
++ UMLAssociationList associations = c->getSpecificAssocs(Uml::at_Association); // BAD! only way to get "general" associations.
++ UMLAssociationList uniAssociations = c->getUniAssociationToBeImplemented();
++
++ UMLAssociationList aggregations = c->getAggregations();
++ UMLAssociationList compositions = c->getCompositions();
++
++ bool hasAssociations = aggregations.count() + associations.count() +
++ compositions.count() + uniAssociations.count() > 0;
++
++ if (hasAssociations) {
++ // import tango, if that mode is set
++ writeBlankLine(d);
++ }
++
++ //only import classes in a different package as this class
++ UMLPackageList imports;
++ findObjectsRelated(c, imports);
++ for (UMLPackage *con = imports.first(); con; con = imports.next()) {
++ if (con->getBaseType() == Uml::ot_Datatype)
++ continue;
++ QString pkg = con->getPackage();
++ if (!pkg.isEmpty() && pkg != c->getPackage())
++ d << "import " << pkg << "." << cleanName(con->getName()) << ";"
++ << m_endl;
++ }
++
++ writeBlankLine(d);
++}
++
++void DWriter::writeClass(UMLClassifier *c) {
++ if (!c) {
++ kDebug()<<"Cannot write class of NULL concept!\n";
++ return;
++ }
++
++ isInterface = c->isInterface();
++
++ QString fileName = cleanName(c->getName().lower());
++
++ //find an appropriate name for our file
++ fileName = findFileName(c, ".d");
++ if (fileName.isEmpty()) {
++ emit codeGenerated(c, false);
++ return;
++ }
++
++ // check that we may open that file for writing
++ QFile file;
++ if ( !openFile(file, fileName) ) {
++ emit codeGenerated(c, false);
++ return;
++ }
++
++ // open text stream to file
++ QTextStream d(&file);
++
++ //try to find a heading file (license, coments, etc)
++ QString str;
++ str = getHeadingFile(".d");
++ if(!str.isEmpty()) {
++ str.replace(QRegExp("%filename%"),fileName);
++ str.replace(QRegExp("%filepath%"),file.name());
++ d<<str<<m_endl;
++ }
++
++ // source file begins with the module declaration
++ writeModuleDecl(c, d);
++
++ // imports
++ writeModuleImports(c, d);
++
++ // write the opening declaration for the class incl any documentation,
++ // interfaces and/or inheritence issues we have
++ writeClassDecl(c, d);
++
++ // start body of class
++ d << " {" << m_endl;
++
++
++ // Preparations
++ //
++
++ // sort attributes by Scope
++ UMLAttributeList atl;
++ UMLAttributeList atpub, atprot, atpriv, atpkg, atexport;
++ UMLAttributeList final_atpub, final_atprot, final_atpriv, final_atpkg, final_atexport;
++
++ atpub.setAutoDelete(false);
++ final_atpub.setAutoDelete(false);
++ atprot.setAutoDelete(false);
++ final_atprot.setAutoDelete(false);
++ atpriv.setAutoDelete(false);
++ final_atpriv.setAutoDelete(false);
++ atpkg.setAutoDelete(false);
++ final_atpkg.setAutoDelete(false);
++ atexport.setAutoDelete(false);
++ final_atexport.setAutoDelete(false);
++
++ if (!isInterface) {
++ UMLAttributeList atl = c->getAttributeList();
++ for (UMLAttribute *at = atl.first(); at ; at = atl.next()) {
++ switch(at->getVisibility())
++ {
++ case Uml::Visibility::Public:
++ if(at->getStatic())
++ final_atpub.append(at);
++ else
++ atpub.append(at);
++ break;
++ case Uml::Visibility::Protected:
++ if(at->getStatic())
++ final_atprot.append(at);
++ else
++ atprot.append(at);
++ break;
++ case Uml::Visibility::Private:
++ if(at->getStatic())
++ final_atpriv.append(at);
++ else
++ atpriv.append(at);
++ break;/* TODO: requires support from the gui & other structures
++ case Uml::Visibility::Package:
++ if(at->getStatic())
++ final_atpkg.append(at);
++ else
++ atpkg.append(at);
++ break;
++ case Uml::Visibility::Export:
++ if(at->getStatic())
++ final_atexport.append(at);
++ else
++ atexport.append(at);
++ break;*/
++ default:
++ break;
++ }
++ }
++ }
++
++ // another preparation, determine what we have
++ UMLAssociationList associations = c->getSpecificAssocs(Uml::at_Association); // BAD! only way to get "general" associations.
++ UMLAssociationList uniAssociations = c->getUniAssociationToBeImplemented();
++
++ UMLAssociationList aggregations = c->getAggregations();
++ UMLAssociationList compositions = c->getCompositions();
++
++ bool hasAssociations = aggregations.count() + associations.count() + compositions.count() + uniAssociations.count() > 0;
++ bool hasAttributes = atl.count() > 0;
++ bool hasAccessorMethods = hasAttributes || hasAssociations;
++ bool hasOperationMethods = c->getOpList().count() > 0;
++
++ // ATTRIBUTES
++ //
++
++ // write comment for section IF needed
++ if (forceDoc() || hasAccessorMethods)
++ {
++ writeComment("", m_indentation, d);
++ writeComment("Fields", m_indentation, d);
++ writeComment("", m_indentation, d);
++ writeBlankLine(d);
++ }
++
++ writeAttributeDecls(final_atpub, final_atprot, final_atpriv, d);
++ writeAttributeDecls(atpub, atprot, atpriv, d);
++
++ writeAssociationDecls(associations, c->getID(), d);
++ writeAssociationDecls(uniAssociations, c->getID(), d);
++ writeAssociationDecls(aggregations, c->getID(), d);
++ writeAssociationDecls(compositions, c->getID(), d);
++
++ //FIXME: find constructors and write them here
++
++ // write constructors
++ if(!isInterface) writeConstructor(c, d);
++
++
++ // METHODS
++ //
++
++ // write comment for sub-section IF needed
++ if (forceDoc() || hasAccessorMethods ) {
++ writeComment("", m_indentation, d);
++ writeComment("Accessors", m_indentation, d);
++ writeComment("", m_indentation, d);
++ writeBlankLine(d);
++ }
++
++
++ // Accessors for attributes
++ writeAttributeMethods(final_atpub, Uml::Visibility::Public, d);
++ writeAttributeMethods(final_atprot, Uml::Visibility::Protected, d);
++ writeAttributeMethods(final_atpriv, Uml::Visibility::Private, d);
++ writeAttributeMethods(atpub, Uml::Visibility::Public, d);
++ writeAttributeMethods(atprot, Uml::Visibility::Protected, d);
++ writeAttributeMethods(atpriv, Uml::Visibility::Private, d);
++
++ // accessor methods for associations
++
++ // first: determine the name of the other class
++ writeAssociationMethods(associations, c, d);
++ writeAssociationMethods(uniAssociations, c, d);
++ writeAssociationMethods(aggregations, c, d);
++ writeAssociationMethods(compositions, c, d);
++
++ // Other operation methods
++ // all other operations are now written
++
++ // write comment for sub-section IF needed
++ if (forceDoc() || hasOperationMethods) {
++ writeComment("", m_indentation, d);
++ writeComment("Other methods", m_indentation, d);
++ writeComment("", m_indentation, d);
++ writeBlankLine(d);
++ }
++
++ writeOperations(c, d);
++
++ d << "}" << m_endl; // end class
++
++ file.close();
++ emit codeGenerated(c, true);
++}
++
++void DWriter::writeClassDecl(UMLClassifier *c, QTextStream &d) {
++
++ // class documentation
++ if (!c->getDoc().isEmpty()) {
++ writeDocumentation("", c->getDoc(), "", "", d);
++ }
++
++ /*
++ * Class declaration
++ *
++ * (private) class foo(T, ..., Z) : class1, ..., classN, interface1, ..., interfaceN
++ * a b c d e f g
++ */
++
++ // (a) visibility modifier
++ switch(c->getVisibility()) {
++ case Uml::Visibility::Private: d << "private "; break;
++ default: break;
++ }
++
++ // (b) keyword
++ // TODO what about structs?
++ if (isInterface) {
++ d << "interface ";
++ } else {
++ if (c->getAbstract()) {
++ d << "abstract ";
++ }
++
++ d << "class ";
++ }
++
++ // (c) class name
++ QString classname = cleanName(c->getName()); // our class name
++ d << classname;
++
++ // (d) template parameters
++ UMLTemplateList template_params = c->getTemplateList();
++ if (template_params.count()) {
++ d << "(";
++
++ for (UMLTemplate *t = template_params.first(); t; ) {
++ // TODO: hm, leaving the type blank results in "class"
++ // so we omit it (also because "class" in this context is illegal)
++ if (t->getTypeName() != "class") {
++ d << t->getTypeName();
++ d << " ";
++ }
++
++ d << t->getName();
++
++ if ((t = template_params.next()) != NULL)
++ d << ", ";
++ }
++
++ d << ")";
++ }
++
++ // (e) inheritances
++ UMLClassifierList superclasses =
++ c->findSuperClassConcepts(UMLClassifier::CLASS);
++ UMLClassifierList superinterfaces =
++ c->findSuperClassConcepts(UMLClassifier::INTERFACE);
++
++ int count = superclasses.count() + superinterfaces.count();
++
++ if (count > 0) {
++ d << " : ";
++
++ // (f) base classes
++ for (UMLClassifier * concept= superclasses.first(); concept; concept = superclasses.next()) {
++ d << cleanName(concept->getName());
++
++ count--;
++
++ if (count>0) d << ", ";
++ }
++
++ // (g) interfaces
++ for (UMLClassifier * concept= superinterfaces.first(); concept; concept = superinterfaces.next()) {
++ d << cleanName(concept->getName());
++
++ count--;
++
++ if (count>0) d << ", ";
++ }
++ }
++}
++
++void DWriter::writeProtectionMod(Uml::Visibility visibility, QTextStream &d) {
++ d << m_indentation << scopeToDDecl(visibility) << ":" << m_endl << m_endl;
++}
++
++void DWriter::writeAttributeDecl(Uml::Visibility visibility, UMLAttributeList &atlist, QTextStream &d) {
++ if (atlist.count()==0) return;
++
++ writeProtectionMod(visibility, d);
++
++ for(UMLAttribute *at=atlist.first(); at; at=atlist.next()) {
++ // documentation
++ if (!at->getDoc().isEmpty()) {
++ writeComment(at->getDoc(), m_indentation, d, true);
++ }
++
++ d << m_indentation;
++
++ // static attribute?
++ if (at->getStatic()) d << "static ";
++
++ // method return type
++ d << fixTypeName(at->getTypeName()) << " ";
++
++ // TODO: find out whether this class has accessors or not
++ bool hasAccessorMethods = true;
++
++ // attribute name
++ if (hasAccessorMethods) {
++ d << "m_";
++ }
++ d << cleanName(at->getName());
++
++ // initial value
++ QString initVal = fixInitialStringDeclValue(at->getInitialValue(), at->getTypeName());
++ if (!initVal.isEmpty()) d << " = " << initVal;
++ d << ";" << m_endl << m_endl;
++ }
++}
++
++void DWriter::writeAttributeDecls(UMLAttributeList &atpub, UMLAttributeList &atprot,
++ UMLAttributeList &atpriv, QTextStream &d ) {
++
++ writeAttributeDecl(Uml::Visibility::Public, atpub, d);
++ writeAttributeDecl(Uml::Visibility::Protected, atprot, d);
++ writeAttributeDecl(Uml::Visibility::Private, atpriv, d);
++ //TODO: export and package
++}
++
++void DWriter::writeAttributeMethods(UMLAttributeList &atpub, Uml::Visibility visibility, QTextStream &d) {
++ if (atpub.count()==0) return;
++
++ writeProtectionMod(visibility, d);
++
++ for(UMLAttribute *at=atpub.first(); at; at=atpub.next()) {
++ QString fieldName = cleanName(at->getName());
++ writeSingleAttributeAccessorMethods(
++ at->getTypeName(), "m_" + fieldName, fieldName, at->getDoc(),
++ visibility, Uml::chg_Changeable, at->getStatic(), d);
++ }
++}
++
++void DWriter::writeComment(const QString &comment, const QString &myIndent,
++ QTextStream &d, bool dDocStyle) {
++ if(dDocStyle) {
++ d << myIndent << "/**" << m_endl;
++ }
++
++ QStringList lines = QStringList::split("\n", comment);
++
++ if (lines.count() == 0) lines << comment;
++
++ for (uint i = 0; i < lines.count(); ++i) {
++ QString tmp = lines[i];
++
++ while (tmp.length() > 77) {
++ uint l = tmp.left(77).findRev(' ');
++ if (l < 1) l = tmp.find(' ', 77);
++ if (l < 1 || l > tmp.length()) {
++ d << myIndent << (dDocStyle ? " * " : "// ") << tmp << m_endl;
++ break;
++ }
++ d << myIndent << (dDocStyle ? " * " : "// ") << tmp.left(l) << m_endl;
++ tmp = tmp.right(tmp.length() - l);
++ }
++
++ d << myIndent << (dDocStyle ? " * " : "// ") << tmp << m_endl;
++ }
++
++ if(dDocStyle) {
++ d << myIndent << " */" << m_endl;
++ }
++}
++
++void DWriter::writeDocumentation(QString header, QString body, QString end, QString indent, QTextStream &d) {
++ d << indent << "/**" << m_endl;
++ if (!header.isEmpty())
++ d << formatDoc(header, indent+" * ");
++ if (!body.isEmpty())
++ d << formatDoc(body, indent+" * ");
++ if (!end.isEmpty())
++ {
++ QStringList lines = QStringList::split( "\n", end);
++ for (uint i= 0; i < lines.count(); i++)
++ d << formatDoc(lines[i], indent + " * ");
++ }
++ d<<indent<< " */" << m_endl;
++}
++
++void DWriter::writeAssociationDecls(UMLAssociationList associations, Uml::IDType id, QTextStream &d) {
++
++ if( forceSections() || !associations.isEmpty() )
++ {
++ bool printRoleA = false, printRoleB = false;
++ for(UMLAssociation *a = associations.first(); a; a = associations.next())
++ {
++ // it may seem counter intuitive, but you want to insert the role of the
++ // *other* class into *this* class.
++ if (a->getObjectId(Uml::A) == id)
++ printRoleB = true;
++
++ if (a->getObjectId(Uml::B) == id)
++ printRoleA = true;
++
++ // First: we insert documentaion for association IF it has either role AND some documentation (!)
++ if ((printRoleA || printRoleB) && !(a->getDoc().isEmpty()))
++ writeComment(a->getDoc(), m_indentation, d);
++
++ // print RoleB decl
++ if (printRoleB)
++ {
++ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::B)));
++ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::B), a->getMulti(Uml::B), a->getRoleDoc(Uml::B), a->getVisibility(Uml::B), d);
++ }
++
++ // print RoleA decl
++ if (printRoleA)
++ {
++ QString fieldClassName = cleanName(getUMLObjectName(a->getObject(Uml::A)));
++ writeAssociationRoleDecl(fieldClassName, a->getRoleName(Uml::A), a->getMulti(Uml::A), a->getRoleDoc(Uml::A), a->getVisibility(Uml::A), d);
++ }
++ }
++ }
++}
++
++void DWriter::writeAssociationRoleDecl(QString fieldClassName,
++ QString roleName, QString multi,
++ QString doc, Uml::Visibility /* visib */, QTextStream &d) {
++ // ONLY write out IF there is a rolename given
++ // otherwise its not meant to be declared in the code
++ if (roleName.isEmpty()) return;
++
++ if (!doc.isEmpty()) {
++ writeComment(doc, m_indentation, d);
++ }
++
++ bool hasAccessors = true;
++
++ // declare the association based on whether it is this a single variable
++ // or a List (Vector). One day this will be done correctly with special
++ // multiplicity object that we don't have to figure out what it means via regex.
++ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$"))) {
++ d << m_indentation << fieldClassName << " ";
++
++ if (hasAccessors) d << "m_";
++
++ d << deCapitaliseFirstLetter(roleName) << ";";
++ } else {
++ d << m_indentation << fieldClassName << "[] ";
++ //TODO: templated containers
++
++ if (hasAccessors) d << "m_";
++
++ d << pluralize(deCapitaliseFirstLetter(roleName)) << ";";
++ // from here we could initialize default values, or put in an init() section
++ // of the constructors
++ }
++
++ // always put space between this and following decl, if any
++ writeBlankLine(d);
++}
++
++void DWriter::writeAssociationMethods (UMLAssociationList associations, UMLClassifier *thisClass, QTextStream &d) {
++ if( forceSections() || !associations.isEmpty() ) {
++ for(UMLAssociation *a = associations.first(); a; a = associations.next()) {
++ // insert the methods to access the role of the other
++ // class in the code of this one
++ if (a->getObjectId(Uml::A) == thisClass->getID()) {
++ // only write out IF there is a rolename given
++ if(!a->getRoleName(Uml::B).isEmpty()) {
++ QString fieldClassName = getUMLObjectName(a->getObject(Uml::B));
++ writeAssociationRoleMethod(fieldClassName,
++ a->getRoleName(Uml::B),
++ a->getMulti(Uml::B), a->getRoleDoc(Uml::B),
++ a->getVisibility(Uml::B),
++ a->getChangeability(Uml::B), d);
++ }
++ }
++
++ if (a->getObjectId(Uml::B) == thisClass->getID()) {
++ // only write out IF there is a rolename given
++ if(!a->getRoleName(Uml::A).isEmpty()) {
++ QString fieldClassName = getUMLObjectName(a->getObject(Uml::A));
++ writeAssociationRoleMethod(fieldClassName, a->getRoleName(Uml::A),
++ a->getMulti(Uml::A),
++ a->getRoleDoc(Uml::A),
++ a->getVisibility(Uml::A),
++ a->getChangeability(Uml::A),
++ d);
++ }
++ }
++ }
++ }
++}
++
++void DWriter::writeAssociationRoleMethod (QString fieldClassName, QString roleName, QString multi,
++ QString description, Uml::Visibility visib, Uml::Changeability_Type change,
++ QTextStream &d) {
++ if(multi.isEmpty() || multi.contains(QRegExp("^[01]$"))) {
++ QString fieldVarName = "m_" + deCapitaliseFirstLetter(roleName);
++
++ writeSingleAttributeAccessorMethods(
++ fieldClassName, fieldVarName, roleName, description, visib, change, false, d);
++ } else {
++ QString fieldVarName = "m_" + pluralize(deCapitaliseFirstLetter(roleName));
++
++ writeVectorAttributeAccessorMethods(
++ fieldClassName, fieldVarName, pluralize(roleName), description, visib, change, d);
++ }
++}
++
++void DWriter::writeVectorAttributeAccessorMethods (QString fieldClassName, QString fieldVarName,
++ QString fieldName, QString description,
++ Uml::Visibility /* visibility */, Uml::Changeability_Type changeType,
++ QTextStream &d) {
++
++ fieldClassName = fixTypeName(fieldClassName);
++ QString fieldNameUP = unPluralize(fieldName);
++ QString fieldNameUC = capitaliseFirstLetter(fieldNameUP);
++
++ // ONLY IF changeability is NOT Frozen
++ if (changeType != Uml::chg_Frozen) {
++ writeDocumentation("Adds a " + fieldNameUP + " to the list of " +
++ fieldName + ".", description, "", m_indentation, d);
++
++ d << m_indentation << "void add" << fieldNameUC << "(";
++ d << fieldClassName << " new" << fieldNameUC << ") {";
++ d << startline << m_indentation << fieldVarName << " ~= new" << fieldNameUC << ";";
++ d << startline << "}" << m_endl << m_endl;
++ }
++
++ // ONLY IF changeability is Changeable
++ if (changeType == Uml::chg_Changeable) {
++ writeDocumentation("Removes a " + fieldNameUP + " from the list of " +
++ fieldName + ".", description, "", m_indentation, d);
++
++ d << m_indentation << "void remove" << fieldNameUC << "(";
++ d << fieldClassName << " " << fieldNameUP << ") {" << startline;
++ d << m_indentation << "int idx = " << fieldVarName << ".length;" << startline;
++ d << m_indentation << "foreach(i, o; " << fieldVarName << ")" << startline;
++ d << m_indentation << m_indentation << "if (o && o == " << fieldNameUP << ") {" << startline;
++ d << m_indentation << m_indentation << m_indentation << "idx = i;" << startline;
++ d << m_indentation << m_indentation << m_indentation << "break;" << startline;
++ d << m_indentation << m_indentation << "}" << m_endl << startline;
++ d << m_indentation << fieldVarName << " = " << fieldVarName;
++ d << "[0..idx] ~ " << fieldVarName << "[idx..$];" << startline;
++ d << "}" << m_endl << m_endl;
++ }
++
++ // always allow getting the list of stuff
++ writeDocumentation("Returns the list of " + fieldName + ".",
++ description, "@return List of "+fieldName + ".",
++ m_indentation, d);
++
++ d << m_indentation << fieldClassName << "[] get" << fieldName << "() {";
++ d << startline << m_indentation << "return " << fieldVarName << ";";
++ d << startline << "}" << m_endl << m_endl;
++}
++
++
++void DWriter::writeSingleAttributeAccessorMethods(QString fieldClassName,
++ QString fieldVarName, QString fieldName, QString description, Uml::Visibility /* visibility */,
++ Uml::Changeability_Type change, bool isFinal, QTextStream &d) {
++
++ fieldClassName = fixTypeName(fieldClassName);
++ QString fieldNameUC = capitaliseFirstLetter(fieldName);
++ if (fieldName.left(2) == "m_") fieldName = fieldName.right(fieldName.length()-2);
++
++ // set method
++ if (change == Uml::chg_Changeable && !isFinal) {
++ writeDocumentation("Sets the value of " + fieldName + ".", description,
++ "@param new" + fieldNameUC + " The new value of " + fieldName + ".",
++ m_indentation, d);
++
++ d << m_indentation << fieldClassName << " " << fieldName << "(";
++ d << fieldClassName << " new" << fieldNameUC << ") {";
++ d << startline << m_indentation << "return " << fieldVarName << " = new" << fieldNameUC << ";";
++ d << startline << "}" << m_endl << m_endl;
++ }
++
++ // get method
++ writeDocumentation("Returns the value of " + fieldName + ".", description,
++ "@return The value of " + fieldName + ".",
++ m_indentation, d);
++
++ d << m_indentation << fieldClassName << " " << fieldName << "() {";
++ d << startline << m_indentation << "return " << fieldVarName << ";";
++ d << startline << "}" << m_endl << m_endl;
++}
++
++void DWriter::writeConstructor(UMLClassifier *c, QTextStream &d) {
++
++ if (forceDoc())
++ {
++ d<<startline;
++ writeComment("", m_indentation, d);
++ writeComment("Constructors", m_indentation, d);
++ writeComment("", m_indentation, d);
++ writeBlankLine(d);
++ }
++
++ // write the first constructor
++ QString className = cleanName(c->getName());
++ d << m_indentation << "public this("<<") { }";
++
++}
++
++// IF the type is "string" we need to declare it as
++// the D Object "String" (there is no string primative in D).
++// Same thing again for "bool" to "boolean"
++QString DWriter::fixTypeName(const QString& string) {
++ if (string.isEmpty())
++ return "void";
++ if (string == "string")
++ return "char[]";
++ if (string == "unsigned short")
++ return "ushort";
++ if (string == "unsigned int")
++ return "uint";
++ if (string == "unsigned long")
++ return "ulong";
++ return string;
++}
++
++QStringList DWriter::defaultDatatypes() {
++ QStringList l;
++ l << "void"
++ << "bool"
++ << "byte"
++ << "ubyte"
++ << "short"
++ << "ushort"
++ << "int"
++ << "uint"
++ << "long"
++ << "ulong"
++ << "cent"
++ << "ucent"
++ << "float"
++ << "double"
++ << "real"
++ << "ifloat"
++ << "idouble"
++ << "ireal"
++ << "cfloat"
++ << "cdouble"
++ << "creal"
++ << "char"
++ << "wchar"
++ << "dchar";
++ return l;
++}
++
++
++bool DWriter::compareDMethod(UMLOperation *op1, UMLOperation *op2) {
++ if (op1 == NULL || op2 == NULL)
++ return false;
++ if (op1 == op2)
++ return true;
++ if (op1->getName() != op2->getName())
++ return false;
++ UMLAttributeList atl1 = op1->getParmList();
++ UMLAttributeList atl2 = op2->getParmList();
++ if (atl1.count() != atl2.count())
++ return false;
++ UMLAttribute *at1;
++ UMLAttribute *at2;
++ for (at1 = atl1.first(), at2 = atl2.first(); at1 && at2 ; at1 = atl1.next(),at2 = atl2.next())
++ {
++ if (at1->getTypeName() != at2->getTypeName())
++ return false;
++ }
++ return true;
++
++}
++
++bool DWriter::dMethodInList(UMLOperation *umlOp, UMLOperationList &opl) {
++ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
++ if (DWriter::compareDMethod(op, umlOp)) {
++ return true;
++ }
++ }
++ return false;
++}
++
++void DWriter::getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath) {
++ UMLClassifierList superClasses = c->findSuperClassConcepts();
++
++ for (UMLClassifier *concept= superClasses.first(); concept; concept = superClasses.next())
++ {
++ getSuperImplementedOperations(concept, yetImplementedOpList, toBeImplementedOpList, (concept->isInterface() && noClassInPath));
++ UMLOperationList opl = concept->getOpList();
++ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
++ if (concept->isInterface() && noClassInPath) {
++ if (!DWriter::dMethodInList(op,toBeImplementedOpList))
++ toBeImplementedOpList.append(op);
++ }
++ else
++ {
++ if (!DWriter::dMethodInList(op, yetImplementedOpList))
++ yetImplementedOpList.append(op);
++ }
++ }
++ }
++
++}
++
++void DWriter::getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opList ) {
++ UMLOperationList yetImplementedOpList;
++ UMLOperationList toBeImplementedOpList;
++
++ getSuperImplementedOperations(c,yetImplementedOpList, toBeImplementedOpList);
++ for (UMLOperation *op = toBeImplementedOpList.first(); op; op = toBeImplementedOpList.next())
++ {
++ if ( ! DWriter::dMethodInList(op, yetImplementedOpList) && ! DWriter::dMethodInList(op, opList) )
++ opList.append(op);
++ }
++}
++
++void DWriter::writeOperations(UMLClassifier *c, QTextStream &d) {
++ UMLOperationList opl;
++ UMLOperationList oppub,opprot,oppriv;
++ oppub.setAutoDelete(false);
++ opprot.setAutoDelete(false);
++ oppriv.setAutoDelete(false);
++
++ //sort operations by scope first and see if there are abstract methods
++ opl = c->getOpList();
++ if (! c->isInterface()) {
++ getInterfacesOperationsToBeImplemented(c, opl);
++ }
++ for (UMLOperation *op = opl.first(); op; op = opl.next()) {
++ switch(op->getVisibility()) {
++ case Uml::Visibility::Public:
++ oppub.append(op);
++ break;
++ case Uml::Visibility::Protected:
++ opprot.append(op);
++ break;
++ case Uml::Visibility::Private:
++ oppriv.append(op);
++ break;
++ default: //TODO: package, export
++ break;
++ }
++ }
++
++ // do people REALLY want these comments? Hmm.
++ /*
++ if(forceSections() || oppub.count())
++ {
++ writeComment("public operations",m_indentation,d);
++ writeBlankLine(d);
++ }
++ */
++
++ if (oppub.count() > 0) {
++ writeProtectionMod(Uml::Visibility::Public, d);
++
++ writeOperations(oppub,d);
++ }
++
++ if (opprot.count() > 0) {
++ writeProtectionMod(Uml::Visibility::Protected, d);
++
++ writeOperations(opprot, d);
++ }
++
++ if (oppriv.count() > 0) {
++ writeProtectionMod(Uml::Visibility::Private, d);
++
++ writeOperations(oppriv, d);
++ }
++
++}
++
++void DWriter::writeOperations(UMLOperationList &oplist, QTextStream &d) {
++ UMLAttributeList atl;
++ QString str;
++
++ // generate method decl for each operation given
++ for(UMLOperation *op=oplist.first(); op; op=oplist.next()) {
++ QString returnStr = "";
++ // write documentation
++
++ QString methodReturnType = fixTypeName(op->getTypeName());
++
++ //TODO: return type comment
++ if(methodReturnType != "void") {
++ returnStr += "@return " + methodReturnType + m_endl;
++ }
++
++ str = ""; // reset for next method
++ if (op->getAbstract() && !isInterface) str += "abstract ";
++ if (op->getStatic()) str += "static ";
++
++ str += methodReturnType + ' ' +cleanName(op->getName()) + "(";
++
++ atl = op->getParmList();
++ int i = atl.count();
++ int j = 0;
++ for (UMLAttribute *at = atl.first(); at; at = atl.next(), j++) {
++ QString typeName = fixTypeName(at->getTypeName());
++ QString atName = cleanName(at->getName());
++ str += typeName + ' ' + atName +
++ (!(at->getInitialValue().isEmpty()) ?
++ (QString(" = ")+at->getInitialValue()) :
++ QString(""))
++ + ((j < i-1)?", ":"");
++ returnStr += "@param " + atName+' '+at->getDoc() + m_endl;
++ }
++
++ str+= ")";
++
++ // method only gets a body IF its not abstract
++ if (op->getAbstract() || isInterface)
++ str += ";"; // terminate now
++ else
++ str += startline + "{" + startline + "}"; // empty method body
++
++ // write it out
++ writeDocumentation("", op->getDoc(), returnStr, m_indentation, d);
++ d << m_indentation << str << m_endl << m_endl;
++ }
++}
++
++QString DWriter::fixInitialStringDeclValue(QString value, QString type) {
++ // check for strings only
++ if (!value.isEmpty() && type == "String") {
++ if (!value.startsWith("\""))
++ value.prepend("\"");
++ if (!value.endsWith("\""))
++ value.append("\"");
++ }
++ return value;
++}
++
++QString DWriter::scopeToDDecl(Uml::Visibility scope) {
++ QString scopeString;
++
++ switch(scope) {
++ case Uml::Visibility::Public: scopeString = "public"; break;
++ case Uml::Visibility::Protected: scopeString = "protected"; break;
++ case Uml::Visibility::Private: scopeString = "private"; break;
++ default: break; //TODO: package and export
++ }
++
++ return scopeString;
++}
++
++// methods like this _shouldn't_ be needed IF we properly did things thruought the code.
++QString DWriter::getUMLObjectName(UMLObject *obj) {
++ return(obj!=0)?obj->getName():QString("NULL");
++}
++
++QString DWriter::capitaliseFirstLetter(QString string) {
++ string.replace( 0, 1, string[0].upper());
++ return string;
++}
++
++QString DWriter::deCapitaliseFirstLetter(QString string) {
++ string.replace( 0, 1, string[0].lower());
++ return string;
++}
++
++QString DWriter::pluralize(QString string) {
++ return string + (string.right(1) == "s" ? "es" : "s");
++}
++
++QString DWriter::unPluralize(QString string) {
++ // does not handle special cases liek datum -> data, etc.
++
++ if (string.length() > 2 && string.right(3) == "ses") {
++ return string.left(string.length() - 2);
++ }
++
++ if (string.right(1) == "s") {
++ return string.left(string.length() - 1);
++ }
++
++ return string;
++}
++
++void DWriter::writeBlankLine(QTextStream &d) {
++ d << m_endl;
++}
++
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/codegenerators/dwriter.h kdesdk/umbrello/umbrello/codegenerators/dwriter.h
+--- kdesdk-3.5.7/umbrello/umbrello/codegenerators/dwriter.h 1970-01-01 01:00:00.000000000 +0100
++++ kdesdk/umbrello/umbrello/codegenerators/dwriter.h 2007-06-03 14:43:50.000000000 +0200
+@@ -0,0 +1,281 @@
++
++/***************************************************************************
++ * *
++ * 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) 2007 Jari-Matti Mäkelä <jmjm at iki.fi> *
++ * Umbrello UML Modeller Authors <uml-devel at uml.sf.net> *
++ ***************************************************************************/
++
++/***************************************************************************
++ This is the "old" code generator that does not support code editing
++ in the Modeller but uses significantly less file space because the
++ source code is not replicated in the XMI file.
++ ***************************************************************************/
++
++#ifndef DWRITER_H
++#define DWRITER_H
++
++#include "simplecodegenerator.h"
++#include "../umloperationlist.h"
++#include "../umlattributelist.h"
++#include "../umlassociationlist.h"
++
++class UMLOperation;
++
++/**
++ * class DWriter is a code generator for UMLClassifier objects.
++ * Create an instance of this class, and feed it a UMLClassifier when
++ * calling writeClass and it will generate a d source file for
++ * that concept
++ */
++class DWriter : public SimpleCodeGenerator {
++public:
++
++ /**
++ * Constructor, initialises a couple of variables
++ */
++ DWriter();
++
++ /**
++ * Destructor, empty
++ */
++ virtual ~DWriter();
++
++ /**
++ * call this method to generate d code for a UMLClassifier
++ * @param c the class to generate code for
++ */
++ virtual void writeClass(UMLClassifier *c);
++
++ /**
++ * returns "D"
++ */
++ virtual Uml::Programming_Language getLanguage();
++
++ /**
++ * Overrides method from class CodeGenerator
++ */
++ QStringList defaultDatatypes();
++
++private:
++
++ /**
++ * Writes the module declaration.
++ */
++ void writeModuleDecl(UMLClassifier *c, QTextStream &d);
++
++ /**
++ * Writes the module imports.
++ */
++ void writeModuleImports(UMLClassifier *c, QTextStream &d);
++
++ /**
++ * Writes class's documentation then the class header
++ * public abstract class Foo extents {
++ */
++ void writeClassDecl(UMLClassifier *c, QTextStream &d);
++
++ /**
++ * Writes the comment and class constructor
++ */
++ void writeConstructor(UMLClassifier *c, QTextStream &d);
++
++ /**
++ * return true if the two operations have the same name and the same parameters
++ * @param op1 first operation to be compared
++ * @param op2 second operation to be compared
++ */
++ static bool compareDMethod(UMLOperation *op1, UMLOperation *op2);
++
++ /**
++ * return true if the operation is in the list
++ * @param umlOp operation to be searched
++ * @param opl list of operations
++ */
++ static bool dMethodInList(UMLOperation *umlOp, UMLOperationList &opl);
++
++ /**
++ * get all operations which a given class inherit from all its super interfaces and get all operations
++ * which this given class inherit from all its super classes
++ * @param c the class for which we are generating code
++ * @param yetImplementedOpList the list of yet implemented operations
++ * @param toBeImplementedOpList the list of to be implemented operations
++ * @param noClassInPath tells if there is a class between the base class and the current interface
++ */
++ void getSuperImplementedOperations(UMLClassifier *c, UMLOperationList &yetImplementedOpList ,UMLOperationList &toBeImplementedOpList, bool noClassInPath = true);
++
++ /**
++ * get all operations which a given class inherit from all its super interfaces and that should be implemented
++ * @param c the class for which we are generating code
++ * @param opl the list of operations used to append the operations
++ */
++ void getInterfacesOperationsToBeImplemented(UMLClassifier *c, UMLOperationList &opl);
++
++ /**
++ * write all operations for a given class
++ * @param c the class for which we are generating code
++ * @param j the stream associated with the output file
++ */
++ void writeOperations(UMLClassifier *c, QTextStream &j);
++
++ /**
++ * write a list of operations for a given class
++ * @param list the list of operations you want to write
++ * @param j the stream associated with the output file
++ */
++ void writeOperations(UMLOperationList &list, QTextStream &j);
++
++ /**
++ * write all attributes for a given class
++ * @param c the class for which we are generating code
++ * @param j the stream associated with the output file
++ */
++ void writeAttributes(UMLClassifier *c, QTextStream &j);
++
++ /**
++ * Writes the protection modifier line.
++ * @param visibility protection modifier
++ * @param d text stream
++ */
++ void writeProtectionMod(Uml::Visibility visibility, QTextStream &d);
++
++ /**
++ * Writes attribute declarations with a specific
++ * protection modifier.
++ * @param prot the protection modifier
++ * @param atlist attribute list
++ * @param d text stream
++ */
++ void writeAttributeDecl(Uml::Visibility visibility, UMLAttributeList &atlist, QTextStream &d);
++
++ /**
++ * writes the Attribute declarations
++ * @param atpub List of public attributes
++ * @param atprot list of protected attributes
++ * @param atpriv list of private attributes
++ * @param d text stream
++ */
++ void writeAttributeDecls(UMLAttributeList &atpub, UMLAttributeList &atprot,
++ UMLAttributeList &atpriv, QTextStream &d );
++
++ /**
++ * Searches a list of associations for appropriate ones to write out as attributes
++ */
++ void writeAssociationDecls(UMLAssociationList associations, Uml::IDType id, QTextStream &d);
++
++ /**
++ * Writes out an association as an attribute using Vector
++ */
++ void writeAssociationRoleDecl(QString fieldClassName, QString roleName, QString multi,
++ QString doc, Uml::Visibility visib, QTextStream &d);
++
++ /**
++ * calls @ref writeSingleAttributeAccessorMethods() on each of the attributes in atpub
++ */
++ void writeAttributeMethods(UMLAttributeList &atpub, Uml::Visibility visibility, QTextStream &d);
++
++ /**
++ * calls @ref writeAssociationRoleMethod() on each of the associations in the given list
++ */
++ void writeAssociationMethods(UMLAssociationList associations, UMLClassifier *thisClass,
++ QTextStream &d);
++
++ /**
++ * calls @ref writeSingleAttributeAccessorMethods() or @ref
++ * writeVectorAttributeAccessorMethods() on the assocaition
++ * role
++ */
++ void writeAssociationRoleMethod(QString fieldClassName, QString roleName, QString multi,
++ QString description, Uml::Visibility visib, Uml::Changeability_Type change,
++ QTextStream &d);
++
++ /**
++ * Writes getFoo() and setFoo() accessor methods for the attribute
++ */
++ void writeSingleAttributeAccessorMethods(QString fieldClassName, QString fieldVarName,
++ QString fieldName, QString description,
++ Uml::Visibility visibility, Uml::Changeability_Type change,
++ bool isFinal, QTextStream &d);
++
++ /**
++ * Writes addFoo() and removeFoo() accessor methods for the Vector attribute
++ */
++ void writeVectorAttributeAccessorMethods(QString fieldClassName, QString fieldVarName,
++ QString fieldName, QString description,
++ Uml::Visibility visibility, Uml::Changeability_Type change,
++ QTextStream &d);
++
++ /**
++ * Writes a // style comment
++ */
++ void writeComment(const QString &text, const QString &indent, QTextStream &d, bool dDocStyle=false);
++
++ /**
++ * Writes a documentation comment
++ */
++ void writeDocumentation(QString header, QString body, QString end, QString indent, QTextStream &d);
++
++ /**
++ * Returns the name of the given object (if it exists)
++ */
++ QString getUMLObjectName(UMLObject *obj);
++
++ /**
++ * Raises the case of the first letter in the given string
++ */
++ QString capitaliseFirstLetter(QString string);
++
++ /**
++ * Lowers the case of the first letter in the given string
++ */
++ QString deCapitaliseFirstLetter(QString string);
++
++ /**
++ * Returns the plural form of a subject.
++ */
++ QString pluralize(QString string);
++
++ /**
++ * Returns the non-plural form of a subject.
++ */
++ QString unPluralize(QString string);
++
++ /**
++ * Replaces `string' with `String' and `bool' with `boolean'
++ */
++ QString fixTypeName(const QString& string);
++
++ /**
++ * check that initial values of strings have quotes around them
++ */
++ QString fixInitialStringDeclValue(QString value, QString type);
++
++ /**
++ * Write a blank line
++ */
++ void writeBlankLine(QTextStream& d);
++
++ /**
++ * a little method for converting scope to string value
++ */
++ QString scopeToDDecl(Uml::Visibility scope);
++
++ /**
++ * A \n, used at the end of each line
++ */
++ QString startline;
++
++ /**
++ * Whether or not this concept is an interface.
++ */
++ bool isInterface;
++
++};
++
++
++#endif // DWRITER_H
++
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/codegenerators/Makefile.am kdesdk/umbrello/umbrello/codegenerators/Makefile.am
+--- kdesdk-3.5.7/umbrello/umbrello/codegenerators/Makefile.am 2007-05-14 09:40:28.000000000 +0200
++++ kdesdk/umbrello/umbrello/codegenerators/Makefile.am 2007-06-06 08:00:33.000000000 +0200
+@@ -27,7 +27,7 @@ libcodegenerator_la_SOURCES = codegenfac
+ rubycodegenerationpolicy.cpp rubycodegenerationpolicypage.cpp \
+ rubycodegenerationformbase.ui \
+ simplecodegenerator.cpp \
+- adawriter.cpp aswriter.cpp cppwriter.cpp csharpwriter.cpp javawriter.cpp jswriter.cpp \
++ adawriter.cpp aswriter.cpp cppwriter.cpp csharpwriter.cpp dwriter.cpp javawriter.cpp jswriter.cpp \
+ idlwriter.cpp pascalwriter.cpp perlwriter.cpp php5writer.cpp phpwriter.cpp \
+ pythonwriter.cpp rubywriter.cpp sqlwriter.cpp tclwriter.cpp xmlschemawriter.cpp \
+ xmlelementcodeblock.cpp xmlcodecomment.cpp \
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/codegenerators/pythonwriter.cpp kdesdk/umbrello/umbrello/codegenerators/pythonwriter.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/codegenerators/pythonwriter.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/codegenerators/pythonwriter.cpp 2007-05-25 23:54:34.000000000 +0200
+@@ -30,6 +30,7 @@
+ #include "../association.h"
+ #include "../attribute.h"
+ #include "../classifier.h"
++#include "../attribute.h"
+ #include "../operation.h"
+ #include "../umlnamespace.h"
+
+@@ -134,15 +135,18 @@ void PythonWriter::writeClass(UMLClassif
+
+ h<<(superclasses.count() > 0 ? ")":"")<<":"<<m_endl<<m_endl;
+
+- if(forceDoc() || !c->getDoc().isEmpty()) {
+- h<<m_indentation<<"\"\"\""<<m_endl;
+- h<<m_indentation<<c->getDoc()<<m_endl;
+- h<<m_indentation<<":version:"<<m_endl;
+- h<<m_indentation<<":author:"<<m_endl;
+- h<<m_indentation<<"\"\"\""<<m_endl<<m_endl;
++ if (forceDoc() || !c->getDoc().isEmpty()) {
++ h << m_indentation << "\"\"\"" << m_endl;
++ h << formatDoc(c->getDoc(), m_indentation + ' ') << m_endl;
++ h << m_indentation << ":version:" << m_endl;
++ h << m_indentation << ":author:" << m_endl;
++ h << m_indentation << "\"\"\"" << m_endl << m_endl;
+ m_bNeedPass = false;
+ }
+
++ // attributes
++ writeAttributes(c->getAttributeList(), h);
++
+ //operations
+ writeOperations(c,h);
+
+@@ -161,7 +165,20 @@ void PythonWriter::writeClass(UMLClassif
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Helper Methods
+
+-void PythonWriter::writeOperations(UMLClassifier *c,QTextStream &h) {
++void PythonWriter::writeAttributes(UMLAttributeList atList, QTextStream &py) {
++ if (!forceDoc() || atList.count() == 0)
++ return;
++ py << m_indentation << "\"\"\" ATTRIBUTES" << m_endl << m_endl;
++ for (UMLAttribute *at = atList.first(); at; at = atList.next()) {
++ py << formatDoc(at->getDoc(), m_indentation + ' ') << m_endl;
++ Uml::Visibility vis = at->getVisibility();
++ py << m_indentation << cleanName(at->getName()) << " ("
++ << vis.toString() << ")" << m_endl << m_endl ;
++ } // end for
++ py << m_indentation << "\"\"\"" << m_endl << m_endl;
++}
++
++void PythonWriter::writeOperations(UMLClassifier *c, QTextStream &h) {
+
+ //Lists to store operations sorted by scope
+ UMLOperationList oppub,opprot,oppriv;
+@@ -247,8 +264,8 @@ void PythonWriter::writeOperations(const
+
+ if( writeDoc ) //write method documentation
+ {
+- h<<m_indentation<<m_indentation<<"\"\"\""<<m_endl;
+- h<<m_indentation<<m_indentation<<op->getDoc()<<m_endl<<m_endl;
++ h << m_indentation << m_indentation << "\"\"\"" << m_endl;
++ h << formatDoc(op->getDoc(), m_indentation + m_indentation + ' ') << m_endl;
+
+ for (at = atl.first(); at; at = atl.next()) //write parameter documentation
+ {
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/codegenerators/pythonwriter.h kdesdk/umbrello/umbrello/codegenerators/pythonwriter.h
+--- kdesdk-3.5.7/umbrello/umbrello/codegenerators/pythonwriter.h 2007-05-14 09:40:28.000000000 +0200
++++ kdesdk/umbrello/umbrello/codegenerators/pythonwriter.h 2007-05-25 23:54:34.000000000 +0200
+@@ -20,6 +20,7 @@
+ #define PYTHONWRITER_H
+
+ #include "simplecodegenerator.h"
++#include "../umlattributelist.h"
+ #include "../umloperationlist.h"
+
+ enum Access {PRIVATE, PUBLIC, PROTECTED};
+@@ -54,6 +55,14 @@ public:
+ private:
+
+ /**
++ * write all attributes for a given class
++ *
++ * @param c the concept we are generating code for
++ * @param py output stream for the header file
++ */
++ void writeAttributes(UMLAttributeList atList, QTextStream &py);
++
++ /**
+ * write all operations for a given class
+ *
+ * @param c the concept we are generating code for
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/codeimport/cppimport.cpp kdesdk/umbrello/umbrello/codeimport/cppimport.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/codeimport/cppimport.cpp 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/codeimport/cppimport.cpp 2007-05-27 07:54:45.000000000 +0200
+@@ -51,6 +51,9 @@ CppImport::CppImport() {
+ CppImport::~CppImport() {}
+
+ void CppImport::feedTheModel(const QString& fileName) {
++ if (ms_seenFiles.find(fileName) != ms_seenFiles.end())
++ return;
++ ms_seenFiles.append(fileName);
+ QMap<QString, Dependence> deps = ms_driver->dependences(fileName);
+ if (! deps.empty()) {
+ QMap<QString, Dependence>::Iterator it;
+@@ -68,9 +71,6 @@ void CppImport::feedTheModel(const QStri
+ feedTheModel(includeFile);
+ }
+ }
+- if (ms_seenFiles.find(fileName) != ms_seenFiles.end())
+- return;
+- ms_seenFiles.append(fileName);
+ TranslationUnitAST *ast = ms_driver->translationUnit( fileName );
+ if (ast == NULL) {
+ kError() << "CppImport::feedTheModel: " << fileName << " not found" << endl;
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/dialogs/umloperationdialog.cpp kdesdk/umbrello/umbrello/dialogs/umloperationdialog.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/dialogs/umloperationdialog.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/dialogs/umloperationdialog.cpp 2007-06-07 11:18:02.000000000 +0200
+@@ -326,10 +326,6 @@ void UMLOperationDialog::slotNewParamete
+ return;
+ }
+ if( !pAtt ) {
+- /*
+- m_pOperation->addParm( dlg.getTypeName(), name, dlg.getInitialValue(),
+- dlg.getDoc(), dlg.getParmKind() );
+- */
+ newAttribute->setID( UniqueID::gen() );
+ newAttribute->setName( name );
+ newAttribute->setTypeName( dlg.getTypeName() );
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/docgenerators/xhtmlgenerator.cpp kdesdk/umbrello/umbrello/docgenerators/xhtmlgenerator.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/docgenerators/xhtmlgenerator.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/docgenerators/xhtmlgenerator.cpp 2007-05-26 20:30:12.000000000 +0200
+@@ -1,5 +1,5 @@
+ /***************************************************************************
+- * xhtmlgenerator.cpp - description *
++ * xhtmlgenerator.cpp - description *
+ * ------------------- *
+ * copyright : (C) 2006 by Gael de Chalendar (aka Kleag) *
+ * (C) 2006 Umbrello UML Modeller Authors <uml-devel at uml.sf.net> *
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/docgenerators/xmi2docbook.xsl kdesdk/umbrello/umbrello/docgenerators/xmi2docbook.xsl
+--- kdesdk-3.5.7/umbrello/umbrello/docgenerators/xmi2docbook.xsl 2006-10-01 19:27:42.000000000 +0200
++++ kdesdk/umbrello/umbrello/docgenerators/xmi2docbook.xsl 2007-05-26 20:30:12.000000000 +0200
+@@ -666,6 +666,12 @@
+ <xsl:value-of select="@name"/>
+ </entry>
+ </row>
++
++ <row>
++ <entry role="comment"/>
++ <entry namest="c2" nameend="c3" role="comment"><xsl:value-of select="@comment"/></entry>
++ </row>
++
+ </xsl:template>
+
+
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/entityattribute.cpp kdesdk/umbrello/umbrello/entityattribute.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/entityattribute.cpp 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/entityattribute.cpp 2007-06-07 11:35:47.000000000 +0200
+@@ -23,7 +23,7 @@
+
+ UMLEntityAttribute::UMLEntityAttribute( const UMLObject *parent, const QString& name,
+ Uml::IDType id, Uml::Visibility s,
+- const QString& type, const QString& iv )
++ UMLObject *type, const QString& iv )
+ : UMLAttribute(parent, name, id, s, type, iv) {
+ init();
+ if (m_pSecondary) {
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/entityattribute.h kdesdk/umbrello/umbrello/entityattribute.h
+--- kdesdk-3.5.7/umbrello/umbrello/entityattribute.h 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/entityattribute.h 2007-06-07 11:36:13.000000000 +0200
+@@ -39,7 +39,7 @@ public:
+ UMLEntityAttribute(const UMLObject* parent, const QString& name,
+ Uml::IDType id = Uml::id_None,
+ Uml::Visibility s = Uml::Visibility::Private,
+- const QString& type = "int", const QString& iv = 0);
++ UMLObject *type = 0, const QString& iv = 0);
+
+ /**
+ * Sets up an entityattribute.
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/entity.cpp kdesdk/umbrello/umbrello/entity.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/entity.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/entity.cpp 2007-06-07 12:16:11.000000000 +0200
+@@ -52,7 +52,7 @@ void UMLEntity::init() {
+ m_BaseType = Uml::ot_Entity;
+ }
+
+-UMLAttribute* UMLEntity::createAttribute(const QString &name /*=null*/) {
++UMLAttribute* UMLEntity::createAttribute(const QString &name /*=null*/, UMLObject *type /*=NULL*/) {
+ Uml::IDType id = UniqueID::gen();
+ QString currentName;
+ if (name.isNull()) {
+@@ -62,7 +62,7 @@ UMLAttribute* UMLEntity::createAttribute
+ }
+ const Settings::OptionState optionState = Settings::getOptionState();
+ Uml::Visibility scope = optionState.classState.defaultAttributeScope;
+- UMLEntityAttribute* newAttribute = new UMLEntityAttribute(this, currentName, id, scope);
++ UMLEntityAttribute* newAttribute = new UMLEntityAttribute(this, currentName, id, scope, type);
+
+ int button = QDialog::Accepted;
+ bool goodName = false;
+@@ -84,6 +84,7 @@ UMLAttribute* UMLEntity::createAttribute
+ }
+
+ if (button != QDialog::Accepted) {
++ delete newAttribute;
+ return NULL;
+ }
+
+@@ -143,8 +144,8 @@ int UMLEntity::removeEntityAttribute(UML
+ kDebug() << "can't find att given in list" << endl;
+ return -1;
+ }
+- UMLObject::emitModified();
+ emit entityAttributeRemoved(literal);
++ UMLObject::emitModified();
+ // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
+ // for us by QObject. -b.t.
+ // disconnect(a,SIGNAL(modified()),this,SIGNAL(modified()));
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/entity.h kdesdk/umbrello/umbrello/entity.h
+--- kdesdk-3.5.7/umbrello/umbrello/entity.h 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/entity.h 2007-06-07 10:48:32.000000000 +0200
+@@ -5,7 +5,7 @@
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+- * copyright (C) 2003-2006 *
++ * copyright (C) 2003-2007 *
+ * Umbrello UML Modeller Authors <uml-devel at uml.sf.net> *
+ ***************************************************************************/
+
+@@ -62,11 +62,12 @@ public:
+ * Creates an entity attribute for the parent concept.
+ * Reimplementation of method from UMLClassifier.
+ *
+- * @param o The parent concept
+ * @param name An optional name, used by when creating through UMLListView
++ * @param type An optional type, used by when creating through UMLListView
+ * @return The UMLEntityAttribute created
+ */
+- UMLAttribute* createAttribute(const QString &name = QString::null);
++ UMLAttribute* createAttribute(const QString &name = QString::null,
++ UMLObject *type = 0);
+
+ /**
+ * Adds an entityAttribute to the entity.
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/enum.cpp kdesdk/umbrello/umbrello/enum.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/enum.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/enum.cpp 2007-05-29 21:26:36.000000000 +0200
+@@ -135,8 +135,8 @@ int UMLEnum::removeEnumLiteral(UMLEnumLi
+ kDebug() << "can't find att given in list" << endl;
+ return -1;
+ }
+- UMLObject::emitModified();
+ emit enumLiteralRemoved(literal);
++ UMLObject::emitModified();
+ // If we are deleting the object, then we don't need to disconnect..this is done auto-magically
+ // for us by QObject. -b.t.
+ // disconnect(a,SIGNAL(modified()),this,SIGNAL(modified()));
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/floatingtextwidgetcontroller.cpp kdesdk/umbrello/umbrello/floatingtextwidgetcontroller.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/floatingtextwidgetcontroller.cpp 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/floatingtextwidgetcontroller.cpp 2007-05-31 01:22:38.000000000 +0200
+@@ -18,6 +18,10 @@
+ FloatingTextWidgetController::FloatingTextWidgetController(FloatingTextWidget *floatingTextWidget):
+ UMLWidgetController(floatingTextWidget) {
+ m_floatingTextWidget = floatingTextWidget;
++ m_unconstrainedPositionX = 0;
++ m_unconstrainedPositionY = 0;
++ m_movementDirectionX = 0;
++ m_movementDirectionY = 0;
+ }
+
+ FloatingTextWidgetController::~FloatingTextWidgetController() {
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/floatingtextwidgetcontroller.h kdesdk/umbrello/umbrello/floatingtextwidgetcontroller.h
+--- kdesdk-3.5.7/umbrello/umbrello/floatingtextwidgetcontroller.h 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/floatingtextwidgetcontroller.h 2007-05-31 01:18:37.000000000 +0200
+@@ -5,7 +5,7 @@
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+- * copyright (C) 2006 *
++ * copyright (C) 2006-2007 *
+ * Umbrello UML Modeller Authors <uml-devel at uml.sf.net> *
+ ***************************************************************************/
+
+@@ -53,7 +53,7 @@ public:
+ protected:
+
+ /**
+- * Overriden from UMLWidgetController.
++ * Overridden from UMLWidgetController.
+ * Saves the values of the widget needed for move/resize.
+ * Calls parent method and then saves the value of m_unconstrainedPositionX/Y
+ * and m_movementDirectionX/Y.
+@@ -63,7 +63,7 @@ protected:
+ virtual void saveWidgetValues(QMouseEvent *me);
+
+ /**
+- * Overriden from UMLWidgetController.
++ * Overridden from UMLWidgetController.
+ * FloatingTextWidgets can't be resized, so this method always returns false.
+ * Cursor isn't changed.
+ *
+@@ -73,7 +73,7 @@ protected:
+ virtual bool isInResizeArea(QMouseEvent *me);
+
+ /**
+- * Overriden from UMLWidgetController.
++ * Overridden from UMLWidgetController.
+ * Moves the widget to a new position using the difference between the
+ * current position and the new position.
+ * If the floating text widget is part of a sequence message, and the
+@@ -94,7 +94,7 @@ protected:
+ virtual void moveWidgetBy(int diffX, int diffY);
+
+ /**
+- * Overriden from UMLWidgetController.
++ * Overridden from UMLWidgetController.
+ * Modifies the value of the diffX and diffY variables used to move the
+ * widgets.
+ * The values are constrained using constrainPosition.
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/headings/heading.d kdesdk/umbrello/umbrello/headings/heading.d
+--- kdesdk-3.5.7/umbrello/umbrello/headings/heading.d 1970-01-01 01:00:00.000000000 +0100
++++ kdesdk/umbrello/umbrello/headings/heading.d 2007-06-03 14:43:50.000000000 +0200
+@@ -0,0 +1,29 @@
++/************************************************************************
++ %filename% - Copyright %author%
++
++Here you can write a license for your code, some comments or any other
++information you want to have in your generated code. To to this simply
++configure the "headings" directory in uml to point to a directory
++where you have your heading files.
++
++or you can just replace the contents of this file with your own.
++If you want to do this, this file is located at
++
++%headingpath%
++
++-->Code Generators searches for heading files based on the file extension
++ i.e. it will look for a file name ending in ".h" to include in C++ header
++ files, and for a file name ending in ".java" to include in all generated
++ java code.
++ If you name the file "heading.<extension>", Code Generator will always
++ choose this file even if there are other files with the same extension in the
++ directory. If you name the file something else, it must be the only one with that
++ extension in the directory to guarantee that Code Generator will choose it.
++
++you can use variables in your heading files which are replaced at generation
++time. possible variables are : author, date, time, filename and filepath.
++just write %variable_name%
++
++This file was generated on %date% at %time%
++The original location of this file is %filepath%
++**************************************************************************/
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/headings/Makefile.am kdesdk/umbrello/umbrello/headings/Makefile.am
+--- kdesdk-3.5.7/umbrello/umbrello/headings/Makefile.am 2005-09-10 10:20:56.000000000 +0200
++++ kdesdk/umbrello/umbrello/headings/Makefile.am 2007-06-06 08:30:10.000000000 +0200
+@@ -4,6 +4,7 @@ heading.ads \
+ heading.as \
+ heading.cpp \
+ heading.cs \
++heading.d \
+ heading.h \
+ heading.idl \
+ heading.java \
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/model_utils.cpp kdesdk/umbrello/umbrello/model_utils.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/model_utils.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/model_utils.cpp 2007-06-05 07:06:39.000000000 +0200
+@@ -572,6 +572,8 @@ QString progLangToString(Uml::Programmin
+ return "C++";
+ case Uml::pl_CSharp:
+ return "C#";
++ case Uml::pl_D:
++ return "D";
+ case Uml::pl_IDL:
+ return "IDL";
+ case Uml::pl_Java:
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/object_factory.cpp kdesdk/umbrello/umbrello/object_factory.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/object_factory.cpp 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/object_factory.cpp 2007-06-07 07:43:05.000000000 +0200
+@@ -127,10 +127,14 @@ UMLObject* createUMLObject(Uml::Object_T
+ bool solicitNewName /* = true */) {
+ UMLDoc *doc = UMLApp::app()->getDocument();
+ if (parentPkg == NULL) {
+- Uml::Model_Type mt = Model_Utils::convert_OT_MT(type);
+- kDebug() << "Object_Factory::createUMLObject(" << n << "): "
+- << "parentPkg is not set, assuming Model_Type " << mt << endl;
+- parentPkg = doc->getRootFolder(mt);
++ if (type == Uml::ot_Datatype) {
++ parentPkg = doc->getDatatypeFolder();
++ } else {
++ Uml::Model_Type mt = Model_Utils::convert_OT_MT(type);
++ kDebug() << "Object_Factory::createUMLObject(" << n << "): "
++ << "parentPkg is not set, assuming Model_Type " << mt << endl;
++ parentPkg = doc->getRootFolder(mt);
++ }
+ }
+ if (!n.isEmpty()) {
+ UMLObject *o = doc->findUMLObject(n, type, parentPkg);
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/operation.cpp kdesdk/umbrello/umbrello/operation.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/operation.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/operation.cpp 2007-06-07 11:20:02.000000000 +0200
+@@ -46,18 +46,6 @@ UMLOperation::UMLOperation(const UMLClas
+ UMLOperation::~UMLOperation() {
+ }
+
+-UMLAttribute * UMLOperation::addParm(const QString& type, const QString& name,
+- const QString& initialValue, const QString& doc,
+- Uml::Parameter_Direction kind) {
+- // make the new parameter (attribute) public, just to be safe
+- UMLAttribute * a = new UMLAttribute(this, name, UniqueID::gen(), Uml::Visibility::Public, type);
+- a -> setDoc(doc);
+- a -> setInitialValue(initialValue);
+- a -> setParmKind(kind);
+- addParm(a);
+- return a;
+-}
+-
+ void UMLOperation::moveParmLeft(UMLAttribute * a) {
+ if (a == NULL) {
+ kDebug() << "UMLOperation::moveParmLeft called on NULL attribute"
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/operation.h kdesdk/umbrello/umbrello/operation.h
+--- kdesdk-3.5.7/umbrello/umbrello/operation.h 2007-01-15 12:24:47.000000000 +0100
++++ kdesdk/umbrello/umbrello/operation.h 2007-06-07 11:20:18.000000000 +0200
+@@ -75,20 +75,6 @@ public:
+ virtual UMLObject* clone() const;
+
+ /**
+- * Add a parameter to the operation.
+- *
+- * @param type The type of the parameter.
+- * @param name The name of the parameter.
+- * @param initialValue The initial value of the parameter.
+- * @param kind Optional: The parameter kind (in|inout|out).
+- * Default is "in".
+- * @return Pointer to the UMLAttribute created.
+- */
+- UMLAttribute * addParm(const QString& type, const QString& name,
+- const QString& initialValue, const QString& doc,
+- Uml::Parameter_Direction kind = Uml::pd_In);
+-
+- /**
+ * Move a parameter one position to the left.
+ *
+ * @param a The parameter to move.
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/umldoc.cpp kdesdk/umbrello/umbrello/umldoc.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/umldoc.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/umldoc.cpp 2007-06-07 08:40:54.000000000 +0200
+@@ -952,7 +952,7 @@ QString UMLDoc::uniqViewName(const Diagr
+ kWarning() << "uniqViewName() called with unknown diagram type" << endl;
+ }
+ QString name = dname;
+- for (int number = 0; findView(type, name); ++number,
++ for (int number = 0; findView(type, name, true); ++number,
+ name = dname + '_' + QString::number(number))
+ ;
+ return name;
+@@ -1184,8 +1184,12 @@ void UMLDoc::removeUMLObject(UMLObject*
+
+ void UMLDoc::signalUMLObjectCreated(UMLObject * o) {
+ emit sigObjectCreated(o);
+- if (!m_bLoading)
+- setModified(true);
++ /* This is the wrong place to do:
++ setModified(true);
++ Instead, that should be done by the callers when object creation and all
++ its side effects (e.g. new widget in view, new list view item, etc.) is
++ finalized.
++ */
+ }
+
+ void UMLDoc::setName(const QString& name) {
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/umllistview.cpp kdesdk/umbrello/umbrello/umllistview.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/umllistview.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/umllistview.cpp 2007-06-07 11:57:09.000000000 +0200
+@@ -821,12 +821,9 @@ void UMLListView::setDocument(UMLDoc *d)
+ }
+ m_doc = d;
+
+- Settings::OptionState optionState = Settings::getOptionState();
+- if (! optionState.generalState.tabdiagrams) {
+- connect(m_doc, SIGNAL(sigDiagramCreated(Uml::IDType)), this, SLOT(slotDiagramCreated(Uml::IDType)));
+- connect(m_doc, SIGNAL(sigDiagramRemoved(Uml::IDType)), this, SLOT(slotDiagramRemoved(Uml::IDType)));
+- connect(m_doc, SIGNAL(sigDiagramRenamed(Uml::IDType)), this, SLOT(slotDiagramRenamed(Uml::IDType)));
+- }
++ connect(m_doc, SIGNAL(sigDiagramCreated(Uml::IDType)), this, SLOT(slotDiagramCreated(Uml::IDType)));
++ connect(m_doc, SIGNAL(sigDiagramRemoved(Uml::IDType)), this, SLOT(slotDiagramRemoved(Uml::IDType)));
++ connect(m_doc, SIGNAL(sigDiagramRenamed(Uml::IDType)), this, SLOT(slotDiagramRenamed(Uml::IDType)));
+ connect(m_doc, SIGNAL(sigObjectCreated(UMLObject *)), this, SLOT(slotObjectCreated(UMLObject *)));
+ connect(m_doc, SIGNAL(sigObjectRemoved(UMLObject *)), this, SLOT(slotObjectRemoved(UMLObject *)));
+ }
+@@ -1387,14 +1384,15 @@ UMLListViewItem * UMLListView::moveObjec
+ if (newParentType == Uml::lvt_Class ||
+ newParentType == Uml::lvt_Interface) {
+ // update list view
++
+ newItem = move->deepCopy(newParent);
+ // we don't delete move right away, it will be deleted in slots,
+ // called by subsequent steps
+ //delete move;
+- UMLClassifierListItem *cli = dynamic_cast<UMLClassifierListItem*>(srcObj);
+- newParent->addClassifierListItem(cli, newItem);
++
+ // update model objects
+ m_bCreatingChildObject = true;
++
+ UMLClassifier *oldParentClassifier = dynamic_cast<UMLClassifier*>(srcObj->parent());
+ UMLClassifier *newParentClassifier = dynamic_cast<UMLClassifier*>(newParentObj);
+ if (srcType == Uml::lvt_Attribute) {
+@@ -1411,11 +1409,14 @@ UMLListViewItem * UMLListView::moveObjec
+ << att->getName() << ") returns NULL" << endl;
+ } else {
+ const QString& nm = att->getName();
+- UMLAttribute *newAtt = newParentClassifier->createAttribute(nm);
+- newAtt->setType(att->getType());
+- newAtt->setVisibility(att->getVisibility());
+- newAtt->setInitialValue(att->getInitialValue());
++ UMLAttribute *newAtt = newParentClassifier->createAttribute(nm,
++ att->getType(),
++ att->getVisibility(),
++ att->getInitialValue());
+ newItem->setUMLObject(newAtt);
++ newParent->addClassifierListItem( newAtt, newItem );
++
++ connectNewObjectsSlots( newAtt );
+ // Let's not forget to update the DocWindow::m_pObject
+ // because the old one is about to be physically deleted !
+ UMLApp::app()->getDocWindow()->showDocumentation(newAtt, true);
+@@ -1440,14 +1441,20 @@ UMLListViewItem * UMLListView::moveObjec
+ UMLAttributeList parmList = op->getParmList();
+ for (UMLAttributeListIt plit(parmList); plit.current(); ++plit) {
+ UMLAttribute *parm = plit.current();
+- UMLAttribute *newParm = new UMLAttribute(newParentClassifier, parm->getName());
+- newParm->setVisibility(parm->getVisibility());
+- newParm->setType(parm->getType());
++ UMLAttribute *newParm = new UMLAttribute(newParentClassifier,
++ parm->getName(),
++ Uml::id_None,
++ parm->getVisibility(),
++ parm->getType(),
++ parm->getInitialValue());
+ newParm->setParmKind(parm->getParmKind());
+- newParm->setInitialValue(parm->getInitialValue());
+ newOp->addParm(newParm);
+ }
+ newItem->setUMLObject(newOp);
++ newParent->addClassifierListItem( newOp, newItem );
++
++ connectNewObjectsSlots( newOp );
++
+ // Let's not forget to update the DocWindow::m_pObject
+ // because the old one is about to be physically deleted !
+ UMLApp::app()->getDocWindow()->showDocumentation(newOp, true);
+@@ -2093,12 +2100,9 @@ bool UMLListView::createChildUMLObject(
+ m_bCreatingChildObject = false;
+ return false;
+ }
+- newObject = owningClass->createAttribute(nt.m_name);
++ newObject = owningClass->createAttribute(nt.m_name, nt.m_type, vis, nt.m_initialValue);
+ UMLAttribute *att = static_cast<UMLAttribute*>(newObject);
+- att->setType(nt.m_type);
+- att->setVisibility(vis);
+ att->setParmKind(nt.m_direction);
+- att->setInitialValue(nt.m_initialValue);
+ text = att->toString(Uml::st_SigNoVis);
+ } else if ( type == Uml::ot_Operation ) {
+ UMLClassifier *owningClassifier = static_cast<UMLClassifier*>(parent);
+@@ -2134,12 +2138,20 @@ bool UMLListView::createChildUMLObject(
+ return false;
+ }
+
++ // make changes to the object visible to this umllistviewitem
++ connectNewObjectsSlots( newObject );
+ item->setUMLObject( newObject );
+ item->setText( text );
+ ensureItemVisible(item);
++
++ // as it's a ClassifierListItem add it to the childObjectMap of the parent
++ UMLClassifierListItem* classifierListItem = static_cast<UMLClassifierListItem*>( newObject );
++ static_cast<UMLListViewItem*>( item->parent() )->addClassifierListItem(classifierListItem, item );
++
+ m_bCreatingChildObject = false;
+
+- //m_doc->setModified();
++ if (! m_doc->loading())
++ m_doc->setModified();
+ return true;
+ }
+
+@@ -2504,11 +2516,7 @@ bool UMLListView::loadChildrenFromXMI( U
+ break;
+ default:
+ if (Model_Utils::typeIsDiagram(lvType)) {
+- Settings::OptionState optionState = Settings::getOptionState();
+- // don't load diagrams any more when using tabbed diagrams
+- if (!optionState.generalState.tabdiagrams) {
+- item = new UMLListViewItem( parent, label, lvType, nID );
+- }
++ item = new UMLListViewItem( parent, label, lvType, nID );
+ } else {
+ kError() << pfx << "INTERNAL ERROR: unexpected listview type "
+ << lvType << " (ID " << ID2STR(nID) << ")" << endl;
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/umlnamespace.h kdesdk/umbrello/umbrello/umlnamespace.h
+--- kdesdk-3.5.7/umbrello/umbrello/umlnamespace.h 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/umlnamespace.h 2007-06-05 07:09:24.000000000 +0200
+@@ -309,6 +309,7 @@ enum Programming_Language {
+ pl_Ada,
+ pl_Cpp,
+ pl_CSharp,
++ pl_D,
+ pl_IDL,
+ pl_Java,
+ pl_JavaScript,
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/umlobject.cpp kdesdk/umbrello/umbrello/umlobject.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/umlobject.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/umlobject.cpp 2007-05-22 06:11:56.000000000 +0200
+@@ -414,16 +414,21 @@ bool UMLObject::resolveRef() {
+ maybeSignalObjectCreated();
+ return true;
+ }
+- }
+- if (m_SecondaryFallback.isEmpty()) {
+- if (m_SecondaryId.isEmpty()) {
+- kError() << "UMLObject::resolveRef(" << m_Name
+- << "): both m_SecondaryId and m_SecondaryFallback are empty"
+- << endl;
+- return false;
++ if (m_SecondaryFallback.isEmpty()) {
++ kDebug() << "UMLObject::resolveRef: object with xmi.id=" << m_SecondaryId
++ << " not found, setting to undef" << endl;
++ UMLFolder *datatypes = pDoc->getDatatypeFolder();
++ m_pSecondary = Object_Factory::createUMLObject(Uml::ot_Datatype, "undef", datatypes, false);
++ return true;
+ }
+ m_SecondaryFallback = m_SecondaryId;
+ }
++ if (m_SecondaryFallback.isEmpty()) {
++ kError() << "UMLObject::resolveRef(" << m_Name
++ << "): cannot find type with id "
++ << m_SecondaryId << endl;
++ return false;
++ }
+ #ifdef VERBOSE_DEBUGGING
+ kDebug() << "UMLObject::resolveRef(" << m_Name
+ << "): could not resolve secondary ID " << m_SecondaryId
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/umlview.cpp kdesdk/umbrello/umbrello/umlview.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/umlview.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/umlview.cpp 2007-06-07 20:25:00.000000000 +0200
+@@ -131,8 +131,6 @@ void UMLView::init() {
+
+ // Initialize other data
+ m_AssociationList.setAutoDelete( true );
+- m_WidgetList.setAutoDelete( true );
+- m_MessageList.setAutoDelete( true );
+
+ //Setup up booleans
+ m_bChildDisplayedDoc = false;
+@@ -697,6 +695,7 @@ void UMLView::checkMessages(ObjectWidget
+ //make sure not in selected list
+ m_SelectedList.remove(obj);
+ m_MessageList.remove(obj);
++ delete obj;
+ }
+ }
+
+@@ -765,17 +764,24 @@ AssociationWidget * UMLView::findAssocWi
+ return 0;
+ }
+
+-AssociationWidget * UMLView::findAssocWidget(UMLWidget *pWidgetA, UMLWidget *pWidgetB) {
+- static QValueList<Association_Type> assocTypes;
+- if (assocTypes.isEmpty()) {
+- assocTypes << Uml::at_Aggregation << Uml::at_Composition << Uml::at_Containment;
+- }
+- AssociationWidget* retval = NULL;
+- for (uint i=0; i < assocTypes.size(); ++i) {
+- retval = findAssocWidget(assocTypes[i], pWidgetA, pWidgetB);
+- if (retval != NULL) return retval;
++AssociationWidget * UMLView::findAssocWidget(UMLWidget *pWidgetA,
++ UMLWidget *pWidgetB, const QString& roleNameB) {
++ AssociationWidget *assoc;
++ AssociationWidgetListIt it(m_AssociationList);
++ while ((assoc = it.current()) != 0) {
++ ++it;
++ const Association_Type testType = assoc->getAssocType();
++ if (testType != Uml::at_Association &&
++ testType != Uml::at_UniAssociation &&
++ testType != Uml::at_Composition &&
++ testType != Uml::at_Aggregation)
++ continue;
++ if (pWidgetA->getID() == assoc->getWidgetID(A) &&
++ pWidgetB->getID() == assoc->getWidgetID(B) &&
++ assoc->getRoleName(Uml::B) == roleNameB)
++ return assoc;
+ }
+- return retval;
++ return 0;
+ }
+
+
+@@ -791,15 +797,6 @@ AssociationWidget * UMLView::findAssocWi
+ if (pWidgetA->getID() == assoc->getWidgetID(A) &&
+ pWidgetB->getID() == assoc->getWidgetID(B))
+ return assoc;
+- // Allow for the swapped roles of generalization/realization assocwidgets.
+- // When the swapped roles bug is fixed, this code can disappear.
+- if (pWidgetA->getID() == assoc->getWidgetID(B) &&
+- pWidgetB->getID() == assoc->getWidgetID(A)) {
+- kDebug() << "UMLView::findAssocWidget: found assoctype " << at
+- << "with swapped roles (A: " << pWidgetA->getName()
+- << ", B: " << pWidgetB->getName() << ")" << endl;
+- return assoc;
+- }
+ }
+ return 0;
+ }
+@@ -826,6 +823,7 @@ void UMLView::removeWidget(UMLWidget * o
+ else
+ m_WidgetList.remove(o);
+ m_pDoc->setModified();
++ delete o;
+ }
+
+ bool UMLView::getUseFillColor() const {
+@@ -1367,6 +1365,7 @@ void UMLView::activate() {
+ obj->setVisible(true);
+ } else {
+ m_WidgetList.remove(obj);
++ delete obj;
+ }
+ }//end while
+
+@@ -2146,7 +2145,7 @@ void UMLView::createAutoAttributeAssocia
+ UMLAttributeList attrList = klass->getAttributeList();
+ for (UMLAttributeListIt ait(attrList); ait.current(); ++ait) {
+ UMLAttribute *attr = ait.current();
+- createAutoAttributeAssociation(attr->getType(), attr,widget);
++ createAutoAttributeAssociation(attr->getType(), attr, widget);
+ /*
+ * The following code from attachment 19935 of http://bugs.kde.org/140669
+ * creates Aggregation/Composition to the template parameters.
+@@ -2173,8 +2172,8 @@ void UMLView::createAutoAttributeAssocia
+ AssociationWidget *aw = NULL;
+ // if the attribute type has a widget representation on this view
+ if (w) {
+- aw = findAssocWidget(widget, w) ;
+- if ( ( aw == NULL || aw->getRoleName(Uml::B) != attr->getName() ) &&
++ aw = findAssocWidget(widget, w, attr->getName());
++ if ( aw == NULL &&
+ // if the current diagram type permits compositions
+ AssocRules::allowAssociation(assocType, widget, w, false) ) {
+ // Create a composition AssocWidget, or, if the attribute type is
+@@ -2205,7 +2204,7 @@ void UMLView::createAutoAttributeAssocia
+ UMLWidget *w = c ? findWidget( c->getID() ) : 0;
+ // if the referenced type has a widget representation on this view
+ if (w) {
+- aw = findAssocWidget(widget, w);
++ aw = findAssocWidget(widget, w, attr->getName());
+ if (aw == NULL &&
+ // if the current diagram type permits aggregations
+ AssocRules::allowAssociation(at_Aggregation, widget, w, false)) {
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/umlview.h kdesdk/umbrello/umbrello/umlview.h
+--- kdesdk-3.5.7/umbrello/umbrello/umlview.h 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/umlview.h 2007-06-07 20:33:03.000000000 +0200
+@@ -399,10 +399,19 @@ public:
+ UMLWidget *pWidgetA, UMLWidget *pWidgetB);
+
+ /**
+- * calls findAssocWidget on three possible types:
+- * Uml::at_Aggregation << Uml::at_Composition << Uml::at_Containment
++ * Finds an association widget with the given widgets and the given role B name.
++ * Considers the following association types:
++ * at_Association, at_UniAssociation, at_Composition, at_Aggregation
++ * This is used for seeking an attribute association.
++ *
++ * @param pWidgetA Pointer to the UMLWidget of role A.
++ * @param pWidgetB Pointer to the UMLWidget of role B.
++ * @param roleNameB Name at the B side of the association (the attribute name)
++ *
++ * @return Returns the widget found, returns 0 if no widget found.
+ */
+- AssociationWidget * findAssocWidget(UMLWidget *pWidgetA, UMLWidget *pWidgetB);
++ AssociationWidget * findAssocWidget(UMLWidget *pWidgetA,
++ UMLWidget *pWidgetB, const QString& roleNameB);
+
+ /**
+ * Remove a widget from view.
+diff -pruN kdesdk-3.5.7/umbrello/umbrello/umlwidget.cpp kdesdk/umbrello/umbrello/umlwidget.cpp
+--- kdesdk-3.5.7/umbrello/umbrello/umlwidget.cpp 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/umbrello/umlwidget.cpp 2007-06-07 09:30:39.000000000 +0200
+@@ -481,7 +481,7 @@ bool UMLWidget::activate(IDChangeLog* /*
+ setSize(getWidth(), getHeight());
+ m_bActivated = true;
+ updateComponentSize();
+- if( m_pView -> getPastePoint().x() != 0 ) {
++ if (m_pView->getPaste()) {
+ FloatingTextWidget * ft = 0;
+ QPoint point = m_pView -> getPastePoint();
+ int x = point.x() + getX();
+diff -pruN kdesdk-3.5.7/umbrello/uml.lsm kdesdk/umbrello/uml.lsm
+--- kdesdk-3.5.7/umbrello/uml.lsm 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/uml.lsm 2007-05-15 19:40:05.000000000 +0200
+@@ -1,6 +1,6 @@
+ Begin3
+ Title: Umbrello UML Modeller
+-Version: 1.5.6
++Version: 1.5.7
+ Entered-date:
+ Description: A UML diagram Modeller
+ Keywords: uml diagram modeller
+diff -pruN kdesdk-3.5.7/umbrello/VERSION kdesdk/umbrello/VERSION
+--- kdesdk-3.5.7/umbrello/VERSION 2007-05-14 09:40:29.000000000 +0200
++++ kdesdk/umbrello/VERSION 2007-05-21 21:59:53.000000000 +0200
+@@ -1 +1 @@
+-1.5.7
++1.5.71
More information about the pkg-kde-commits
mailing list