Undo/redo on gorgon seem to work.

Originally committed to SVN as r2050.
This commit is contained in:
Rodrigo Braz Monteiro 2008-03-14 03:59:46 +00:00
parent 000271c087
commit 828ada86b0
5 changed files with 114 additions and 120 deletions

View file

@ -60,6 +60,7 @@ namespace Gorgonsub {
ActionList(Model &model,const String actionName,const String owner,bool undoAble); ActionList(Model &model,const String actionName,const String owner,bool undoAble);
void Start(const String actionName); void Start(const String actionName);
void AddAction(const Action &action); void AddAction(const Action &action);
void AddActionStart(const Action &action);
public: public:
~ActionList(); ~ActionList();

View file

@ -68,18 +68,15 @@ namespace Gorgonsub {
bool readOnly; bool readOnly;
FormatPtr format; FormatPtr format;
void ProcessActionList(const ActionList &actionList); void ProcessActionList(const ActionList &actionList,int type=0);
void DoActionList(const ActionListPtr list);
void DoAction(const Action &action); void DoAction(const Action &action);
ActionListPtr CreateAntiActionList(const ActionListPtr &manipulator);
Action GetAntiAction(const Action &action); Action GetAntiAction(const Action &action);
bool CanUndo(const String owner=L"") const; bool CanUndo(const String owner=L"") const;
bool CanRedo(const String owner=L"") const; bool CanRedo(const String owner=L"") const;
void Undo(const String owner=L""); void Undo(const String owner=L"");
void Redo(const String owner=L""); void Redo(const String owner=L"");
void ActivateStack(ActionStack &from,ActionStack &to,const String &owner); void ActivateStack(ActionStack &stack,bool isUndo,const String &owner);
void DispatchNotifications(const Notification &notification) const; void DispatchNotifications(const Notification &notification) const;

View file

@ -42,6 +42,7 @@ using namespace Gorgonsub;
ActionList::ActionList(Model &_model,String _actionName,const String _owner,bool _undoAble) ActionList::ActionList(Model &_model,String _actionName,const String _owner,bool _undoAble)
: model(_model), owner(_owner), undoAble(_undoAble) : model(_model), owner(_owner), undoAble(_undoAble)
{ {
valid = false;
Start(_actionName); Start(_actionName);
} }
@ -59,6 +60,23 @@ void ActionList::AddAction(const Action &action)
{ {
if (!valid) throw Exception(Exception::Invalid_ActionList); if (!valid) throw Exception(Exception::Invalid_ActionList);
actions.push_back(action); actions.push_back(action);
if (actions.size() > 2) {
int a = 0;
a++;
}
}
///////////////////////////////////////////
// Add an action to the start of the queue
void ActionList::AddActionStart(const Action &action)
{
if (!valid) throw Exception(Exception::Invalid_ActionList);
actions.push_front(action);
if (actions.size() > 2) {
int a = 0;
a++;
}
} }

View file

@ -58,32 +58,33 @@ void Model::DispatchNotifications(const Notification &notification) const
//////////////////////////// ////////////////////////////
// Processes an action list // Processes an action list
void Model::ProcessActionList(const ActionList &_actionList) void Model::ProcessActionList(const ActionList &_actionList,int type)
{ {
// Copy the list // Copy the list
ActionListPtr actions = ActionListPtr(new ActionList(_actionList)); ActionListPtr actions = ActionListPtr(new ActionList(_actionList));
// Inserts the opposite into the undo stack // Setup undo
if (actions->undoAble) { ActionListPtr undo = ActionListPtr(new ActionList(actions->model,actions->actionName,actions->owner,actions->undoAble));
undoStack.push(CreateAntiActionList(actions)); ActionStack *stack;
redoStack = ActionStack(); if (type == 1) stack = &redoStack;
} else stack = &undoStack;
// Execute list // Execute actions
DoActionList(actions);
}
//////////////////////////
// Execute an action list
void Model::DoActionList(const ActionListPtr actions)
{
// Do each action
std::list<Action>::const_iterator cur; std::list<Action>::const_iterator cur;
for (cur=actions->actions.begin();cur!=actions->actions.end();cur++) { for (cur=actions->actions.begin();cur!=actions->actions.end();cur++) {
// Inserts the opposite into the undo action first
if (actions->undoAble) undo->AddActionStart(GetAntiAction(*cur));
// Execute the action itself
DoAction(*cur); DoAction(*cur);
} }
// Insert into undo stack
if (actions->undoAble) {
stack->push(undo);
if (type == 0) redoStack = ActionStack();
}
// Notify listeners // Notify listeners
DispatchNotifications(Notification()); DispatchNotifications(Notification());
} }
@ -124,26 +125,6 @@ void Model::DoAction(const Action &action)
} }
//////////////////////////////////////////////////////////////////////
// Create an anti-actionlist to undo the actions made by a actionlist
ActionListPtr Model::CreateAntiActionList(const ActionListPtr &src)
{
// Create list
ActionListPtr dst(new ActionList(*this,src->actionName,src->owner,false));
// Insert anti-actions
std::list<Action>::const_reverse_iterator cur;
for (cur=src->actions.rbegin();cur!=src->actions.rend();cur++) {
//std::list<Action>::const_iterator cur;
//for (cur=src->actions.begin();cur!=src->actions.end();cur++) {
dst->AddAction(GetAntiAction(*cur));
}
// Return
return dst;
}
/////////////////////////////////////////// ///////////////////////////////////////////
// Create the action opposite to the input // Create the action opposite to the input
Action Model::GetAntiAction(const Action &action) Action Model::GetAntiAction(const Action &action)
@ -286,7 +267,7 @@ bool Model::CanRedo(const String owner) const
// Perform an undo // Perform an undo
void Model::Undo(const String owner) void Model::Undo(const String owner)
{ {
ActivateStack(undoStack,redoStack,owner); ActivateStack(undoStack,true,owner);
} }
@ -294,23 +275,20 @@ void Model::Undo(const String owner)
// Perform a redo // Perform a redo
void Model::Redo(const String owner) void Model::Redo(const String owner)
{ {
ActivateStack(redoStack,undoStack,owner); ActivateStack(redoStack,false,owner);
} }
///////////////////// /////////////////////
// Perform undo/redo // Perform undo/redo
void Model::ActivateStack(ActionStack &from,ActionStack &to,const String &owner) void Model::ActivateStack(ActionStack &stack,bool isUndo,const String &owner)
{ {
// TODO: do something with this // TODO: do something with this
(void) owner; (void) owner;
// Create opposite
to.push(CreateAntiActionList(from.top()));
// Process list // Process list
DoActionList(from.top()); ProcessActionList(*stack.top(),isUndo?1:2);
// Pop original // Pop original
from.pop(); stack.pop();
} }