my log
[synfig.git] / synfig-studio / trunk / src / synfigapp / action_system.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file action_system.h
3 **      \brief Template Header
4 **
5 **      $Id: action_system.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === S T A R T =========================================================== */
23
24 #ifndef __SYNFIGAPP_ACTIONSYSTEM_H
25 #define __SYNFIGAPP_ACTIONSYSTEM_H
26
27 /* === H E A D E R S ======================================================= */
28
29 #include "action.h"
30 #include <sigc++/signal.h>
31 #include <sigc++/object.h>
32 #include <ETL/handle>
33 #include <synfig/canvas.h>
34 #include "uimanager.h"
35
36 /* === M A C R O S ========================================================= */
37
38 /* === T Y P E D E F S ===================================================== */
39
40 /* === C L A S S E S & S T R U C T S ======================================= */
41
42 namespace synfigapp {
43
44 class CanvasInterface;
45         
46 namespace Action {
47
48
49         
50         
51         
52 class System;
53
54 //! Passive action grouping class
55 class PassiveGrouper
56 {
57         etl::loose_handle<System> instance_;
58         synfig::String name_;
59         bool redraw_requested_;
60         int depth_;
61         etl::handle<CanvasInterface> canvas_interface_;
62 public:
63
64         PassiveGrouper(etl::loose_handle<System> instance_,synfig::String name_);
65
66         ~PassiveGrouper();
67
68         const synfig::String &get_name()const { return name_; }
69
70         void set_name(const synfig::String &x) { name_=x; }
71
72         etl::loose_handle<System> get_instance() { return instance_; }
73         
74         void request_redraw(etl::handle<CanvasInterface>);
75         
76         void cancel();
77         
78         void inc_depth() { depth_++; }
79
80         void dec_depth() { depth_--; }
81
82         const int &get_depth()const { return depth_; }
83 }; // END of class Action::PassiveGrouper
84
85 typedef std::list< etl::handle<Action::Undoable> > Stack;
86         
87 class System : public etl::shared_object, public sigc::trackable
88 {
89         friend class PassiveGrouper;
90                 
91         /*
92  -- ** -- P U B L I C   T Y P E S ---------------------------------------------
93         */
94
95 public:
96
97         /*
98  -- ** -- P U B L I C  D A T A ------------------------------------------------
99         */
100
101 public:
102         
103         /*
104  -- ** -- P R I V A T E   D A T A ---------------------------------------------
105         */
106
107 private:
108
109         Stack undo_action_stack_;
110         Stack redo_action_stack_;
111
112         etl::handle<Action::Base> most_recent_action_;
113
114         std::list<PassiveGrouper*> group_stack_;
115
116         sigc::signal<void,bool> signal_undo_status_;
117         sigc::signal<void,bool> signal_redo_status_;
118         sigc::signal<void,etl::handle<Action::Undoable> > signal_new_action_;
119         sigc::signal<void> signal_undo_stack_cleared_;
120         sigc::signal<void> signal_redo_stack_cleared_;
121         sigc::signal<void> signal_undo_;
122         sigc::signal<void> signal_redo_;
123         sigc::signal<void,etl::handle<Action::Undoable> > signal_action_status_changed_;
124         
125         mutable sigc::signal<void,bool> signal_unsaved_status_changed_;
126
127         //! If this is non-zero, then the changes have not yet been saved.
128         mutable int action_count_;
129
130         etl::handle<UIInterface> ui_interface_;
131
132         bool clear_redo_stack_on_new_action_;
133         
134         /*
135  -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
136         */
137
138 private:
139
140         bool undo_(etl::handle<UIInterface> uim);
141         bool redo_(etl::handle<UIInterface> uim);
142
143         /*
144  -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
145         */
146
147 private:
148
149         /*
150  -- ** -- P U B L I C   M E T H O D S -----------------------------------------
151         */
152
153 public:
154
155         System();
156         ~System();
157
158         /*
159         template <typename T> bool
160         perform_action(T x)
161         {
162                 etl::handle<Action::Base> action((Action::Base*)new T(x));
163                 return perform_action(action);
164         }
165         */
166
167         const etl::handle<Action::Base>& get_most_recent_action() { return most_recent_action_; }
168
169         bool get_clear_redo_stack_on_new_action()const { return clear_redo_stack_on_new_action_; }
170         
171         void set_clear_redo_stack_on_new_action(bool x) { clear_redo_stack_on_new_action_=x; }
172
173         bool perform_action(etl::handle<Action::Base> action);
174
175         bool set_action_status(etl::handle<Action::Undoable> action, bool x);
176
177         const Stack &undo_action_stack()const { return undo_action_stack_; }
178
179         const Stack &redo_action_stack()const { return redo_action_stack_; }
180
181         //! Undoes the last action
182         bool undo();
183
184         //! Redoes the last undone action
185         bool redo();
186         
187         //! Clears the undo stack. 
188         void clear_undo_stack();
189         
190         //! Clears the redo stack. 
191         void clear_redo_stack();
192         
193         //! Increments the action counter
194         /*! \note You should not have to call this under normal circumstances.
195         **      \see dec_action_count(), reset_action_count(), get_action_count() */
196         void inc_action_count()const;
197
198         //! Decrements the action counter
199         /*! \note You should not have to call this under normal circumstances.
200         **      \see inc_action_count(), reset_action_count(), get_action_count() */
201         void dec_action_count()const;
202
203         //! Resets the action counter
204         /*! \note You should not have to call this under normal circumstances.
205         **      \see inc_action_count(), dec_action_count(), get_action_count() */
206         void reset_action_count()const;
207
208         //! Returns the number of actions performed since last save.
209         /*!     \see inc_action_count(), dec_action_count(), reset_action_count() */
210         int get_action_count()const { return action_count_; }
211
212         void set_ui_interface(const etl::handle<UIInterface> &uim) { assert(uim); ui_interface_=uim; }
213         void unset_ui_interface() { ui_interface_=new DefaultUIInterface(); }
214         const etl::handle<UIInterface> &get_ui_interface() { return ui_interface_; }    
215
216         /*
217  -- ** -- S I G N A L   I N T E R F A C E S -----------------------------------
218         */
219
220 public:
221
222         sigc::signal<void,bool>& signal_unsaved_status_changed() { return signal_unsaved_status_changed_; }
223
224         sigc::signal<void,bool>& signal_undo_status() { return signal_undo_status_; }
225
226         sigc::signal<void,bool>& signal_redo_status() { return signal_redo_status_; }
227
228         sigc::signal<void>& signal_undo_stack_cleared() { return signal_undo_stack_cleared_; }
229
230         sigc::signal<void>& signal_redo_stack_cleared() { return signal_redo_stack_cleared_; }
231
232         sigc::signal<void>& signal_undo() { return signal_undo_; }
233
234         sigc::signal<void>& signal_redo() { return signal_redo_; }
235
236         //!     Called whenever an undoable action is processed and added to the stack.
237         sigc::signal<void,etl::handle<Action::Undoable> >& signal_new_action() { return signal_new_action_; }
238
239         sigc::signal<void,etl::handle<Action::Undoable> >& signal_action_status_changed() { return signal_action_status_changed_; }
240
241 }; // END of class Action::System
242
243
244 }; // END of namespace synfigapp::Action
245 }; // END of namespace synfigapp
246
247 /* === E N D =============================================================== */
248
249 #endif