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