Made a note that type names shouldn't be translated.
[synfig.git] / synfig-core / trunk / src / synfig / value.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file value.cpp
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 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "value.h"
33 #include "general.h"
34 #include <ETL/stringf>
35 #include "canvas.h"
36 #include "gradient.h"
37
38
39
40 #include "vector.h"
41 #include "time.h"
42 #include "segment.h"
43 #include "color.h"
44
45 #endif
46
47 using namespace synfig;
48 using namespace std;
49 using namespace etl;
50
51 /* === M A C R O S ========================================================= */
52
53 /* === G L O B A L S ======================================================= */
54
55 /* === P R O C E D U R E S ================================================= */
56
57 /* === M E T H O D S ======================================================= */
58
59 ValueBase::ValueBase():type(TYPE_NIL),data(0),ref_count(0),loop_(0)
60 {
61 }
62
63 ValueBase::ValueBase(Type x):
64         type(x),
65         data(0),
66         loop_(0)
67 {
68
69         switch(type)
70         {
71         case TYPE_BOOL:
72                 data=static_cast<void*>(new bool());
73                 break;
74         case TYPE_INTEGER:
75                 data=static_cast<void*>(new int());
76                 break;
77         case TYPE_ANGLE:
78                 data=static_cast<void*>(new Angle());
79                 break;
80         case TYPE_VECTOR:
81                 data=static_cast<void*>(new Vector());
82                 break;
83         case TYPE_TIME:
84                 data=static_cast<void*>(new Time());
85                 break;
86         case TYPE_REAL:
87                 data=static_cast<void*>(new Real());
88                 break;
89         case TYPE_COLOR:
90                 data=static_cast<void*>(new Color());
91                 break;
92         case TYPE_SEGMENT:
93                 data=static_cast<void*>(new Segment());
94                 break;
95         case TYPE_BLINEPOINT:
96                 data=static_cast<void*>(new BLinePoint());
97                 break;
98         case TYPE_LIST:
99                 data=static_cast<void*>(new list_type());
100                 break;
101         case TYPE_STRING:
102                 data=static_cast<void*>(new String());
103                 break;
104         case TYPE_GRADIENT:
105                 data=static_cast<void*>(new Gradient());
106                 break;
107         case TYPE_CANVAS:
108                 data=static_cast<void*>(new etl::handle<Canvas>());
109                 break;
110         default:
111                 break;
112         }
113 }
114
115 ValueBase::~ValueBase()
116 {
117         clear();
118 }
119
120 const char*
121 ValueBase::get(const char*)const
122 {
123         return get(String()).c_str();
124 }
125
126
127
128
129 void
130 ValueBase::set(Canvas* x)
131 {
132         clear();
133         if(x && x->is_inline())
134         {
135                 _set(etl::handle<Canvas>(x));
136         }
137         else
138         {
139                 _set(etl::loose_handle<Canvas>(x));
140         }
141         assert(get(x)==x);
142 }
143
144 void
145 ValueBase::set(etl::loose_handle<Canvas> x)
146 {
147         clear();
148         if(x && x->is_inline())
149         {
150                 _set(etl::handle<Canvas>(x));
151         }
152         else
153         {
154                 _set(etl::loose_handle<Canvas>(x));
155         }
156         assert(get(x)==x);
157 }
158
159 void
160 ValueBase::set(etl::handle<Canvas> x)
161 {
162         clear();
163         if(x && x->is_inline())
164         {
165                 _set(etl::handle<Canvas>(x));
166         }
167         else
168         {
169                 _set(etl::loose_handle<Canvas>(x));
170         }
171         assert(get(x)==x);
172 }
173
174 void
175 ValueBase::set(const list_type &x)
176 {
177         _set(x);
178 }
179
180 void
181 ValueBase::set(const char* x)
182 {
183         _set(String(x));
184 }
185
186 bool
187 ValueBase::is_valid()const
188 {
189         return type>TYPE_NIL && type<TYPE_END && ref_count;
190 }
191
192 bool
193 ValueBase::empty()const
194 {
195         return !is_valid() || ((type==TYPE_LIST)?get_list().empty():false);
196 }
197
198 ValueBase::Type
199 ValueBase::get_contained_type()const
200 {
201         if(type!=TYPE_LIST || empty())
202                 return TYPE_NIL;
203         return get_list().front().get_type();
204 }
205
206 ValueBase&
207 ValueBase::operator=(const ValueBase& x)
208 {
209         if(data!=x.data)
210         {
211                 clear();
212                 type=x.type;
213                 data=x.data;
214                 ref_count=x.ref_count;
215         }
216         loop_=x.loop_;
217         return *this;
218 }
219
220 void
221 ValueBase::clear()
222 {
223         if(ref_count.unique() && data)
224         {
225                 switch(type)
226                 {
227                 case TYPE_BOOL:
228                         delete static_cast<bool*>(data);
229                         break;
230                 case TYPE_INTEGER:
231                         delete static_cast<int*>(data);
232                         break;
233                 case TYPE_ANGLE:
234                         delete static_cast<Angle*>(data);
235                         break;
236                 case TYPE_VECTOR:
237                         delete static_cast<Vector*>(data);
238                         break;
239                 case TYPE_TIME:
240                         delete static_cast<Time*>(data);
241                         break;
242                 case TYPE_REAL:
243                         delete static_cast<Real*>(data);
244                         break;
245                 case TYPE_COLOR:
246                         delete static_cast<Color*>(data);
247                         break;
248                 case TYPE_SEGMENT:
249                         delete static_cast<Segment*>(data);
250                         break;
251                 case TYPE_BLINEPOINT:
252                         delete static_cast<BLinePoint*>(data);
253                         break;
254                 case TYPE_LIST:
255                         delete static_cast<list_type*>(data);
256                         break;
257                 case TYPE_STRING:
258                         delete static_cast<String*>(data);
259                         break;
260                 case TYPE_GRADIENT:
261                         delete static_cast<Gradient*>(data);
262                         break;
263
264
265                 case TYPE_CANVAS:
266                 {
267                         etl::handle<Canvas> canvas(get(etl::loose_handle<Canvas>()));
268                         if(canvas && canvas->is_inline())
269                         {
270                                 delete static_cast<etl::handle<Canvas>*>(data);
271                         }
272                         else
273                         {
274                                 delete static_cast<etl::loose_handle<Canvas>*>(data);
275                         }
276                         break;
277                 }
278                 default:
279                         break;
280                 }
281         }
282
283         ref_count.detach();
284         data=0;
285         type=TYPE_NIL;
286 }
287
288
289 String
290 ValueBase::type_name(Type id)
291 {
292         // don't internationalize these type names - they're using in .sif files
293         switch(id)
294         {
295         case TYPE_REAL:
296                 return "real";
297         case TYPE_TIME:
298                 return "time";
299         case TYPE_INTEGER:
300                 return "integer";
301         case TYPE_BOOL:
302                 return "bool";
303         case TYPE_ANGLE:
304                 return "angle";
305         case TYPE_VECTOR:
306                 return "vector";
307         case TYPE_COLOR:
308                 return "color";
309         case TYPE_STRING:
310                 return "string";
311         case TYPE_CANVAS:
312                 return "canvas";
313         case TYPE_LIST:
314                 return "list";
315         case TYPE_SEGMENT:
316                 return "segment";
317         case TYPE_GRADIENT:
318                 return "gradient";
319         case TYPE_BLINEPOINT:
320                 return "bline_point";
321         case TYPE_NIL:
322                 return "nil";
323         default:
324                 break;
325         }
326         synfig::warning("Encountered unknown ValueBase with an Type of %d",id);
327 //      assert(0);
328         return "UNKNOWN";
329 }
330
331 ValueBase::Type
332 ValueBase::ident_type(const String &str)
333 {
334         if(str=="nil" || str=="null")
335                 return TYPE_NIL;
336         else if(str=="time" || str==_("time"))
337                 return TYPE_TIME;
338         else if(str=="real" || str=="float" || str==_("real"))
339                 return TYPE_REAL;
340         else if(str=="integer" || str=="int" || str==_("integer"))
341                 return TYPE_INTEGER;
342         else if(str=="bool" || str==_("bool"))
343                 return TYPE_BOOL;
344         else if(str=="angle" || str=="degrees" || str=="radians" || str=="rotations")
345                 return TYPE_ANGLE;
346         else if(str=="vector" || str=="point")
347                 return TYPE_VECTOR;
348         else if(str=="color")
349                 return TYPE_COLOR;
350         else if(str=="string")
351                 return TYPE_STRING;
352         else if(str=="canvas")
353                 return TYPE_CANVAS;
354         else if(str=="list")
355                 return TYPE_LIST;
356         else if(str=="segment")
357                 return TYPE_SEGMENT;
358         else if(str=="gradient")
359                 return TYPE_GRADIENT;
360         else if(str=="bline_point" || str=="blinepoint")
361                 return TYPE_BLINEPOINT;
362
363         return TYPE_NIL;
364 }
365
366 bool
367 ValueBase::operator==(const ValueBase& rhs)const
368 {
369         if(get_type()!=rhs.get_type())
370                 return false;
371         if(data==rhs.data)
372                 return true;
373
374         switch(get_type())
375         {
376         case TYPE_TIME:
377                 return get(Time()).is_equal(rhs.get(Time()));
378         case TYPE_REAL:
379                 return abs(get(Real())-rhs.get(Real()))<=0.00000000000001;
380         case TYPE_INTEGER:
381                 return get(int())==rhs.get(int());
382         case TYPE_BOOL:
383                 return get(bool())==rhs.get(bool());
384         case TYPE_ANGLE:
385                 return get(Angle())==rhs.get(Angle());
386         case TYPE_VECTOR:
387                 return get(Vector()).is_equal_to(rhs.get(Vector()));
388         case TYPE_COLOR:
389                 return get(Color())==rhs.get(Color());
390         case TYPE_STRING:
391                 return get(String())==rhs.get(String());
392         case TYPE_CANVAS:
393                 return get(Canvas::LooseHandle())==rhs.get(Canvas::LooseHandle());
394         case TYPE_LIST:
395                 return get_list()==rhs.get_list();
396         case TYPE_SEGMENT:
397 //              return get(Segment())==rhs.get(Segment());
398         case TYPE_GRADIENT:
399 //              return get(Gradient())==rhs.get(Gradient());
400         case TYPE_BLINEPOINT:
401 //              return get(BLinePoint())==rhs.get(BLinePoint());
402         case TYPE_NIL:
403         default:
404                 return false;
405                 break;
406         }
407         return false;
408 }