File indexing completed on 2024-05-12 16:23:27

0001 /***************************************************************************
0002  *   Copyright (C) 2013 by Linuxstopmotion contributors;                   *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 
0021 #ifndef COMMAND_H_
0022 #define COMMAND_H_
0023 
0024 #include <stdint.h>
0025 #include <string>
0026 
0027 class CommandList;
0028 class FileNameVisitor;
0029 class UndoRedoObserver;
0030 class ErrorHandler;
0031 
0032 /**
0033  * Base class of all command classes, objects of which are manipulated by the
0034  * undo system. Most commands should derive from CommandAtomic.
0035  */
0036 class Command {
0037     Command(const Command&);
0038     Command& operator=(const Command&);
0039 public:
0040     Command();
0041     virtual ~Command() = 0;
0042     /**
0043      * Performs its action, creating a NullAdder from inverseStack once only to
0044      * add its inverse to the history. For exception safety the model must not
0045      * be updated until the inverse command has been constructed and all
0046      * necessary memory preallocations have been done to enable an atomic
0047      * update of the model.
0048      * @par
0049      * This command must delete itself within the {@c execute} method, unless
0050      * it returns itself as its own inverse or otherwise recycles itself.
0051      * @return The inverse command; ownership is relinquished.
0052      */
0053     virtual Command* execute() = 0;
0054     /**
0055      * calls v.Add(f) for each file f referenced by the command
0056      */
0057     virtual void accept(FileNameVisitor& v) const;
0058 };
0059 
0060 /**
0061  * A command factory reads the parameters for its command from here. They
0062  * either come from a log file (if it is being replayed) or from the
0063  * application.
0064  */
0065 class Parameters {
0066 public:
0067     virtual ~Parameters() = 0;
0068     /**
0069      * Returns an integer. Might throw IncorrectParameterException if
0070      * unsuccessful, but this behaviour must not be relied upon.
0071      * @param min The minimum permissible value that could be returned based
0072      * on the current state of the model being altered.
0073      * @param max The maximum permissible value that could be returned based
0074      * on the current state of the model being altered.
0075      * @note @a min and @a max are used by @ref TestUndo in order to create
0076      * commands that are appropriate for testing. They are also used to assert
0077      * that the values passed to @ref Executor::Execute are within range.
0078      */
0079     virtual int32_t getInteger(int32_t min, int32_t max) = 0;
0080     /**
0081      * Returns an integer from 1 to {@c 1^31-1}. Test code assumes that smaller
0082      * numbers are just as good a test as larger numbers, unlike
0083      * {@ref getInteger}, which assumes the full range must be tested.
0084      */
0085     virtual int32_t getHowMany();
0086     /**
0087      * Returns a string. If the parameters come from test code, the string will
0088      * match the pattern provided. The pattern is ignored in normal code and
0089      * may be null.
0090      * @param out The returned string.
0091      * @param pattern The pattern to which the output should conform; with a
0092      * random alphanumeric character replacing each {@c ?} and a random
0093      * (possibly zero-length) string of such characters replacing each {@c *}.
0094      * Ignored in non-test code. If null, a string of at length at least one is
0095      * produced.
0096      */
0097     virtual void getString(std::string& out, const char* pattern) = 0;
0098 };
0099 
0100 /**
0101  * Produces one sort of command.
0102  */
0103 class CommandFactory {
0104 public:
0105     virtual ~CommandFactory() = 0;
0106     /**
0107      * Creates a command from the Parameters given in ps.
0108      * @param The source of parameters to use, ownership is not passed.
0109      * @param e An error handler that collects errors that would have been thrown.
0110      * @return The command created, ownership is returned. @c NULL is returned
0111      * if no such command can be created at the moment (for example a delete
0112      * when the model is empty).
0113      */
0114     virtual Command* create(Parameters& ps, ErrorHandler& e) = 0;
0115 };
0116 
0117 /**
0118  * Creates a command that does nothing. This can be used whenever a command's
0119  * {@ref Command::execute} function discovers that it does nothing, and it
0120  * wants to return an inverse that also does nothing.
0121  * @return New command that does nothing. Ownership is passed.
0122  */
0123 Command* createNullCommand();
0124 
0125 /**
0126  * Command history for undo and redo.
0127  */
0128 class CommandHistory {
0129     CommandList* past;
0130     CommandList* future;
0131     UndoRedoObserver* observer;
0132     bool previousCanUndo;
0133     bool previousCanRedo;
0134     void notifyObserver();
0135 public:
0136     CommandHistory();
0137     ~CommandHistory();
0138     /**
0139      * Sets a new observer to be notified when the functions {@ref canUndo} and
0140      * {@ref canRedo} change what they would return.
0141      * @param observer The new observer. Any previous observer is unset. A null
0142      * pointer means that the old observer will be unset and no new observer
0143      * will be set. Ownership is not passed.
0144      */
0145     void setUndoRedoObserver(UndoRedoObserver* observer);
0146     /**
0147      * Returns 'true' if and only if Undo will perform an action, i.e. if
0148      * there are any actions in the history to undo.
0149      */
0150     bool canUndo() const;
0151     /**
0152      * Returns 'true' if and only if Redo will perform an action, i.e. if
0153      * there are any actions in the history to redo.
0154      */
0155     bool canRedo() const;
0156     /**
0157      * Undoes the last action in the history, if any.
0158      */
0159     void undo();
0160     /**
0161      * Redoes the next action in the history, if any.
0162      */
0163     void redo();
0164     /**
0165      * Executes the command c, placing its inverse into the undo history,
0166      * deleting the Redo history. Any partial composite function remaining
0167      * after a thrown exception will be on the Redo stack. Ownership of
0168      * the command is passed.
0169      * @param c The command to be executed.
0170      */
0171     void execute(Command& c);
0172     /**
0173      * Clears all the undo history (and future)
0174      */
0175     void clear();
0176     /**
0177      * Calls v.add(f) for each filename f referenced by the commands in the
0178      * history.
0179      */
0180     void accept(FileNameVisitor& v) const;
0181 };
0182 
0183 #endif /* COMMAND_H_ */