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