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.
koffice/lib/kformula/kformulacommand.h

563 lines
12 KiB

/* This file is part of the KDE project
Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org>
Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de>
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.
*/
#ifndef KFORMULACOMMAND_H
#define KFORMULACOMMAND_H
#include <tqmap.h>
#include <tqptrlist.h>
#include <tqptrdict.h>
#include <tqvaluevector.h>
#include <kcommand.h>
#include "fontstyle.h"
#include "kformulacontainer.h"
#include "formulacursor.h"
KFORMULA_NAMESPACE_BEGIN
/**
* Base for all kformula commands.
*
* Each command works in the same way. The constructor sets up
* everything. After the command is created you can execute
* it. To create a command doesn't mean to execute it. These are
* two different things.
*
* If the command execution fails or has nothing to do in the first place
* you must not put it in the command history. isSenseless()
* will return true then.
*
* If you don't like what you've done feel free to unexecute() .
*/
class PlainCommand : public KNamedCommand
{
public:
/**
* Sets up the command. Be careful not to change the cursor in
* the constructor of any command. Each command must use the selection
* it finds when it is executed for the first time. This way
* you can use the @ref KMacroCommand .
*
* @param name a description to be used as menu entry.
*/
PlainCommand(const TQString& name);
virtual ~PlainCommand();
/**
* debug only.
*/
static int getEvilDestructionCount() { return evilDestructionCount; }
private:
// debug
static int evilDestructionCount;
};
class Command : public PlainCommand
{
public:
/**
* Sets up the command. Be careful not to change the cursor in
* the constructor of any command. Each command must use the selection
* it finds when it is executed for the first time. This way
* you can use the @ref KMacroCommand .
*
* @param name a description to be used as menu entry.
* @param document the container we are working for.
*/
Command(const TQString& name, Container* document);
virtual ~Command();
protected:
/**
* @returns the cursor that is to be used to @ref execute the
* command.
*/
FormulaCursor* getExecuteCursor();
/**
* @returns the cursor that is to be used to @ref unexecute the
* command.
*/
FormulaCursor* getUnexecuteCursor();
/**
* Saves the cursor that is used to execute the command.
*/
void setExecuteCursor(FormulaCursor* cursor);
/**
* Sets the cursor that is to be used to @ref unexecute the
* command. This has to be called by @ref execute after the
* formula has been changed but before the cursor has been
* normalized.
*/
void setUnexecuteCursor(FormulaCursor* cursor);
/**
* @returns the cursor that is active. It will be used to @ref execute
* the command.
*/
FormulaCursor* getActiveCursor() { return doc->activeCursor(); }
/**
* Tells the document to check if the formula changed.
* Needs to be called by each @ref execute and @ref unexecute .
*/
void testDirty() { doc->testDirty(); }
/**
* @returns our document.
*/
Container* getDocument() const { return doc; }
private:
void destroyUndoCursor() { delete undocursor; undocursor = 0; }
/**
* Cursor position before the command execution.
*/
FormulaCursor::CursorData* cursordata;
/**
* Cursor position after the command execution.
*/
FormulaCursor::CursorData* undocursor;
/**
* The container we belong to.
*/
Container* doc;
};
/**
* Base for all commands that want to add a simple element.
*/
class KFCAdd : public Command
{
public:
KFCAdd(const TQString &name, Container* document);
virtual void execute();
virtual void unexecute();
/**
* Collects all elements that are to be added.
*/
void addElement(BasicElement* element) { addList.append(element); }
private:
/**
* the list where all elements are stored that are removed
* from the tree.
*/
TQPtrList<BasicElement> addList;
};
/**
* Command that is used to remove the current selection
* if we want to replace it with another element.
*/
class KFCRemoveSelection : public Command
{
public:
/**
* generic add command, default implementation do nothing
*/
KFCRemoveSelection(Container* document,
Direction dir = beforeCursor);
virtual void execute();
virtual void unexecute();
private:
/**
* the list where all elements are stored that are removed
* from the tree.
*/
TQPtrList<BasicElement> removedList;
Direction dir;
};
/**
* Removes the current selection and adds any new elements
* afterwards.
*/
class KFCReplace : public KFCAdd
{
public:
KFCReplace(const TQString &name, Container* document);
~KFCReplace();
virtual void execute();
virtual void unexecute();
private:
/**
* The command that needs to be executed first if there is a selection.
*/
KFCRemoveSelection* removeSelection;
};
/**
* Command to add a token element, with content.
*/
class KFCAddToken : public Command
{
public:
KFCAddToken( const TQString &name, Container *document);
~KFCAddToken();
virtual void execute();
virtual void unexecute();
/**
* Collect all tokens that are to be added
*/
void addToken( BasicElement* element );
/**
* Collect content for each token
*/
void addContent( BasicElement* element, BasicElement* content ) {
contentList.find( element )->append( content );
}
private:
/**
* List where all token elements are stored.
*/
TQPtrList< BasicElement > tokenList;
/**
* Dictionary where all content elements are stored
*/
TQPtrDict< TQPtrList< BasicElement > > contentList;
};
/**
* Removes the current selection and adds any new tokens
* afterwards.
*/
class KFCReplaceToken : public KFCAddToken
{
public:
KFCReplaceToken(const TQString &name, Container* document);
~KFCReplaceToken();
virtual void execute();
virtual void unexecute();
private:
/**
* The command that needs to be executed first if there is a selection.
*/
KFCRemoveSelection* removeSelection;
};
/**
* Add and remove arbitrary token elements and their contents. This command
* add needed flexibility in order to remove and insert new tokens in the
* middle of a token, that is, splitting the token and creating new ones.
*/
class KFCSplitToken : public KFCAddToken
{
public:
KFCSplitToken(const TQString &name, Container* document);
~KFCSplitToken();
virtual void execute();
virtual void unexecute();
/**
* Collect cursor data that will be needed to do the stuff properly
*/
void addCursor( FormulaCursor* cursor ) { setExecuteCursor( cursor ); }
private:
/**
* The command that needs to be executed first if there is a selection.
*/
KFCRemoveSelection* removeSelection;
/**
* The list of elements that are splited into another token
*/
TQPtrList< BasicElement > splitList;
/**
* Information about cursor position where the split is made.
* Needed to restore splited elements.
*/
FormulaCursor::CursorData* splitCursor;
};
/**
* Command that is used to remove the currently
* selected element.
*/
class KFCRemove : public Command
{
public:
/**
* generic add command, default implementation do nothing
*/
KFCRemove(Container* document, Direction dir);
~KFCRemove();
virtual void execute();
virtual void unexecute();
/**
* A command might have no effect.
* @returns true if nothing happened.
*/
//virtual bool isSenseless() { return removedList.isEmpty(); }
private:
/**
* the list where all elements are stored that are removed
* from the tree.
*/
TQPtrList<BasicElement> removedList;
/**
* The element we might have extracted.
*/
BasicElement* element;
/**
* If this is a complex remove command we need to remember two
* cursor positions. The one after the first removal (this one)
* and another at the end.
*/
FormulaCursor::CursorData* simpleRemoveCursor;
Direction dir;
};
/**
* Command to remove the parent element.
*/
class KFCRemoveEnclosing : public Command
{
public:
KFCRemoveEnclosing(Container* document, Direction dir);
~KFCRemoveEnclosing();
virtual void execute();
virtual void unexecute();
private:
BasicElement* element;
Direction direction;
};
/**
* The command that takes the main child out of the selected
* element and replaces the element with it.
*/
class KFCAddReplacing : public Command
{
public:
KFCAddReplacing(const TQString &name, Container* document);
~KFCAddReplacing();
virtual void execute();
virtual void unexecute();
void setElement(BasicElement* e) { element = e; }
private:
/**
* The element that is to be inserted.
*/
BasicElement* element;
};
/**
* Add an index. The element that gets the index needs to be there
* already.
*/
class KFCAddGenericIndex : public KFCAdd
{
public:
KFCAddGenericIndex(Container* document, ElementIndexPtr index);
virtual void execute();
private:
ElementIndexPtr index;
};
class IndexElement;
/**
* Add an IndexElement.
*/
class KFCAddIndex : public KFCAddReplacing
{
public:
KFCAddIndex(Container* document, IndexElement* element, ElementIndexPtr index);
~KFCAddIndex();
virtual void execute();
virtual void unexecute();
private:
KFCAddGenericIndex addIndex;
};
class FormulaElement;
class KFCChangeBaseSize : public PlainCommand {
public:
KFCChangeBaseSize( const TQString& name, Container* document, FormulaElement* formula, int size );
void execute();
void unexecute();
private:
Container* m_document;
FormulaElement* m_formula;
int m_size;
int m_oldSize;
};
/**
* Base for all font commands that act on the current selection.
* Implements the visitor pattern. (Really?)
*/
class FontCommand : public Command {
public:
FontCommand( const TQString& name, Container* document );
/**
* Collects all elements that are to be modified.
*/
void addTextElement( TextElement* element ) { list.append(element); }
/**
* Collects all parent elements those children are to be changend.
*/
void addElement( BasicElement* element ) { elementList.append( element ); }
protected:
TQPtrList<TextElement>& childrenList() { return list; }
void collectChildren();
void parseSequences( const TQMap<SequenceElement*, int>& parents );
private:
/**
* the list where all elements are stored that are removed
* from the tree.
*/
TQPtrList<TextElement> list;
TQPtrList<BasicElement> elementList;
};
/**
* Changes the char style of a number of elements an their children.
*/
class CharStyleCommand : public FontCommand {
public:
CharStyleCommand( CharStyle cs, const TQString& name, Container* document );
virtual void execute();
virtual void unexecute();
private:
typedef TQValueVector<CharStyle> StyleList;
StyleList styleList;
CharStyle charStyle;
};
/**
* Changes the char family of a number of elements an their children.
*/
class CharFamilyCommand : public FontCommand {
public:
CharFamilyCommand( CharFamily cf, const TQString& name, Container* document );
virtual void execute();
virtual void unexecute();
private:
typedef TQValueVector<CharFamily> FamilyList;
FamilyList familyList;
CharFamily charFamily;
};
KFORMULA_NAMESPACE_END
#endif // KFORMULACOMMAND_H