forked from mia/Aegisub
Undo/redo on gorgon seem to work.
Originally committed to SVN as r2050.
This commit is contained in:
parent
000271c087
commit
828ada86b0
5 changed files with 114 additions and 120 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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 ¬ification) const;
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,32 +58,33 @@ void Model::DispatchNotifications(const Notification ¬ification) 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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue