00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <klocale.h>
00022
00023 #include <qvaluelist.h>
00024
00025 #include "formulacursor.h"
00026 #include "formulaelement.h"
00027 #include "indexelement.h"
00028 #include "kformulacommand.h"
00029 #include "matrixelement.h"
00030 #include "sequenceelement.h"
00031 #include "textelement.h"
00032 #include "tokenelement.h"
00033
00034
00035 KFORMULA_NAMESPACE_BEGIN
00036
00037 int PlainCommand::evilDestructionCount = 0;
00038
00039 PlainCommand::PlainCommand( const QString& name )
00040 : KNamedCommand(name)
00041 {
00042 evilDestructionCount++;
00043 }
00044
00045 PlainCommand::~PlainCommand()
00046 {
00047 evilDestructionCount--;
00048 }
00049
00050 Command::Command(const QString &name, Container* document)
00051 : PlainCommand(name), cursordata(0), undocursor(0), doc(document)
00052 {
00053 }
00054
00055 Command::~Command()
00056 {
00057 delete undocursor;
00058 delete cursordata;
00059 }
00060
00061 FormulaCursor* Command::getExecuteCursor()
00062 {
00063 FormulaCursor* cursor = getActiveCursor();
00064 if (cursordata == 0) {
00065 setExecuteCursor(getActiveCursor());
00066 }
00067 else {
00068 cursor->setCursorData(cursordata);
00069 }
00070 return cursor;
00071 }
00072
00073 void Command::setExecuteCursor(FormulaCursor* cursor)
00074 {
00075
00076 cursordata = cursor->getCursorData();
00077 }
00078
00079 FormulaCursor* Command::getUnexecuteCursor()
00080 {
00081 FormulaCursor* cursor = getActiveCursor();
00082 cursor->setCursorData(undocursor);
00083 destroyUndoCursor();
00084 return cursor;
00085 }
00086
00087 void Command::setUnexecuteCursor(FormulaCursor* cursor)
00088 {
00089
00090 undocursor = cursor->getCursorData();
00091 }
00092
00093
00094
00095
00096 KFCAdd::KFCAdd(const QString &name, Container *document)
00097 : Command(name, document)
00098 {
00099 addList.setAutoDelete( true );
00100 }
00101
00102
00103 void KFCAdd::execute()
00104 {
00105 FormulaCursor* cursor = getExecuteCursor();
00106 cursor->insert(addList, beforeCursor);
00107 setUnexecuteCursor(cursor);
00108 cursor->setSelection(false);
00109 testDirty();
00110 }
00111
00112
00113 void KFCAdd::unexecute()
00114 {
00115 FormulaCursor* cursor = getUnexecuteCursor();
00116 cursor->remove(addList, beforeCursor);
00117
00118 cursor->normalize();
00119 testDirty();
00120 }
00121
00122
00123
00124
00125 KFCRemoveSelection::KFCRemoveSelection(Container *document,
00126 Direction direction)
00127 : Command(i18n("Remove Selected Text"), document),
00128 dir(direction)
00129 {
00130 removedList.setAutoDelete( true );
00131 }
00132
00133 void KFCRemoveSelection::execute()
00134 {
00135 FormulaCursor* cursor = getExecuteCursor();
00136 cursor->remove(removedList, dir);
00137 setUnexecuteCursor(cursor);
00138 testDirty();
00139 }
00140
00141 void KFCRemoveSelection::unexecute()
00142 {
00143 FormulaCursor* cursor = getUnexecuteCursor();
00144 cursor->insert(removedList);
00145 cursor->setSelection(false);
00146 testDirty();
00147 }
00148
00149
00150
00151 KFCReplace::KFCReplace(const QString &name, Container* document)
00152 : KFCAdd(name, document), removeSelection(0)
00153 {
00154 }
00155
00156 KFCReplace::~KFCReplace()
00157 {
00158 delete removeSelection;
00159 }
00160
00161 void KFCReplace::execute()
00162 {
00163 if (getActiveCursor()->isSelection() && (removeSelection == 0)) {
00164 removeSelection = new KFCRemoveSelection(getDocument());
00165 }
00166 if (removeSelection != 0) {
00167 removeSelection->execute();
00168 }
00169 KFCAdd::execute();
00170 }
00171
00172 void KFCReplace::unexecute()
00173 {
00174 KFCAdd::unexecute();
00175 if (removeSelection != 0) {
00176 removeSelection->unexecute();
00177 }
00178 }
00179
00180
00181
00182
00183 KFCAddToken::KFCAddToken(const QString &name, Container *document)
00184 : Command(name, document)
00185 {
00186 }
00187
00188 KFCAddToken::~KFCAddToken()
00189 {
00190 QPtrDictIterator< QPtrList< BasicElement > > it( contentList );
00191 QPtrList< BasicElement >* list;
00192 while ( ( list = it.current() ) != 0 ) {
00193 delete list;
00194 ++it;
00195 }
00196 }
00197
00198 void KFCAddToken::execute()
00199 {
00200 kdDebug( DEBUGID ) << k_funcinfo << endl;
00201 FormulaCursor* cursor = getExecuteCursor();
00202 QPtrList<BasicElement> tokenListTmp = tokenList;
00203 cursor->insert( tokenList, beforeCursor );
00204 tokenList = tokenListTmp;
00205 QPtrListIterator< BasicElement > it( tokenList );
00206 BasicElement* element;
00207 BasicElement* current = cursor->getElement();
00208 while ( (element = it.current()) != 0 ) {
00209 element->goInside( cursor );
00210 cursor->insert( *contentList.find( element ), beforeCursor );
00211 ++it;
00212 }
00213 setUnexecuteCursor( cursor );
00214 cursor->setSelection(false);
00215 testDirty();
00216 }
00217
00218
00219 void KFCAddToken::unexecute()
00220 {
00221 kdDebug( DEBUGID ) << k_funcinfo << endl;
00222 FormulaCursor* cursor = getUnexecuteCursor();
00223 SequenceElement* parent = static_cast<SequenceElement*>(cursor->getElement()->getParent());
00224
00225 for ( int i = 0; i < tokenList.count(); i++ ) {
00226 SequenceElement* current = static_cast<SequenceElement*>(cursor->getElement());
00227 QPtrList< BasicElement > list;
00228 for ( uint i = 0; i < current->countChildren(); ++i ) {
00229 cursor->remove( list, beforeCursor );
00230 }
00231 if ( parent ) {
00232 int pos = parent->childPos( current );
00233 cursor->setTo( parent, pos + 1);
00234 cursor->remove( list, beforeCursor );
00235 if ( pos > 0 ) {
00236 BasicElement* element = parent->getChild( pos - 1 );
00237 if (element)
00238 element->moveEnd( cursor );
00239 }
00240 }
00241 }
00242 testDirty();
00243 }
00244
00248 void KFCAddToken::addToken( BasicElement* element )
00249 {
00250 tokenList.append( element );
00251 contentList.insert( element, new QPtrList< BasicElement > );
00252 contentList.find( element )->setAutoDelete( true );
00253 }
00254
00255 KFCReplaceToken::KFCReplaceToken(const QString &name, Container* document)
00256 : KFCAddToken(name, document), removeSelection(0)
00257 {
00258 }
00259
00260 KFCReplaceToken::~KFCReplaceToken()
00261 {
00262 delete removeSelection;
00263 }
00264
00265 void KFCReplaceToken::execute()
00266 {
00267 kdDebug( DEBUGID ) << k_funcinfo << endl;
00268 if (getActiveCursor()->isSelection() && (removeSelection == 0)) {
00269 removeSelection = new KFCRemoveSelection(getDocument());
00270 }
00271 if (removeSelection != 0) {
00272 removeSelection->execute();
00273 }
00274 KFCAddToken::execute();
00275 }
00276
00277 void KFCReplaceToken::unexecute()
00278 {
00279 kdDebug( DEBUGID ) << k_funcinfo << endl;
00280 KFCAddToken::unexecute();
00281 if (removeSelection != 0) {
00282 removeSelection->unexecute();
00283 }
00284 }
00285
00286
00287 KFCSplitToken::KFCSplitToken(const QString &name, Container* document)
00288 : KFCAddToken(name, document), removeSelection(0)
00289 {
00290 splitList.setAutoDelete( true );
00291 }
00292
00293 KFCSplitToken::~KFCSplitToken()
00294 {
00295 delete splitCursor;
00296 delete removeSelection;
00297 }
00298
00299 void KFCSplitToken::execute()
00300 {
00301 FormulaCursor* cursor = getExecuteCursor();
00302 if (getActiveCursor()->isSelection() && (removeSelection == 0)) {
00303 removeSelection = new KFCRemoveSelection(getDocument());
00304 }
00305 if (removeSelection != 0) {
00306 removeSelection->execute();
00307 }
00308 splitCursor = cursor->getCursorData();
00309 SequenceElement* parent = static_cast<SequenceElement*>( cursor->getElement() );
00310 if ( parent ) {
00311 cursor->setMark( parent->countChildren() );
00312 cursor->setSelection( true );
00313 }
00314 cursor->remove( splitList, afterCursor );
00315 TokenElement *token = new TokenElement();
00316 addToken( token );
00317 QPtrListIterator< BasicElement > it ( splitList );
00318 BasicElement* element;
00319 while ( ( element = it.current() ) != 0 ) {
00320 addContent( token, element );
00321 ++it;
00322 }
00323 KFCAddToken::execute();
00324 cursor = getExecuteCursor();
00325 if ( parent ) {
00326 BasicElement* child = parent->getChild( cursor->getPos() );
00327 if ( child ) {
00328 child->moveEnd( cursor );
00329 }
00330 }
00331 }
00332
00333 void KFCSplitToken::unexecute()
00334 {
00335 kdDebug( DEBUGID ) << k_funcinfo << endl;
00336 KFCAddToken::unexecute();
00337 FormulaCursor *cursor = getUnexecuteCursor();
00338 cursor->setCursorData( splitCursor );
00339 cursor->insert( splitList, afterCursor );
00340 if (removeSelection != 0) {
00341 removeSelection->unexecute();
00342 }
00343 testDirty();
00344 }
00345
00346
00347 KFCRemove::KFCRemove(Container *document,
00348 Direction direction)
00349 : Command(i18n("Remove Selected Text"), document),
00350 element(0), simpleRemoveCursor(0), dir(direction)
00351 {
00352 removedList.setAutoDelete( true );
00353 }
00354
00355 KFCRemove::~KFCRemove()
00356 {
00357 delete simpleRemoveCursor;
00358 delete element;
00359 }
00360
00361 void KFCRemove::execute()
00362 {
00363 FormulaCursor* cursor = getExecuteCursor();
00364 cursor->remove(removedList, dir);
00365 if (cursor->elementIsSenseless()) {
00366 simpleRemoveCursor = cursor->getCursorData();
00367 element = cursor->replaceByMainChildContent();
00368 }
00369 setUnexecuteCursor(cursor);
00370 cursor->normalize( dir );
00371 testDirty();
00372 }
00373
00374 void KFCRemove::unexecute()
00375 {
00376 FormulaCursor* cursor = getUnexecuteCursor();
00377 if (element != 0) {
00378 cursor->replaceSelectionWith(element);
00379 element = 0;
00380
00381 cursor->setCursorData(simpleRemoveCursor);
00382 delete simpleRemoveCursor;
00383 simpleRemoveCursor = 0;
00384 }
00385 cursor->insert(removedList, dir);
00386 cursor->setSelection(false);
00387 testDirty();
00388 }
00389
00390
00391 KFCRemoveEnclosing::KFCRemoveEnclosing(Container* document,
00392 Direction dir)
00393 : Command(i18n("Remove Enclosing Element"), document),
00394 element(0), direction(dir)
00395 {
00396 }
00397
00398 KFCRemoveEnclosing::~KFCRemoveEnclosing()
00399 {
00400 delete element;
00401 }
00402
00403 void KFCRemoveEnclosing::execute()
00404 {
00405 FormulaCursor* cursor = getExecuteCursor();
00406 element = cursor->removeEnclosingElement(direction);
00407 setUnexecuteCursor(cursor);
00408
00409 cursor->setSelection(false);
00410 testDirty();
00411 }
00412
00413 void KFCRemoveEnclosing::unexecute()
00414 {
00415 FormulaCursor* cursor = getUnexecuteCursor();
00416 if ( element ) {
00417 cursor->replaceSelectionWith(element);
00418 }
00419 cursor->normalize();
00420 cursor->setSelection(false);
00421 element = 0;
00422 testDirty();
00423 }
00424
00425
00426
00427
00428 KFCAddReplacing::KFCAddReplacing(const QString &name, Container* document)
00429 : Command(name, document), element(0)
00430 {
00431 }
00432
00433 KFCAddReplacing::~KFCAddReplacing()
00434 {
00435 delete element;
00436 }
00437
00438
00439 void KFCAddReplacing::execute()
00440 {
00441 FormulaCursor* cursor = getExecuteCursor();
00442 cursor->replaceSelectionWith(element);
00443 setUnexecuteCursor(cursor);
00444 cursor->goInsideElement(element);
00445 element = 0;
00446 testDirty();
00447 }
00448
00449
00450 void KFCAddReplacing::unexecute()
00451 {
00452 FormulaCursor* cursor = getUnexecuteCursor();
00453 element = cursor->replaceByMainChildContent();
00454 cursor->normalize();
00455 testDirty();
00456 }
00457
00458
00459
00460
00461 KFCAddGenericIndex::KFCAddGenericIndex(Container* document, ElementIndexPtr _index)
00462 : KFCAdd(i18n("Add Index"), document), index(_index)
00463 {
00464 addElement(new SequenceElement());
00465 }
00466
00467 void KFCAddGenericIndex::execute()
00468 {
00469 index->setToIndex(getActiveCursor());
00470 KFCAdd::execute();
00471 }
00472
00473
00474 KFCAddIndex::KFCAddIndex(Container* document,
00475 IndexElement* element, ElementIndexPtr index)
00476 : KFCAddReplacing(i18n("Add Index"), document),
00477 addIndex(document, index)
00478 {
00479 setElement(element);
00480 }
00481
00482 KFCAddIndex::~KFCAddIndex()
00483 {
00484 }
00485
00486 void KFCAddIndex::execute()
00487 {
00488 KFCAddReplacing::execute();
00489 addIndex.execute();
00490 }
00491
00492 void KFCAddIndex::unexecute()
00493 {
00494 addIndex.unexecute();
00495 KFCAddReplacing::unexecute();
00496 }
00497
00498
00499 KFCChangeBaseSize::KFCChangeBaseSize( const QString& name, Container* document,
00500 FormulaElement* formula, int size )
00501 : PlainCommand( name ), m_document( document ), m_formula( formula ), m_size( size )
00502 {
00503 m_oldSize = formula->getBaseSize();
00504 }
00505
00506 void KFCChangeBaseSize::execute()
00507 {
00508 m_formula->setBaseSize( m_size );
00509 m_document->recalc();
00510 }
00511
00512 void KFCChangeBaseSize::unexecute()
00513 {
00514 m_formula->setBaseSize( m_oldSize );
00515 m_document->recalc();
00516 }
00517
00518
00519 FontCommand::FontCommand( const QString& name, Container* document )
00520 : Command( name, document )
00521 {
00522 list.setAutoDelete( false );
00523 elementList.setAutoDelete( false );
00524 }
00525
00526
00527 void FontCommand::collectChildren()
00528 {
00529 list.clear();
00530 uint count = elementList.count();
00531 for ( uint i=0; i<count; ++i ) {
00532 elementList.at( i )->dispatchFontCommand( this );
00533 }
00534 }
00535
00536
00537 void FontCommand::parseSequences( const QMap<SequenceElement*, int>& parents )
00538 {
00539 QValueList<SequenceElement*> sequences = parents.keys();
00540 for ( QValueList<SequenceElement*>::iterator i = sequences.begin();
00541 i != sequences.end();
00542 ++i ) {
00543 ( *i )->parse();
00544 }
00545 }
00546
00547
00548 CharStyleCommand::CharStyleCommand( CharStyle cs, const QString& name, Container* document )
00549 : FontCommand( name, document ), charStyle( cs )
00550 {
00551 }
00552
00553 void CharStyleCommand::execute()
00554 {
00555 collectChildren();
00556 QMap<SequenceElement*, int> parentCollector;
00557
00558 styleList.clear();
00559 uint count = childrenList().count();
00560 styleList.reserve( count );
00561 for ( uint i=0; i<count; ++i ) {
00562 TextElement* child = childrenList().at( i );
00563 styleList[i] = child->getCharStyle();
00564 child->setCharStyle( charStyle );
00565 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
00566 }
00567 parseSequences( parentCollector );
00568 testDirty();
00569 }
00570
00571 void CharStyleCommand::unexecute()
00572 {
00573 QMap<SequenceElement*, int> parentCollector;
00574 uint count = childrenList().count();
00575
00576 for ( uint i=0; i<count; ++i ) {
00577 TextElement* child = childrenList().at( i );
00578 child->setCharStyle( styleList[i] );
00579 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
00580 }
00581 parseSequences( parentCollector );
00582 testDirty();
00583 }
00584
00585
00586 CharFamilyCommand::CharFamilyCommand( CharFamily cf, const QString& name, Container* document )
00587 : FontCommand( name, document ), charFamily( cf )
00588 {
00589 }
00590
00591 void CharFamilyCommand::execute()
00592 {
00593 collectChildren();
00594
00595 QMap<SequenceElement*, int> parentCollector;
00596
00597 familyList.clear();
00598 uint count = childrenList().count();
00599 familyList.reserve( count );
00600 for ( uint i=0; i<count; ++i ) {
00601 TextElement* child = childrenList().at( i );
00602 familyList[i] = child->getCharFamily();
00603 child->setCharFamily( charFamily );
00604 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
00605 }
00606 parseSequences( parentCollector );
00607 testDirty();
00608 }
00609
00610 void CharFamilyCommand::unexecute()
00611 {
00612 QMap<SequenceElement*, int> parentCollector;
00613 uint count = childrenList().count();
00614
00615 for ( uint i=0; i<count; ++i ) {
00616 TextElement* child = childrenList().at( i );
00617 child->setCharFamily( familyList[i] );
00618 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
00619 }
00620 parseSequences( parentCollector );
00621 testDirty();
00622 }
00623
00624
00625 KFORMULA_NAMESPACE_END