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