summaryrefslogtreecommitdiffstats
path: root/karbon/commands/vcommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'karbon/commands/vcommand.cpp')
-rw-r--r--karbon/commands/vcommand.cpp384
1 files changed, 384 insertions, 0 deletions
diff --git a/karbon/commands/vcommand.cpp b/karbon/commands/vcommand.cpp
new file mode 100644
index 000000000..fe5e9adaf
--- /dev/null
+++ b/karbon/commands/vcommand.cpp
@@ -0,0 +1,384 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001, The Karbon Developers
+ Copyright (C) 2002, The Karbon Developers
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+
+#include "tdeaction.h"
+#include "tdelocale.h"
+
+#include "vcommand.h"
+#include "karbon_part.h"
+
+
+VCommandHistory::VCommandHistory( KarbonPart* part )
+ : m_part( part ), m_undoLimit( 50 ), m_redoLimit( 30 ), m_savedPos( 0 )
+{
+ m_commands.setAutoDelete( true );
+
+ m_undo = KStdAction::undo( this, TQT_SLOT( undo() ), m_part->actionCollection(), "koffice_undo" );
+ m_redo = KStdAction::redo( this, TQT_SLOT( redo() ), m_part->actionCollection(), "koffice_redo" );
+
+ clear();
+}
+
+VCommandHistory::~VCommandHistory()
+{
+}
+
+void
+VCommandHistory::clear()
+{
+ if( m_savedPos != int( m_commands.count() - 1 ) )
+ m_savedPos = -1;
+ else
+ m_savedPos = 0;
+
+ m_commands.clear();
+
+ emit historyCleared();
+
+ if( m_undo != 0 )
+ {
+ m_undo->setEnabled( false );
+ m_undo->setText( i18n( "&Undo" ) );
+ }
+
+ if( m_redo != 0 )
+ {
+ m_redo->setEnabled( false );
+ m_redo->setText( i18n( "&Redo" ) );
+ }
+}
+
+void
+VCommandHistory::addCommand( VCommand* command, bool execute )
+{
+ if( command == 0L )
+ return;
+
+ if( !m_commands.isEmpty() )
+ {
+ while( m_commands.last() && !m_commands.last()->success() )
+ {
+ m_commands.removeLast();
+ emit lastCommandRemoved();
+ }
+ }
+
+ m_commands.append( command );
+ kdDebug(38000) << "History: new command: " << m_commands.findRef( command ) << endl;
+
+ if( execute )
+ {
+ command->execute();
+ emit commandExecuted( command );
+ }
+
+ updateActions();
+
+ emit commandAdded( command );
+}
+
+void
+VCommandHistory::setUndoLimit( unsigned int limit )
+{
+ m_undoLimit = limit;
+ clipCommands();
+}
+
+void
+VCommandHistory::setRedoLimit( unsigned int limit )
+{
+ m_redoLimit = limit;
+ clipCommands();
+}
+
+void
+VCommandHistory::undo()
+{
+ int i = m_commands.count() - 1;
+
+ if( i == -1 )
+ return;
+
+ while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
+ {
+ i--;
+ }
+
+ if( i < 0 )
+ return;
+
+ VCommand* cmd = m_commands.at( i );
+
+ cmd->unexecute();
+
+ emit commandExecuted( cmd );
+
+ emit commandExecuted();
+
+ clipCommands();
+
+ updateActions();
+
+ m_part->repaintAllViews();
+}
+
+void
+VCommandHistory::redo()
+{
+ int i = m_commands.count() - 1;
+
+ if( i == -1 )
+ return;
+
+ while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
+ {
+ i--;
+ }
+
+ i++;
+
+ if( i >= int( m_commands.count() ) )
+ return;
+
+ VCommand* cmd;
+
+ if( ( cmd = m_commands.at( i ) ) == 0L )
+ return;
+
+ cmd->execute();
+
+ emit commandExecuted( cmd );
+ emit commandExecuted();
+
+ updateActions();
+
+ m_part->repaintAllViews();
+}
+
+void
+VCommandHistory::undo( VCommand* command )
+{
+ if( ( m_commands.findRef( command ) == -1 ) || ( !command->success() ) )
+ return;
+
+ command->unexecute();
+
+ emit commandExecuted( command );
+ emit commandExecuted();
+
+ updateActions();
+
+ m_part->repaintAllViews();
+}
+
+void
+VCommandHistory::redo( VCommand* command )
+{
+ if( ( m_commands.findRef( command ) == -1 ) || ( command->success() ) )
+ return;
+
+ command->execute();
+
+ emit commandExecuted( command );
+ emit commandExecuted();
+
+ updateActions();
+
+ m_part->repaintAllViews();
+}
+
+void
+VCommandHistory::undoAllTo( VCommand* command )
+{
+ int to;
+
+ if( ( to = m_commands.findRef( command ) ) == -1 )
+ return;
+
+ int i = m_commands.count() - 1;
+
+ VCommand* cmd;
+
+ while( i > to )
+ {
+ cmd = m_commands.at( i-- );
+
+ if( cmd->success() )
+ {
+ cmd->unexecute();
+ emit commandExecuted( cmd );
+ }
+ }
+
+ emit commandExecuted();
+ updateActions();
+
+ m_part->repaintAllViews();
+}
+
+void
+VCommandHistory::redoAllTo( VCommand* command )
+{
+ int to;
+
+ if( ( to = m_commands.findRef( command ) ) == -1 )
+ return;
+
+ int i = 0;
+
+ VCommand* cmd;
+
+ while( i <= to )
+ {
+ cmd = m_commands.at( i++ );
+
+ if( !cmd->success() )
+ {
+ cmd->execute();
+ emit commandExecuted( cmd );
+ }
+ }
+
+ emit commandExecuted();
+ updateActions();
+
+ m_part->repaintAllViews();
+}
+
+void
+VCommandHistory::documentSaved()
+{
+ // I don't know how to make this work... This is a temporary hack...
+ // Maybe remove all undone commands before the current one ?
+ int i = m_commands.count() - 1;
+
+ while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
+ {
+ i--;
+ }
+
+ i++;
+
+ m_savedPos = i;
+}
+
+void
+VCommandHistory::clipCommands()
+{
+ while( m_commands.count() > m_undoLimit )
+ {
+ if( m_commands.removeFirst() )
+ m_savedPos--, emit firstCommandRemoved();
+ }
+
+ int i = 0;
+
+ int c = m_commands.count();
+
+ while( ( i < c ) && ( !m_commands.at( c - 1 - i )->success() ) )
+ {
+ i++;
+ }
+
+ i = i - m_redoLimit;
+
+ for( int j = 0; j < i; j++ )
+ {
+ if( m_commands.removeLast() )
+ emit lastCommandRemoved();
+ }
+}
+
+void
+VCommandHistory::updateActions()
+{
+ if( m_commands.count() == 0 )
+ {
+ if( m_undo != 0 )
+ {
+ m_undo->setEnabled( false );
+ m_undo->setText( i18n( "&Undo" ) );
+ }
+
+ if( m_redo != 0 )
+ {
+ m_redo->setEnabled( false );
+ m_redo->setText( i18n( "&Redo" ) );
+ }
+
+ return;
+ }
+
+ int i = m_commands.count() - 1;
+
+ while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
+ {
+ i--;
+ }
+
+ if( m_undo != 0 )
+ {
+ if( i < 0 )
+ {
+ m_undo->setEnabled( false );
+ m_undo->setText( i18n( "&Undo" ) );
+ }
+ else
+ {
+ m_undo->setEnabled( true );
+ m_undo->setText( i18n( "&Undo: " ) + m_commands.at( i )->name() );
+ }
+ }
+
+ if( m_redo != 0 )
+ {
+ if( ++i == int( m_commands.count() ) )
+ {
+ m_redo->setEnabled( false );
+ m_redo->setText( i18n( "&Redo" ) );
+ }
+ else
+ {
+ m_redo->setEnabled( true );
+ m_redo->setText( i18n( "&Redo: " ) + m_commands.at( i )->name() );
+ }
+ }
+
+ if( m_savedPos >= 0 )
+ {
+ for( i = 0; i < m_savedPos; i++ )
+ {
+ if( !m_commands.at( i )->success() )
+ return;
+ }
+
+ for( i = m_savedPos; i < int( m_commands.count() ); i++ )
+ {
+ if( m_commands.at( i )->success() )
+ return;
+ }
+
+ emit documentRestored();
+ }
+}
+
+#include "vcommand.moc"
+