From 828ada86b06bcda0b7b893f4e871f40f3bb151d5 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Fri, 14 Mar 2008 03:59:46 +0000 Subject: [PATCH] Undo/redo on gorgon seem to work. Originally committed to SVN as r2050. --- aegilib/include/aegilib/actionlist.h | 1 + aegilib/include/aegilib/controller.h | 142 +++++++++++++-------------- aegilib/include/aegilib/model.h | 7 +- aegilib/src/actionlist.cpp | 18 ++++ aegilib/src/model.cpp | 66 +++++-------- 5 files changed, 114 insertions(+), 120 deletions(-) diff --git a/aegilib/include/aegilib/actionlist.h b/aegilib/include/aegilib/actionlist.h index 1922322fe..17570f639 100644 --- a/aegilib/include/aegilib/actionlist.h +++ b/aegilib/include/aegilib/actionlist.h @@ -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(); diff --git a/aegilib/include/aegilib/controller.h b/aegilib/include/aegilib/controller.h index 15cf423b4..f347fbf8f 100644 --- a/aegilib/include/aegilib/controller.h +++ b/aegilib/include/aegilib/controller.h @@ -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 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 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; + }; + +}; diff --git a/aegilib/include/aegilib/model.h b/aegilib/include/aegilib/model.h index 5a1517f43..32b112120 100644 --- a/aegilib/include/aegilib/model.h +++ b/aegilib/include/aegilib/model.h @@ -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; diff --git a/aegilib/src/actionlist.cpp b/aegilib/src/actionlist.cpp index d2fa2303c..9b6fbc733 100644 --- a/aegilib/src/actionlist.cpp +++ b/aegilib/src/actionlist.cpp @@ -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++; + } } diff --git a/aegilib/src/model.cpp b/aegilib/src/model.cpp index 9874c1edb..1b557e779 100644 --- a/aegilib/src/model.cpp +++ b/aegilib/src/model.cpp @@ -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::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::const_reverse_iterator cur; - for (cur=src->actions.rbegin();cur!=src->actions.rend();cur++) { - //std::list::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(); }