/* This file is part of the KDE project Copyright (C) 2001 Andrea Rizzi Ulrich Kuettler 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 #include #include #include #include #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 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 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 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); KFCAddGenericIndex(KFCAddGenericIndex const &) = delete; KFCAddGenericIndex& operator=(KFCAddGenericIndex const &) = delete; 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& childrenList() { return list; } void collectChildren(); void parseSequences( const TQMap& parents ); private: /** * the list where all elements are stored that are removed * from the tree. */ TQPtrList list; TQPtrList 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 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 FamilyList; FamilyList familyList; CharFamily charFamily; }; KFORMULA_NAMESPACE_END #endif // KFORMULACOMMAND_H