Improved the formatting of ValueNode descriptions for use in the History dialog.
[synfig.git] / synfig-core / trunk / src / synfig / valuenode.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode.h
3 **      \brief Header file for implementation of the "Placeholder" valuenode conversion.
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_VALUENODE_H
26 #define __SYNFIG_VALUENODE_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include "vector.h"
31 #include "value.h"
32 #include "string.h"
33 #include <ETL/handle>
34 #include <ETL/stringf>
35 #include "exception.h"
36 #include <map>
37 #include <sigc++/signal.h>
38 #include "guid.h"
39
40 #ifndef SYNFIG_NO_ANGLE
41 #include <ETL/angle>
42 #endif
43
44 #include "node.h"
45
46 #include <set>
47
48 /* === M A C R O S ========================================================= */
49
50 // This is a hack for GCC 3.0.4... which has a broken dynamic_cast<>
51 // It is deprecated, and will be removed soon.
52 #if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
53 # define DCAST_HACK_BASECLASS() int cast__
54 # define DCAST_HACK_ID(x)               static const int my_cast__(void) { return x; }
55 # define DCAST_HACK_ENABLE()    cast__=my_cast__()
56 #else
57 # define DCAST_HACK_BASECLASS()
58 # define DCAST_HACK_ID(x)
59 # define DCAST_HACK_ENABLE()
60 #endif
61
62 #define CHECK_TYPE_AND_SET_VALUE(variable, type)                                                \
63         /* I don't think this ever happens - maybe remove this code? */         \
64         if (get_type() == ValueBase::TYPE_NIL) {                                                        \
65                 warning("%s:%d get_type() IS nil sometimes!",                                   \
66                                 __FILE__, __LINE__);                                                                    \
67                 return false;                                                                                                   \
68         }                                                                                                                                       \
69         if (get_type() != ValueBase::TYPE_NIL &&                                                        \
70                 !(ValueBase::same_type_as(value->get_type(), type)) &&                  \
71                 !PlaceholderValueNode::Handle::cast_dynamic(value)) {                   \
72                 error(_("%s:%d wrong type for %s: need %s but got %s"),                 \
73                           __FILE__, __LINE__,                                                                           \
74                           link_local_name(i).c_str(),                                                           \
75                           ValueBase::type_local_name(type).c_str(),                                     \
76                           ValueBase::type_local_name(value->get_type()).c_str());       \
77                 return false;                                                                                                   \
78         }                                                                                                                                       \
79         variable = value;                                                                                                       \
80         signal_child_changed()(i);                                                                                      \
81         signal_value_changed()();                                                                                       \
82         return true
83
84 /* === T Y P E D E F S ===================================================== */
85
86 /* === C L A S S E S & S T R U C T S ======================================= */
87
88 namespace synfig {
89
90 class Canvas;
91 class LinkableValueNode;
92 class Layer;
93
94 /*!     \class ValueNode
95 **      \todo writeme
96 */
97 class ValueNode : public synfig::Node
98 {
99         friend class Layer;
100         friend class LinkableValueNode;
101
102         /*
103  --     ** -- T Y P E S -----------------------------------------------------------
104         */
105
106 public:
107
108         typedef etl::handle<ValueNode> Handle;
109
110         typedef etl::loose_handle<ValueNode> LooseHandle;
111
112         typedef etl::handle<const ValueNode> ConstHandle;
113
114         typedef etl::rhandle<ValueNode> RHandle;
115
116
117         static bool subsys_init();
118
119         static bool subsys_stop();
120
121         /*
122  --     ** -- D A T A -------------------------------------------------------------
123         */
124
125 private:
126         ValueBase::Type type;
127         String name;
128         etl::loose_handle<Canvas> canvas_;
129         etl::loose_handle<Canvas> root_canvas_;
130
131         /*
132  -- ** -- S I G N A L S -------------------------------------------------------
133         */
134
135 private:
136
137         //!     ValueBase Changed
138         sigc::signal<void> signal_value_changed_;
139
140         //!     Children Reordered
141         sigc::signal<void,int*> signal_children_reordered_;
142
143         //!     Child Changed
144         sigc::signal<void,int> signal_child_changed_;
145
146         //!     Child Removed
147         sigc::signal<void,int> signal_child_removed_;
148
149         //!     Child Inserted
150         sigc::signal<void,int> signal_child_inserted_;
151
152         //!     ID Changed
153         sigc::signal<void> signal_id_changed_;
154
155         /*
156  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
157         */
158
159 public:
160
161         //!     ValueBase Changed
162         sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
163
164         //!     Children Reordered
165         sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
166
167         //!     Child Changed
168         sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
169
170         //!     Child Removed
171         sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
172
173         //!     Child Inserted
174         sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
175
176         //!     ID Changed
177         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
178
179         /*
180  --     ** -- C O N S T R U C T O R S ---------------------------------------------
181         */
182
183 protected:
184
185         ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
186
187 public:
188
189         virtual ~ValueNode();
190
191         /*
192  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
193         */
194
195 public:
196
197         //! Returns the value of the ValueNode at time \a t
198         virtual ValueBase operator()(Time /*t*/)const
199                 { return ValueBase(); }
200
201         //! \internal Sets the id of the ValueNode
202         void set_id(const String &x);
203
204         //! Returns the id of the ValueNode
205         /*!     The ID is used for keeping track of a
206         **      specific instance of a ValueNode. */
207         const String &get_id()const { return name; }
208
209         //! Returns the name of the ValueNode type
210         virtual String get_name()const=0;
211
212         //! Returns the localized name of the ValueNode type
213         virtual String get_local_name()const=0;
214
215         //! Return a full description of the ValueNode and its parentage
216         virtual String get_description(bool show_exported_name = true)const;
217
218
219         //! \writeme
220         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
221
222         //! \writeme
223         bool is_exported()const { return !get_id().empty(); }
224
225         //! Returns the type of the ValueNode
226         ValueBase::Type get_type()const { return type; }
227
228         //! Returns a handle to the parent canvas, if it has one.
229         etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
230
231         //! Returns a handle to the parent canvas, if it has one.
232         etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
233
234         //! \writeme
235         void set_parent_canvas(etl::loose_handle<Canvas> x);
236
237         //! \writeme
238         void set_root_canvas(etl::loose_handle<Canvas> x);
239
240         //! \writeme
241         String get_relative_id(etl::loose_handle<const Canvas> x)const;
242
243         int replace(etl::handle<ValueNode> x);
244
245 protected:
246         //! Sets the type of the ValueNode
247         void set_type(ValueBase::Type t) { type=t; }
248
249         virtual void on_changed();
250
251 public:
252         DCAST_HACK_BASECLASS();
253         DCAST_HACK_ID(0);
254 }; // END of class ValueNode
255
256 /*!     \class PlaceholderValueNode
257 **      \todo writeme
258 */
259 class PlaceholderValueNode : public ValueNode
260 {
261 public:
262         typedef etl::handle<PlaceholderValueNode> Handle;
263         typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
264         typedef etl::handle<const PlaceholderValueNode> ConstHandle;
265         typedef etl::rhandle<PlaceholderValueNode> RHandle;
266
267 private:
268
269         PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
270
271 public:
272
273         virtual ValueBase operator()(Time t)const;
274
275         virtual String get_name()const;
276
277         virtual String get_local_name()const;
278
279         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
280
281         static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
282
283 protected:
284         virtual void get_times_vfunc(Node::time_set &/*set*/) const {}
285 }; // END of class PlaceholderValueNode
286
287
288 /*!     \class LinkableValueNode
289 **      \todo writeme
290 */
291 class LinkableValueNode : public ValueNode
292 {
293         friend class ValueNode;
294 public:
295
296         typedef etl::handle<LinkableValueNode> Handle;
297
298         typedef etl::loose_handle<LinkableValueNode> LooseHandle;
299
300         typedef etl::handle<const LinkableValueNode> ConstHandle;
301
302         typedef etl::rhandle<LinkableValueNode> RHandle;
303
304
305         //! Type that represents a pointer to a ValueNode's constructor
306         typedef LinkableValueNode* (*Factory)(const ValueBase&);
307
308         typedef bool (*CheckType)(ValueBase::Type);
309
310         struct BookEntry
311         {
312                 String local_name;
313                 Factory factory;
314                 CheckType check_type;
315         };
316
317         typedef std::map<String,BookEntry> Book;
318
319         static Book& book();
320
321         static Handle create(const String &name, const ValueBase& x);
322
323         static bool check_type(const String &name, ValueBase::Type x);
324
325 public:
326         LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
327                 ValueNode(type) { }
328
329 protected:
330         virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
331
332         void unlink_all();
333
334 public:
335
336         virtual int link_count()const=0;
337
338         virtual String link_local_name(int i)const=0;
339
340         virtual String link_name(int i)const=0;
341
342         virtual int get_link_index_from_name(const String &name)const=0;
343
344         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
345
346         bool set_link(int i,ValueNode::Handle x);
347         bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x);      }
348
349         ValueNode::LooseHandle get_link(int i)const;
350         ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
351
352         String
353         get_description(int index, bool show_exported_name = true)const;
354
355 protected:
356         //! Sets the type of the ValueNode
357         void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
358
359         virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
360
361         // Wrapper for new operator, used by clone()
362         virtual LinkableValueNode* create_new()const=0;
363
364         virtual void get_times_vfunc(Node::time_set &set) const;
365 }; // END of class LinkableValueNode
366
367 /*!     \class ValueNodeList
368 **      \brief A searchable value_node list container
369 **      \warning Do not confuse with ValueNode_DynamicList!
370 **      \todo writeme
371 */
372 class ValueNodeList : public std::list<ValueNode::RHandle>
373 {
374         int placeholder_count_;
375 public:
376         ValueNodeList();
377
378         //! Finds the ValueNode in the list with the given \a name
379         /*!     \return If found, returns a handle to the ValueNode.
380         **              Otherwise, returns an empty handle.
381         */
382         ValueNode::Handle find(const String &name);
383
384         //! Finds the ValueNode in the list with the given \a name
385         /*!     \return If found, returns a handle to the ValueNode.
386         **              Otherwise, returns an empty handle.
387         */
388         ValueNode::ConstHandle find(const String &name)const;
389
390         //! Removes the \a value_node from the list
391         bool erase(ValueNode::Handle value_node);
392
393         //! \writeme
394         bool add(ValueNode::Handle value_node);
395
396         //! \writeme
397         bool count(const String &id)const;
398
399         //! Similar to find, but will create a placeholder value_node if it cannot be found.
400         ValueNode::Handle surefind(const String &name);
401
402         //! Removes any value_nodes with reference counts of 1.
403         void audit();
404
405         //! Placeholder Count
406         int placeholder_count()const { return placeholder_count_; }
407 };
408
409 ValueNode::LooseHandle find_value_node(const GUID& guid);
410
411 }; // END of namespace synfig
412
413 /* === E N D =============================================================== */
414
415 #endif