You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
385 lines
6.3 KiB
385 lines
6.3 KiB
/* 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"
|
|
|