/*! \file action_system.cpp
** \brief Template File
**
-** $Id: action_system.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+** $Id$
**
** \legal
-** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
**
-** This software and associated documentation
-** are CONFIDENTIAL and PROPRIETARY property of
-** the above-mentioned copyright holder.
+** 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.
**
-** You may not copy, print, publish, or in any
-** other way distribute this software without
-** a prior written agreement with
-** the copyright holder.
+** 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
*/
/* ========================================================================= */
#include "instance.h"
#include "canvasinterface.h"
+#include "general.h"
+
#endif
/* === U S I N G =========================================================== */
Action::System::perform_action(handle<Action::Base> action)
{
handle<UIInterface> uim(get_ui_interface());
-
+
assert(action);
-
+
if(!action->is_ready())
{
uim->error(action->get_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());
}
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(err.get_type()!=Action::Error::TYPE_UNABLE)
{
if(err.get_desc().empty())
- uim->error(action->get_name()+": "+strprintf("%d",err.get_type()));
+ uim->error(action->get_name()+": "+strprintf("%d",err.get_type()));
else
- uim->error(action->get_name()+": "+err.get_desc());
+ uim->error(action->get_name()+": "+err.get_desc());
}
// If action failed for whatever reason, just return false and do
uim->task(action->get_name()+' '+_("Failed"));
inuse=false;
- uim->error(action->get_name()+": "+err.what());
+ uim->error(action->get_name()+": "+err.what());
// If action failed for whatever reason, just return false and do
// not add the action onto the list
// Clear the redo stack
if(clear_redo_stack_on_new_action_)
- clear_redo_stack();
+ 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);
if(group_stack_.empty())
signal_new_action()(undoable_action);
}
-
+
inuse=false;
uim->task(action->get_name()+' '+_("Successful"));
{
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_name()+_(" (Undo): ")+strprintf("%d",err.get_type()));
+ uim->error(action->get_name()+_(" (Undo): ")+strprintf("%d",err.get_type()));
else
- uim->error(action->get_name()+_(" (Undo): ")+err.get_desc());
+ uim->error(action->get_name()+_(" (Undo): ")+err.get_desc());
}
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())
{
if(err.get_type()!=Action::Error::TYPE_UNABLE)
{
if(err.get_desc().empty())
- uim->error(action->get_name()+_(" (Redo): ")+strprintf("%d",err.get_type()));
+ uim->error(action->get_name()+_(" (Redo): ")+strprintf("%d",err.get_type()));
else
- uim->error(action->get_name()+_(" (Redo): ")+err.get_desc());
+ uim->error(action->get_name()+_(" (Redo): ")+err.get_desc());
}
return false;
signal_undo_status_(false);
signal_undo_stack_cleared_();
}
-
+
void
Action::System::clear_redo_stack()
{
{
Stack::iterator iter;
int failed=false;
-
+
if(action->is_active()==x)
return true;
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())
{
{
return false;
}
- }
+ }
if(!undo_(uim))
{
return false;
}
-
+
action->set_active(x);
if(redo_(get_ui_interface()))
action->set_active(!x);
failed=true;
}
-
-
+
+
while(undo_action_stack_.front()!=cur_pos)
{
if(!redo_(uim))
Action::PassiveGrouper::~PassiveGrouper()
{
assert(instance_->group_stack_.front()==this);
-
+
// Remove this group from the group stack
instance_->group_stack_.pop_front();
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());
+ request_redraw(canvas_specific->get_canvas_interface());
}
}
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();
else
instance_->group_stack_.front()->inc_depth();
}
-
+
if(0)if(redraw_requested_)
{
if(instance_->group_stack_.empty())
// 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