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