karbon
vcommand.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kaction.h"
00023 #include "klocale.h"
00024
00025 #include "vcommand.h"
00026 #include "karbon_part.h"
00027
00028
00029 VCommandHistory::VCommandHistory( KarbonPart* part )
00030 : m_part( part ), m_undoLimit( 50 ), m_redoLimit( 30 ), m_savedPos( 0 )
00031 {
00032 m_commands.setAutoDelete( true );
00033
00034 m_undo = KStdAction::undo( this, SLOT( undo() ), m_part->actionCollection(), "koffice_undo" );
00035 m_redo = KStdAction::redo( this, SLOT( redo() ), m_part->actionCollection(), "koffice_redo" );
00036
00037 clear();
00038 }
00039
00040 VCommandHistory::~VCommandHistory()
00041 {
00042 }
00043
00044 void
00045 VCommandHistory::clear()
00046 {
00047 if( m_savedPos != int( m_commands.count() - 1 ) )
00048 m_savedPos = -1;
00049 else
00050 m_savedPos = 0;
00051
00052 m_commands.clear();
00053
00054 emit historyCleared();
00055
00056 if( m_undo != 0 )
00057 {
00058 m_undo->setEnabled( false );
00059 m_undo->setText( i18n( "&Undo" ) );
00060 }
00061
00062 if( m_redo != 0 )
00063 {
00064 m_redo->setEnabled( false );
00065 m_redo->setText( i18n( "&Redo" ) );
00066 }
00067 }
00068
00069 void
00070 VCommandHistory::addCommand( VCommand* command, bool execute )
00071 {
00072 if( command == 0L )
00073 return;
00074
00075 if( !m_commands.isEmpty() )
00076 {
00077 while( m_commands.last() && !m_commands.last()->success() )
00078 {
00079 m_commands.removeLast();
00080 emit lastCommandRemoved();
00081 }
00082 }
00083
00084 m_commands.append( command );
00085 kdDebug(38000) << "History: new command: " << m_commands.findRef( command ) << endl;
00086
00087 if( execute )
00088 {
00089 command->execute();
00090 emit commandExecuted( command );
00091 }
00092
00093 updateActions();
00094
00095 emit commandAdded( command );
00096 }
00097
00098 void
00099 VCommandHistory::setUndoLimit( unsigned int limit )
00100 {
00101 m_undoLimit = limit;
00102 clipCommands();
00103 }
00104
00105 void
00106 VCommandHistory::setRedoLimit( unsigned int limit )
00107 {
00108 m_redoLimit = limit;
00109 clipCommands();
00110 }
00111
00112 void
00113 VCommandHistory::undo()
00114 {
00115 int i = m_commands.count() - 1;
00116
00117 if( i == -1 )
00118 return;
00119
00120 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
00121 {
00122 i--;
00123 }
00124
00125 if( i < 0 )
00126 return;
00127
00128 VCommand* cmd = m_commands.at( i );
00129
00130 cmd->unexecute();
00131
00132 emit commandExecuted( cmd );
00133
00134 emit commandExecuted();
00135
00136 clipCommands();
00137
00138 updateActions();
00139
00140 m_part->repaintAllViews();
00141 }
00142
00143 void
00144 VCommandHistory::redo()
00145 {
00146 int i = m_commands.count() - 1;
00147
00148 if( i == -1 )
00149 return;
00150
00151 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
00152 {
00153 i--;
00154 }
00155
00156 i++;
00157
00158 if( i >= int( m_commands.count() ) )
00159 return;
00160
00161 VCommand* cmd;
00162
00163 if( ( cmd = m_commands.at( i ) ) == 0L )
00164 return;
00165
00166 cmd->execute();
00167
00168 emit commandExecuted( cmd );
00169 emit commandExecuted();
00170
00171 updateActions();
00172
00173 m_part->repaintAllViews();
00174 }
00175
00176 void
00177 VCommandHistory::undo( VCommand* command )
00178 {
00179 if( ( m_commands.findRef( command ) == -1 ) || ( !command->success() ) )
00180 return;
00181
00182 command->unexecute();
00183
00184 emit commandExecuted( command );
00185 emit commandExecuted();
00186
00187 updateActions();
00188
00189 m_part->repaintAllViews();
00190 }
00191
00192 void
00193 VCommandHistory::redo( VCommand* command )
00194 {
00195 if( ( m_commands.findRef( command ) == -1 ) || ( command->success() ) )
00196 return;
00197
00198 command->execute();
00199
00200 emit commandExecuted( command );
00201 emit commandExecuted();
00202
00203 updateActions();
00204
00205 m_part->repaintAllViews();
00206 }
00207
00208 void
00209 VCommandHistory::undoAllTo( VCommand* command )
00210 {
00211 int to;
00212
00213 if( ( to = m_commands.findRef( command ) ) == -1 )
00214 return;
00215
00216 int i = m_commands.count() - 1;
00217
00218 VCommand* cmd;
00219
00220 while( i > to )
00221 {
00222 cmd = m_commands.at( i-- );
00223
00224 if( cmd->success() )
00225 {
00226 cmd->unexecute();
00227 emit commandExecuted( cmd );
00228 }
00229 }
00230
00231 emit commandExecuted();
00232 updateActions();
00233
00234 m_part->repaintAllViews();
00235 }
00236
00237 void
00238 VCommandHistory::redoAllTo( VCommand* command )
00239 {
00240 int to;
00241
00242 if( ( to = m_commands.findRef( command ) ) == -1 )
00243 return;
00244
00245 int i = 0;
00246
00247 VCommand* cmd;
00248
00249 while( i <= to )
00250 {
00251 cmd = m_commands.at( i++ );
00252
00253 if( !cmd->success() )
00254 {
00255 cmd->execute();
00256 emit commandExecuted( cmd );
00257 }
00258 }
00259
00260 emit commandExecuted();
00261 updateActions();
00262
00263 m_part->repaintAllViews();
00264 }
00265
00266 void
00267 VCommandHistory::documentSaved()
00268 {
00269
00270
00271 int i = m_commands.count() - 1;
00272
00273 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
00274 {
00275 i--;
00276 }
00277
00278 i++;
00279
00280 m_savedPos = i;
00281 }
00282
00283 void
00284 VCommandHistory::clipCommands()
00285 {
00286 while( m_commands.count() > m_undoLimit )
00287 {
00288 if( m_commands.removeFirst() )
00289 m_savedPos--, emit firstCommandRemoved();
00290 }
00291
00292 int i = 0;
00293
00294 int c = m_commands.count();
00295
00296 while( ( i < c ) && ( !m_commands.at( c - 1 - i )->success() ) )
00297 {
00298 i++;
00299 }
00300
00301 i = i - m_redoLimit;
00302
00303 for( int j = 0; j < i; j++ )
00304 {
00305 if( m_commands.removeLast() )
00306 emit lastCommandRemoved();
00307 }
00308 }
00309
00310 void
00311 VCommandHistory::updateActions()
00312 {
00313 if( m_commands.count() == 0 )
00314 {
00315 if( m_undo != 0 )
00316 {
00317 m_undo->setEnabled( false );
00318 m_undo->setText( i18n( "&Undo" ) );
00319 }
00320
00321 if( m_redo != 0 )
00322 {
00323 m_redo->setEnabled( false );
00324 m_redo->setText( i18n( "&Redo" ) );
00325 }
00326
00327 return;
00328 }
00329
00330 int i = m_commands.count() - 1;
00331
00332 while( ( i >= 0 ) && !( m_commands.at( i )->success() ) )
00333 {
00334 i--;
00335 }
00336
00337 if( m_undo != 0 )
00338 {
00339 if( i < 0 )
00340 {
00341 m_undo->setEnabled( false );
00342 m_undo->setText( i18n( "&Undo" ) );
00343 }
00344 else
00345 {
00346 m_undo->setEnabled( true );
00347 m_undo->setText( i18n( "&Undo: " ) + m_commands.at( i )->name() );
00348 }
00349 }
00350
00351 if( m_redo != 0 )
00352 {
00353 if( ++i == int( m_commands.count() ) )
00354 {
00355 m_redo->setEnabled( false );
00356 m_redo->setText( i18n( "&Redo" ) );
00357 }
00358 else
00359 {
00360 m_redo->setEnabled( true );
00361 m_redo->setText( i18n( "&Redo: " ) + m_commands.at( i )->name() );
00362 }
00363 }
00364
00365 if( m_savedPos >= 0 )
00366 {
00367 for( i = 0; i < m_savedPos; i++ )
00368 {
00369 if( !m_commands.at( i )->success() )
00370 return;
00371 }
00372
00373 for( i = m_savedPos; i < int( m_commands.count() ); i++ )
00374 {
00375 if( m_commands.at( i )->success() )
00376 return;
00377 }
00378
00379 emit documentRestored();
00380 }
00381 }
00382
00383 #include "vcommand.moc"
00384
|