rev 3071 - trunk/packages/kdesdk/debian/patches

Christopher Martin chrsmrtn at costa.debian.org
Thu Feb 2 15:57:19 UTC 2006


Author: chrsmrtn
Date: 2006-02-02 15:57:18 +0000 (Thu, 02 Feb 2006)
New Revision: 3071

Added:
   trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r504925.diff
Removed:
   trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r486002.diff
   trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r490305.diff
   trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r497528.diff
Log:
kdesdk branch pulls.


Deleted: trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r486002.diff

Deleted: trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r490305.diff

Deleted: trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r497528.diff

Added: trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r504925.diff
===================================================================
--- trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r504925.diff	2006-02-01 23:41:24 UTC (rev 3070)
+++ trunk/packages/kdesdk/debian/patches/01_kdesdk_branch_r504925.diff	2006-02-02 15:57:18 UTC (rev 3071)
@@ -0,0 +1,2828 @@
+#DPATCHLEVEL=0
+--- kbabel/kbabel/kbabelview.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/kbabel/kbabelview.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1833,7 +1833,8 @@
+ 
+    autoCheck(false);
+ 
+-   if(_diffEnabled)
++   // no need to display diff if this message wasn't translated
++   if(_diffEnabled && !(_catalog->isUntranslated(_currentIndex)))
+    {
+        autoDiff();
+    }
+@@ -2859,9 +2860,8 @@
+     }
+     else
+     {
+-	uint max = _catalog->numberOfEntries();
+ 	// check, if we are already showing the last entry
+-	if(_currentIndex+1>=max)
++	if(_currentIndex>=_catalog->numberOfEntries()-1)
+ 	{
+     	    return;
+ 	}
+@@ -2914,8 +2914,9 @@
+ 
+       if(number>max)
+           number=max;
+-      if(number<0)
+-          number=0;
++      else
++          if(number<0)
++              number=0;
+ 
+       DocPosition pos;
+       pos.item=number;
+--- kbabel/VERSION	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/VERSION	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1 +1 @@
+-1.11.1
++1.11.2
+--- kbabel/ChangeLog	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/ChangeLog	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1,3 +1,5 @@
++Changes 1.11.2 (KDE 3.5.2)
++
+ Changes 1.11.1 (KDE 3.5.1)
+ - Avoid user-visible strings that need to be translated in two ways (bug #114151)
+ - Fix and improve source references
+--- kbabel/common/kbproject.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/common/kbproject.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1,8 +1,8 @@
+ /* ****************************************************************************
+   This file is part of KBabel
+ 
+-  Copyright (C) 2004 by Stanislav Visnovsky
+-                            <visnovsky at kde.org>
++  Copyright (C) 2004 by Stanislav Visnovsky <visnovsky at kde.org>
++  Copyright (C) 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -61,11 +61,14 @@
+ 
+     if(info.exists())
+     {
++        // ### TODO: can a setting file only be a text/plain file?
++        // ### TODO: why not use KMimeType::findByPath if the fileis always local?
+ 	// first, for existing file check the MIME type
+ 	// it has to be text file
+ 	KMimeType::Ptr mime = KMimeType::findByURL( KURL::fromPathOrURL( file ) );
+ 	if( mime->name() != "text/plain" )
+ 	{
++            // ### TODO: should the user not be asked instead?
+ 	    kdWarning () << "File type is " << mime->name() << endl;
+ 	    return;
+ 	}
+@@ -76,10 +79,10 @@
+     
+     // read the project name
+     _config->setGroup( "Project" );
+-    _name = _config->readEntry( "Name", "" );
+-    
+-    // now, try to read the version information
+-    if ( _config->readEntry( "Version", "" ) != "1.0.0" )
++    _name = _config->readEntry( "Name", QString() );
++
++    // ### FIXME: why is the Version number not written to the project file?
++    if ( _config->readEntry( "Version", QString() ) != "1.0.1" )
+     {
+ 	kdWarning() << "Old project format assumed" << endl;
+ 	
+@@ -155,7 +158,7 @@
+     if (_settings) 
+     {
+ 	// store the project name
+-	_settings->setVersion("1.0.0");
++	_settings->setVersion( "1.0.1" );
+ 	_settings->setName(_name);
+ 	
+ 	kdDebug () << "Writing configuration" << endl;
+@@ -174,6 +177,11 @@
+     return _config;
+ }
+ 
++KSharedConfig* Project::sharedConfig( void )
++{
++    return _config;
++}
++
+ ProjectSettingsBase* Project::settings ()
+ {
+     return _settings;
+@@ -296,6 +304,7 @@
+ 
+     settings.killCmdOnExit=_settings->killCmdOnExit();
+     settings.indexWords=_settings->indexWords();
++    settings.msgfmt=_settings->msgfmt();
+ 
+ 
+     settings.dirCommands = _settings->dirCommands();
+--- kbabel/common/kbproject.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/common/kbproject.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1,8 +1,8 @@
+ /* ****************************************************************************
+   This file is part of KBabel
+ 
+-  Copyright (C) 2004 by Stanislav Visnovsky
+-                            <visnovsky at kde.org>
++  Copyright (C) 2004 by Stanislav Visnovsky <visnovsky at kde.org>
++  Copyright (C) 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -58,6 +58,12 @@
+ 	    void setName( const QString& name ) { _name = name; }
+ 
+ 	    KConfig* config ();
++            /**
++             * Returns the KSharedConfig pointer of the project data
++             * @since 1.11.2 (KDE 3.5.2)
++             */
++            KSharedConfig* sharedConfig( void );
++            
+ 	    ProjectSettingsBase* settings ();
+ 	    
+ 	    bool valid () { return _valid; }
+--- kbabel/common/kbprojectsettings.kcfg	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/common/kbprojectsettings.kcfg	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -291,7 +291,7 @@
+     </entry>
+     <entry name="Version"  type="String">
+         <label>Version of the configuration file</label>
+-        <default>1.0.0</default>
++        <default></default>
+     </entry>
+   </group>
+   <group name="Spellcheck">
+--- kbabel/datatools/regexp/kbabel_regexptool.desktop	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/datatools/regexp/kbabel_regexptool.desktop	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,6 +2,7 @@
+ Encoding=UTF-8
+ Name=Catalan Grammar
+ Name[br]=Yezhadur gatalaneg
++Name[ca]=Gramàtica catalana
+ Name[cs]=Katalánská gramatika
+ Name[da]=Katalansk grammatik
+ Name[de]=Katalanische Grammatik
+@@ -35,6 +36,7 @@
+ Type=Service
+ Commands=validate
+ Comment=Check Translated Messages with a set of Regular Expressions
++Comment[ca]=Comprova els missatges traduïts amb un conjunt d'expressions regulars
+ Comment[cs]=Zkontrolovat přeložené zprávy pomocí sady reg. výrazů
+ Comment[da]=Tjek oversat besked med et sæt regulære udtryk
+ Comment[de]=Überprüfung übersetzter Meldungen mit einem Satz regulärer Ausdrücke
+--- kbabel/catalogmanager/libcvs/cvshandler.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libcvs/cvshandler.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,6 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -45,6 +46,8 @@
+ class QStringList;
+ class QWidget;
+ 
++class KSharedConfig;
++
+ /**
+  * This class is the backend for CVS support in Catalog Manager.
+  *
+@@ -75,8 +78,8 @@
+     QString fileStatus( const FileStatus status ) const;
+     QString cvsStatus( const QString& filename ) const;
+ 
+-    void execCVSCommand( QWidget* parent, CVS::Command cmd, const QString& filename, bool templates = false );
+-    void execCVSCommand( QWidget* parent, CVS::Command cmd, const QStringList& files, bool templates = false );
++    void execCVSCommand( QWidget* parent, CVS::Command cmd, const QString& filename, bool templates, KSharedConfig* config );
++    void execCVSCommand( QWidget* parent, CVS::Command cmd, const QStringList& files, bool templates, KSharedConfig* config );
+ 
+     void setAutoUpdateTemplates( bool update );
+ 
+@@ -91,7 +94,7 @@
+     void signalFilesCommitted( const QStringList& );
+ 
+   private:
+-    void showDialog( QWidget* parent, CVS::Command cmd, const QStringList& files, const QString& commandLine );
++      void showDialog( QWidget* parent, CVS::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config );
+     void checkToAdd( const QStringList& files );
+     void processStatusOutput( const QString& status );
+     void processDiff( QString output );
+--- kbabel/catalogmanager/libcvs/cvsdialog.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libcvs/cvsdialog.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,6 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -71,7 +72,7 @@
+      * Constructor for creating the dialog.
+      * @param cmd The type of command to be executed.
+      */
+-    CVSDialog( CVS::Command cmd, QWidget * parent = 0, const char * name = 0, bool modal = false, WFlags f = 0 );
++    CVSDialog( CVS::Command cmd, QWidget * parent, KSharedConfig* config );
+     ~CVSDialog();
+     /**
+      * Set the list of files which will be used for the CVS command.
+@@ -149,6 +150,9 @@
+ 
+     /// Combo box for the encoding
+     KComboBox* m_encodingComboBox;
++
++    /// Configuration data (of the KBabel project)
++    KSharedConfig* m_config;
+ };
+ 
+ #endif // CVSDIALOG_H
+--- kbabel/catalogmanager/libcvs/cvshandler.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libcvs/cvshandler.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,6 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -181,7 +182,7 @@
+   return map[filename];
+ }
+ 
+-void CVSHandler::execCVSCommand( QWidget* parent, CVS::Command cmd, const QString& filename, bool templates)
++void CVSHandler::execCVSCommand( QWidget* parent, CVS::Command cmd, const QString& filename, bool templates, KSharedConfig* config )
+ {
+   if ( !_isPORepository ) {
+     // This message box should never be visible but who knows... ;-)
+@@ -192,7 +193,7 @@
+ 
+   QFileInfo info( filename );
+   if ( !info.isDir( ) ) {
+-    execCVSCommand( parent, cmd, QStringList( filename ), templates );
++    execCVSCommand( parent, cmd, QStringList( filename ), templates, config );
+     return;
+   }
+ 
+@@ -217,10 +218,10 @@
+       break;
+   }
+ 
+-  showDialog( parent, cmd, QStringList( filename ), command );
++  showDialog( parent, cmd, QStringList( filename ), command, config );
+ }
+ 
+-void CVSHandler::execCVSCommand( QWidget* parent, CVS::Command cmd, const QStringList& files, bool templates )
++void CVSHandler::execCVSCommand( QWidget* parent, CVS::Command cmd, const QStringList& files, bool templates, KSharedConfig* config )
+ {
+   if ( !_isPORepository ) {
+     // This message box should never be visible but who knows... ;-)
+@@ -261,7 +262,7 @@
+     command += " \'" + temp + "\'";
+   }
+ 
+-  showDialog( parent, cmd, files, command );
++  showDialog( parent, cmd, files, command, config );
+ }
+ 
+ void CVSHandler::setAutoUpdateTemplates( bool update )
+@@ -269,9 +270,9 @@
+   _autoUpdateTemplates = update;
+ }
+ 
+-void CVSHandler::showDialog( QWidget* parent, CVS::Command cmd, const QStringList& files, const QString& commandLine )
++void CVSHandler::showDialog( QWidget* parent, CVS::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config )
+ {
+-  CVSDialog * dia = new CVSDialog( cmd, parent, "CVS DIALOG", true );
++  CVSDialog * dia = new CVSDialog( cmd, parent, config );
+   dia->setFiles( files );
+   dia->setCommandLine( commandLine );
+   if ( cmd == CVS::Commit ) {
+--- kbabel/catalogmanager/libcvs/cvsdialog.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libcvs/cvsdialog.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,6 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -59,8 +60,8 @@
+ #include "cvsdialog.h"
+ 
+ 
+-CVSDialog::CVSDialog( CVS::Command cmd, QWidget * parent, const char * name, bool modal, WFlags f )
+-  : KDialog( parent, name, modal, f )
++CVSDialog::CVSDialog( CVS::Command cmd, QWidget * parent, KSharedConfig* config )
++  : KDialog( parent, "CVSDIALOG", true ), m_config( config )
+ {
+   _cmd = cmd;
+   p=0L;
+@@ -372,8 +373,7 @@
+ 
+ void CVSDialog::readSettings( )
+ {
+-  // FIXME: does not care about different projects yet
+-  KConfig * config = KGlobal::config( );
++  KSharedConfig * config = m_config;
+   config->setGroup( "CVSSupport" );
+ 
+   if ( _cmd == CVS::Commit ) {
+@@ -397,11 +397,6 @@
+       }
+     }
+ 
+-    // ### TODO: why is this not simply the first entry?
+-    // Set the last log message as the one to be used.
+-    if ( config->readBoolEntry( "PresetLastUsedMessage", false ) )
+-      logedit->setText( m_squeezedLogMessages.first( ) );
+-
+     m_encoding = config->readEntry( "CVSEncoding", "UTF-8" );
+     m_encodingComboBox->insertItem( i18n( "Descriptive encoding name", "Last choice ( %1 )" ).arg( m_encoding ), 0);
+   }
+@@ -409,8 +404,7 @@
+ 
+ void CVSDialog::saveSettings( )
+ {
+-  // FIXME: does not care about different projects yet
+-  KConfig * config = KGlobal::config( );
++  KSharedConfig * config = m_config;
+   config->setGroup( "CVSSupport" );
+   if ( _cmd == CVS::Commit ) {
+     config->writeEntry( "AutoAddFiles", autoAddBox->isChecked( ) );
+@@ -423,6 +417,7 @@
+ 
+     config->writeEntry( "CVSEncoding", m_encoding );
+   }
++  m_config->sync();
+ }
+ 
+ #include "cvsdialog.moc"
+--- kbabel/catalogmanager/catalogmanagerview.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/catalogmanagerview.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -4,6 +4,7 @@
+   Copyright (C) 1999-2000 by Matthias Kiefer
+                             <matthias.kiefer at gmx.de>
+                 2001-2004 by Stanislav Visnovsky <visnovsky at kde.org>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+--- kbabel/catalogmanager/libsvn/svnhandler.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libsvn/svnhandler.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,7 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
+-  Copyright (C) 2005 by Nicolas GOUTTE <goutte at kde.org>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -210,13 +210,14 @@
+   return map[filename];
+ }
+ 
+-void SVNHandler::execSVNCommand( QWidget* parent, SVN::Command cmd, const QString& filename, bool templates)
++void SVNHandler::execSVNCommand( QWidget* parent, SVN::Command cmd, const QString& filename, bool templates, KSharedConfig* config)
+ {
+     // Unlike cvs, svn works also from outside the repository(as long as the path is in a repository of course!)
+-    execSVNCommand( parent, cmd, QStringList( filename ), templates);
++    // ### FIXME: wrong, svn commit cannot work if the current directory is not a SVN one
++    execSVNCommand( parent, cmd, QStringList( filename ), templates, config );
+ }
+ 
+-void SVNHandler::execSVNCommand( QWidget* parent, SVN::Command cmd, const QStringList& files, bool templates)
++void SVNHandler::execSVNCommand( QWidget* parent, SVN::Command cmd, const QStringList& files, bool templates, KSharedConfig* config )
+ {
+   if ( !_isPORepository ) {
+     // This message box should never be visible but who knows... ;-)
+@@ -263,7 +264,7 @@
+     command += " \'" + temp + "\'";
+   }
+ 
+-  showDialog( parent, cmd, files, command );
++  showDialog( parent, cmd, files, command, config );
+ }
+ 
+ void SVNHandler::setAutoUpdateTemplates( bool update )
+@@ -271,9 +272,9 @@
+   _autoUpdateTemplates = update;
+ }
+ 
+-void SVNHandler::showDialog( QWidget* parent, SVN::Command cmd, const QStringList& files, const QString& commandLine )
++void SVNHandler::showDialog( QWidget* parent, SVN::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config )
+ {
+-  SVNDialog * dia = new SVNDialog( cmd, parent, "SVN DIALOG", true );
++  SVNDialog * dia = new SVNDialog( cmd, parent, config );
+   dia->setFiles( files );
+   dia->setCommandLine( commandLine );
+   if ( cmd == SVN::Commit ) {
+--- kbabel/catalogmanager/libsvn/svndialog.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libsvn/svndialog.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,7 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
+-  Copyright (C) 2005 by Nicolas GOUTTE <goutte at kde.org>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -57,8 +57,8 @@
+ #include "svndialog.h"
+ 
+ 
+-SVNDialog::SVNDialog( SVN::Command cmd, QWidget * parent, const char * name, bool modal, WFlags f )
+-  : KDialog( parent, name, modal, f ), m_tempFile( 0 )
++SVNDialog::SVNDialog( SVN::Command cmd, QWidget * parent, KSharedConfig* config )
++  : KDialog( parent, "SVN DIALOG", true ), m_tempFile( 0 ), m_config( config )
+ {
+   _cmd = cmd;
+   p=0L;
+@@ -352,8 +352,7 @@
+ 
+ void SVNDialog::readSettings( )
+ {
+-  // FIXME: does not care about different projects yet
+-  KConfig * config = KGlobal::config( );
++  KSharedConfig * config = m_config;
+   config->setGroup( "SVNSupport" );
+ 
+   if ( _cmd == SVN::Commit ) {
+@@ -377,17 +376,12 @@
+         }
+       }
+ 
+-    // ### TODO: why is this not simply the first entry?
+-    // Set the last log message as the one to be used.
+-    if ( config->readBoolEntry( "PresetLastUsedMessage", false ) )
+-      logedit->setText( m_squeezedLogMessages.first( ) );
+   }
+ }
+ 
+ void SVNDialog::saveSettings( )
+ {
+-  // FIXME: does not care about different projects yet
+-  KConfig * config = KGlobal::config( );
++  KSharedConfig * config = m_config;
+   config->setGroup( "SVNSupport" );
+   if ( _cmd == SVN::Commit ) {
+     config->writeEntry( "AutoAddFiles", autoAddBox->isChecked( ) );
+@@ -398,6 +392,7 @@
+     for ( it = m_logMessages.constBegin( ); it != m_logMessages.constEnd( ) && cnt < 10 ; ++it, ++cnt )
+       config->writeEntry( QString( "CommitLogMessage%1" ).arg( cnt ), *it );
+   }
++  m_config->sync();
+ }
+ 
+ #include "svndialog.moc"
+--- kbabel/catalogmanager/libsvn/svnhandler.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libsvn/svnhandler.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,7 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
+-  Copyright (C) 2005 by Nicolas GOUTTE <goutte at kde.org>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -45,6 +45,8 @@
+ class QString;
+ class QStringList;
+ 
++class KSharedConfig;
++
+ /**
+  * This class is the backend for SVN support in Catalog Manager.
+  *
+@@ -75,8 +77,8 @@
+     QString fileStatus( const FileStatus status ) const;
+     QString svnStatus( const QString& filename ) const;
+ 
+-    void execSVNCommand( QWidget* parent, SVN::Command cmd, const QString& filename, bool templates = false );
+-    void execSVNCommand( QWidget* parent, SVN::Command cmd, const QStringList& files, bool templates = false );
++    void execSVNCommand( QWidget* parent, SVN::Command cmd, const QString& filename, bool templates, KSharedConfig* config );
++    void execSVNCommand( QWidget* parent, SVN::Command cmd, const QStringList& files, bool templates, KSharedConfig* config );
+ 
+     void setAutoUpdateTemplates( bool update );
+ 
+@@ -91,7 +93,7 @@
+     void signalFilesCommitted( const QStringList& );
+ 
+   private:
+-    void showDialog( QWidget* parent, SVN::Command cmd, const QStringList& files, const QString& commandLine );
++      void showDialog( QWidget* parent, SVN::Command cmd, const QStringList& files, const QString& commandLine, KSharedConfig* config );
+     /// Check quickly if the file is part of a SVN repository
+     bool isInSvn( const QString& path );
+     void checkToAdd( const QStringList& files );
+--- kbabel/catalogmanager/libsvn/svndialog.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/libsvn/svndialog.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2,7 +2,7 @@
+   This file is part of KBabel
+ 
+   Copyright (C) 2002-2003 by Marco Wegner <mail at marcowegner.de>
+-  Copyright (C) 2005 by Nicolas GOUTTE <goutte at kde.org>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -50,6 +50,7 @@
+ // Forwarding KDE classes
+ class KProcess;
+ class KTempFile;
++class KSharedConfig;
+ 
+ /**
+  * This class represents the dialog which is used for executing SVN commands
+@@ -70,7 +71,7 @@
+      * Constructor for creating the dialog.
+      * @param cmd The type of command to be executed.
+      */
+-    SVNDialog( SVN::Command cmd, QWidget * parent = 0, const char * name = 0, bool modal = false, WFlags f = 0 );
++    SVNDialog( SVN::Command cmd, QWidget * parent, KSharedConfig* config );
+     ~SVNDialog();
+     /**
+      * Set the list of files which will be used for the SVN command.
+@@ -142,6 +143,9 @@
+ 
+     /// Temporary file (for commits)
+     KTempFile* m_tempFile;
++
++    /// Configuration data (of the KBabel project)
++    KSharedConfig* m_config;
+ };
+ 
+ #endif // SVNDIALOG_H
+--- kbabel/catalogmanager/catalogmanagerview.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbabel/catalogmanager/catalogmanagerview.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -5,6 +5,7 @@
+                             <matthias.kiefer at gmx.de>
+                 2001-2004 by Stanislav Visnovsky
+                             <visnovsky at kde.org>
++  Copyright (C) 2005, 2006 by Nicolas GOUTTE <goutte at kde.org>
+ 
+   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
+@@ -1120,8 +1121,9 @@
+ 
+ void CatalogManagerView::doCVSCommand( CVS::Command cmd, bool marked, bool templates )
+ {
++  KSharedConfig* config = _project->sharedConfig();
+   if ( marked ) {
+-    if ( _markerList.count( ) == 0 ) return;
++    if ( _markerList.isEmpty() ) return;
+     QStringList fileList;
+     QStringList::const_iterator it;
+     for ( it = _markerList.constBegin( ); it != _markerList.constEnd( ); ++it ) {
+@@ -1131,7 +1133,7 @@
+       else if ( !templates && i->hasPo( ) )
+         fileList << i->poFile( );
+     }
+-    cvshandler->execCVSCommand( this, cmd, fileList, templates );
++    cvshandler->execCVSCommand( this, cmd, fileList, templates, config );
+   } else {
+     const QString basedir = ( templates ? _settings.potBaseDir : _settings.poBaseDir );
+     QString cvsItem;
+@@ -1140,7 +1142,7 @@
+       // all children including directories
+       QStringList cvsItems = item->allChildrenFileList (true, false, true);
+       if ( !cvsItems.isEmpty( ) )
+-        cvshandler->execCVSCommand( this, cmd, cvsItems, templates );
++        cvshandler->execCVSCommand( this, cmd, cvsItems, templates, config );
+     } else {
+       if ( templates && item->hasPot( ) )
+         cvsItem = item->potFile( );
+@@ -1148,7 +1150,7 @@
+         cvsItem = item->poFile( );
+ 
+       if ( !cvsItem.isEmpty( ) )
+-        cvshandler->execCVSCommand( this, cmd, cvsItem, templates );
++        cvshandler->execCVSCommand( this, cmd, cvsItem, templates, config );
+     }
+   }
+ }
+@@ -1231,8 +1233,9 @@
+ 
+ void CatalogManagerView::doSVNCommand( SVN::Command cmd, bool marked, bool templates )
+ {
++    KSharedConfig* config = _project->sharedConfig();
+     if ( marked ) {
+-        if ( _markerList.count( ) == 0 ) return;
++        if ( _markerList.isEmpty() ) return;
+         QStringList fileList;
+         QStringList::const_iterator it;
+         for ( it = _markerList.constBegin( ); it != _markerList.constEnd( ); ++it ) {
+@@ -1242,7 +1245,7 @@
+             else if ( !templates && i->hasPo( ) )
+                 fileList << i->poFile( );
+         }
+-        svnhandler->execSVNCommand( this, cmd, fileList, templates );
++        svnhandler->execSVNCommand( this, cmd, fileList, templates, config );
+     } else {
+         const QString basedir = ( templates ? _settings.potBaseDir : _settings.poBaseDir );
+         QString svnItem;
+@@ -1251,7 +1254,7 @@
+       // all children including directories
+             QStringList svnItems = item->allChildrenFileList (true, false, true);
+             if ( !svnItems.isEmpty( ) )
+-                svnhandler->execSVNCommand( this, cmd, svnItems, templates );
++                svnhandler->execSVNCommand( this, cmd, svnItems, templates, config );
+         } else {
+             if ( templates && item->hasPot( ) )
+                 svnItem = item->potFile( );
+@@ -1259,7 +1262,7 @@
+                 svnItem = item->poFile( );
+ 
+             if ( !svnItem.isEmpty( ) )
+-                svnhandler->execSVNCommand( this, cmd, svnItem, templates );
++                svnhandler->execSVNCommand( this, cmd, svnItem, templates, config );
+     }
+   }
+ }
+--- umbrello/umbrello/classifier.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/classifier.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -18,6 +18,10 @@
+ #include "operation.h"
+ #include "attribute.h"
+ #include "template.h"
++#include "enumliteral.h"
++#include "entityattribute.h"
++#include "enum.h"
++#include "entity.h"
+ #include "stereotype.h"
+ #include "umldoc.h"
+ #include "uml.h"
+@@ -185,7 +189,10 @@
+     }
+ 
+     // operation name is ok, formally add it to the classifier
+-    addOperation( op );
++    if (! addOperation(op)) {
++        delete op;
++        return NULL;
++    }
+ 
+     UMLDoc *umldoc = UMLApp::app()->getDocument();
+     umldoc->signalUMLObjectCreated(op);
+@@ -206,9 +213,17 @@
+         return false;
+     }
+ 
+-    if( position >= 0 && position <= (int)m_List.count() )
++    if( position >= 0 && position <= (int)m_List.count() ) {
++        kdDebug() << "UMLClassifier::addOperation(" << op->getName()
++            << "): inserting at position " << position << endl;
+         m_List.insert(position,op);
+-    else
++        UMLClassifierListItemList itemList = getFilteredList(Uml::ot_Operation);
++        UMLClassifierListItem* currentAtt;
++        QString buf;
++        for (UMLClassifierListItemListIt it0(itemList); (currentAtt = it0.current()); ++it0)
++            buf.append(" " + currentAtt->getName());
++        kdDebug() << "  UMLClassifier::addOperation list after change: " << buf << endl;
++     } else
+         m_List.append( op );
+     emit operationAdded(op);
+     emit modified();
+@@ -244,16 +259,6 @@
+     return m_List.count();
+ }
+ 
+-UMLOperation* UMLClassifier::takeOperation(UMLOperation* o, int *wasAtIndex) {
+-    int index = m_List.findRef(o);
+-    if (wasAtIndex)
+-        *wasAtIndex = index;
+-    if (removeOperation(o) >= 0) {
+-        return o;
+-    }
+-    return 0;
+-}
+-
+ UMLObject* UMLClassifier::createTemplate(QString currentName /*= QString::null*/) {
+     bool goodName = !currentName.isEmpty();
+     if (!goodName)
+@@ -573,21 +578,6 @@
+     return m_List.count();
+ }
+ 
+-UMLAttribute* UMLClassifier::takeAttribute(UMLAttribute* a, int *wasAtIndex) {
+-    int index = m_List.findRef( a );
+-    if (wasAtIndex)
+-        *wasAtIndex = index;
+-    UMLAttribute *retval = NULL;
+-    if (index != -1)
+-        retval = dynamic_cast<UMLAttribute*>(m_List.take( ));
+-    if (retval) {
+-        emit attributeRemoved(retval);
+-        emit modified();
+-    }
+-    kdDebug() << "UMLClassifier::takeAttribute: findRef returns " << index
+-    << ", a=" << a << ", retval=" << retval << endl;
+-    return retval;
+-}
+ 
+ void UMLClassifier::setClassAssoc(UMLAssociation *assoc) {
+     m_pClassAssoc = assoc;
+@@ -708,17 +698,6 @@
+     return m_List.count();
+ }
+ 
+-UMLTemplate* UMLClassifier::takeTemplate(UMLTemplate* t, int *wasAtIndex) {
+-    int index = m_List.findRef( t );
+-    if (wasAtIndex)
+-        *wasAtIndex = index;
+-    t = (index == -1 ? 0 : dynamic_cast<UMLTemplate*>(m_List.take( )));
+-    if (t) {
+-        emit templateRemoved(t);
+-        emit modified();
+-    }
+-    return t;
+-}
+ 
+ UMLTemplate *UMLClassifier::findTemplate(QString name) {
+     UMLTemplateList templParams = getTemplateList();
+@@ -745,6 +724,75 @@
+     return templateList;
+ }
+ 
++int UMLClassifier::takeItem(UMLClassifierListItem *item) {
++        UMLObject* currentAtt;
++        QString buf;
++        for (UMLObjectListIt it0(m_List);
++             (currentAtt = it0.current()); ++it0) {
++            QString txt = currentAtt->getName();
++            if (txt.isEmpty())
++              txt = "Type-" + QString::number((int) currentAtt->getBaseType());
++            buf.append(" " + currentAtt->getName());
++        }
++        kdDebug() << "  UMLClassifier::takeItem (before): m_List is " << buf << endl;
++    int index = m_List.findRef(item);
++    if (index == -1)
++        return -1;
++    switch (item->getBaseType()) {
++        case Uml::ot_Operation: {
++            if (removeOperation(dynamic_cast<UMLOperation*>(item)) < 0)
++                index = -1;
++            break;
++        }
++        case Uml::ot_Attribute: {
++            UMLAttribute *retval = dynamic_cast<UMLAttribute*>(m_List.take());
++            if (retval) {
++                emit attributeRemoved(retval);
++                emit modified();
++            } else {
++                index = -1;
++            }
++            break;
++        }
++        case Uml::ot_Template: {
++            UMLTemplate *t = dynamic_cast<UMLTemplate*>(m_List.take());
++            if (t) {
++                emit templateRemoved(t);
++                emit modified();
++            } else {
++                index = -1;
++            }
++            break;
++        }
++        case Uml::ot_EnumLiteral: {
++            UMLEnumLiteral *el = dynamic_cast<UMLEnumLiteral*>(m_List.take());
++            if (el) {
++                UMLEnum *e = static_cast<UMLEnum*>(this);
++                e->signalEnumLiteralRemoved(el);
++                emit modified();
++            } else {
++                index = -1;
++            }
++            break;
++        }
++        case Uml::ot_EntityAttribute: {
++            UMLEntityAttribute* el = dynamic_cast<UMLEntityAttribute*>(m_List.take());
++            if (el) {
++                UMLEntity *e = static_cast<UMLEntity*>(this);
++                e->signalEntityAttributeRemoved(el);
++                emit modified();
++            } else {
++                index = -1;
++            }
++            break;
++        }
++        default:
++            index = -1;
++            break;
++    }
++    return index;
++}
++
+ void UMLClassifier::saveToXMI(QDomDocument & qDoc, QDomElement & qElement) {
+     QDomElement classifierElement;
+     if (this->isInterface())
+--- umbrello/umbrello/associationwidget.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/associationwidget.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1723,7 +1723,7 @@
+     // is at top or bottom edge of widget.
+     bool is_top_or_bottom(false);
+     UMLWidget *pWidget(0);
+-        
++
+     if (role == tr_MultiA || role == tr_ChangeA || role == tr_RoleAName) {
+         p = m_LinePath.getPoint( 0 );
+         q = m_LinePath.getPoint( 1 );
+@@ -1752,17 +1752,14 @@
+     int x = 0, y = 0;
+ 
+     if (role == tr_MultiA || role == tr_MultiB) {
++        const bool isHorizontal = (p.y() == q.y());
++        const int atBottom = p.y() + SPACE;
++        const int atTop = p.y() - SPACE - textH;
++        const int atLeft = p.x() - SPACE - textW;
++        const int atRight = p.x() + SPACE;
++        y = (p.y() > q.y()) == isHorizontal ? atBottom : atTop;
++        x = (p.x() < q.x()) == isHorizontal ? atRight : atLeft;
+ 
+-        if( (p.y() > q.y()) != is_top_or_bottom )
+-            y = p.y() + SPACE;
+-        else
+-            y = p.y() - SPACE - textH;
+-
+-        if( p.x() < q.x() != is_top_or_bottom )
+-            x = p.x() + SPACE;
+-        else
+-            x = p.x() - SPACE - textW;
+-
+     } else if (role == tr_ChangeA || role == tr_ChangeB) {
+ 
+         if( p.y() > q.y() )
+--- umbrello/umbrello/petaltree2uml.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 0)
++++ umbrello/umbrello/petaltree2uml.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -0,0 +1,40 @@
++/***************************************************************************
++ *                                                                         *
++ *   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) 2006                                                     *
++ *  Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>                  *
++ *                                                                         *
++ ***************************************************************************/
++
++#ifndef PETALTREE2UML_H
++#define PETALTREE2UML_H
++
++// fwd decl
++class PetalNode;
++
++/**
++ * Traverse the PetalNode tree and create corresponding Umbrello objects
++ * for the PetalNodes encountered.
++ *
++ * @author Oliver Kellogg
++ * Bugs and comments to uml-devel at lists.sf.net or http://bugs.kde.org
++ */
++namespace Import_Rose {
++
++    /**
++     * This is really an auxiliary method for loadFromMDL() but is kept in a
++     * separate file to reflect that it is not coupled with the parser
++     * (other than by the PetalNode.)
++     *
++     * @return  true for success.
++     */
++    bool petalTree2Uml(PetalNode *root);
++
++}
++
++#endif
++
+--- umbrello/umbrello/messagewidget.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/messagewidget.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -41,8 +41,7 @@
+         y -= m_pOw[Uml::B]->getHeight() / 2;
+         m_pOw[Uml::B]->setY(y);
+     }
+-    UMLWidget::m_bResizable = (m_pOw[Uml::A] == m_pOw[Uml::B]);
+-
++    updateResizability();
+     calculateWidget();
+     y = y < getMinHeight() ? getMinHeight() : y;
+     y = y > getMaxHeight() ? getMaxHeight() : y;
+@@ -71,6 +70,14 @@
+ MessageWidget::~MessageWidget() {
+ }
+ 
++void MessageWidget::updateResizability() {
++    if (m_sequenceMessageType == Uml::sequence_message_synchronous ||
++        m_pOw[Uml::A] == m_pOw[Uml::B])
++        UMLWidget::m_bResizable = true;
++    else
++        UMLWidget::m_bResizable = false;
++}
++
+ void MessageWidget::draw(QPainter& p, int offsetX, int offsetY) {
+     if(!m_pOw[Uml::A] || !m_pOw[Uml::B]) {
+         return;
+@@ -737,7 +744,7 @@
+ 
+ void MessageWidget::setWidget(ObjectWidget * ow, Uml::Role_Type role) {
+     m_pOw[role] = ow;
+-    UMLWidget::m_bResizable = (m_pOw[Uml::A] == m_pOw[Uml::B]);
++    updateResizability();
+ }
+ 
+ ObjectWidget* MessageWidget::getWidget(Uml::Role_Type role) {
+@@ -805,7 +812,7 @@
+         << ID2STR(bId) << " is not an ObjectWidget" << endl;
+         return false;
+     }
+-    UMLWidget::m_bResizable = (m_pOw[Uml::A] == m_pOw[Uml::B]);
++    updateResizability();
+ 
+     UMLClassifier *c = dynamic_cast<UMLClassifier*>( pWB->getUMLObject() );
+     if (c) {
+--- umbrello/umbrello/Makefile.am	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/Makefile.am	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -51,6 +51,7 @@
+ kplayerslideraction.cpp \
+ hierarchicalcodeblock.cpp \
+ idlimport.cpp \
++import_rose.cpp \
+ import_utils.cpp \
+ infowidget.cpp \
+ javaimport.cpp \
+@@ -72,6 +73,8 @@
+ ownedhierarchicalcodeblock.cpp \
+ package.cpp \
+ packagewidget.cpp \
++petalnode.cpp \
++petaltree2uml.cpp \
+ plugin.cpp \
+ pluginloader.cpp \
+ pythonimport.cpp \
+--- umbrello/umbrello/umllistviewitem.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/umllistviewitem.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -336,9 +336,13 @@
+     UMLDoc* doc = s_pListView->getDocument();
+     if (m_bCreating) {
+         m_bCreating = false;
++        QString savedLabel = m_Label;
++        m_Label = text(col);
+         if ( s_pListView->slotItemRenamed( this, col ) ) {
+-            m_Label = text(col);
++            s_pListView->ensureItemVisible(this);
+             doc->setModified(true);
++        } else {
++            m_Label = savedLabel;
+         }
+         return;
+     }
+@@ -534,7 +538,7 @@
+ }
+ 
+ // Sort the listview items by type and position within the corresponding list
+-// of UMLObjects. If the item does not have an UMLObject then sort alphabetically.
++// of UMLObjects. If the item does not have an UMLObject then place it last.
+ int UMLListViewItem::compare(QListViewItem *other, int col, bool ascending) const
+ {
+     UMLListViewItem *ulvi = static_cast<UMLListViewItem*>(other);
+@@ -546,21 +550,59 @@
+     if ( ourType > otherType )
+         return 1;
+     // ourType == otherType
+-    const int alphaOrder = key(col, ascending).compare(other->key(col, ascending));
+     UMLObject *otherObj = ulvi->getUMLObject();
+-    if (m_pObject == NULL || otherObj == NULL)
+-        return alphaOrder;
++    if (m_pObject == NULL) {
++        kdDebug() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return 1 because (m_pObject==NULL)" << endl;
++        return 1;
++    }
++    if (otherObj == NULL) {
++        kdDebug() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return -1 because (otherObj==NULL)" << endl;
++        return -1;
++    }
+     UMLClassifier *ourParent = dynamic_cast<UMLClassifier*>(m_pObject->parent());
+     UMLClassifier *otherParent = dynamic_cast<UMLClassifier*>(otherObj->parent());
+-    if (ourParent == NULL || otherParent == NULL || ourParent != otherParent)
+-        return alphaOrder;
++    if (ourParent == NULL) {
++        kdDebug() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return 1 because (ourParent==NULL)" << endl;
++        return 1;
++    }
++    if (otherParent == NULL) {
++        kdDebug() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return -1 because (otherParent==NULL)" << endl;
++        return -1;
++    }
++    if (ourParent != otherParent) {
++        kdDebug() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return 0 because (ourParent != otherParentL)" << endl;
++        return 0;
++    }
+     UMLClassifierListItem *thisUmlItem = dynamic_cast<UMLClassifierListItem*>(m_pObject);
+     UMLClassifierListItem *otherUmlItem = dynamic_cast<UMLClassifierListItem*>(otherObj);
+-    if (thisUmlItem == NULL || otherUmlItem == NULL)
+-        return alphaOrder;
++    if (thisUmlItem == NULL) {
++        kdDebug() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return 1 because (thisUmlItem==NULL)" << endl;
++        return 1;
++    }
++    if (otherUmlItem == NULL) {
++        kdDebug() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return -1 because (otherUmlItem==NULL)" << endl;
++        return -1;
++    }
+     UMLClassifierListItemList items = ourParent->getFilteredList(thisUmlItem->getBaseType());
+     int myIndex = items.findRef(thisUmlItem);
+     int otherIndex = items.findRef(otherUmlItem);
++    if (myIndex < 0) {
++        kdError() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return -1 because (myIndex < 0)" << endl;
++        return -1;
++    }
++    if (otherIndex < 0) {
++        kdError() << "compare(self=" << getText() << ", other=" << ulvi->getText()
++            << "): return 1 because (otherIndex < 0)" << endl;
++        return 1;
++    }
+     return (myIndex < otherIndex ? -1 : myIndex > otherIndex ? 1 : 0);
+ }
+ 
+--- umbrello/umbrello/petalnode.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 0)
++++ umbrello/umbrello/petalnode.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -0,0 +1,86 @@
++#ifndef PETALNODE__H
++#define PETALNODE__H
++
++/***************************************************************************
++ *                                                                         *
++ *   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) 2006                                                     *
++ *  Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>                  *
++ ***************************************************************************/
++
++#include <qstring.h>
++#include <qpair.h>
++#include <qvaluelist.h>
++#include <qstringlist.h>
++
++/**
++ * Rose petal node - parse tree for model import
++ *
++ * A Rose petal node can be of type:
++ *  + object    - initialArgs() contains the object type name and further
++ *                initial arguments which depend on the exact object type
++ *              - subordinate attributes are contained in attributes()
++ *  + list      - initialArgs() contains the list type name
++ *              - list elements are contained in attributes() but the name
++ *                of each NameValue is empty.
++ *  + value     - not represented as a node, instead the stripped down value
++ *                is saved in the value string of the NameValue.
++ *                Example: for the input
++ *                  (value Text "This is some text")
++ *                the following is saved in the value string of the NameValue:
++ *                  "This is some text"
++ *
++ * @author Oliver Kellogg
++ * Bugs and comments to uml-devel at lists.sf.net or http://bugs.kde.org
++ */
++class PetalNode {
++public:
++    /**
++     * Use `string' if it is not empty.
++     * Use `node' if it is not NULL.
++     * Either `string' is set, or `node', but never both.
++     * (Perhaps this should be a union but that is ugly.)
++     */
++    struct StringOrNode {
++        QString string;
++        PetalNode *node;
++        StringOrNode() { node = 0; }
++        virtual ~StringOrNode() { }
++        bool isEmpty() { return (string.isEmpty() && node == 0); }
++    };
++    typedef QPair<QString, StringOrNode> NameValue;
++    typedef QValueList<NameValue> NameValueList;
++
++    enum NodeType { nt_object, nt_list };
++
++    PetalNode(NodeType nt);
++    virtual ~PetalNode();
++
++    // getters
++    NodeType type() const;
++    QStringList initialArgs() const;  // name and other initial args
++    QString name() const;  // convenience function: equal to initialArgs().first()
++    NameValueList attributes() const;
++    // setters
++    //void setType(NodeType nt);   see constructor
++    void setInitialArgs(QStringList args);
++    void setAttributes(NameValueList vl);
++    // utilities
++    /**
++     * Find an attribute by name.
++     * @return  The value of the attribute. StringOrNode::isEmpty() returns true
++     *          if the name could not be found.
++     */
++    StringOrNode findAttribute(QString name) const;
++private:
++    NodeType m_type;
++    QStringList m_initialArgs;
++    NameValueList m_attributes;
++};
++
++#endif
++
+--- umbrello/umbrello/entity.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/entity.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -114,19 +114,12 @@
+      * @return  Count of the remaining entityAttributes after removal.
+      *          Returns -1 if the given entityAttribute was not found.
+      */
+-    int removeEntityAttribute(UMLObject* a);
++    int removeEntityAttribute(UMLClassifierListItem* a);
+ 
+     /**
+-     * Take and return an entityAttribute from class.
+-     * It is the callers responsibility to pass on ownership of
+-     * the returned entityAttribute (or to delete the entityAttribute)
+-     *
+-     * @param  el entityAttribute to tkae
+-     * @param wasAtIndex        if given, the index in m_List of the item taken
+-     *                  is returned in the int pointed-to.
+-     * @return pointer to the entityAttribute or null if not found.
++     * Emit the entityAttributeRemoved signal.
+      */
+-    UMLEntityAttribute* takeEntityAttribute(UMLEntityAttribute* el, int *wasAtIndex = NULL);
++    void signalEntityAttributeRemoved(UMLClassifierListItem *eattr);
+ 
+     /**
+      * Returns the number of entityAttributes for the class.
+@@ -141,8 +134,8 @@
+     virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+ 
+ signals:
+-    void entityAttributeAdded(UMLObject*);
+-    void entityAttributeRemoved(UMLObject*);
++    void entityAttributeAdded(UMLClassifierListItem*);
++    void entityAttributeRemoved(UMLClassifierListItem*);
+ 
+ protected:
+     /**
+--- umbrello/umbrello/umlview.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/umlview.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -404,12 +404,12 @@
+     AssociationWidget * findAssocWidget(Uml::Association_Type at,
+                                         UMLWidget *pWidgetA, UMLWidget *pWidgetB);
+ 
+-
+     /**
+-        calls findAssocWidget on three possible types:
+-        Uml::at_Aggregation << Uml::at_Composition << Uml::at_Containment
+-        */
++     * calls findAssocWidget on three possible types:
++     * Uml::at_Aggregation << Uml::at_Composition << Uml::at_Containment
++     */
+     AssociationWidget * findAssocWidget(UMLWidget *pWidgetA, UMLWidget *pWidgetB);
++
+     /**
+      * Remove a widget from view.
+      *
+--- umbrello/umbrello/uml.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/uml.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -682,7 +682,11 @@
+ 
+     } else {
+         KURL url=KFileDialog::getOpenURL(":open-umbrello-file",
+-                                         i18n("*.xmi *.xmi.tgz *.xmi.tar.bz2|All Supported Files (*.xmi, *.xmi.tgz, *.xmi.tar.bz2)\n*.xmi|Uncompressed XMI Files (*.xmi)\n*.xmi.tgz|Gzip Compressed XMI Files (*.xmi.tgz)\n*.xmi.tar.bz2|Bzip2 Compressed XMI Files (*.xmi.tar.bz2)"), this, i18n("Open File"));
++            i18n("*.xmi *.xmi.tgz *.xmi.tar.bz2 *.mdl|All Supported Files (*.xmi, *.xmi.tgz, *.xmi.tar.bz2, *.mdl)\n"
++                 "*.xmi|Uncompressed XMI Files (*.xmi)\n"
++                 "*.xmi.tgz|Gzip Compressed XMI Files (*.xmi.tgz)\n"
++                 "*.xmi.tar.bz2|Bzip2 Compressed XMI Files (*.xmi.tar.bz2)\n"
++                 "*.mdl|Rose model files"), this, i18n("Open File"));
+         if(!url.isEmpty()) {
+             if(m_doc->openDocument(url))
+                 fileOpenRecent->addURL( url );
+--- umbrello/umbrello/petalnode.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 0)
++++ umbrello/umbrello/petalnode.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -0,0 +1,61 @@
++/***************************************************************************
++ *                                                                         *
++ *   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) 2006                                                     *
++ *  Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>                  *
++ ***************************************************************************/
++
++// own header
++#include "petalnode.h"
++
++PetalNode::PetalNode(NodeType nt) {
++    m_type = nt;
++}
++
++PetalNode::~PetalNode() {
++}
++
++PetalNode::NodeType PetalNode::type() const {
++    return m_type;
++}
++
++QStringList PetalNode::initialArgs() const {
++    return m_initialArgs;
++}
++
++QString PetalNode::name() const {
++    if (m_initialArgs.count() == 0)
++        return QString::null;
++    return m_initialArgs.first();
++}
++
++PetalNode::NameValueList PetalNode::attributes() const {
++    return m_attributes;
++}
++
++/*
++void PetalNode::setType(PetalNode::NodeType t) {
++    m_type = t;
++}
++ */
++
++void PetalNode::setInitialArgs(QStringList args) {
++    m_initialArgs = args;
++}
++
++void PetalNode::setAttributes(PetalNode::NameValueList vl) {
++    m_attributes = vl;
++}
++
++PetalNode::StringOrNode PetalNode::findAttribute(QString name) const {
++    for (uint i = 0; i < m_attributes.count(); i++) {
++        if (m_attributes[i].first == name)
++            return m_attributes[i].second;
++    }
++    return StringOrNode();
++}
++
+--- umbrello/umbrello/umlcanvasobject.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/umlcanvasobject.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -43,7 +43,6 @@
+      */
+     UMLCanvasObject(const QString & name = "", Uml::IDType id = Uml::id_None);
+ 
+-
+     /**
+      * Standard deconstructor.
+      */
+@@ -189,6 +188,13 @@
+     virtual QString uniqChildName(const Uml::Object_Type type,
+                                   bool seekStereo = false);
+ 
++    /**
++     * Return the list of subordinate items.
++     */
++    UMLObjectList subordinates() const {
++        return m_List;
++    }
++
+     // The abstract method UMLObject::saveToXMI() is implemented
+     // in the classes inheriting from UMLCanvasObject.
+ 
+--- umbrello/umbrello/entity.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/entity.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -140,7 +140,7 @@
+     return false;
+ }
+ 
+-int UMLEntity::removeEntityAttribute(UMLObject* literal) {
++int UMLEntity::removeEntityAttribute(UMLClassifierListItem* literal) {
+     if (!m_List.remove((UMLEntityAttribute*)literal)) {
+         kdDebug() << "can't find att given in list" << endl;
+         return -1;
+@@ -154,23 +154,14 @@
+     return m_List.count();
+ }
+ 
+-UMLEntityAttribute* UMLEntity::takeEntityAttribute(UMLEntityAttribute* el, int *wasAtIndex) {
+-    int index = m_List.findRef( el );
+-    if (wasAtIndex)
+-        *wasAtIndex = index;
+-    el = (index == -1 ? 0 : dynamic_cast<UMLEntityAttribute*>(m_List.take( )));
+-    if (el) {
+-        emit entityAttributeRemoved(el);
+-        emit modified();
+-    }
+-    return el;
+-}
+-
+ int UMLEntity::entityAttributes() {
+     UMLClassifierListItemList entityAttributes = getFilteredList(Uml::ot_EntityAttribute);
+     return entityAttributes.count();
+ }
+ 
++void UMLEntity::signalEntityAttributeRemoved(UMLClassifierListItem *eattr) {
++    emit entityAttributeRemoved(eattr);
++}
+ 
+ void UMLEntity::saveToXMI(QDomDocument& qDoc, QDomElement& qElement) {
+     QDomElement entityElement = UMLObject::save("UML:Entity", qDoc);
+--- umbrello/umbrello/umldoc.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/umldoc.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -60,6 +60,7 @@
+ #include "stereotype.h"
+ #include "classifierlistitem.h"
+ #include "object_factory.h"
++#include "import_rose.h"
+ #include "model_utils.h"
+ #include "widget_utils.h"
+ #include "uml.h"
+@@ -496,7 +497,10 @@
+             newDocument();
+             return false;
+         }
+-        status = loadFromXMI( file, ENC_UNKNOWN );
++        if (filetype.endsWith(".mdl"))
++            status = Import_Rose::loadFromMDL(file);
++        else
++            status = loadFromXMI( file, ENC_UNKNOWN );
+     }
+ 
+     file.close();
+@@ -1223,7 +1227,8 @@
+             UMLEnum *e = static_cast<UMLEnum*>(parent);
+             e->removeEnumLiteral(static_cast<UMLEnumLiteral*>(umlobject));
+         } else if (type == ot_EntityAttribute) {
+-            static_cast<UMLEntity*>(parent)->removeEntityAttribute(umlobject);
++            UMLEntity *ent = static_cast<UMLEntity*>(parent);
++            ent->removeEntityAttribute(static_cast<UMLClassifierListItem*>(umlobject));
+         } else {
+             UMLClassifier* pClass = dynamic_cast<UMLClassifier*>(parent);
+             if (pClass == NULL)  {
+--- umbrello/umbrello/petaltree2uml.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 0)
++++ umbrello/umbrello/petaltree2uml.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -0,0 +1,90 @@
++/***************************************************************************
++ *                                                                         *
++ *   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) 2006                                                     *
++ *  Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>                  *
++ ***************************************************************************/
++
++// own header
++#include "petaltree2uml.h"
++// qt/kde includes
++#include <qregexp.h>
++#include <kdebug.h>
++// app includes
++#include "petalnode.h"
++#include "import_utils.h"
++#include "package.h"
++#include "classifier.h"
++
++namespace Import_Rose {
++
++bool umbrellify(PetalNode *node, UMLPackage *parentPkg = NULL) {
++    if (node == NULL) {
++        kdError() << "umbrellify: node is NULL" << endl;
++        return false;
++    }
++    QStringList args = node->initialArgs();
++    QString objType = args[0];
++    QString name = args[1];
++    name.remove(QRegExp("\""));
++    Uml::Object_Type ot;
++    if (objType == "Class_Category") {
++        ot = Uml::ot_Package;
++        UMLObject *o = Import_Utils::createUMLObject(Uml::ot_Package, name, parentPkg);
++        parentPkg = static_cast<UMLPackage*>(o);
++        PetalNode *logical_models = node->findAttribute("logical_models").node;
++        if (logical_models == NULL) {
++            kdError() << "umbrellify: cannot find logical_models" << endl;
++            return false;
++        }
++        PetalNode::NameValueList atts = logical_models->attributes();
++        for (uint i = 0; i < atts.count(); i++) {
++            umbrellify(atts[i].second.node, parentPkg);
++        }
++    } else if (objType == "Class") {
++        UMLObject *o = Import_Utils::createUMLObject(Uml::ot_Class, name, parentPkg);
++        UMLClassifier *c = static_cast<UMLClassifier*>(o);
++        // .. to be continued: insert attributes, operations ..
++    } else {
++        kdDebug() << "umbrellify: object type " << objType
++                  << " is not yet implemented" << endl;
++    }
++    return true;
++}
++
++bool petalTree2Uml(PetalNode *root) {
++    if (root == NULL) {
++        kdError() << "petalTree2Uml: root is NULL" << endl;
++        return false;
++    }
++    if (root->name() != "Design") {
++        kdError() << "petalTree2Uml: expecting root name Design" << endl;
++        return false;
++    }
++    PetalNode *root_category = root->findAttribute("root_category").node;
++    if (root_category == NULL) {
++        kdError() << "petalTree2Uml: cannot find root_category" << endl;
++        return false;
++    }
++    if (root_category->name() != "Class_Category") {
++        kdError() << "petalTree2Uml: expecting root_category object Class_Category" << endl;
++        return false;
++    }
++    PetalNode *logical_models = root_category->findAttribute("logical_models").node;
++    if (logical_models == NULL) {
++        kdError() << "petalTree2Uml: cannot find logical_models" << endl;
++        return false;
++    }
++    PetalNode::NameValueList atts = logical_models->attributes();
++    for (uint i = 0; i < atts.count(); i++) {
++        umbrellify(atts[i].second.node);
++    }
++    return true;
++}
++
++}  // namespace Import_Rose
++
+--- umbrello/umbrello/import_rose.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 0)
++++ umbrello/umbrello/import_rose.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -0,0 +1,386 @@
++/***************************************************************************
++ *                                                                         *
++ *   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) 2006                                                     *
++ *  Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>                  *
++ ***************************************************************************/
++
++// own header
++#include "import_rose.h"
++
++// qt includes
++#include <qstring.h>
++#include <qtextstream.h>
++#include <qptrlist.h>
++#include <qstringlist.h>
++#include <qregexp.h>
++#include <qmessagebox.h>
++#include <klocale.h>
++#include <kdebug.h>
++// app includes
++#include "petalnode.h"
++#include "petaltree2uml.h"
++
++namespace Import_Rose {
++
++typedef QPtrList<PetalNode> PetalNodeList;
++
++uint nClosures; // Multiple closing parentheses may appear on a single
++                // line. The parsing is done line-by-line and using
++                // recursive descent. This means that we can only handle
++                // _one_ closing parenthesis at a time, i.e. the closing
++                // of the currently parsed node. Since we may see more
++                // closing parentheses than we can handle, we need a
++                // counter indicating how many additional node closings
++                // have been seen.
++
++uint linum;  // line number
++QString g_methodName;
++void methodName(QString m) {
++    g_methodName = m;
++}
++/**
++ * Auxiliary function for diagnostics: Return current location.
++ */
++QString loc() {
++    return "Import_Rose::" + g_methodName + " line " + linum + ": ";
++}
++
++/**
++ * Split a line into lexemes.
++ */
++QStringList scan(QString line) {
++    QStringList result;
++    line = line.stripWhiteSpace();
++    if (line.isEmpty())
++        return result;  // empty
++    QString lexeme;
++    const uint len = line.length();
++    bool inString = false;
++    for (uint i = 0; i < len; i++) {
++        QChar c = line[i];
++        if (c == '"') {
++            lexeme += c;
++            if (inString) {
++                result.append(lexeme);
++                lexeme = QString::null;
++            }
++            inString = !inString;
++        } else if (inString ||
++                   c.isLetterOrNumber() || c == '_' || c == '@') {
++            lexeme += c;
++        } else {
++            if (!lexeme.isEmpty()) {
++                result.append(lexeme);
++                lexeme = QString::null;
++            }
++            if (! c.isSpace()) {
++                result.append(QString(c));
++            }
++        }
++    }
++    if (!lexeme.isEmpty())
++        result.append(lexeme);
++    return result;
++}
++
++/**
++ * Emulate perl shift().
++ */
++QString shift(QStringList& l) {
++    QString first = l.first();
++    l.pop_front();
++    return first;
++}
++
++/**
++ * Check for closing of one or more scopes.
++ */
++bool checkClosing(QStringList& tokens) {
++    if (tokens.count() == 0)
++        return false;
++    if (tokens.last() == ")") {
++        // For a single closing parenthesis, we just return true.
++        // But if there are more closing parentheses, we need to increment
++        // nClosures for each scope.
++        tokens.pop_back();
++        while (tokens.count() && tokens.last() == ")") {
++            nClosures++;
++            tokens.pop_back();
++        }
++        return true;
++    }
++    return false;
++}
++
++/**
++ * Immediate values are numbers or quoted strings.
++ * @return  True if the given text is a natural or negative number
++ *          or a quoted string.
++ */
++bool isImmediateValue(QString s) {
++    return s.contains(QRegExp("^[\\d\\-\"]"));
++}
++
++/**
++ * Extract immediate values out of `l'.
++ * Examples of immediate value lists:
++ *   number list:     ( 123 , 456 )
++ *   string list:     ( "SomeText" 888 )
++ * Any enclosing parentheses are removed.
++ * All extracted items are also removed from `l'.
++ * For the example given above the following is returned:
++ *   "123 456"
++ * or
++ *   "\"SomeText\" 888"
++ */
++QString extractImmediateValues(QStringList& l) {
++    if (l.count() == 0)
++        return QString::null;
++    if (l.first() == "(")
++        l.pop_front();
++    QString result;
++    bool start = true;
++    while (l.count() && isImmediateValue(l.first())) {
++        if (start)
++            start = false;
++        else
++            result += " ";
++        result += shift(l);
++        if (l.first() == ",")
++            l.pop_front();
++    }
++    if (l.first() == ")")
++        l.pop_front();
++    while (l.count() && l.first() == ")") {
++        nClosures++;
++        l.pop_front();
++    }
++    return result;
++}
++
++QString collectVerbatimText(QTextStream& stream) {
++    QString result;
++    QString line;
++    methodName("collectVerbatimText");
++    while ((line = stream.readLine()) != QString::null) {
++        linum++;
++        line = line.stripWhiteSpace();
++        if (line.isEmpty() || line.startsWith(")"))
++            break;
++        if (line[0] != '|') {
++            kdError() << loc() << "expecting '|' at start of verbatim text" << endl;
++            return QString::null;
++        } else {
++            result += line.mid(1) + "\n";
++        }
++    }
++    if (line == QString::null) {
++        kdError() << loc() << "premature EOF" << endl;
++        return QString::null;
++    }
++    if (! line.isEmpty()) {
++        for (uint i = 0; i < line.length(); i++) {
++            const QChar& clParenth = line[i];
++            if (clParenth != ')') {
++                kdError() << loc() << "expected ')', found: " << clParenth << endl;
++                return QString::null;
++            }
++            nClosures++;
++        }
++    }
++    return result;
++}
++
++/**
++ * Extract the stripped down value from a (value ...) element.
++ * Example: for the input
++ *            (value Text "This is some text")
++ *          the following is extracted:
++ *            "This is some text"
++ * Extracted elements and syntactic sugar of the value element are
++ * removed from the input list.
++ * The stream is passed into this method because it may be necessary
++ * to read new lines - in the case of verbatim text.
++ * The format of verbatim text in petal files is as follows:
++ *
++ *         (value Text
++ * |This is the first line of verbatim text.
++ * |This is another line of verbatim text.
++ *         )
++ * (The '|' character is supposed to be in the first column of the line)
++ * In this case the two lines are extracted without the leading '|'.
++ * The line ending '\n' of each line is preserved.
++ */
++QString extractValue(QStringList& l, QTextStream& stream) {
++    methodName("extractValue");
++    if (l.count() == 0)
++        return QString::null;
++    if (l.first() == "(")
++        l.pop_front();
++    if (l.first() != "value")
++        return QString::null;
++    l.pop_front();  // remove "value"
++    l.pop_front();  // remove the value type: could be e.g. "Text" or "cardinality"
++    QString result;
++    if (l.count() == 0) {  // expect verbatim text to follow on subsequent lines
++        QString text = collectVerbatimText(stream);
++        nClosures--;  // expect own closure
++        return text;
++    } else {
++        result = shift(l);
++        if (l.first() != ")") {
++            kdError() << loc() << "expecting closing parenthesis" << endl;
++            return result;
++        }
++        l.pop_front();
++    }
++    while (l.count() && l.first() == ")") {
++        nClosures++;
++        l.pop_front();
++    }
++    return result;
++}
++
++/**
++ * Read attributes of a node.
++ * @param initialArgs  Tokens on the line of the opening "(" of the node
++ *                   but with leading whitespace and the opening "(" removed.
++ * @param stream     The QTextStream from which to read following lines.
++ * @return           Pointer to the created PetalNode or NULL on error.
++ */
++PetalNode *readAttributes(QStringList initialArgs, QTextStream& stream) {
++    methodName("readAttributes");
++    if (initialArgs.count() == 0) {
++        kdError() << loc() << "initialArgs is empty" << endl;
++        return NULL;
++    }
++    PetalNode::NodeType nt;
++    QString type = shift(initialArgs);
++    if (type == "object")
++        nt = PetalNode::nt_object;
++    else if (type == "list")
++        nt = PetalNode::nt_list;
++    else {
++        kdError() << loc() << "unknown node type " << type << endl;
++        return NULL;
++    }
++    PetalNode *node = new PetalNode(nt);
++    bool seenClosing = checkClosing(initialArgs);
++    node->setInitialArgs(initialArgs);
++    if (seenClosing)
++        return node;
++    PetalNode::NameValueList attrs;
++    QString line;
++    while ((line = stream.readLine()) != QString::null) {
++        linum++;
++        line = line.stripWhiteSpace();
++        if (line.isEmpty())
++            continue;
++        QStringList tokens = scan(line);
++        QString stringOrNodeOpener = shift(tokens);
++        QString name;
++        if (nt == PetalNode::nt_object && !stringOrNodeOpener.contains(QRegExp("^[A-Za-z]"))) {
++            kdError() << loc() << "unexpected line " << line << endl;
++            return NULL;
++        }
++        PetalNode::StringOrNode value;
++        if (nt == PetalNode::nt_object) {
++            name = stringOrNodeOpener;
++            if (tokens.count() == 0) {  // expect verbatim text to follow on subsequent lines
++                value.string = collectVerbatimText(stream);
++                PetalNode::NameValue attr(name, value);
++                attrs.append(attr);
++                if (nClosures) {
++                    // Decrement nClosures exactly once, namely for the own scope.
++                    // Each recursion of readAttributes() is only responsible for
++                    // its own scope. I.e. each further scope closing is handled by
++                    // an outer recursion in case of multiple closing parentheses.
++                    nClosures--;
++                    break;
++                }
++                continue;
++            }
++            stringOrNodeOpener = shift(tokens);
++        } else if (stringOrNodeOpener != "(") {
++            value.string = stringOrNodeOpener;
++            PetalNode::NameValue attr(QString::null, value);
++            attrs.append(attr);
++            if (tokens.count() && tokens.first() != ")") {
++                kdDebug() << loc()
++                    << "NYI - immediate list entry with more than one item" << endl;
++            }
++            if (checkClosing(tokens))
++                break;
++            continue;
++        }
++        if (stringOrNodeOpener == "(") {
++            QString nxt = tokens.first();
++            if (isImmediateValue(nxt)) {
++                value.string = extractImmediateValues(tokens);
++            } else if (nxt == "value" || nxt.startsWith("\"")) {
++                value.string = extractValue(tokens, stream);
++            } else {
++                value.node = readAttributes(tokens, stream);
++                if (value.node == NULL)
++                    return NULL;
++            }
++            PetalNode::NameValue attr(name, value);
++            attrs.append(attr);
++            if (nClosures) {
++                // Decrement nClosures exactly once, namely for the own scope.
++                // Each recursion of readAttributes() is only responsible for
++                // its own scope. I.e. each further scope closing is handled by
++                // an outer recursion in case of multiple closing parentheses.
++                nClosures--;
++                break;
++            }
++        } else {
++            value.string = stringOrNodeOpener;
++            bool seenClosing = checkClosing(tokens);
++            PetalNode::NameValue attr(name, value);
++            attrs.append(attr);
++            if (seenClosing) {
++                break;
++            }
++        }
++    }
++    node->setAttributes(attrs);
++    return node;
++}
++
++bool loadFromMDL(QIODevice& file) {
++    QTextStream stream(&file);
++    QString line;
++    PetalNode *root = NULL;
++    linum = 0;
++    while ((line = stream.readLine()) != QString::null) {
++        linum++;
++        if (line.contains( QRegExp("^\\s*\\(object Petal") )) {
++            while ((line = stream.readLine()) != QString::null && !line.contains(')')) {
++                linum++; // CHECK: do we need petal version info?
++            }
++            if (line == QString::null)
++                return false;
++        } else {
++            QRegExp objectRx("^\\s*\\(object ");
++            if (line.contains(objectRx)) {
++                nClosures = 0;
++                QStringList initialArgs = scan(line);
++                initialArgs.pop_front();  // remove opening parenthesis
++                root = readAttributes(initialArgs, stream);
++            }
++        }
++    }
++    file.close();
++    if (root == NULL)
++        return false;
++    return petalTree2Uml(root);
++}
++
++}
++
+--- umbrello/umbrello/messagewidget.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/messagewidget.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -363,6 +363,12 @@
+      */
+     static void drawSolidArrowhead(QPainter& p, int x, int y, Qt::ArrowType direction);
+ 
++    /**
++     * Update the UMLWidget::m_bResizable flag according to the
++     * charactersitics of this message.
++     */
++    void updateResizability();
++
+     // Data loaded/saved
+     QString m_SequenceNumber;
+     QString m_CustomOp;
+--- umbrello/umbrello/dialogs/classifierlistpage.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/dialogs/classifierlistpage.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -87,15 +87,20 @@
+     bool addClassifier(UMLClassifierListItem* classifier, int position = -1);
+ 
+     /**
+-     * Take classifier, It is the client responsibility to hand over
+-     * ownership of the classifier, or to delete it.
+-     * @param classifier        Classifier to take.
+-     * @param wasAtIndex        Return value: Index in the UMLClassifier's item
+-     *                  list at which the item was taken.
+-     * @return  Pointer to the UMLClassifierListItem taken.
++     * Take a classifier's subordinate item.
++     * Ownership of the classifier list item is transferred to the caller.
++     * @param listitem        UMLClassifierListItem to take.
++     * @param seekPeerBefore  True if a peer index should be sought which
++     *                        is smaller than the current listitem's index.
++     * @param peerIndex       Return value: Index in the UMLClassifier's
++     *                        item list at which a peer item, i.e. another
++     *                        UMLClassifierListItem of the same type as
++     *                        listItem, is found.  If no such item exists
++     *                        then return -1.
++     * @return   True for success.
+      */
+-    UMLClassifierListItem* takeClassifier(UMLClassifierListItem* classifier,
+-                                          int &wasAtIndex);
++    bool takeItem(UMLClassifierListItem* listitem,
++                  bool seekPeerBefore, int &peerIndex);
+ 
+     UMLClassifier* m_pClassifier;
+     QGroupBox* m_pDocGB;
+--- umbrello/umbrello/dialogs/classifierlistpage.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/dialogs/classifierlistpage.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -341,13 +341,28 @@
+     m_pItemListLB->setSelected( item, true );
+ 
+     //now change around in the list
+-    UMLClassifierListItem* currentAtt = getItemList().at( index );
++    UMLClassifierListItemList itemList = getItemList();
++    UMLClassifierListItem* currentAtt;
++    QString buf;
++    for (UMLClassifierListItemListIt it0(itemList); (currentAtt = it0.current()); ++it0)
++        buf.append(" " + currentAtt->getName());
++    kdDebug() << "itemList before change: " << buf << endl;
++    currentAtt = itemList.at( index );
+     // NB: The index in the m_pItemListLB is not necessarily the same
+     //     as the index in the UMLClassifier::m_List.
+     //     Reason: getItemList() returns only a subset of all entries
+     //     in UMLClassifier::m_List.
+-    takeClassifier(currentAtt, index);  // now we index the UMLClassifier::m_List
+-    addClassifier(currentAtt, index - 1);
++    takeItem(currentAtt, true, index);  // now we index the UMLClassifier::m_List
++    kdDebug() << "ClassifierListPage::slotUpClicked(" << currentAtt->getName()
++        << "): peer index in UMLCanvasItem::m_List is " << index << endl;
++    if (index == -1)
++        index = 0;
++    addClassifier(currentAtt, index);
++    itemList = getItemList();
++    buf = QString::null;
++    for (UMLClassifierListItemListIt it1(itemList); (currentAtt = it1.current()); ++it1)
++        buf.append(" " + currentAtt->getName());
++    kdDebug() << "itemList after change: " << buf << endl;
+     slotClicked( item );
+ }
+ 
+@@ -368,13 +383,28 @@
+     QListBoxItem* item = m_pItemListLB->item( index + 1 );
+     m_pItemListLB->setSelected( item, true );
+     //now change around in the list
+-    UMLClassifierListItem* currentAtt = getItemList().at( index );
++    UMLClassifierListItemList itemList = getItemList();
++    UMLClassifierListItem* currentAtt;
++    QString buf;
++    for (UMLClassifierListItemListIt it0(itemList); (currentAtt = it0.current()); ++it0)
++        buf.append(" " + currentAtt->getName());
++    kdDebug() << "itemList before change: " << buf << endl;
++    currentAtt = getItemList().at( index );
+     // NB: The index in the m_pItemListLB is not necessarily the same
+     //     as the index in the UMLClassifier::m_List.
+     //     Reason: getItemList() returns only a subset of all entries
+     //     in UMLClassifier::m_List.
+-    takeClassifier(currentAtt, index);  // now we index the UMLClassifier::m_List
+-    addClassifier(currentAtt, index + 1);
++    takeItem(currentAtt, false, index);  // now we index the UMLClassifier::m_List
++    kdDebug() << "ClassifierListPage::slotDownClicked(" << currentAtt->getName()
++        << "): peer index in UMLCanvasItem::m_List is " << index << endl;
++    if (index != -1)
++        index++;   // because we want to go _after_ the following peer item
++    addClassifier(currentAtt, index);
++    itemList = getItemList();
++    buf = QString::null;
++    for (UMLClassifierListItemListIt it1(itemList); (currentAtt = it1.current()); ++it1)
++        buf.append(" " + currentAtt->getName());
++    kdDebug() << "itemList after change: " << buf << endl;
+     slotClicked( item );
+ }
+ 
+@@ -462,42 +492,32 @@
+     return false;
+ }
+ 
+-UMLClassifierListItem* ClassifierListPage::takeClassifier(UMLClassifierListItem* listitem,
+-        int &wasAtIndex) {
+-    switch (m_itemType) {
+-    case ot_Attribute: {
+-            UMLAttribute *att = dynamic_cast<UMLAttribute*>(listitem);
+-            return m_pClassifier->takeAttribute(att, &wasAtIndex);
+-        }
+-    case ot_Operation: {
+-            UMLOperation *op = dynamic_cast<UMLOperation*>(listitem);
+-            return m_pClassifier->takeOperation(op, &wasAtIndex);
+-        }
+-    case ot_Template: {
+-            UMLTemplate* t = dynamic_cast<UMLTemplate*>(listitem);
+-            return m_pClassifier->takeTemplate(t, &wasAtIndex);
+-        }
+-    case ot_EnumLiteral: {
+-            UMLEnum* c = dynamic_cast<UMLEnum*>(m_pClassifier);
+-            if (c) {
+-                return c->takeEnumLiteral(dynamic_cast<UMLEnumLiteral*>(listitem), &wasAtIndex);
++bool ClassifierListPage::takeItem(UMLClassifierListItem* listItem,
++                                  bool seekPeerBefore, int &peerIndex) {
++    int wasAtIndex = m_pClassifier->takeItem(listItem);
++    if (wasAtIndex == -1)
++        return false;
++    peerIndex = -1;
++    UMLObject *o;
++    const Uml::Object_Type seekType = listItem->getBaseType();
++    UMLObjectList listItems = m_pClassifier->subordinates();
++    UMLObjectListIt it(listItems);
++    for (int i = 0; (o = it.current()) != NULL; ++i, ++it) {
++        if (seekPeerBefore) {
++            if (i >= wasAtIndex)
++                break;
++            if (o->getBaseType() == seekType)
++                peerIndex = i;
++        } else {    // seekPeerAfter
++            if (i < wasAtIndex)
++                continue;
++            if (o->getBaseType() == seekType) {
++                peerIndex = i;
++                break;
+             }
+-            break;
+         }
+-    case ot_EntityAttribute: {
+-            UMLEntity* c = dynamic_cast<UMLEntity*>(m_pClassifier);
+-            if (c) {
+-                return c->takeEntityAttribute(dynamic_cast<UMLEntityAttribute*>(listitem), &wasAtIndex);
+-            }
+-            break;
+-        }
+-    default: {
+-            kdWarning() << "unknown type in ClassifierListPage" << endl;
+-            return 0;
+-        }
+     }
+-    kdError() << "ClassifierListPage::takeClassifier unable to handle listitem type in current state" << endl;
+-    return 0;
++    return true;
+ }
+ 
+ 
+--- umbrello/umbrello/import_rose.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 0)
++++ umbrello/umbrello/import_rose.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -0,0 +1,35 @@
++/***************************************************************************
++ *                                                                         *
++ *   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) 2006                                                     *
++ *  Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>                  *
++ ***************************************************************************/
++
++#ifndef IMPORT_ROSE__H
++#define IMPORT_ROSE__H
++
++#include <qiodevice.h>
++
++/**
++ * Rose model import
++ *
++ * @author Oliver Kellogg
++ * Bugs and comments to uml-devel at lists.sf.net or http://bugs.kde.org
++ */
++namespace Import_Rose {
++
++    /**
++     * Parse a file into the PetalNode internal tree representation
++     * and then create Umbrello objects by traversing the tree.
++     *
++     * @return  True for success, false in case of error.
++     */
++    bool loadFromMDL(QIODevice & file);
++
++}
++
++#endif
+--- umbrello/umbrello/enum.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/enum.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -113,17 +113,6 @@
+      *          Returns -1 if the given enumliteral was not found.
+      */
+     int removeEnumLiteral(UMLEnumLiteral *a);
+-    /**
+-     * Take and return an enumliteral from class.
+-     * It is the callers responsibility to pass on ownership of
+-     * the returned enumliteral (or to delete the enumliteral)
+-     *
+-     * @param el  enumliteral to take
+-     * @param wasAtIndex  if given, the index in m_List of the item taken
+-     *                    is returned in the int pointed to.
+-     * @return pointer to the enumliteral or null if not found.
+-     */
+-    UMLEnumLiteral* takeEnumLiteral(UMLEnumLiteral* el, int *wasAtIndex = NULL);
+ 
+     /**
+      * Returns the number of enumliterals for the class.
+@@ -133,6 +122,11 @@
+     int enumLiterals();
+ 
+     /**
++     * Emit the enumLiteralRemoved signal.
++     */
++    void signalEnumLiteralRemoved(UMLClassifierListItem *elit);
++
++    /**
+      * Creates the <UML:Enum> element including its enumliterals.
+      */
+     virtual void saveToXMI( QDomDocument & qDoc, QDomElement & qElement );
+--- umbrello/umbrello/notewidget.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/notewidget.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -246,82 +246,74 @@
+     QString text = getDoc();
+     if( text.length() == 0 )
+         return;
+-    uint i = 0;
+     QString word = "";
++    QString fullLine = "";
++    QString testCombineLine = "";
+     const int margin = fm.width( "W" );
+     int textY = fontHeight / 2;
+     int textX = margin;
+     const int width = this -> width() - margin * 2;
+     const int height = this -> height() - fontHeight;
+     QChar returnChar('\n');
+-    while( i <= text.length() ) {
+-        QChar c = text[ i++ ];
+-        if( c == returnChar ) {
+-            if( word.length() > 0 ) {
+-                int textWidth = fm.width( word );
+-                if( ( textX + textWidth ) > width )//wrap word
+-                {
+-                    textWidth = textWidth < width ? textWidth: width;
++    QChar c;
++    for (uint i = 0; i <= text.length(); i++) {
++        if (i < text.length()) {
++            c = text[i];
++        } else {
++            // all chars of text have been handled already ->
++            // perform this last run to spool current content of "word"
++            c = returnChar; 
++        }
++        if (c == returnChar || c.isSpace()) {
++            // new word delimiter found -> its time to decide on word wrap
++            testCombineLine = fullLine + " " + word;
++            int textWidth = fm.width( testCombineLine );
++            if (textX + textWidth > width) {
++                // combination of "fullLine" and "word" doesn't fit into one line ->
++                // print "fullLine" in current line, update write position to next line
++                // and decide then on following actions
++                p->drawText(offsetX + textX, offsetY + textY,
++                            textWidth, fontHeight, Qt::AlignLeft, fullLine );
++                fullLine = word;
++                word = "";
++                // update write position
++                textX = margin;
++                textY += fontHeight;
++                if (textY > height)
++                    return;
++                // in case of c==newline ->
++                // print "word" and set write position one additional line lower
++                if (c == returnChar) {
++                    // print "word" - which is now "fullLine" and set to next line
++                    p->drawText(offsetX + textX, offsetY + textY,
++                                textWidth, fontHeight, Qt::AlignLeft, fullLine);
++                    fullLine = "";
+                     textX = margin;
+                     textY += fontHeight;
+-                    if( textY > height )
+-                        return;
+-                    p->drawText( offsetX + textX, offsetY + textY , textWidth, fontHeight, Qt::AlignLeft, word );
+-                }//end if
+-                else
+-                {
+-                    if ( textY > height )
+-                        return;
+-                    p->drawText( offsetX + textX, offsetY + textY , textWidth, fontHeight, Qt::AlignLeft, word );
++                    if( textY > height ) return;
+                 }
+-            }//end if
+-            textX = margin;
+-            textY += fontHeight;
+-            word = "";
+-        } else if( c.isSpace() ) {
+-            if( word.length() > 0 ) {
+-                int textWidth = fm.width( word );
+-                if( ( textX + textWidth ) > width )//wrap word
+-                {
+-                    textWidth = textWidth < width ? textWidth: width;
+-                    if( textX != margin )
+-                        textY += fontHeight;
+-                    textX = margin;
+-                    if( textY > height )
+-                        return;
+-                    p->drawText( offsetX + textX, offsetY + textY , textWidth, fontHeight, Qt::AlignLeft, word );
+-                }//end if
+-                else
+-                {
+-                    if ( textY > height )
+-                        return;
+-                    p->drawText( offsetX + textX, offsetY + textY , textWidth, fontHeight, Qt::AlignLeft, word );
+-                }
+-                textX += textWidth;
+-            }//end if
+-            textX += fm.width( " " );
+-            word = "";
++            }
++            else if ( c == returnChar ) {
++                // newline found and combination of "fullLine" and "word" fits
++                // in one line
++                p->drawText(offsetX + textX, offsetY + textY,
++                            textWidth, fontHeight, Qt::AlignLeft, testCombineLine);
++                fullLine = word = "";
++                textX = margin;
++                textY += fontHeight;
++                if (textY > height)
++                    return;
++            } else {
++                // word delimiter found, and combination of "fullLine", space and "word" fits into one line
++                fullLine = testCombineLine;
++                word = "";
++            }
+         } else {
+-            if (c!='\0') word += c;
++            // no word delimiter found --> add current char to "word"
++            if (c != '\0')
++                word += c;
+         }
+-    }//end while
+-    if( word.length() > 0 ) {
+-        const int textWidth = fm.width( word );
+-        if( ( textWidth + textX ) > width )//wrap word
+-        {
+-            textX = margin;
+-            textY += fontHeight;
+-            if( textY > height )
+-                return;
+-            p->drawText( offsetX + textX, offsetY + textY , textWidth, fontHeight, Qt::AlignLeft, word );
+-        }//end if
+-        else
+-        {
+-            if ( textY > height )
+-                return;
+-            p->drawText( offsetX + textX, offsetY + textY , textWidth, fontHeight, Qt::AlignLeft, word );
+-        }
+-    }//end if
++    }//end for
+ #endif
+ }
+ 
+--- umbrello/umbrello/enum.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/enum.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -147,23 +147,13 @@
+     return m_List.count();
+ }
+ 
+-UMLEnumLiteral* UMLEnum::takeEnumLiteral(UMLEnumLiteral* el, int *wasAtIndex) {
+-    int index = m_List.findRef( el );
+-    if (wasAtIndex)
+-        *wasAtIndex = index;
+-    el = (index == -1 ? 0 : dynamic_cast<UMLEnumLiteral*>(m_List.take( )));
+-    if (el) {
+-        emit enumLiteralRemoved(el);
+-        emit modified();
+-    }
+-    return el;
+-}
+-
+-
+ int UMLEnum::enumLiterals() {
+     return m_List.count();
+ }
+ 
++void UMLEnum::signalEnumLiteralRemoved(UMLClassifierListItem *elit) {
++    emit enumLiteralRemoved(elit);
++}
+ 
+ void UMLEnum::saveToXMI(QDomDocument& qDoc, QDomElement& qElement) {
+     QDomElement enumElement = UMLObject::save("UML:Enumeration", qDoc);
+--- umbrello/umbrello/classifier.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/classifier.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -128,18 +128,6 @@
+     int removeAttribute(UMLAttribute *a);
+ 
+     /**
+-     * Take and return an attribute from class.
+-     * It is the callers responsibility to pass on ownership of
+-     * the returned attribute (or to delete the attribute)
+-     *
+-     * @param  a                attribute to take
+-     * @param wasAtIndex        if given, the index in m_List of the item taken
+-     *                  is returned in the int pointed-to.
+-     * @return  pointer to the attribute or null if not found.
+-     */
+-    UMLAttribute* takeAttribute(UMLAttribute* a, int *wasAtIndex = NULL);
+-
+-    /**
+      * Returns the number of attributes for the class.
+      *
+      * @return  The number of attributes for the class.
+@@ -231,18 +219,6 @@
+     int removeOperation(UMLOperation *op);
+ 
+     /**
+-     * Take and return an operation from class.
+-     * It is the callers responsibility to pass on ownership of
+-     * the returned operation (or to delete the operation)
+-     *
+-     * @param  o operation to take
+-     * @param wasAtIndex        if given, the index in m_List of the item taken
+-     *                  is returned in the int pointed-to.
+-     * @return pointer to the operation or null if not found.
+-     */
+-    UMLOperation* takeOperation(UMLOperation* o, int *wasAtIndex = NULL);
+-
+-    /**
+      * counts the number of operations in the Classifier.
+      *
+      * @return  The number of operations for the Classifier.
+@@ -306,18 +282,6 @@
+     int removeTemplate(UMLTemplate* umltemplate);
+ 
+     /**
+-     * Take and return a template parameter from class.
+-     * It is the callers responsibility to pass on ownership of
+-     * the returned template (or to delete the template)
+-     *
+-     * @param t         template to take
+-     * @param wasAtIndex        if given, the index in m_List of the item taken
+-     *                  is returned in the int pointed-to.
+-     * @return  pointer to the template or null if not found.
+-     */
+-    UMLTemplate* takeTemplate(UMLTemplate* t, int *wasAtIndex = NULL);
+-
+-    /**
+      * Seeks the template parameter of the given name.
+      */
+     UMLTemplate *findTemplate(QString name);
+@@ -338,6 +302,15 @@
+      */
+     UMLTemplateList getTemplateList();
+ 
++    /**
++     * Take and return a subordinate item from this classifier.
++     * Ownership of the item is passed to the caller.
++     *
++     * @param item    Subordinate item to take.
++     * @return        Index in m_List of the item taken.
++     *                Return -1 if the item is not found in m_List.
++     */
++    int takeItem(UMLClassifierListItem* item);
+ 
+     /**
+      * Returns the entries in m_List that are of the requested type.
+--- umbrello/umbrello/umllistview.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/umbrello/umllistview.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -674,6 +674,12 @@
+ }
+ 
+ void UMLListView::slotObjectCreated(UMLObject* object) {
++    if (m_bCreatingChildObject) {
++        // @todo eliminate futile signal traffic
++        // e.g. we get here thru various indirections from
++        // ClassifierListPage::slot{Up,Down}Clicked()
++        return;
++    }
+     UMLListViewItem* newItem = findUMLObject(object);
+     if (newItem) {
+         kdDebug() << "UMLListView::slotObjectCreated(" << object->getName()
+@@ -1316,12 +1322,11 @@
+             UMLClassifier *newParentClassifier = dynamic_cast<UMLClassifier*>(newParentObj);
+             if (srcType == Uml::lvt_Attribute) {
+                 UMLAttribute *att = dynamic_cast<UMLAttribute*>(srcObj);
+-                att = oldParentClassifier->takeAttribute(att);
+                 // We can't use the existing 'att' directly
+                 // because its parent is fixed to the old classifier
+                 // and we have no way of changing that:
+                 // QObject does not permit changing the parent().
+-                if (att) {
++                if (att && oldParentClassifier->takeItem(att) != -1) {
+                     UMLAttribute *newAtt = static_cast<UMLAttribute*>(
+                                                newParentClassifier->createAttribute(
+                                                    att->getName()));
+@@ -1335,17 +1340,16 @@
+                     delete att;
+ 
+                 } else {
+-                    kdError() << "moveObject: oldParentClassifier->takeAttribute returns NULL"
++                    kdError() << "moveObject: oldParentClassifier->takeItem(att) returns NULL"
+                     << endl;
+                 }
+             } else {
+                 UMLOperation *op = dynamic_cast<UMLOperation*>(srcObj);
+-                op = oldParentClassifier->takeOperation(op);
+                 // We can't use the existing 'op' directly
+                 // because its parent is fixed to the old classifier
+                 // and we have no way of changing that:
+                 // QObject does not permit changing the parent().
+-                if (op) {
++                if (op && oldParentClassifier->takeItem(op) != -1) {
+                     bool isExistingOp;
+                     Model_Utils::NameAndType_List ntDummyList;
+                     // We need to provide a dummy NameAndType_List
+@@ -1371,7 +1375,7 @@
+                     UMLApp::app()->getDocWindow()->showDocumentation(newOp, true);
+                     delete op;
+                 } else {
+-                    kdError() << "moveObject: oldParentClassifier->takeOperation returns NULL"
++                    kdError() << "moveObject: oldParentClassifier->takeItem(op) returns NULL"
+                     << endl;
+                 }
+             }
+@@ -2448,11 +2452,12 @@
+         }
+         bool isExistingOp = false;
+         newObject = owningClassifier->createOperation(od.m_name, &isExistingOp, &od.m_args);
+-        if (isExistingOp) {
+-            KMessageBox::error(
+-                kapp -> mainWidget(),
+-                i18n( "The name you entered was not unique!\nCreation process has been canceled." ),
+-                i18n( "Name Not Unique" ) );
++        if (newObject == NULL || isExistingOp) {
++            if (isExistingOp)
++                KMessageBox::error(
++                    kapp -> mainWidget(),
++                    i18n( "The name you entered was not unique!\nCreation process has been canceled." ),
++                    i18n( "Name Not Unique" ) );
+             delete item;
+             m_bCreatingChildObject = false;
+             return false;
+@@ -2471,6 +2476,7 @@
+ 
+     item->setUMLObject( newObject );
+     item->setText( text );
++    ensureItemVisible(item);
+     m_bCreatingChildObject = false;
+ 
+     //m_doc->setModified();
+--- umbrello/ChangeLog	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ umbrello/ChangeLog	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1,3 +1,10 @@
++Version 1.5.2
++
++* fix problem reordering methods in classes/interfaces (http://bugs.debian.org/348940,
++  http://bugs.kde.org/119991)
++* Bugs/wishes from http://bugs.kde.org:
++* Multiplicity labels positioned incorrectly when moving entities (120598)
++
+ Version 1.5.1
+ 
+ * fix loading of associationwidget with non-default color
+--- scripts/fixfsfaddr.sed	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ scripts/fixfsfaddr.sed	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -17,6 +17,7 @@
+ s/59 Temple Place,/51 Franklin Street,/
+ s/59 Temple Place -/51 Franklin Street,/
+ s/Suite 330,/Fifth Floor,/
++s/Suite 330$/Fifth Floor/
+ s/02111-1307/02110-1301/
+ 
+ # Very old address: 675 Mass Ave, Cambridge, MA  02139
+@@ -24,5 +25,6 @@
+ s/Cambridge/Boston/
+ s/02139/02110-1301/
+ # Warning: the last two replaces seem to match the address of the MIT too.
++
+ # Typo in KDE: Franklin Steet
+ s/Franklin Steet/Franklin Street/
+--- kunittest/dcopinterface.h	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kunittest/dcopinterface.h	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -30,9 +30,8 @@
+        K_DCOP
+ 
+     k_dcop:
+-        virtual bool addDebugInfo(const QString &name, const QString &info) = 0L;
+-        virtual bool addSlotDebugInfo(const QString &name, const QString &slt, const QString &info) = 0L;
+-    
++        virtual bool addDebugInfo(const QString &name, const QString &info) = 0;
++        virtual bool addSlotDebugInfo(const QString &name, const QString &slt, const QString &info) = 0;
+     };
+ }
+ 
+--- kdeaccounts-plugin/kdeaccountsplugin.desktop	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kdeaccounts-plugin/kdeaccountsplugin.desktop	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1,6 +1,7 @@
+ [Misc]
+ Encoding=UTF-8
+ Name=KDE Repository Accounts
++Name[ca]=Comptes del repositori de KDE
+ Name[cs]=Účty z KDE repository
+ Name[da]=KDE lager-konti
+ Name[de]=KDE Repositorium-Zugänge
+--- kcachegrind/kcachegrind/partview.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kcachegrind/kcachegrind/partview.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -115,7 +115,9 @@
+   addGoMenu(&popup);
+ 
+   int r = popup.exec(pos);
+-  if (r == 95) ;
++  if (r == 95) {
++    ;
++  }
+ 
+   // TODO: ...
+ }
+--- kcachegrind/kcachegrind/x-kcachegrind.desktop	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kcachegrind/kcachegrind/x-kcachegrind.desktop	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1,7 +1,7 @@
+ [Desktop Entry]
+ Encoding=UTF-8
+ Comment=Cachegrind/Callgrind Profile Dump
+-Comment[ca]=Resultat de l'anàlisis de Cachegrind/Callgring
++Comment[ca]=Resultat del anàlisis de Cachegrind/Callgring
+ Comment[cs]=Data profilace Cachegrind/Callgrind
+ Comment[cy]=Tomen Proffil Cachegrind/Callgrind
+ Comment[da]=Cachegrind/Callgrind profile-dump
+--- kcachegrind/kcachegrind/callgraphview.cpp	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kcachegrind/kcachegrind/callgraphview.cpp	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -2563,15 +2563,12 @@
+ 	  TraceFunction* f = activeFunction();
+ 	  if (!f) break;
+ 
+-	  QString n = QString("callgraph");
+ 	  GraphExporter ge(data(), f, costType(), groupType(),
+-			   QString("%1.dot").arg(n));
++			   QString("callgraph.dot"));
+ 	  ge.setGraphOptions(this);
+ 	  ge.writeDot();
+ 
+-	  QString cmd = QString("(dot %1.dot -Tps > %2.ps; kghostview %3.ps)&")
+-	      .arg(n).arg(n).arg(n);
+-	  system(cmd.ascii());
++	  system("(dot callgraph.dot -Tps > callgraph.ps; kghostview callgraph.ps)&");
+       }
+       break;
+ 
+--- cervisia/eventsrc	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ cervisia/eventsrc	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -5,6 +5,7 @@
+ [cvs_commit_done]
+ Name=CVS commit job done
+ Name[bg]=Предаването в CVS е готово
++Name[ca]=Entrega al CVS completada
+ Name[cs]=CVS commit úloha dokončena
+ Name[da]=CVS-indsending udført
+ Name[de]=CVS-Einspielvorgang ausgeführt
+@@ -35,6 +36,7 @@
+ Name[zh_CN]=CVS 提交任务已完成
+ Comment=A CVS commit job is done
+ Comment[bg]=Предаването в CVS е готово
++Comment[ca]=S'ha completat una entrega al CVS
+ Comment[cs]=CVS commit úloha je dokončena
+ Comment[da]=En CVS-indsending er udført
+ Comment[de]=Ein CVS-Einspielvorgang wurde ausgeführt
+--- kbugbuster/kresources/bugzilla.desktop	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kbugbuster/kresources/bugzilla.desktop	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -1,6 +1,7 @@
+ [Desktop Entry]
+ Encoding=UTF-8
+ Name=Bugzilla To-do List
++Name[ca]=Llista de pendents de Bugzilla
+ Name[cs]=Seznam úkolů (Bugzilla)
+ Name[da]=Bugzilla gøremålsliste
+ Name[de]=Bugzilla Todo-Liste
+--- kioslave/svn/svnhelper/subversion_toplevel.desktop	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kioslave/svn/svnhelper/subversion_toplevel.desktop	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -8,6 +8,7 @@
+ [Desktop Action Update]
+ Name=SVN Update
+ Name[bg]=Обновяване SVN
++Name[ca]=Actualitza SVN
+ Name[cs]=SVN update
+ Name[da]=SVN Opdatér
+ Name[de]=Aktualisieren (SVN)
+@@ -16,6 +17,7 @@
+ Name[et]=SVN uuendamine
+ Name[eu]=SVN eguneratu
+ Name[fr]=Mise à jour SVN
++Name[he]=עדכון SVN
+ Name[hu]=SVN frissítés
+ Name[is]=Uppfæra SVN
+ Name[it]=Aggiornamento SVN
+@@ -39,6 +41,7 @@
+ [Desktop Action Commit]
+ Name=SVN Commit
+ Name[bg]=Предаване SVN
++Name[ca]=Entrega SVN
+ Name[cs]=SVN commit
+ Name[de]=Einspielen (SVN)
+ Name[el]=Καταχώρηση SVN
+@@ -46,6 +49,7 @@
+ Name[et]=SVN sissekanne
+ Name[eu]=SVN entregatu
+ Name[fr]=Validation SVN
++Name[he]=שליחת שינויים של ה־SVN
+ Name[hu]=SVN eltárolás
+ Name[is]=Setja inn í SVN
+ Name[it]=Deposito SVN
+--- kioslave/svn/svnhelper/subversion.desktop	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kioslave/svn/svnhelper/subversion.desktop	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -11,6 +11,7 @@
+ Name=Add to Repository
+ Name[bg]=Добавяне в хранилището
+ Name[br]=Ouzhpennañ d'an daveiñ
++Name[ca]=Afegeix al repositori
+ Name[cs]=Přidat do repository
+ Name[da]=Tilføj til lager
+ Name[de]=Zum SVN-Archiv hinzufügen
+@@ -46,6 +47,7 @@
+ Name=Delete From Repository
+ Name[bg]=Изтриване от хранилището
+ Name[br]=Lemel eus an daveiñ
++Name[ca]=Elimina del repositori
+ Name[cs]=Smazat z repository
+ Name[da]=Slet fra lager
+ Name[de]=Aus dem SVN-Archiv löschen
+@@ -79,6 +81,7 @@
+ [Desktop Action Revert]
+ Name=Revert Local Changes
+ Name[bg]=Игнориране на локалните промени
++Name[ca]=Reverteix els canvis locals
+ Name[cs]=Vrátit místní změny
+ Name[da]=Vend lokale ændringer om
+ Name[de]=Lokale Änderungen zurücknehmen
+@@ -110,6 +113,7 @@
+ Exec=kio_svn_helper -r %U
+ Comment=Remove any changes made locally. Warning - this cannot be undone.
+ Comment[bg]=Премахване на локалните промени, които са направени. Забележете, че данните ще се загубят безвъзвратно.
++Comment[ca]=Elimina qualsevol canvi local. Avís: No es pot desfer.
+ Comment[cs]=Odstraní změny provedené lokálně; nelze vrátit, pozor.
+ Comment[da]=Fjern alle ændringer der er lavet lokalt. Advarsel - dette kan ikke fortrydes.
+ Comment[de]=Nimmt alle lokal durchgeführten Änderungen zurück. Warnung: Dieser Vorgang kann nicht rückgängig gemacht werden.
+@@ -140,6 +144,7 @@
+ Name=Rename...
+ Name[bg]=Преименуване...
+ Name[br]=Adenvel ...
++Name[ca]=Renomena...
+ Name[cs]=Přejmenovat...
+ Name[cy]=Ail-enwi...
+ Name[da]=Omdøb...
+@@ -173,6 +178,7 @@
+ Exec=kio_svn_helper -r %U
+ Comment=Rename a file locally and in the repository.  Use this rather than adding and deleting to rename a file.
+ Comment[bg]=Преименуване на файл локално и в хранилището. За предпочитане е да използвате този метод, вместо изтриване и добавяне.
++Comment[ca]=Renomena un fitxer localment i en el repositori. Use-ho en comptes d'afegir i eliminar per a renomenar un fitxer.
+ Comment[cs]=Přejmenovat soubor lokálně a v repository. Použijte raději než přidání a smazání souboru k docílení jeho přejmenování.
+ Comment[da]=Omdøb en fil lokalt og i lageret. Brug dette i stedet for at tilføje og slette fro at omdøbe en fil.
+ Comment[de]=Benennt eine Datei lokal und im SVN-Archiv um. Verwenden Sie besser diese Funktion zum Umbenennen einer Datei als Hinzufügen und Löschen.
+@@ -202,6 +208,7 @@
+ Name=Import Repository
+ Name[bg]=Импорт на директория
+ Name[br]=Enporzh an daveiñ
++Name[ca]=Importa repositori
+ Name[cs]=Importovat repository
+ Name[da]=Importér lager
+ Name[de]=SVN-Archiv importieren
+@@ -232,6 +239,7 @@
+ Exec=kio_svn_helper -i %U
+ Comment=Put folder into an existing repository to put it under revision control.
+ Comment[bg]=Импорт на директория в съществуващо хранилище.
++Comment[ca]=Situa la carpeta en un repositori existent per a posar-la sota el control de revisions.
+ Comment[cs]=Zařadit složku do repository a správy verzí
+ Comment[da]=Put mappe ind i et eksisterende lager for at få den ind under revisionskontrol.
+ Comment[de]=Schiebt den Ordner in ein existierendes SVN-Archiv, um ihn in die Versionsverwaltung aufzunehmen.
+@@ -261,6 +269,7 @@
+ [Desktop Action Checkout]
+ Name=Checkout From Repository...
+ Name[bg]=Изтегляне от хранилището...
++Name[ca]=Obtenir del repositori...
+ Name[cs]=Získat z repository...
+ Name[da]=Tjek ud fra lager...
+ Name[de]=Aus SVN-Archiv herausholen ...
+@@ -291,6 +300,7 @@
+ Exec=kio_svn_helper -C %U
+ Comment=Checkout out files from an existing repository into this folder.
+ Comment[bg]=Изтегляне на файлове от хранилището в текущата директория.
++Comment[ca]=Obté fitxers des d'un repositori existent cap aquesta carpeta.
+ Comment[cs]=Získat soubory z existující repository do této složky.
+ Comment[da]=Tjek filer ud fra et eksisterende lager til denne mappe.
+ Comment[de]=Legt Dateien aus einem existierenden SVN-Archiv in diesem Ordner ab.
+@@ -321,6 +331,7 @@
+ Name=Switch...
+ Name[bg]=Превключване...
+ Name[br]=Gwintañ ...
++Name[ca]=Canvia...
+ Name[cs]=Přepnout...
+ Name[de]=Wechseln (switch)
+ Name[el]=Εναλλαγή...
+@@ -328,6 +339,7 @@
+ Name[et]=Lülitumine...
+ Name[eu]=Aldatu...
+ Name[fr]=Basculer...
++Name[he]=החלף...
+ Name[hu]=Váltás...
+ Name[is]=Skipta...
+ Name[it]=Passa...
+@@ -349,6 +361,7 @@
+ Icon=svn_switch
+ Comment=Switch given working copy to another branch
+ Comment[bg]=Превключване на работното копие към друго разклонение.
++Comment[ca]=Canvia una còpia de treball indicada a una altra branca
+ Comment[cs]=Přepnout danou pracovní kopii na jinou větev
+ Comment[da]=Skift given arbejdskopi til en anden gren.
+ Comment[de]=Wechselt von der vorhandenen Arbeitskopie zu einer anderen Verzweigung (branch).
+@@ -379,6 +392,7 @@
+ [Desktop Action Merge]
+ Name=Merge...
+ Name[bg]=Смесване...
++Name[ca]=Fusiona...
+ Name[cs]=Sloučit...
+ Name[da]=Indflet...
+ Name[de]=Zusammenführen ...
+@@ -388,6 +402,7 @@
+ Name[eu]=Bateratu...
+ Name[fr]=Fusionner...
+ Name[ga]=Cumaisc...
++Name[he]=מזג...
+ Name[hu]=Összeolvasztás...
+ Name[is]=Bræða saman...
+ Name[it]=Fondi...
+@@ -409,6 +424,7 @@
+ Icon=svn_merge
+ Comment=Merge changes between this and another branch
+ Comment[bg]=Смесване на промените от това разклонение с друго разклонение.
++Comment[ca]=Fusiona els canvis entre aquesta i una altra branca
+ Comment[cs]=Sloučit změny mezi touto a jinou větví
+ Comment[da]=Indflet ændringer mellem denne og en anden gren
+ Comment[de]=Führt Änderungen aus dieser und einer anderen Verzweigung zusammen
+@@ -439,6 +455,7 @@
+ [Desktop Action Blame]
+ Name=Blame...
+ Name[bg]=Информация...
++Name[ca]=Responsabilitza...
+ Name[cs]=Obvinit...
+ Name[de]=Blame ...
+ Name[el]=Συσχέτιση...
+@@ -446,6 +463,7 @@
+ Name[et]=Autorsus...
+ Name[eu]=Erruduna...
+ Name[fr]=Blâmer...
++Name[he]=האשם...
+ Name[hu]=Ki tette ezt...
+ Name[is]=Kenna um...
+ Name[it]=Traccia...
+@@ -466,6 +484,7 @@
+ Icon=svn_blame
+ Comment=See who wrote each line of the file and in what revision
+ Comment[bg]=Информация за файла.
++Comment[ca]=Veu qui va escriure cada línia del fitxer i en qui l'ha revisat
+ Comment[cs]=Zobrazit, kdo napsal kterou řádku souboru spolu s revizí
+ Comment[da]=Se hvem der skrev hver linje i filen og i hvilken revision
+ Comment[de]=Zeigt an, wer die Zeilen einer Datei wann geändert hat.
+@@ -495,6 +514,7 @@
+ [Desktop Action CreatePatch]
+ Name=Create Patch...
+ Name[bg]=Създаване на кръпка...
++Name[ca]=Crea pedaç...
+ Name[cs]=Vytvořit záplatu...
+ Name[da]=Lav rettelse...
+ Name[de]=Patch erstellen ...
+@@ -503,6 +523,7 @@
+ Name[et]=Paiga loomine...
+ Name[eu]=Sortu adabakia...
+ Name[fr]=Créer un correctif...
++Name[he]=צור טלאי...
+ Name[hu]=Folt készítése...
+ Name[is]=Búa til plástur...
+ Name[it]=Crea correzione...
+@@ -527,6 +548,7 @@
+ Name=Export...
+ Name[bg]=Експорт...
+ Name[br]=Ezporzh ...
++Name[ca]=Exporta...
+ Name[cs]=Exportovat...
+ Name[cy]=Allforio...
+ Name[da]=Eksportér...
+@@ -537,6 +559,7 @@
+ Name[eu]=Esportatu...
+ Name[fr]=Exporter...
+ Name[ga]=Easpórtáil...
++Name[he]=ייצא....
+ Name[hu]=Exportálás...
+ Name[is]=Flytja út...
+ Name[it]=Esporta...
+@@ -559,6 +582,7 @@
+ Exec=kio_svn_helper -e %U
+ Comment=Checkout out an unversioned copy of a tree from a repository
+ Comment[bg]=Изтегляне на копие на дървото от хранилището.
++Comment[ca]=Exporta una còpia sense versió d'un arbre del repositori
+ Comment[cs]=Získat z repository kopii stromu bez verze
+ Comment[da]=Tjek en kopi uden version ud af et træ fra et lager
+ Comment[de]=Herausholen eines Baums aus dem SVN-Archiv ohne Versionsinformationen
+@@ -597,6 +621,7 @@
+ Name[eu]=Desberdintasunak (lokala)
+ Name[fr]=Différences (locales)
+ Name[ga]=Diff (logánta)
++Name[he]=Diff (מקומי)
+ Name[hu]=Diff (helyi)
+ Name[is]=Bera saman (staðbundið)
+ Name[it]=Differenza (locale)
+@@ -619,6 +644,7 @@
+ Exec=kio_svn_helper -D %U
+ Comment=Show local changes since last update
+ Comment[bg]=Показване на локалните промени след последното обновяване.
++Comment[ca]=Mostra els canvis locals des de l'última actualització
+ Comment[cs]=Zobrazit lokální změny od poslední aktualizace
+ Comment[da]=Vis lokale ændringer siden sidste opdatering
+ Comment[de]=Zeigt die lokal durchgeführten Änderungen seit der letzten Aktualisierung
+--- kioslave/svn/svnhelper/apply_patch.desktop	(.../tags/KDE/3.5.1/kdesdk)	(revision 504925)
++++ kioslave/svn/svnhelper/apply_patch.desktop	(.../branches/KDE/3.5/kdesdk)	(revision 504925)
+@@ -7,6 +7,7 @@
+ [Desktop Action Apply]
+ Name=Apply Patch...
+ Name[bg]=Прилагане на кръпка...
++Name[ca]=Aplica pedaç...
+ Name[cs]=Aplikovat záplatu...
+ Name[da]=Anvend rettelse...
+ Name[de]=Patch einspielen ...
+@@ -39,6 +40,7 @@
+ Exec=
+ Comment=Apply the patch to another folder/file
+ Comment[bg]=Прилагане на кръпка към друга директория/файл.
++Comment[ca]=Aplica el pedaç a una altra carpeta o fitxer
+ Comment[cs]=Aplikovat záplatu na jiný soubor/složku
+ Comment[da]=Anvend rettelsen på en anden mappe/fil
+ Comment[de]=Spielt den Patch in einen/eine andere(n) Ordner/Datei ein




More information about the pkg-kde-commits mailing list