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);
void Start(const String actionName);
void AddAction(const Action &action);
void AddActionStart(const Action &action);
public:
~ActionList();

View File

@ -1,71 +1,71 @@
// Copyright (c) 2008, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB/GORGONSUB
//
// Website: http://www.aegisub.net
// Contact: mailto:amz@aegisub.net
//
#pragma once
#include "gorgonstring.h"
#include "tr1.h"
#include "format.h"
namespace Gorgonsub {
// Prototypes
class Model;
class ActionList;
typedef shared_ptr<ActionList> ActionListPtr;
// Controller class
class Controller {
private:
Model &model;
public:
Controller (Model &model);
ActionListPtr CreateActionList(const String title,const String owner=L"",bool undoAble=true);
void LoadFile(const String filename,const String encoding=L"");
void SaveFile(const String filename,const String encoding=L"UTF-8");
bool CanUndo(const String owner=L"") const;
bool CanRedo(const String owner=L"") const;
void Undo(const String owner=L"");
void Redo(const String owner=L"");
SectionEntryDialoguePtr CreateDialogue();
SectionEntryStylePtr CreateStyle();
const FormatPtr GetFormat() const;
};
};
// Copyright (c) 2008, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB/GORGONSUB
//
// Website: http://www.aegisub.net
// Contact: mailto:amz@aegisub.net
//
#pragma once
#include "gorgonstring.h"
#include "tr1.h"
#include "format.h"
namespace Gorgonsub {
// Prototypes
class Model;
class ActionList;
typedef shared_ptr<ActionList> ActionListPtr;
// Controller class
class Controller {
private:
Model &model;
public:
Controller (Model &model);
ActionListPtr CreateActionList(const String title,const String owner=L"",bool undoAble=true);
void LoadFile(const String filename,const String encoding=L"");
void SaveFile(const String filename,const String encoding=L"UTF-8");
bool CanUndo(const String owner=L"") const;
bool CanRedo(const String owner=L"") const;
void Undo(const String owner=L"");
void Redo(const String owner=L"");
SectionEntryDialoguePtr CreateDialogue();
SectionEntryStylePtr CreateStyle();
const FormatPtr GetFormat() const;
};
};

View File

@ -68,18 +68,15 @@ namespace Gorgonsub {
bool readOnly;
FormatPtr format;
void ProcessActionList(const ActionList &actionList);
void DoActionList(const ActionListPtr list);
void ProcessActionList(const ActionList &actionList,int type=0);
void DoAction(const Action &action);
ActionListPtr CreateAntiActionList(const ActionListPtr &manipulator);
Action GetAntiAction(const Action &action);
bool CanUndo(const String owner=L"") const;
bool CanRedo(const String owner=L"") const;
void Undo(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;

View File

@ -42,6 +42,7 @@ using namespace Gorgonsub;
ActionList::ActionList(Model &_model,String _actionName,const String _owner,bool _undoAble)
: model(_model), owner(_owner), undoAble(_undoAble)
{
valid = false;
Start(_actionName);
}
@ -59,6 +60,23 @@ void ActionList::AddAction(const Action &action)
{
if (!valid) throw Exception(Exception::Invalid_ActionList);
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
void Model::ProcessActionList(const ActionList &_actionList)
void Model::ProcessActionList(const ActionList &_actionList,int type)
{
// Copy the list
ActionListPtr actions = ActionListPtr(new ActionList(_actionList));
// Inserts the opposite into the undo stack
if (actions->undoAble) {
undoStack.push(CreateAntiActionList(actions));
redoStack = ActionStack();
}
// Setup undo
ActionListPtr undo = ActionListPtr(new ActionList(actions->model,actions->actionName,actions->owner,actions->undoAble));
ActionStack *stack;
if (type == 1) stack = &redoStack;
else stack = &undoStack;
// Execute list
DoActionList(actions);
}
//////////////////////////
// Execute an action list
void Model::DoActionList(const ActionListPtr actions)
{
// Do each action
// Execute actions
std::list<Action>::const_iterator 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);
}
// Insert into undo stack
if (actions->undoAble) {
stack->push(undo);
if (type == 0) redoStack = ActionStack();
}
// Notify listeners
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
Action Model::GetAntiAction(const Action &action)
@ -286,7 +267,7 @@ bool Model::CanRedo(const String owner) const
// Perform an undo
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
void Model::Redo(const String owner)
{
ActivateStack(redoStack,undoStack,owner);
ActivateStack(redoStack,false,owner);
}
/////////////////////
// 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
(void) owner;
// Create opposite
to.push(CreateAntiActionList(from.top()));
// Process list
DoActionList(from.top());
ProcessActionList(*stack.top(),isUndo?1:2);
// Pop original
from.pop();
stack.pop();
}