summaryrefslogtreecommitdiffstats
path: root/kpovmodeler/pmaddcommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kpovmodeler/pmaddcommand.cpp')
-rw-r--r--kpovmodeler/pmaddcommand.cpp233
1 files changed, 233 insertions, 0 deletions
diff --git a/kpovmodeler/pmaddcommand.cpp b/kpovmodeler/pmaddcommand.cpp
new file mode 100644
index 00000000..b8d4ea49
--- /dev/null
+++ b/kpovmodeler/pmaddcommand.cpp
@@ -0,0 +1,233 @@
+/*
+**************************************************************************
+ description
+ --------------------
+ copyright : (C) 2000-2001 by Andreas Zehender
+ email : zehender@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 *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+**************************************************************************/
+
+
+#include "pmaddcommand.h"
+#include "pmcommandmanager.h"
+#include "pmpart.h"
+#include "pmdeclare.h"
+#include "pmerrorflags.h"
+#include "pmrecursiveobjectiterator.h"
+#include "pmmemento.h"
+
+#include <klocale.h>
+
+PMAddCommand::PMAddCommand( PMObject* obj, PMObject* parent, PMObject* after )
+ : PMCommand( i18n( "Add New %1" ).arg( obj->description( ) ) )
+{
+ m_objects.append( obj );
+ m_pParent = parent;
+ m_pAfter = after;
+ m_executed = false;
+ m_firstExecution = true;
+ m_linksCreated = false;
+ m_pParentChangeMemento = 0;
+}
+
+PMAddCommand::PMAddCommand( const PMObjectList& list, PMObject* parent,
+ PMObject* after )
+ : PMCommand( i18n( "Add Objects" ) )
+{
+ m_objects = list;
+ m_pParent = parent;
+ m_pAfter = after;
+ m_executed = false;
+ m_firstExecution = true;
+ m_linksCreated = false;
+ m_pParentChangeMemento = 0;
+}
+
+PMAddCommand::~PMAddCommand( )
+{
+ if( !m_executed )
+ {
+ m_objects.setAutoDelete( true );
+ m_objects.clear( );
+ }
+
+ m_insertErrors.setAutoDelete( true );
+ m_insertErrors.clear( );
+}
+
+void PMAddCommand::execute( PMCommandManager* theManager )
+{
+ if( !m_executed )
+ {
+ PMObjectListIterator it( m_objects );
+ PMObject* prev = m_pAfter;
+ PMObjectList errors;
+ PMObject* current;
+ bool error = false;
+
+ if( m_firstExecution )
+ if( m_pParent->dataChangeOnInsertRemove( ) )
+ m_pParent->createMemento( );
+
+ for( ; it.current( ); ++it )
+ {
+ current = it.current( );
+ if( !prev )
+ {
+ if( m_pParent->canInsert( current, 0 ) )
+ {
+ m_pParent->insertChild( current, 0 );
+ prev = current;
+ theManager->cmdObjectChanged( current, PMCAdd );
+ }
+ else
+ error = true;
+ }
+ else
+ {
+ if( m_pParent->canInsert( current, prev ) )
+ {
+ m_pParent->insertChildAfter( current, prev );
+ prev = current;
+ theManager->cmdObjectChanged( current, PMCAdd );
+ }
+ else
+ error = true;
+ }
+
+ if( error )
+ {
+ errors.append( current );
+ theManager->cmdObjectChanged( current, PMCAdd | PMCInsertError );
+ if( current->isA( "Declare" ) )
+ {
+ // the object, that couldn't be inserted was a declare,
+ // remove all links
+ PMObjectListIterator links =
+ ( ( PMDeclare* ) current )->linkedObjects( );
+ for( ; links.current( ); ++links )
+ {
+ PMObject* l = links.current( );
+ if( l->parent( ) )
+ l->parent( )->takeChild( l );
+ else
+ m_objects.removeRef( l );
+ m_insertErrors.append( l );
+ }
+ }
+ if( current->linkedObject( ) )
+ current->linkedObject( )->removeLinkedObject( current );
+ error = false;
+ }
+ }
+
+ if( m_pParent->mementoCreated( ) )
+ m_pParentChangeMemento = m_pParent->takeMemento( );
+
+ if( m_pParentChangeMemento )
+ {
+ PMObjectChangeListIterator c = m_pParentChangeMemento->changedObjects( );
+ for( ; c.current( ); ++c )
+ theManager->cmdObjectChanged( c.current( )->object( ),
+ c.current( )->mode( ) );
+ }
+
+ if( m_linksCreated )
+ {
+ PMObjectListIterator rit( m_links );
+ for( ; rit.current( ); ++rit )
+ rit.current( )->linkedObject( )->addLinkedObject( rit.current( ) );
+ PMObjectListIterator dit( m_linkedDeclares );
+ for( ; dit.current( ); ++dit )
+ theManager->cmdObjectChanged( dit.current( ), PMCData );
+ }
+
+ PMObjectListIterator errorit( errors );
+ for( ; errorit.current( ); ++errorit )
+ {
+ m_objects.removeRef( errorit.current( ) );
+ m_insertErrors.append( errorit.current( ) );
+
+ PMRecursiveObjectIterator lit( errorit.current( ) );
+ for( ; lit.current( ); ++lit )
+ if( lit.current( )->linkedObject( ) )
+ lit.current( )->linkedObject( )->removeLinkedObject( lit.current( ) );
+ }
+
+ m_executed = true;
+ m_firstExecution = false;
+ }
+}
+
+void PMAddCommand::undo( PMCommandManager* theManager )
+{
+ if( m_executed )
+ {
+ PMObjectListIterator it( m_objects );
+ PMObject* obj;
+ PMDeclare* decl;
+
+ if( !m_linksCreated )
+ {
+ for( ; it.current( ); ++it )
+ {
+ PMRecursiveObjectIterator lit( it.current( ) );
+ for( ; lit.current( ); ++lit )
+ {
+ decl = lit.current( )->linkedObject( );
+ if( decl )
+ {
+ m_links.append( lit.current( ) );
+ if( !m_linkedDeclares.containsRef( decl ) )
+ m_linkedDeclares.append( decl );
+ }
+ }
+ }
+ m_linksCreated = true;
+ }
+
+ PMObjectListIterator rit( m_links );
+ for( ; rit.current( ); ++rit )
+ rit.current( )->linkedObject( )->removeLinkedObject( rit.current( ) );
+
+ for( it.toLast( ) ; it.current( ); --it )
+ {
+ obj = it.current( );
+ // signal has to be emitted before the item is removed
+ theManager->cmdObjectChanged( obj, PMCRemove );
+
+ if( obj->parent( ) )
+ obj->parent( )->takeChild( obj );
+ }
+
+ if( m_pParentChangeMemento )
+ {
+ m_pParent->restoreMemento( m_pParentChangeMemento );
+ PMObjectChangeListIterator c = m_pParentChangeMemento->changedObjects( );
+ for( ; c.current( ); ++c )
+ {
+ theManager->cmdObjectChanged( c.current( )->object( ),
+ c.current( )->mode( ) );
+ }
+ }
+
+ PMObjectListIterator dit( m_linkedDeclares );
+ for( ; dit.current( ); ++dit )
+ theManager->cmdObjectChanged( dit.current( ), PMCData );
+
+ m_executed = false;
+ }
+}
+
+int PMAddCommand::errorFlags( PMPart* )
+{
+ return PMENone;
+}