Remove ancient trunk folder from svn repository
[synfig.git] / synfig-studio / trunk / src / synfigapp / action_system.cpp
diff --git a/synfig-studio/trunk/src/synfigapp/action_system.cpp b/synfig-studio/trunk/src/synfigapp/action_system.cpp
deleted file mode 100644 (file)
index 7aef925..0000000
+++ /dev/null
@@ -1,704 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file action_system.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "action_system.h"
-#include "instance.h"
-#include "canvasinterface.h"
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfigapp;
-using namespace synfig;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-
-
-Action::System::System():
-       action_count_(0)
-{
-       unset_ui_interface();
-       clear_redo_stack_on_new_action_=false;
-}
-
-Action::System::~System()
-{
-}
-
-bool
-Action::System::perform_action(etl::handle<Action::Base> action)
-{
-       //// debug actions
-       // synfig::info("%s:%d perform_action: '%s'", __FILE__, __LINE__, action->get_name().c_str());
-
-       handle<UIInterface> uim(get_ui_interface());
-
-       assert(action);
-
-       if(!action->is_ready())
-       {
-               uim->error(action->get_local_name()+": "+_("Action is not ready."));
-               return false;
-       }
-
-       most_recent_action_=action;
-
-       static bool inuse=false;
-
-       if(inuse) return false;
-
-       inuse=true;
-       try {
-
-       assert(action);
-
-       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
-
-       if(canvas_specific && canvas_specific->get_canvas())
-       {
-               handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas_specific->get_canvas());
-               assert(canvas_interface);
-               uim=canvas_interface->get_ui_interface();
-       }
-
-       handle<Action::Undoable> undoable_action=handle<Action::Undoable>::cast_dynamic(action);
-
-       // If we cannot undo this action, make sure
-       // that the user knows this.
-       if(!undoable_action)
-       {
-               if(uim->yes_no(
-                       action->get_local_name(),
-                       _("This action cannot be undone! Are you sure you want to continue?"),
-                       UIInterface::RESPONSE_NO
-                       ) == UIInterface::RESPONSE_NO
-               )
-                       return false;
-               else
-               {
-                       // Because this action cannot be undone,
-                       // we need to clear the undo stack
-                       clear_undo_stack();
-               }
-       }
-       else
-               assert(undoable_action->is_active());
-
-       // Perform the action
-       try { action->perform(); }
-       catch(Action::Error err)
-       {
-               uim->task(action->get_local_name()+' '+_("Failed"));
-               inuse=false;
-
-               if(err.get_type()!=Action::Error::TYPE_UNABLE)
-               {
-                       if(err.get_desc().empty())
-                               uim->error(action->get_local_name()+": "+strprintf("%d",err.get_type()));
-                       else
-                               uim->error(action->get_local_name()+": "+err.get_desc());
-               }
-
-               // If action failed for whatever reason, just return false and do
-               // not add the action onto the list
-               return false;
-       }
-       catch(std::exception err)
-       {
-               uim->task(action->get_local_name()+' '+_("Failed"));
-               inuse=false;
-
-               uim->error(action->get_local_name()+": "+err.what());
-
-               // If action failed for whatever reason, just return false and do
-               // not add the action onto the list
-               return false;
-       }
-       catch(...)
-       {
-               uim->task(action->get_local_name()+' '+_("Failed"));
-               inuse=false;
-
-               // If action failed for whatever reason, just return false and do
-               // not add the action onto the list
-               return false;
-       }
-
-       // Clear the redo stack
-       if(clear_redo_stack_on_new_action_)
-               clear_redo_stack();
-
-       if(!group_stack_.empty())
-               group_stack_.front()->inc_depth();
-       else
-               inc_action_count();
-
-       // Push this action onto the action list if we can undo it
-       if(undoable_action)
-       {
-               // If necessary, signal the change in status of undo
-               if(undo_action_stack_.empty()) signal_undo_status_(true);
-
-               // Add it to the list
-               undo_action_stack_.push_front(undoable_action);
-
-               // Signal that a new action has been added
-               if(group_stack_.empty())
-                       signal_new_action()(undoable_action);
-       }
-
-       inuse=false;
-
-       uim->task(action->get_local_name()+' '+_("Successful"));
-
-       // If the action has "dirtied" the preview, signal it.
-       if(0)if(canvas_specific && canvas_specific->is_dirty())
-       {
-               Canvas::Handle canvas=canvas_specific->get_canvas();
-               if(!group_stack_.empty())
-                       group_stack_.front()->request_redraw(canvas_specific->get_canvas_interface());
-               else
-               {
-                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
-                       assert(canvas_interface);
-                       //canvas_interface->signal_dirty_preview()();
-               }
-       }
-
-       }catch(...) { inuse=false; throw; }
-
-       return true;
-}
-
-bool
-synfigapp::Action::System::undo_(etl::handle<UIInterface> uim)
-{
-       handle<Action::Undoable> action(undo_action_stack().front());
-       most_recent_action_=action;
-
-       try { if(action->is_active()) action->undo(); }
-       catch(Action::Error err)
-       {
-               if(err.get_type()!=Action::Error::TYPE_UNABLE)
-               {
-                       if(err.get_desc().empty())
-                               uim->error(action->get_local_name()+_(" (Undo): ")+strprintf("%d",err.get_type()));
-                       else
-                               uim->error(action->get_local_name()+_(" (Undo): ")+err.get_desc());
-               }
-
-               return false;
-       }
-       catch(std::runtime_error x)
-       {
-               uim->error(x.what());
-               return false;
-       }
-       catch(...)
-       {
-               return false;
-       }
-
-       dec_action_count();
-
-       if(redo_action_stack_.empty())  signal_redo_status()(true);
-
-       redo_action_stack_.push_front(undo_action_stack_.front());
-       undo_action_stack_.pop_front();
-
-       if(undo_action_stack_.empty())  signal_undo_status()(false);
-
-       if(!group_stack_.empty())
-               group_stack_.front()->dec_depth();
-
-       signal_undo_();
-
-       return true;
-}
-
-bool
-synfigapp::Action::System::undo()
-{
-       //! \todo This function is not exception safe!
-       static bool inuse=false;
-
-       // If there is nothing on the action list, there is nothing to undo
-       if(undo_action_stack().empty() || inuse)
-               return false;
-
-       handle<Action::Undoable> action=undo_action_stack().front();
-       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
-
-       handle<UIInterface> uim;
-       if(canvas_specific && canvas_specific->get_canvas())
-       {
-               Canvas::Handle canvas=canvas_specific->get_canvas();
-               handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
-               assert(canvas_interface);
-               uim=canvas_interface->get_ui_interface();
-       }
-       else
-               uim=get_ui_interface();
-
-       inuse=true;
-
-       if(!undo_(uim))
-       {
-               uim->error(undo_action_stack_.front()->get_local_name()+": "+_("Failed to undo."));
-               inuse=false;
-               return false;
-       }
-
-       inuse=false;
-
-       // If the action has "dirtied" the preview, signal it.
-       if(0)if(action->is_active() && canvas_specific && canvas_specific->is_dirty())
-       {
-               Canvas::Handle canvas=canvas_specific->get_canvas();
-               if(!group_stack_.empty())
-                       group_stack_.front()->request_redraw(canvas_specific->get_canvas_interface());
-               else
-               {
-                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
-                       assert(canvas_interface);
-                       //canvas_interface->signal_dirty_preview()();
-               }
-       }
-
-       return true;
-}
-
-bool
-Action::System::redo_(etl::handle<UIInterface> uim)
-{
-       handle<Action::Undoable> action(redo_action_stack().front());
-       most_recent_action_=action;
-
-       try { if(action->is_active()) action->perform(); }
-       catch(Action::Error err)
-       {
-               if(err.get_type()!=Action::Error::TYPE_UNABLE)
-               {
-                       if(err.get_desc().empty())
-                               uim->error(action->get_local_name()+_(" (Redo): ")+strprintf("%d",err.get_type()));
-                       else
-                               uim->error(action->get_local_name()+_(" (Redo): ")+err.get_desc());
-               }
-
-               return false;
-       }
-       catch(std::runtime_error x)
-       {
-               uim->error(x.what());
-               return false;
-       }
-       catch(...)
-       {
-               return false;
-       }
-
-       inc_action_count();
-
-       if(undo_action_stack_.empty())  signal_undo_status()(true);
-
-       undo_action_stack_.push_front(redo_action_stack_.front());
-       redo_action_stack_.pop_front();
-
-       if(redo_action_stack_.empty())  signal_redo_status()(false);
-
-       if(!group_stack_.empty())
-               group_stack_.front()->inc_depth();
-
-       signal_redo_();
-
-       return true;
-}
-
-bool
-Action::System::redo()
-{
-       //! \todo This function is not exception safe!
-       static bool inuse=false;
-
-       // If there is nothing on the action list, there is nothing to undo
-       if(redo_action_stack_.empty() || inuse)
-               return false;
-
-       inuse=true;
-
-       handle<Action::Undoable> action=redo_action_stack().front();
-       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
-
-       handle<UIInterface> uim;
-       if(canvas_specific && canvas_specific->get_canvas())
-       {
-               Canvas::Handle canvas=canvas_specific->get_canvas();
-               handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
-               assert(canvas_interface);
-               uim=canvas_interface->get_ui_interface();
-       }
-       else
-               uim=get_ui_interface();
-
-       if(!redo_(uim))
-       {
-               uim->error(redo_action_stack_.front()->get_local_name()+": "+_("Failed to redo."));
-               inuse=false;
-               return false;
-       }
-
-       inuse=false;
-
-       // If the action has "dirtied" the preview, signal it.
-       if(0)if(action->is_active() && canvas_specific && canvas_specific->is_dirty())
-       {
-               Canvas::Handle canvas=canvas_specific->get_canvas();
-               if(!group_stack_.empty())
-                       group_stack_.front()->request_redraw(canvas_specific->get_canvas_interface());
-               else
-               {
-                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
-                       assert(canvas_interface);
-                       //canvas_interface->signal_dirty_preview()();
-               }
-       }
-
-       return true;
-}
-
-void
-Action::System::inc_action_count()const
-{
-       action_count_++;
-       if(action_count_==1)
-               signal_unsaved_status_changed_(true);
-       if(!action_count_)
-               signal_unsaved_status_changed_(false);
-}
-
-void
-Action::System::dec_action_count()const
-{
-       action_count_--;
-       if(action_count_==-1)
-               signal_unsaved_status_changed_(true);
-       if(!action_count_)
-               signal_unsaved_status_changed_(false);
-}
-
-void
-Action::System::reset_action_count()const
-{
-       if(!action_count_)
-               return;
-
-       action_count_=0;
-       signal_unsaved_status_changed_(false);
-}
-
-void
-Action::System::clear_undo_stack()
-{
-       if(undo_action_stack_.empty()) return;
-       undo_action_stack_.clear();
-       signal_undo_status_(false);
-       signal_undo_stack_cleared_();
-}
-
-void
-Action::System::clear_redo_stack()
-{
-       if(redo_action_stack_.empty()) return;
-       redo_action_stack_.clear();
-       signal_redo_status_(false);
-       signal_redo_stack_cleared_();
-}
-
-bool
-Action::System::set_action_status(etl::handle<Action::Undoable> action, bool x)
-{
-       Stack::iterator iter;
-       int failed=false;
-
-       if(action->is_active()==x)
-               return true;
-
-       handle<Action::Undoable> cur_pos=undo_action_stack_.front();
-
-       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
-
-       handle<UIInterface> uim=new ConfidentUIInterface();
-
-       iter=find(undo_action_stack_.begin(),undo_action_stack_.end(),action);
-       if(iter!=undo_action_stack_.end())
-       {
-               while(undo_action_stack_.front()!=action)
-               {
-                       if(!undo_(uim))
-                       {
-                               return false;
-                       }
-               }
-               if(!undo_(uim))
-               {
-                       return false;
-               }
-
-               action->set_active(x);
-
-               if(redo_(get_ui_interface()))
-               {
-                       signal_action_status_changed_(action);
-               }
-               else
-               {
-                       action->set_active(!x);
-                       failed=true;
-               }
-
-
-               while(undo_action_stack_.front()!=cur_pos)
-               {
-                       if(!redo_(uim))
-                       {
-                               redo_action_stack_.front()->set_active(false);
-                               signal_action_status_changed_(redo_action_stack_.front());
-                       }
-               }
-
-               if(!failed && canvas_specific && canvas_specific->is_dirty())
-               {
-                       Canvas::Handle canvas=canvas_specific->get_canvas();
-                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
-                       assert(canvas_interface);
-                       //canvas_interface->signal_dirty_preview()();
-               }
-
-               return true;
-       }
-
-       iter=find(redo_action_stack_.begin(),redo_action_stack_.end(),action);
-       if(iter!=redo_action_stack_.end())
-       {
-               action->set_active(x);
-               signal_action_status_changed_(action);
-
-
-
-
-               if(canvas_specific && canvas_specific->is_dirty())
-               {
-                       Canvas::Handle canvas=canvas_specific->get_canvas();
-                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
-                       assert(canvas_interface);
-                       //canvas_interface->signal_dirty_preview()();
-               }
-
-               return true;
-       }
-
-       return false;
-}
-
-Action::PassiveGrouper::PassiveGrouper(etl::loose_handle<System> instance_,synfig::String name_):
-       instance_(instance_),
-       name_(name_),
-       redraw_requested_(false),
-       depth_(0)
-{
-       // Add this group onto the group stack
-       instance_->group_stack_.push_front(this);
-}
-
-void
-Action::PassiveGrouper::request_redraw(etl::handle<CanvasInterface> x)
-{
-/*     if(instance_->group_stack_.empty())
-       {
-               if(x!=canvas_interface_)
-               {
-                       x->signal_dirty_preview()();
-               }
-
-               redraw_requested_=false;
-       }
-       else
-       {
-               if(instance_->group_stack_.back()==this)
-               {
-                       redraw_requested_=true;
-               }
-               else
-               {
-                       instance_->group_stack_.back()->request_redraw(x);
-                       redraw_requested_=false;
-               }
-       }
-*/
-       if(x)
-       {
-               redraw_requested_=true;
-               canvas_interface_=x;
-       }
-}
-
-Action::PassiveGrouper::~PassiveGrouper()
-{
-       assert(instance_->group_stack_.front()==this);
-
-       // Remove this group from the group stack
-       instance_->group_stack_.pop_front();
-
-       handle<Action::Group> group;
-
-       if(depth_==1)
-       {
-               handle<Action::Undoable> action(instance_->undo_action_stack_.front());
-
-               group=handle<Action::Group>::cast_dynamic(action);
-
-               if(group)
-               {
-                       // If the only action inside of us is a group,
-                       // then we should rename the group to our name.
-                       group->set_name(name_);
-               }
-               else
-               {
-                       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
-
-                       if(0)if(canvas_specific && canvas_specific->is_dirty() && canvas_specific->get_canvas_interface())
-                       {
-                               if(instance_->group_stack_.empty())
-                                       request_redraw(canvas_specific->get_canvas_interface());
-                       }
-               }
-
-               if(instance_->group_stack_.empty())
-               {
-                       instance_->inc_action_count();
-                       instance_->signal_new_action()(instance_->undo_action_stack_.front());
-               }
-               else
-                       instance_->group_stack_.front()->inc_depth();
-
-       }
-       else
-       if(depth_>0)
-       {
-               group=new Action::Group(name_);
-
-               for(int i=0;i<depth_;i++)
-       //      for(;depth_;depth_--)
-               {
-                       handle<Action::Undoable> action(instance_->undo_action_stack_.front());
-                       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
-
-                       if(0)if(canvas_specific && canvas_specific->is_dirty())
-                       {
-                               group->set_dirty(true);
-                               group->set_canvas(canvas_specific->get_canvas());
-                               group->set_canvas_interface(canvas_specific->get_canvas_interface());
-                       }
-
-                       // Copy the action from the undo stack to the group
-                       group->add_action_front(action);
-
-                       // Remove the action from the undo stack
-                       instance_->undo_action_stack_.pop_front();
-               }
-
-               // Push the group onto the stack
-               instance_->undo_action_stack_.push_front(group);
-
-               if(0)if(group->is_dirty())
-                       request_redraw(group->get_canvas_interface());
-               //      group->get_canvas_interface()->signal_dirty_preview()();
-
-               if(instance_->group_stack_.empty())
-               {
-                       instance_->inc_action_count();
-                       instance_->signal_new_action()(instance_->undo_action_stack_.front());
-               }
-               else
-                       instance_->group_stack_.front()->inc_depth();
-       }
-
-       if(0)if(redraw_requested_)
-       {
-               if(instance_->group_stack_.empty())
-               {
-                       assert(canvas_interface_);
-                       canvas_interface_->signal_dirty_preview()();
-               }
-               else
-               {
-                       instance_->group_stack_.front()->request_redraw(canvas_interface_);
-                       redraw_requested_=false;
-               }
-       }
-}
-
-void
-Action::PassiveGrouper::cancel()
-{
-       bool error=false;
-
-       // Cancel any groupers that may be on top of us first
-       //while(instance_->group_stack_.front()!=this)
-       //      instance_->group_stack_.front()->cancel();
-
-       synfig::warning("Cancel depth: %d",depth_);
-
-       while(depth_)
-               if(!instance_->undo())
-               {
-                       error=true;
-                       break;
-               }
-
-       if(error)
-               instance_->get_ui_interface()->error(_("State restore failure"));
-       else
-               redraw_requested_=false;
-}