lib

kformulacommand.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org>
3 Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de>
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#include <tdelocale.h> //This is for undo descriptions
22
23#include <tqvaluelist.h>
24
25#include "formulacursor.h"
26#include "formulaelement.h"
27#include "indexelement.h"
28#include "kformulacommand.h"
29#include "matrixelement.h"
30#include "sequenceelement.h"
31#include "textelement.h"
32#include "tokenelement.h"
33
34
35KFORMULA_NAMESPACE_BEGIN
36
37int PlainCommand::evilDestructionCount = 0;
38
41{
42 evilDestructionCount++;
43}
44
45PlainCommand::~PlainCommand()
46{
47 evilDestructionCount--;
48}
49
50Command::Command(const TQString &name, Container* document)
51 : PlainCommand(name), cursordata(0), undocursor(0), doc(document)
52{
53}
54
55Command::~Command()
56{
57 delete undocursor;
58 delete cursordata;
59}
60
61FormulaCursor* Command::getExecuteCursor()
62{
63 FormulaCursor* cursor = getActiveCursor();
64 if (cursordata == 0) {
65 setExecuteCursor(getActiveCursor());
66 }
67 else {
68 cursor->setCursorData(cursordata);
69 }
70 return cursor;
71}
72
73void Command::setExecuteCursor(FormulaCursor* cursor)
74{
75 // assert(cursordata == 0);
76 cursordata = cursor->getCursorData();
77}
78
79FormulaCursor* Command::getUnexecuteCursor()
80{
81 FormulaCursor* cursor = getActiveCursor();
82 cursor->setCursorData(undocursor);
83 destroyUndoCursor();
84 return cursor;
85}
86
87void Command::setUnexecuteCursor(FormulaCursor* cursor)
88{
89 // assert(undocursor == 0);
90 undocursor = cursor->getCursorData();
91}
92
93
94// ****** Generic Add command
95
96KFCAdd::KFCAdd(const TQString &name, Container *document)
97 : Command(name, document)
98{
99 addList.setAutoDelete( true );
100}
101
102
103void KFCAdd::execute()
104{
105 FormulaCursor* cursor = getExecuteCursor();
106 cursor->insert(addList, beforeCursor);
107 setUnexecuteCursor(cursor);
108 cursor->setSelection(false);
109 testDirty();
110}
111
112
114{
115 FormulaCursor* cursor = getUnexecuteCursor();
116 cursor->remove(addList, beforeCursor);
117 //cursor->setSelection(false);
118 cursor->normalize();
119 testDirty();
120}
121
122
123// ****** Remove selection command
124
126 Direction direction)
127 : Command(i18n("Remove Selected Text"), document),
128 dir(direction)
129{
130 removedList.setAutoDelete( true );
131}
132
134{
135 FormulaCursor* cursor = getExecuteCursor();
136 cursor->remove(removedList, dir);
137 setUnexecuteCursor(cursor);
138 testDirty();
139}
140
142{
143 FormulaCursor* cursor = getUnexecuteCursor();
144 cursor->insert(removedList);
145 cursor->setSelection(false);
146 testDirty();
147}
148
149
150
151KFCReplace::KFCReplace(const TQString &name, Container* document)
152 : KFCAdd(name, document), removeSelection(0)
153{
154}
155
156KFCReplace::~KFCReplace()
157{
158 delete removeSelection;
159}
160
162{
163 if (getActiveCursor()->isSelection() && (removeSelection == 0)) {
164 removeSelection = new KFCRemoveSelection(getDocument());
165 }
166 if (removeSelection != 0) {
167 removeSelection->execute();
168 }
170}
171
173{
175 if (removeSelection != 0) {
176 removeSelection->unexecute();
177 }
178}
179
180
181// ****** Token Add command
182
183KFCAddToken::KFCAddToken(const TQString &name, Container *document)
184 : Command(name, document)
185{
186}
187
188KFCAddToken::~KFCAddToken()
189{
190 TQPtrDictIterator< TQPtrList< BasicElement > > it( contentList );
191 TQPtrList< BasicElement >* list;
192 while ( ( list = it.current() ) != 0 ) {
193 delete list;
194 ++it;
195 }
196}
197
199{
200 kdDebug( DEBUGID ) << k_funcinfo << endl;
201 FormulaCursor* cursor = getExecuteCursor();
202 TQPtrList<BasicElement> tokenListTmp = tokenList;
203 cursor->insert( tokenList, beforeCursor );
204 tokenList = tokenListTmp;
205 TQPtrListIterator< BasicElement > it( tokenList );
206 BasicElement* element;
207 BasicElement* current = cursor->getElement();
208 while ( (element = it.current()) != 0 ) {
209 element->goInside( cursor );
210 cursor->insert( *contentList.find( element ), beforeCursor );
211 ++it;
212 }
213 setUnexecuteCursor( cursor );
214 cursor->setSelection(false);
215 testDirty();
216}
217
218
220{
221 kdDebug( DEBUGID ) << k_funcinfo << endl;
222 FormulaCursor* cursor = getUnexecuteCursor();
223 SequenceElement* parent = static_cast<SequenceElement*>(cursor->getElement()->getParent());
224
225 for ( int i = 0; i < tokenList.count(); i++ ) {
226 SequenceElement* current = static_cast<SequenceElement*>(cursor->getElement());
227 TQPtrList< BasicElement > list;
228 for ( uint i = 0; i < current->countChildren(); ++i ) {
229 cursor->remove( list, beforeCursor );
230 }
231 if ( parent ) {
232 int pos = parent->childPos( current );
233 cursor->setTo( parent, pos + 1);
234 cursor->remove( list, beforeCursor );
235 if ( pos > 0 ) {
236 BasicElement* element = parent->getChild( pos - 1 );
237 if (element)
238 element->moveEnd( cursor );
239 }
240 }
241 }
242 testDirty();
243}
244
249{
250 tokenList.append( element );
251 contentList.insert( element, new TQPtrList< BasicElement > );
252 contentList.find( element )->setAutoDelete( true );
253}
254
255KFCReplaceToken::KFCReplaceToken(const TQString &name, Container* document)
256 : KFCAddToken(name, document), removeSelection(0)
257{
258}
259
260KFCReplaceToken::~KFCReplaceToken()
261{
262 delete removeSelection;
263}
264
266{
267 kdDebug( DEBUGID ) << k_funcinfo << endl;
268 if (getActiveCursor()->isSelection() && (removeSelection == 0)) {
269 removeSelection = new KFCRemoveSelection(getDocument());
270 }
271 if (removeSelection != 0) {
272 removeSelection->execute();
273 }
275}
276
278{
279 kdDebug( DEBUGID ) << k_funcinfo << endl;
281 if (removeSelection != 0) {
282 removeSelection->unexecute();
283 }
284}
285
286
287KFCSplitToken::KFCSplitToken(const TQString &name, Container* document)
288 : KFCAddToken(name, document), removeSelection(0)
289{
290 splitList.setAutoDelete( true );
291}
292
293KFCSplitToken::~KFCSplitToken()
294{
295 delete splitCursor;
296 delete removeSelection;
297}
298
300{
301 FormulaCursor* cursor = getExecuteCursor();
302 if (getActiveCursor()->isSelection() && (removeSelection == 0)) {
303 removeSelection = new KFCRemoveSelection(getDocument());
304 }
305 if (removeSelection != 0) {
306 removeSelection->execute();
307 }
308 splitCursor = cursor->getCursorData();
309 SequenceElement* parent = static_cast<SequenceElement*>( cursor->getElement() );
310 if ( parent ) {
311 cursor->setMark( parent->countChildren() );
312 cursor->setSelection( true );
313 }
314 cursor->remove( splitList, afterCursor );
315 TokenElement *token = new TokenElement();// TODO
316 addToken( token );
317 TQPtrListIterator< BasicElement > it ( splitList );
318 BasicElement* element;
319 while ( ( element = it.current() ) != 0 ) {
320 addContent( token, element );
321 ++it;
322 }
324 cursor = getExecuteCursor();
325 if ( parent ) {
326 BasicElement* child = parent->getChild( cursor->getPos() );
327 if ( child ) {
328 child->moveEnd( cursor );
329 }
330 }
331}
332
334{
335 kdDebug( DEBUGID ) << k_funcinfo << endl;
337 FormulaCursor *cursor = getUnexecuteCursor();
338 cursor->setCursorData( splitCursor );
339 cursor->insert( splitList, afterCursor );
340 if (removeSelection != 0) {
341 removeSelection->unexecute();
342 }
343 testDirty();
344}
345
346
348 Direction direction)
349 : Command(i18n("Remove Selected Text"), document),
350 element(0), simpleRemoveCursor(0), dir(direction)
351{
352 removedList.setAutoDelete( true );
353}
354
355KFCRemove::~KFCRemove()
356{
357 delete simpleRemoveCursor;
358 delete element;
359}
360
362{
363 FormulaCursor* cursor = getExecuteCursor();
364 cursor->remove(removedList, dir);
365 if (cursor->elementIsSenseless()) {
366 simpleRemoveCursor = cursor->getCursorData();
367 element = cursor->replaceByMainChildContent();
368 }
369 setUnexecuteCursor(cursor);
370 cursor->normalize( dir );
371 testDirty();
372}
373
375{
376 FormulaCursor* cursor = getUnexecuteCursor();
377 if (element != 0) {
378 cursor->replaceSelectionWith(element);
379 element = 0;
380
381 cursor->setCursorData(simpleRemoveCursor);
382 delete simpleRemoveCursor;
383 simpleRemoveCursor = 0;
384 }
385 cursor->insert(removedList, dir);
386 cursor->setSelection(false);
387 testDirty();
388}
389
390
391KFCRemoveEnclosing::KFCRemoveEnclosing(Container* document,
392 Direction dir)
393 : Command(i18n("Remove Enclosing Element"), document),
394 element(0), direction(dir)
395{
396}
397
398KFCRemoveEnclosing::~KFCRemoveEnclosing()
399{
400 delete element;
401}
402
404{
405 FormulaCursor* cursor = getExecuteCursor();
406 element = cursor->removeEnclosingElement(direction);
407 setUnexecuteCursor(cursor);
408 //cursor->normalize();
409 cursor->setSelection(false);
410 testDirty();
411}
412
414{
415 FormulaCursor* cursor = getUnexecuteCursor();
416 if ( element ) {
417 cursor->replaceSelectionWith(element);
418 }
419 cursor->normalize();
420 cursor->setSelection(false);
421 element = 0;
422 testDirty();
423}
424
425
426// ****** Add root, bracket etc command
427
428KFCAddReplacing::KFCAddReplacing(const TQString &name, Container* document)
429 : Command(name, document), element(0)
430{
431}
432
433KFCAddReplacing::~KFCAddReplacing()
434{
435 delete element;
436}
437
438
440{
441 FormulaCursor* cursor = getExecuteCursor();
442 cursor->replaceSelectionWith(element);
443 setUnexecuteCursor(cursor);
444 cursor->goInsideElement(element);
445 element = 0;
446 testDirty();
447}
448
449
451{
452 FormulaCursor* cursor = getUnexecuteCursor();
453 element = cursor->replaceByMainChildContent();
454 cursor->normalize();
455 testDirty();
456}
457
458
459// ****** Add index command
460
461KFCAddGenericIndex::KFCAddGenericIndex(Container* document, ElementIndexPtr &_index)
462 : KFCAdd(i18n("Add Index"), document), index(std::move(_index))
463{
464 addElement(new SequenceElement());
465}
466
468{
469 index->setToIndex(getActiveCursor());
471}
472
473
474KFCAddIndex::KFCAddIndex(Container* document,
475 IndexElement* element, ElementIndexPtr index)
476 : KFCAddReplacing(i18n("Add Index"), document),
477 addIndex(document, index)
478{
479 setElement(element);
480}
481
482KFCAddIndex::~KFCAddIndex()
483{
484}
485
487{
489 addIndex.execute();
490}
491
493{
494 addIndex.unexecute();
496}
497
498
499KFCChangeBaseSize::KFCChangeBaseSize( const TQString& name, Container* document,
500 FormulaElement* formula, int size )
501 : PlainCommand( name ), m_document( document ), m_formula( formula ), m_size( size )
502{
503 m_oldSize = formula->getBaseSize();
504}
505
507{
508 m_formula->setBaseSize( m_size );
509 m_document->recalc();
510}
511
513{
514 m_formula->setBaseSize( m_oldSize );
515 m_document->recalc();
516}
517
518
519FontCommand::FontCommand( const TQString& name, Container* document )
520 : Command( name, document )
521{
522 list.setAutoDelete( false );
523 elementList.setAutoDelete( false );
524}
525
526
527void FontCommand::collectChildren()
528{
529 list.clear();
530 uint count = elementList.count();
531 for ( uint i=0; i<count; ++i ) {
532 elementList.at( i )->dispatchFontCommand( this );
533 }
534}
535
536
537void FontCommand::parseSequences( const TQMap<SequenceElement*, int>& parents )
538{
539 TQValueList<SequenceElement*> sequences = parents.keys();
540 for ( TQValueList<SequenceElement*>::iterator i = sequences.begin();
541 i != sequences.end();
542 ++i ) {
543 ( *i )->parse();
544 }
545}
546
547
548CharStyleCommand::CharStyleCommand( CharStyle cs, const TQString& name, Container* document )
549 : FontCommand( name, document ), charStyle( cs )
550{
551}
552
554{
555 collectChildren();
556 TQMap<SequenceElement*, int> parentCollector;
557
558 styleList.clear();
559 uint count = childrenList().count();
560 styleList.reserve( count );
561 for ( uint i=0; i<count; ++i ) {
562 TextElement* child = childrenList().at( i );
563 styleList[i] = child->getCharStyle();
564 child->setCharStyle( charStyle );
565 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
566 }
567 parseSequences( parentCollector );
568 testDirty();
569}
570
572{
573 TQMap<SequenceElement*, int> parentCollector;
574 uint count = childrenList().count();
575 //styleList.reserve( count );
576 for ( uint i=0; i<count; ++i ) {
577 TextElement* child = childrenList().at( i );
578 child->setCharStyle( styleList[i] );
579 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
580 }
581 parseSequences( parentCollector );
582 testDirty();
583}
584
585
586CharFamilyCommand::CharFamilyCommand( CharFamily cf, const TQString& name, Container* document )
587 : FontCommand( name, document ), charFamily( cf )
588{
589}
590
592{
593 collectChildren();
594
595 TQMap<SequenceElement*, int> parentCollector;
596
597 familyList.clear();
598 uint count = childrenList().count();
599 familyList.reserve( count );
600 for ( uint i=0; i<count; ++i ) {
601 TextElement* child = childrenList().at( i );
602 familyList[i] = child->getCharFamily();
603 child->setCharFamily( charFamily );
604 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
605 }
606 parseSequences( parentCollector );
607 testDirty();
608}
609
611{
612 TQMap<SequenceElement*, int> parentCollector;
613 uint count = childrenList().count();
614 //familyList.reserve( count );
615 for ( uint i=0; i<count; ++i ) {
616 TextElement* child = childrenList().at( i );
617 child->setCharFamily( familyList[i] );
618 parentCollector[static_cast<SequenceElement*>( child->getParent() )] = 1;
619 }
620 parseSequences( parentCollector );
621 testDirty();
622}
623
624
625KFORMULA_NAMESPACE_END
Basis of every formula element.
virtual void goInside(FormulaCursor *cursor)
Sets the cursor inside this element to its start position.
virtual void moveEnd(FormulaCursor *)
Moves the cursor to the last position in this sequence.
The document.
Base for all font commands that act on the current selection.
The selection.
void normalize(Direction direction=beforeCursor)
Moves the cursor to a normal position.
void insert(BasicElement *, Direction=beforeCursor)
Inserts the child at the current position.
void replaceSelectionWith(BasicElement *, Direction=beforeCursor)
Replaces the current selection with the supplied element.
void setCursorData(CursorData *data)
Sets the cursor to where the CursorData points to.
void setSelection(bool selection)
Sets the selection mode.
CursorData * getCursorData()
Creates a new CursorData object that describes the cursor.
BasicElement * replaceByMainChildContent(Direction=beforeCursor)
Replaces the element the cursor points to with its main child's content.
BasicElement * removeEnclosingElement(Direction=beforeCursor)
Trys to find the element we are the main child of and replace it with our content.
void goInsideElement(BasicElement *element)
Moves the cursor inside the element.
void setTo(BasicElement *element, uint cursor, int mark=-1)
Sets the cursor to a new position.
bool elementIsSenseless()
Returns wether the element the cursor points to should be replaced.
BasicElement * getElement()
The element we are in.
void remove(TQPtrList< BasicElement > &, Direction=beforeCursor)
Removes the current selected children and returns them.
The main element.
The element with up to four indexes in the four corners.
virtual void unexecute()=0
virtual void execute()=0
The command that takes the main child out of the selected element and replaces the element with it.
Command to add a token element, with content.
void addContent(BasicElement *element, BasicElement *content)
Collect content for each token.
void addToken(BasicElement *element)
Collect all tokens that are to be added.
Base for all commands that want to add a simple element.
KFCRemoveSelection(Container *document, Direction dir=beforeCursor)
generic add command, default implementation do nothing
KFCRemove(Container *document, Direction dir)
generic add command, default implementation do nothing
virtual TQString name() const
KNamedCommand(const TQString &name)
Base for all kformula commands.
PlainCommand(const TQString &name)
Sets up the command.
uint countChildren() const
virtual BasicElement * getChild(FormulaCursor *, Direction=beforeCursor)
Returns the child at the cursor.
const char * name(StdAction id)