Implement undo/redo history for dialog text fields

- Also fixed a minor issue with pasting (the character before the insertion point was removed before pasting)
This commit is contained in:
2015-06-05 15:07:28 -04:00
parent 4fa22a34f1
commit d398bfaa80
5 changed files with 199 additions and 36 deletions

View File

@@ -8,23 +8,34 @@
#include "undo.hpp"
cAction::~cAction() {}
cUndoList::cUndoList(){
lastSave = cur = theList.begin();
}
size_t cUndoList::maxUndoSize = 0;
size_t cUndoList::maxUndoSize = 50;
// TODO: These functions should have error checking to ensure they do not access an out of bounds action
void cUndoList::undo(){
if(noUndo()) return;
(*cur)->undo();
cur--;
cur++;
}
void cUndoList::redo(){
cur++;
if(noRedo()) return;
cur--;
(*cur)->redo();
}
bool cUndoList::noUndo() {
return cur == theList.end();
}
bool cUndoList::noRedo() {
return cur == theList.begin();
}
void cUndoList::save(){
lastSave = cur;
}
@@ -33,8 +44,18 @@ void cUndoList::revert(){
while(cur != lastSave) undo();
}
void cUndoList::add(cAction* what){
theList.push_back(what);
num_actions++;
while(num_actions > maxUndoSize) theList.pop_front(), num_actions--;
void cUndoList::clear() {
theList.clear();
}
void cUndoList::add(action_ptr what){
if(!what) return;
theList.erase(theList.begin(), cur);
theList.push_front(what);
num_actions++;
while(num_actions > maxUndoSize) {
theList.pop_back();
num_actions--;
}
cur = theList.begin();
}

View File

@@ -10,27 +10,38 @@
*/
#include <list>
#include <memory>
#include <string>
class cAction {
std::string actname;
protected:
bool done = false;
public:
virtual void undo() = 0; // undoes this action if it has not already been undone
virtual void redo() = 0; // redoes this action if it has been undone
virtual bool isDone() = 0; // checks to see whether the action has been undone; returns false if it has
virtual std::string getActionName() = 0; // returns the name of this action for display in the Edit menu
cAction(std::string name) : actname(name) {}
virtual void undo() = 0; ///< Undoes this action if it has not already been undone
virtual void redo() = 0; ///< Redoes this action if it has been undone
bool isDone() {return done;}; ///< checks to see whether the action has been undone; returns false if it has
std::string getActionName() {return actname;} ///< returns the name of this action for display in the Edit menu
virtual ~cAction();
};
using action_ptr = std::shared_ptr<cAction>;
class cUndoList {
std::list<cAction*> theList;
std::list<cAction*>::iterator cur, lastSave;
size_t num_actions;
std::list<action_ptr> theList;
std::list<action_ptr>::iterator cur, lastSave;
size_t num_actions = 0;
public:
cUndoList();
void undo(); // undoes the current action and decrements the cur pointer
void redo(); // increments the cur pointer and redoes the current action
void save(); // sets the last saved action to the current action
void revert(); // undoes all actions back to (but excluding) the last saved action
void add(cAction* what);
void undo(); ///< Undoes the current action and decrements the cur pointer
void redo(); ///< Increments the cur pointer and redoes the current action
void save(); ///< Sets the last saved action to the current action
void revert(); ///< Undoes all actions back to (but excluding) the last saved action
void clear(); ///< Clears the list
bool noUndo(); ///< Check whether there's an action to undo
bool noRedo(); ///< Check whether there's an action to redo
void add(action_ptr what);
static size_t maxUndoSize;
};