vcommand.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001, The Karbon Developers
3 Copyright (C) 2002, The Karbon Developers
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21
22#include "tdeaction.h"
23#include "tdelocale.h"
24
25#include "vcommand.h"
26#include "karbon_part.h"
27
28
30 : m_part( part ), m_undoLimit( 50 ), m_redoLimit( 30 ), m_savedPos( 0 )
31{
32 m_commands.setAutoDelete( true );
33
34 m_undo = KStdAction::undo( this, TQ_SLOT( undo() ), m_part->actionCollection(), "koffice_undo" );
35 m_redo = KStdAction::redo( this, TQ_SLOT( redo() ), m_part->actionCollection(), "koffice_redo" );
36
37 clear();
38}
39
43
44void
46{
47 if( m_savedPos != int( m_commands.count() - 1 ) )
48 m_savedPos = -1;
49 else
50 m_savedPos = 0;
51
52 m_commands.clear();
53
54 emit historyCleared();
55
56 if( m_undo != 0 )
57 {
58 m_undo->setEnabled( false );
59 m_undo->setText( i18n( "&Undo" ) );
60 }
61
62 if( m_redo != 0 )
63 {
64 m_redo->setEnabled( false );
65 m_redo->setText( i18n( "&Redo" ) );
66 }
67}
68
69void
70VCommandHistory::addCommand( VCommand* command, bool execute )
71{
72 if( command == 0L )
73 return;
74
75 if( !m_commands.isEmpty() )
76 {
77 while( m_commands.last() && !m_commands.last()->success() )
78 {
79 m_commands.removeLast();
80 emit lastCommandRemoved();
81 }
82 }
83
84 m_commands.append( command );
85 kdDebug(38000) << "History: new command: " << m_commands.findRef( command ) << endl;
86
87 if( execute )
88 {
89 command->execute();
90 emit commandExecuted( command );
91 }
92
93 updateActions();
94
95 emit commandAdded( command );
96}
97
98void
99VCommandHistory::setUndoLimit( unsigned int limit )
100{
101 m_undoLimit = limit;
102 clipCommands();
103}
104
105void
106VCommandHistory::setRedoLimit( unsigned int limit )
107{
108 m_redoLimit = limit;
109 clipCommands();
110}
111
112void
114{
115 int i = m_commands.count() - 1;
116
117 if( i == -1 )
118 return;
119
120 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
121 {
122 i--;
123 }
124
125 if( i < 0 )
126 return;
127
128 VCommand* cmd = m_commands.at( i );
129
130 cmd->unexecute();
131
132 emit commandExecuted( cmd );
133
134 emit commandExecuted();
135
136 clipCommands();
137
138 updateActions();
139
140 m_part->repaintAllViews();
141}
142
143void
145{
146 int i = m_commands.count() - 1;
147
148 if( i == -1 )
149 return;
150
151 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
152 {
153 i--;
154 }
155
156 i++;
157
158 if( i >= int( m_commands.count() ) )
159 return;
160
161 VCommand* cmd;
162
163 if( ( cmd = m_commands.at( i ) ) == 0L )
164 return;
165
166 cmd->execute();
167
168 emit commandExecuted( cmd );
169 emit commandExecuted();
170
171 updateActions();
172
173 m_part->repaintAllViews();
174}
175
176void
178{
179 if( ( m_commands.findRef( command ) == -1 ) || ( !command->success() ) )
180 return;
181
182 command->unexecute();
183
184 emit commandExecuted( command );
185 emit commandExecuted();
186
187 updateActions();
188
189 m_part->repaintAllViews();
190}
191
192void
194{
195 if( ( m_commands.findRef( command ) == -1 ) || ( command->success() ) )
196 return;
197
198 command->execute();
199
200 emit commandExecuted( command );
201 emit commandExecuted();
202
203 updateActions();
204
205 m_part->repaintAllViews();
206}
207
208void
210{
211 int to;
212
213 if( ( to = m_commands.findRef( command ) ) == -1 )
214 return;
215
216 int i = m_commands.count() - 1;
217
218 VCommand* cmd;
219
220 while( i > to )
221 {
222 cmd = m_commands.at( i-- );
223
224 if( cmd->success() )
225 {
226 cmd->unexecute();
227 emit commandExecuted( cmd );
228 }
229 }
230
231 emit commandExecuted();
232 updateActions();
233
234 m_part->repaintAllViews();
235}
236
237void
239{
240 int to;
241
242 if( ( to = m_commands.findRef( command ) ) == -1 )
243 return;
244
245 int i = 0;
246
247 VCommand* cmd;
248
249 while( i <= to )
250 {
251 cmd = m_commands.at( i++ );
252
253 if( !cmd->success() )
254 {
255 cmd->execute();
256 emit commandExecuted( cmd );
257 }
258 }
259
260 emit commandExecuted();
261 updateActions();
262
263 m_part->repaintAllViews();
264}
265
266void
268{
269 // I don't know how to make this work... This is a temporary hack...
270 // Maybe remove all undone commands before the current one ?
271 int i = m_commands.count() - 1;
272
273 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
274 {
275 i--;
276 }
277
278 i++;
279
280 m_savedPos = i;
281}
282
283void
284VCommandHistory::clipCommands()
285{
286 while( m_commands.count() > m_undoLimit )
287 {
288 if( m_commands.removeFirst() )
289 m_savedPos--, emit firstCommandRemoved();
290 }
291
292 int i = 0;
293
294 int c = m_commands.count();
295
296 while( ( i < c ) && ( !m_commands.at( c - 1 - i )->success() ) )
297 {
298 i++;
299 }
300
301 i = i - m_redoLimit;
302
303 for( int j = 0; j < i; j++ )
304 {
305 if( m_commands.removeLast() )
306 emit lastCommandRemoved();
307 }
308}
309
310void
311VCommandHistory::updateActions()
312{
313 if( m_commands.count() == 0 )
314 {
315 if( m_undo != 0 )
316 {
317 m_undo->setEnabled( false );
318 m_undo->setText( i18n( "&Undo" ) );
319 }
320
321 if( m_redo != 0 )
322 {
323 m_redo->setEnabled( false );
324 m_redo->setText( i18n( "&Redo" ) );
325 }
326
327 return;
328 }
329
330 int i = m_commands.count() - 1;
331
332 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
333 {
334 i--;
335 }
336
337 if( m_undo != 0 )
338 {
339 if( i < 0 )
340 {
341 m_undo->setEnabled( false );
342 m_undo->setText( i18n( "&Undo" ) );
343 }
344 else
345 {
346 m_undo->setEnabled( true );
347 m_undo->setText( i18n( "&Undo: " ) + m_commands.at( i )->name() );
348 }
349 }
350
351 if( m_redo != 0 )
352 {
353 if( ++i == int( m_commands.count() ) )
354 {
355 m_redo->setEnabled( false );
356 m_redo->setText( i18n( "&Redo" ) );
357 }
358 else
359 {
360 m_redo->setEnabled( true );
361 m_redo->setText( i18n( "&Redo: " ) + m_commands.at( i )->name() );
362 }
363 }
364
365 if( m_savedPos >= 0 )
366 {
367 for( i = 0; i < m_savedPos; i++ )
368 {
369 if( !m_commands.at( i )->success() )
370 return;
371 }
372
373 for( i = m_savedPos; i < int( m_commands.count() ); i++ )
374 {
375 if( m_commands.at( i )->success() )
376 return;
377 }
378
379 emit documentRestored();
380 }
381}
382
383#include "vcommand.moc"
384
Keeps track of visual per document properties.
Definition karbon_part.h:46
void repaintAllViews(bool repaint=true)
repaint all views attached to this koDocument
void historyCleared()
This signal is emitted when the command history gets cleared.
VCommandHistory(KarbonPart *part)
Constructs a command history.
Definition vcommand.cpp:29
void setUndoLimit(unsigned int limit)
Sets a new undo limit.
Definition vcommand.cpp:99
void documentRestored()
This signal is emitted when the actual document state matches the last saved one.
void clear()
Clears the command history by removing all commands.
Definition vcommand.cpp:45
void addCommand(VCommand *command, bool execute=true)
Adds a new command to the history.
Definition vcommand.cpp:70
void undo()
Undoes the last command not already undone.
Definition vcommand.cpp:113
void redo()
Redoes the last command not already undone.
Definition vcommand.cpp:144
void setRedoLimit(unsigned int limit)
Sets a new redo limit.
Definition vcommand.cpp:106
void commandAdded(VCommand *)
This signal is emitted when a command is added to the history.
void lastCommandRemoved()
This signal is emitted when the last (latest) command is removed.
void redoAllTo(VCommand *command)
Redoes all command up to the specified command.
Definition vcommand.cpp:238
void undoAllTo(VCommand *command)
Undoes all command up to the specified command.
Definition vcommand.cpp:209
void firstCommandRemoved()
This signal is emitted when the first (oldest) command is removed.
void commandExecuted()
This signal is emitted when a command is executed.
void documentSaved()
Marks the actual document state as saved.
Definition vcommand.cpp:267
~VCommandHistory()
Destroys the command history.
Definition vcommand.cpp:40
The base class for all karbon commands.
Definition vcommand.h:42
virtual void unexecute()
Unexecutes the command.
Definition vcommand.h:75
virtual void execute()=0
Executes the command.
bool success() const
Return if the operation was a success or not.
Definition vvisitor.h:125