Česky
Kamil Dudka

GED 2006 (C++)

File detail

Name:Downloadcommand.h [Download]
Location: ged2006 > src
Size:6.0 KB
Last modification:2007-08-29 02:16

Source code

/*
 * File: command.h - Command abstraction and command history
 * Project: GED - bitmap editor (ICP)
 * Author: Kamil Dudka, xdudka00
 * Team: xdudka00, xfilak01, xhefka00, xhradi08
 * Created: 2006-03-10
 */
 
#ifndef COMMAND_H
#define COMMAND_H
 
#include <list>
#include <string>
 
#include "framebuffer.h"
 
class GedMacroCommand;
 
/**
 * Virtual class command. This class is base for all drawing commands and operation.
 * This is needed especially for undo/redo support and macros support.
 * For more information see the CmdHistory class.
 * Design pattern command.
 */
class Cmd {
public:
	virtual ~Cmd () { }			///< All Cmd based classes will have virtual destructor.
	virtual void exec () = 0;		///< Command execution. This should save undo informations.
	virtual void unExec () = 0;		///< Revert command execution using undo informations.
	virtual std::string name () = 0;	///< Command identification. This will appear in config file.
	virtual std::string args () = 0;	///< Command export to text string. Needed for macro saving.
 
protected:
	/**
	 * Initialize base.
	 * \param pFB Pointer to frame buffer to work with.
	 */
	Cmd (FrameBuffer *pFB): _fb (*pFB) { }
 
	/**
	 * Frame buffer reference. All derived class should use this reference.
	 */
	FrameBuffer &_fb;
 
	/**
	 * Needed to obtain Cmd::_fb while creating MacroCmd
	 */
	friend class CmdHistory;
};
 
/**
 * Very simple (and slow) undo for commands.
 * This class save whole frame buffer on exec() method call.
 * This is used for (untrusted) plugin call.
 */
class SlowUndoCmd: public Cmd {
public:
	virtual void exec () { _savePoint = _fb; }	///< Save current frame buffer as undo information.
	virtual void unExec () { _fb = _savePoint; }	///< Restore saved frame buffer.
	virtual std::string name () = 0;
	virtual std::string args () = 0;
 
protected:
	/**
	 * Initialize base.
	 * \param pFB Pointer to frame buffer to work with.
	 */
	SlowUndoCmd (FrameBuffer *pFB): Cmd (pFB) { }
 
private:
	FrameBuffer _savePoint;				///< Saved frame buffer
};
 
 
/**
 * Simple and slow undo (as SlowUndoCmd), but works only with selected area.
 * See SlowUndoCmd documentation for more information.
 */
class SlowUndoSelectCmd: public Cmd {
public:
	virtual void exec ();
	virtual void unExec ();
	virtual std::string name () = 0;
	virtual std::string args () = 0;
 
protected:
	/**
	 * Initialize base.
	 * \param pFB Pointer to frame buffer to work with.
	 */
	SlowUndoSelectCmd (FrameBuffer *pFB): Cmd (pFB) { }
 
private:
	Rect _sa;
	FrameBuffer _fbUndo;
};
 
/**
 * Plugin call command
 */
class PluginCmd: public SlowUndoCmd {
public:
	/**
	 * Initialize plugin command.
	 * \param pFB Pointer to frame buffer to work with.
	 * \param pluginName Plugin name (identification)
	 * \param args Plugin arguments passed to plugin.
	 */
	PluginCmd (FrameBuffer *pFB, std::string pluginName, std::string args):
		SlowUndoCmd (pFB),
		_pluginName (pluginName),
		_pluginArgs (args) { }
 
	virtual void exec ();
	virtual std::string name () { return _pluginName; }
	virtual std::string args () { return _pluginArgs; }
 
private:
	std::string _pluginName;
	std::string _pluginArgs;
};
 
/**
 * Macro command abstraction. Design patterns: command, composite
 */
class MacroCmd: public Cmd {
public:
	/**
	 * Initialize base.
	 * \param pFB Pointer to frame buffer to work with.
	 */
	MacroCmd (FrameBuffer *pFB): Cmd (pFB) { }
 
	/**
	 * Read macro from configuration file.
	 * \param pFB Pointer to frame buffer to work with.
	 * \param macName Macro name.
	 */
	MacroCmd (FrameBuffer *pFB, std::string macName);
 
	/**
	 * Put command to MacroCmd. *pCmd object must exist all the time since MacroCmd object is destroyed.
	 * \param pCmd pointer to command.
	 * \return Reference to this. Needed for << operator concatenation.
	 */
	MacroCmd &operator<< (Cmd *pCmd);
 
	/**
	 * Execute macro command.
	 * This means all elementary commands are executed.
	 */
	virtual void exec ();
 
	/**
	 * Undo macro command.
	 * This means all elementary commands are unexecuted in reverse order.
	 */
	virtual void unExec ();
 
	virtual std::string name () { return szCmdName; }
	virtual std::string args () { return _macName; }
 
	/**
	 * Set macro name.
	 * \param name New macro name.
	 */
	void name (std::string name) { _macName = name; }
 
	/**
	 * Save macro to configuration file.
	 */
	void save ();
 
	static const char *szCmdName;				///< Command id string.
 
private:
	void addFromConf (GedMacroCommand &);
	void addToConf (Cmd *);
 
	std::list<Cmd *> _cmdList;
	std::list<Cmd *>::iterator _crashPoint;
	std::string _macName;
};
 
/**
 * Class maintaing command history and macro recording. This is one of base classes for Image class.
 */
class CmdHistory {
public:
	CmdHistory ();
	~CmdHistory ();
 
	/**
	 * Put command to history list.
	 * *pCmd object must by allocated on the heap and can never be destroyed. CmdHistory destroys it.
	 * \param pCmd Pointer to command.
	 * \return Reference to this. Needed for << operator concatenation.
	 */
	CmdHistory &operator<< (Cmd *pCmd);
 
	int undoAvailable () const;		///< How many undo step is available.
	bool canUndo () const;			///< True if undo is possible.
	bool canRedo () const;			///< True if redo is possible.
 
	void rollBack ();			///< Cancel last operation. Needed if command crashes during execution.
	void undo ();				///< Undo last command.
	void redo ();				///< Undo last undo.
 
	bool needSave ();			///< True if image has changed since last saving.
	void setSaved ();			///< May be called when document is saved.
 
	/**
	 * Start macro loading.
	 */
	void startMacro ();
 
	/**
	 * Create new macro. Note that startMacro method should be called first.
	 * \return Return pointer to on heap allocated MacroCmd.
	 */
	MacroCmd *createMacroCmd ();
 
	/**
	 * This is an exception thrown from CmdHistory if operation is not permitted. This should never happen.
	 * Use canUndo(), canRedo() or undoAvailable() methods to avoid this exception.
	 */
	class ErrUnderflow { };
 
private:
	std::list<Cmd *> _histList;
	std::list<Cmd *>::iterator _now;
	int _iMacroOffset;
	int _iLastSave;
	bool _bSavePointLost;
	bool _bMacroLoading;
};
 
#endif