d23039c802f543ce644e68b66e15ddc4a44387fb
[synfig.git] / synfig-studio / trunk / src / synfigapp / action.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file action.h
3 **      \brief Template File
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 __SYNFIG_APP_ACTION_H
26 #define __SYNFIG_APP_ACTION_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include <synfig/string.h>
31 #include <synfig/canvas.h>
32 #include <ETL/handle>
33 #include <ETL/stringf>
34 #include <ETL/trivial>
35
36 #include <map>
37 #include <list>
38
39 #include <synfig/layer.h>
40 #include <synfig/canvas.h>
41 #include <synfig/valuenode.h>
42 #include <synfigapp/value_desc.h>
43 #include <synfig/value.h>
44 #include <synfig/activepoint.h>
45 #include <synfig/valuenode_animated.h>
46 #include <synfig/string.h>
47 #include <synfig/keyframe.h>
48
49 #include "action_param.h"
50 #include "editmode.h"
51
52 /* === M A C R O S ========================================================= */
53
54 #define ACTION_MODULE_EXT public: \
55         static const char name__[], local_name__[], version__[], cvs_id__[], task__[]; \
56         static const Category category__; \
57         static const int priority__; \
58         static Action::Base *create(); \
59         virtual synfig::String get_name()const; \
60         virtual synfig::String get_local_name()const;
61
62
63 #define ACTION_SET_NAME(class,x) const char class::name__[]=x
64
65 #define ACTION_SET_CATEGORY(class,x) const Category class::category__(x)
66
67 #define ACTION_SET_TASK(class,x) const char class::task__[]=x
68
69 #define ACTION_SET_PRIORITY(class,x) const int class::priority__=x
70
71 #define ACTION_SET_LOCAL_NAME(class,x) const char class::local_name__[]=x
72
73 #define ACTION_SET_VERSION(class,x) const char class::version__[]=x
74
75 #define ACTION_SET_CVS_ID(class,x) const char class::cvs_id__[]=x
76
77 //! don't define get_local_name() - allow the action code to define its own
78 #define ACTION_INIT_NO_GET_LOCAL_NAME(class)                      \
79         Action::Base* class::create() { return new class(); } \
80         synfig::String class::get_name()const { return name__; }
81
82 #define ACTION_INIT(class)                               \
83         ACTION_INIT_NO_GET_LOCAL_NAME(class) \
84         synfig::String class::get_local_name()const { return dgettext("synfigstudio",local_name__); }
85
86 /* === T Y P E D E F S ===================================================== */
87
88 /* === C L A S S E S & S T R U C T S ======================================= */
89
90 namespace synfig {
91 class ProgressCallback;
92 class Canvas;
93 }; // END of namespace synfig
94
95 namespace synfigapp {
96
97 class Instance;
98 class Main;
99
100 namespace Action {
101
102 class System;
103
104
105 //! Exception class, thrown when redoing or undoing an action
106 class Error
107 {
108 public:
109         enum Type
110         {
111                 TYPE_UNKNOWN,
112                 TYPE_UNABLE,
113                 TYPE_BADPARAM,
114                 TYPE_CRITICAL,
115                 TYPE_NOTREADY,
116                 TYPE_BUG,
117
118                 TYPE_END
119         };
120 private:
121
122         Type type_;
123         synfig::String desc_;
124
125 public:
126
127         Error(Type type, const char *format, ...):
128                 type_(type)
129         {
130                 va_list args;
131                 va_start(args,format);
132                 desc_=etl::vstrprintf(format,args);
133         }
134
135         Error(const char *format, ...):
136                 type_(TYPE_UNKNOWN)
137         {
138                 va_list args;
139                 va_start(args,format);
140                 desc_=etl::vstrprintf(format,args);
141         }
142
143         Error(Type type=TYPE_UNABLE):
144                 type_(type)
145         {
146         }
147
148         Type get_type()const { return type_; }
149         synfig::String get_desc()const { return desc_; }
150
151 }; // END of class Action::Error
152
153 class Param;
154 class ParamList;
155 class ParamDesc;
156 class ParamVocab;
157
158 // Action Category
159 enum Category
160 {
161         CATEGORY_NONE                   =0,
162         CATEGORY_LAYER                  =(1<<0),
163         CATEGORY_CANVAS                 =(1<<1),
164         CATEGORY_WAYPOINT               =(1<<2),
165         CATEGORY_ACTIVEPOINT    =(1<<3),
166         CATEGORY_VALUEDESC              =(1<<4),
167         CATEGORY_VALUENODE              =(1<<5),
168         CATEGORY_KEYFRAME               =(1<<6),
169         CATEGORY_GROUP                  =(1<<7),
170
171         CATEGORY_OTHER                  =(1<<12),
172
173         CATEGORY_DRAG                   =(1<<24),
174
175         CATEGORY_HIDDEN                 =(1<<31),
176         CATEGORY_ALL                    =(~0)-(1<<31)           //!< All categories (EXCEPT HIDDEN)
177 }; // END of enum Category
178
179 inline Category operator|(Category lhs, Category rhs)
180 { return static_cast<Category>(int(lhs)|int(rhs)); }
181
182
183
184 //! Action Base Class
185 /*!     An action should implement the following functions:
186 **      static bool is_candidate(const ParamList &x);
187 **              -       Checks the ParamList to see if this action could be performed.
188 **      static ParamVocab get_param_vocab();
189 **              -       Yields the ParamVocab object which describes what
190 **                      this action needs before it can perform the act.
191 **      static Action::Base* create();
192 **              -       Factory for creating this action from a ParamList
193 **
194 */
195 class Base : public etl::shared_object
196 {
197 protected:
198         Base() { }
199
200 public:
201         virtual ~Base() { };
202
203         //! This function will throw an Action::Error() on failure
204         virtual void perform()=0;
205
206         virtual bool set_param(const synfig::String& /*name*/, const Param &) { return false; }
207         virtual bool is_ready()const=0;
208
209         virtual synfig::String get_name()const =0;
210         virtual synfig::String get_local_name()const { return get_name(); }
211
212         void set_param_list(const ParamList &);
213
214         static synfig::String get_layer_descriptions(const std::list<synfig::Layer::Handle> layers, synfig::String singular_prefix = "", synfig::String plural_prefix = "");
215         static synfig::String get_layer_descriptions(const std::list<std::pair<synfig::Layer::Handle,int> > layers, synfig::String singular_prefix = "", synfig::String plural_prefix = "");
216 }; // END of class Action::Base
217
218 typedef Action::Base* (*Factory)();
219 typedef bool (*CandidateChecker)(const ParamList &x);
220 typedef ParamVocab (*GetParamVocab)();
221
222 typedef etl::handle<Base> Handle;
223
224 //! Undoable Action Base Class
225 class Undoable : public Base
226 {
227         friend class System;
228         bool active_;
229
230 protected:
231         Undoable():active_(true) { }
232
233 private:
234         void set_active(bool x) { active_=x; }
235
236 public:
237
238         //! This function will throw an Action::Error() on failure
239         virtual void undo()=0;
240
241         bool is_active()const { return active_; }
242
243 }; // END of class Action::Undoable
244
245 //! Action base class for canvas-specific actions
246 class CanvasSpecific
247 {
248 private:
249         bool is_dirty_;
250         EditMode        mode_;
251
252         etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
253         synfig::Canvas::Handle canvas_;
254
255 protected:
256         CanvasSpecific(const synfig::Canvas::Handle &canvas):is_dirty_(true),mode_(MODE_UNDEFINED),canvas_(canvas) { }
257         CanvasSpecific():is_dirty_(true), mode_(MODE_UNDEFINED) { }
258
259         virtual ~CanvasSpecific() { };
260
261
262 public:
263
264         void set_canvas(synfig::Canvas::Handle x) { canvas_=x; }
265         void set_canvas_interface(etl::loose_handle<synfigapp::CanvasInterface> x) { canvas_interface_=x; }
266
267         synfig::Canvas::Handle get_canvas()const { return canvas_; }
268         etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
269
270         static ParamVocab get_param_vocab();
271         virtual bool set_param(const synfig::String& name, const Param &);
272         virtual bool is_ready()const;
273
274         EditMode get_edit_mode()const;
275
276         void set_edit_mode(EditMode x) { mode_=x; }
277
278         bool is_dirty()const { return is_dirty_; }
279         void set_dirty(bool x=true) { is_dirty_=x; }
280
281 }; // END of class Action::Undoable
282
283 typedef std::list< etl::handle<Action::Undoable> > ActionList;
284
285 /*!     \class synfigapp::Action::Super
286 **      \brief Super-Action base class for actions composed of several other actions.
287 **
288 **      Actions deriving from this class should only implement prepare(), and
289 **      NOT implement perform() or undo().
290 */
291 class Super : public Undoable, public CanvasSpecific
292 {
293         ActionList action_list_;
294
295 public:
296
297         ActionList &action_list() { return action_list_; }
298         const ActionList &action_list()const { return action_list_; }
299
300         virtual void prepare()=0;
301
302         void clear() { action_list().clear(); }
303
304         bool first_time()const { return action_list_.empty(); }
305
306         void add_action(etl::handle<Undoable> action);
307
308         void add_action_front(etl::handle<Undoable> action);
309
310         virtual void perform();
311         virtual void undo();
312
313 }; // END of class Action::Super
314
315
316 class Group : public Super
317 {
318         synfig::String name_;
319
320         ActionList action_list_;
321 protected:
322         bool ready_;
323 public:
324         Group(const synfig::String &str="Group");
325         virtual ~Group();
326
327         virtual synfig::String get_name()const { return name_; }
328
329         virtual void prepare() { };
330
331         virtual bool set_param(const synfig::String& /*name*/, const Param &)const { return false; }
332         virtual bool is_ready()const { return ready_; }
333
334         void set_name(std::string&x) { name_=x; }
335 }; // END of class Action::Group
336
337
338
339
340
341 struct BookEntry
342 {
343         synfig::String  name;
344         synfig::String  local_name;
345         synfig::String  version;
346         synfig::String  task;
347         int                     priority;
348         Category                category;
349         Factory                 factory;
350         CandidateChecker        is_candidate;
351         GetParamVocab   get_param_vocab;
352
353         bool operator<(const BookEntry &rhs)const { return priority<rhs.priority; }
354 }; // END of struct BookEntry
355
356 typedef std::map<synfig::String,BookEntry> Book;
357
358 class CandidateList : public std::list<BookEntry>
359 {
360 public:
361         iterator find(const synfig::String& x);
362         const_iterator find(const synfig::String& x)const { return const_cast<CandidateList*>(this)->find(x); }
363 };
364
365 Book& book();
366
367 Handle create(const synfig::String &name);
368
369 //! Compiles a list of potential candidate actions with the given \a param_list and \a category
370 CandidateList compile_candidate_list(const ParamList& param_list, Category category=CATEGORY_ALL);
371
372 /*!     \class synfigapp::Action::Main
373 **      \brief \writeme
374 **
375 **      \writeme
376 */
377 class Main
378 {
379         friend class synfigapp::Main;
380
381         Main();
382
383 public:
384         ~Main();
385
386 }; // END of class Action::Main
387
388 }; // END of namespace Action
389
390 }; // END of namespace synfigapp
391
392 /* === E N D =============================================================== */
393
394 #endif