Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_03 / synfig-core / src / synfig / valuenode_dynamiclist.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode_dynamiclist.cpp
3 **      \brief Template File
4 **
5 **      $Id: valuenode_dynamiclist.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
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 "valuenode_dynamiclist.h"
33 #include "valuenode_const.h"
34 #include "valuenode_composite.h"
35 #include "general.h"
36 #include "exception.h"
37 #include <vector>
38 #include <list>
39 #include <algorithm>
40 #include "canvas.h"
41
42 #endif
43
44 /* === U S I N G =========================================================== */
45
46 using namespace std;
47 using namespace etl;
48 using namespace synfig;
49
50 /* === M A C R O S ========================================================= */
51
52 /* === G L O B A L S ======================================================= */
53
54 /* === P R O C E D U R E S ================================================= */
55
56 /* === M E T H O D S ======================================================= */
57
58 ValueNode_DynamicList::ListEntry::ListEntry():
59         index(0)
60 {
61 }
62
63 ValueNode_DynamicList::ListEntry::ListEntry(const ValueNode::Handle &value_node):
64         value_node(value_node),
65         index(0)
66 {
67 }
68
69 ValueNode_DynamicList::ListEntry::ListEntry(const ValueNode::Handle &value_node,Time begin, Time end):
70         value_node(value_node)
71 {
72         add(begin,false);
73         add(end,false);
74         add((begin+end)*0.5,true);
75 }
76
77 ValueNode_DynamicList::ListEntry::ActivepointList::iterator
78 ValueNode_DynamicList::ListEntry::add(Time time, bool status, int priority)
79 {
80         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList::iterator iterator;
81         
82         //! \optimize
83         Activepoint ap(time,status,priority);
84         ap.set_parent_index(get_index());
85         ap.set_parent_value_node(get_parent_value_node());
86         timing_info.push_back(ap);
87         iterator iter(--iterator(timing_info.end()));
88         timing_info.sort();
89         
90         return iter;
91 }
92
93 ValueNode_DynamicList::ListEntry::ActivepointList::iterator
94 ValueNode_DynamicList::ListEntry::add(const Activepoint &x)
95 {
96         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList::iterator iterator;
97         
98         //! \optimize
99         Activepoint ap(x);
100         ap.set_parent_index(get_index());
101         ap.set_parent_value_node(get_parent_value_node());
102         timing_info.push_back(ap);
103         iterator iter(--iterator(timing_info.end()));
104         timing_info.sort();
105         
106         return iter;
107 }
108
109 void
110 ValueNode_DynamicList::reindex()
111 {
112         int i(0);
113         
114         std::vector<ListEntry>::iterator iter;
115
116         for(iter=list.begin();iter!=list.end();++iter)
117         {
118                 assert(iter->value_node);
119                 if(iter->index!=i || iter->get_parent_value_node().get()!=this)
120                 {
121                         ActivepointList::iterator iter2;
122
123                         if(iter->timing_info.size()) // is this line really necessary?
124                         for(iter2=iter->timing_info.begin();iter2!=iter->timing_info.end();++iter2)
125                         {
126                                 iter2->set_parent_index(i);
127                                 iter2->set_parent_value_node(this);
128                         }
129                         iter->index=i;          
130                         iter->set_parent_value_node(this);
131                 }
132         }
133 }
134
135 ValueNode_DynamicList::ListEntry
136 ValueNode_DynamicList::create_list_entry(int index, Time time, Real origin)
137 {
138         ValueNode_DynamicList::ListEntry ret;
139         
140         
141         synfig::ValueBase prev,next;
142
143         index=index%link_count();
144
145         assert(index>=0);
146         
147         ret.index=index;
148         ret.set_parent_value_node(this);
149         
150         next=(*list[index].value_node)(time);
151         
152         if(index!=0)
153                 prev=(*list[index-1].value_node)(time);
154         else
155         {
156                 if(get_loop())
157                         prev=(*list[link_count()-1].value_node)(time);
158                 else
159                 {
160                         prev=next;
161                 }
162         }
163         
164         
165         switch(get_contained_type())
166         {
167         case ValueBase::TYPE_VECTOR:
168         {
169                 Vector a(prev.get(Vector())), b(next.get(Vector()));
170                 ret.value_node=ValueNode_Const::create((b-a)*origin+a);
171                 break;
172         }
173         case ValueBase::TYPE_REAL:
174         {
175                 Real a(prev.get(Real())), b(next.get(Real()));
176                 ret.value_node=ValueNode_Const::create((b-a)*origin+a);
177                 break;
178         }
179         case ValueBase::TYPE_COLOR:
180         {
181                 Color a(prev.get(Color())), b(next.get(Color()));
182                 ret.value_node=ValueNode_Composite::create((b-a)*origin+a);
183                 break;
184         }
185         case ValueBase::TYPE_ANGLE:
186         {
187                 Angle a(prev.get(Angle())), b(next.get(Angle()));
188                 ret.value_node=ValueNode_Const::create((b-a)*origin+a);
189                 break;
190         }
191         case ValueBase::TYPE_TIME:
192         {
193                 Time a(prev.get(Time())), b(next.get(Time()));
194                 ret.value_node=ValueNode_Const::create((b-a)*origin+a);
195                 break;
196         }
197         default:
198                 ret.value_node=ValueNode_Const::create(get_contained_type());
199                 break;
200         }
201
202         
203         return ret;
204 }
205
206 ValueNode_DynamicList::ListEntry::ActivepointList::iterator
207 ValueNode_DynamicList::ListEntry::find(const UniqueID& x)
208 {
209         return std::find(timing_info.begin(),timing_info.end(),x);
210 }
211
212 ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
213 ValueNode_DynamicList::ListEntry::find(const UniqueID& x)const
214 {
215         return std::find(timing_info.begin(),timing_info.end(),x);
216 }
217
218 void
219 ValueNode_DynamicList::ListEntry::erase(const UniqueID& x)
220 {
221         timing_info.erase(find(x));
222 }
223
224 ValueNode_DynamicList::ListEntry::ActivepointList::iterator
225 ValueNode_DynamicList::ListEntry::find(const Time& x)
226 {
227         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
228         
229         ActivepointList::iterator iter;
230
231         for(iter=timing_info.begin();iter!=timing_info.end();++iter)
232                 if(iter->time==x)
233                         return iter;
234
235         throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find():"+x.get_string());  
236 }
237
238 ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
239 ValueNode_DynamicList::ListEntry::find(const Time& x)const
240 {
241         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
242         
243         ActivepointList::const_iterator iter;
244
245         for(iter=timing_info.begin();iter!=timing_info.end();++iter)
246                 if(iter->time==x)
247                         return iter;
248
249         throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find()const:"+x.get_string());     
250 }
251
252 ValueNode_DynamicList::ListEntry::ActivepointList::iterator
253 ValueNode_DynamicList::ListEntry::find_next(const Time& x)
254 {
255         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
256         
257         ActivepointList::iterator iter;
258
259         for(iter=timing_info.begin();iter!=timing_info.end();++iter)
260                 if(iter->time>x)
261                         return iter;
262
263         throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_next():"+x.get_string());     
264 }
265
266 ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
267 ValueNode_DynamicList::ListEntry::find_next(const Time& x)const
268 {
269         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
270         
271         ActivepointList::const_iterator iter;
272
273         for(iter=timing_info.begin();iter!=timing_info.end();++iter)
274                 if(iter->time>x)
275                         return iter;
276
277         throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_next()const:"+x.get_string());        
278 }
279
280 ValueNode_DynamicList::ListEntry::ActivepointList::iterator
281 ValueNode_DynamicList::ListEntry::find_prev(const Time& x)
282 {
283         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
284         
285         ActivepointList::iterator iter;
286         iter=timing_info.end();
287         do
288         {
289                 --iter;
290                 if(iter->time<x)
291                         return iter;
292         }
293         while(iter!=timing_info.begin());
294
295         throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_prev():"+x.get_string());     
296 }
297
298 ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator
299 ValueNode_DynamicList::ListEntry::find_prev(const Time& x)const
300 {
301         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
302         
303         ActivepointList::const_iterator iter;
304         iter=timing_info.end();
305         do
306         {
307                 --iter;
308                 if(iter->time<x)
309                         return iter;
310         }
311         while(iter!=timing_info.begin());
312
313         throw Exception::NotFound("ValueNode_DynamicList::ListEntry::find_prev()const:"+x.get_string());        
314 }
315
316 int
317 ValueNode_DynamicList::ListEntry::find(const Time& begin,const Time& end,std::vector<Activepoint*>& selected)
318 {
319         Time curr_time(begin);
320         int ret(0);
321         
322         // try to grab first waypoint
323         try
324         {
325                 ActivepointList::iterator iter;
326                 iter=find(curr_time);
327                 selected.push_back(&*iter);
328                 ret++;
329         }
330         catch(...) { }
331         
332         try
333         {
334                 ActivepointList::iterator iter;
335                 while(true)
336                 {
337                         iter=find_next(curr_time);
338                         curr_time=iter->get_time();
339                         if(curr_time>=end)
340                                 break;
341                         selected.push_back(&*iter);
342                         ret++;
343                 }
344         }
345         catch(...) { }
346         
347         return ret;
348 }
349
350 float
351 ValueNode_DynamicList::ListEntry::amount_at_time(const Time &t,bool *rising)const
352 {
353         typedef synfig::ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
354         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
355         
356         if(timing_info.empty())
357                 return 1.0f;
358                 
359         try
360         {
361                 ActivepointList::const_iterator iter;
362                 iter=find(t);
363                 return iter->state?1.0f:0.0f;
364         }
365         catch(...) { }
366
367         ActivepointList::const_iterator prev_iter;
368         ActivepointList::const_iterator next_iter;
369
370         try     { prev_iter=find_prev(t); }
371         catch(...) { return find_next(t)->state?1.0f:0.0f; }
372         
373         try     { next_iter=find_next(t); }
374         catch(...) { return prev_iter->state?1.0f:0.0f; }
375         
376         if(next_iter->state==prev_iter->state)
377                 return next_iter->state?1.0f:0.0f;
378         
379         if(rising)*rising=next_iter->state;
380
381         if(next_iter->state==true)
382                 return float((t-prev_iter->time)/(next_iter->time-prev_iter->time));
383
384         return float((next_iter->time-t)/(next_iter->time-prev_iter->time));
385 }
386
387 Activepoint
388 ValueNode_DynamicList::ListEntry::new_activepoint_at_time(const Time& time)const
389 {
390         Activepoint activepoint;
391         
392         activepoint.set_state(status_at_time(time));
393         activepoint.set_priority(0);
394         
395         return activepoint;
396 }
397
398 bool
399 ValueNode_DynamicList::ListEntry::status_at_time(const Time &t)const
400 {
401         typedef synfig::ValueNode_DynamicList::ListEntry::Activepoint Activepoint;
402         typedef synfig::ValueNode_DynamicList::ListEntry::ActivepointList ActivepointList;
403         
404         ActivepointList::const_iterator entry_iter;
405         ActivepointList::const_iterator prev_iter;
406         bool state(true);
407
408         // New "symetric" state mechanism
409         if(!timing_info.empty())
410         {
411                 if(timing_info.size()==1)
412                         state=timing_info.front().state;
413                 else
414                 {
415                         //! \optimize Perhaps we should use a binary search...?
416                         // This will give us the first activepoint that is after t.
417                         for(entry_iter=timing_info.begin();entry_iter!=timing_info.end();++entry_iter)
418                         {
419                                 if(entry_iter->time==t)
420                                 {
421                                         // If we hit the entry right on the nose, then we don't
422                                         // have to do anything more
423                                         return entry_iter->state;
424                                 }
425                                 if(entry_iter->time>t)
426                                         break;
427                                 
428                         }
429                         prev_iter=entry_iter;
430                         prev_iter--;
431                         
432                         // ie:
433                         //
434                         //              |-------|---t---|-------|
435                         //         prev_iter^           ^entry_iter
436                         
437                         if(entry_iter==timing_info.end())
438                         {
439                                 state=prev_iter->state;
440                         }
441                         else
442                         if(entry_iter==timing_info.begin())
443                         {
444                                 state=entry_iter->state;
445                         }
446                         else
447                         if(entry_iter->priority==prev_iter->priority)
448                         {
449                                 state=entry_iter->state || prev_iter->state;
450                         }
451                         else
452                         if(entry_iter->priority>prev_iter->priority)
453                         {
454                                 state=entry_iter->state;
455                         }
456                         else
457                         {
458                                 state=prev_iter->state;                         
459                         }                               
460                 }
461         }
462         return state;
463 }
464
465
466
467
468 void
469 ValueNode_DynamicList::add(const ValueNode::Handle &value_node, int index)
470 {
471         ListEntry list_entry(value_node);
472         list_entry.timing_info.size();
473         
474         if(index<0 || index>=(int)list.size())
475         {
476                 list.push_back(list_entry);
477         }
478         else
479         {
480                 list.insert(list.begin()+index,list_entry);
481         }
482
483         add_child(value_node.get());
484         reindex();
485         //changed();
486
487         if(get_parent_canvas())
488                 get_parent_canvas()->signal_value_node_child_added()(this,value_node);
489         else if(get_root_canvas() && get_parent_canvas())
490                 get_root_canvas()->signal_value_node_child_added()(this,value_node);
491 }
492
493 void
494 ValueNode_DynamicList::add(const ListEntry &list_entry, int index)
495 {
496         if(index<0 || index>=(int)list.size())
497                 list.push_back(list_entry);
498         else
499                 list.insert(list.begin()+index,list_entry);
500         add_child(list_entry.value_node.get());
501
502         reindex();
503         //changed();
504
505         if(get_parent_canvas())
506                 get_parent_canvas()->signal_value_node_child_added()(this,list_entry.value_node);
507         else if(get_root_canvas() && get_parent_canvas())
508                 get_root_canvas()->signal_value_node_child_added()(this,list_entry.value_node);
509 }
510
511 void
512 ValueNode_DynamicList::erase(const ValueNode::Handle &value_node_)
513 {
514         ValueNode::Handle value_node(value_node_);
515         
516         assert(value_node);
517         if(!value_node)
518                 throw String("ValueNode_DynamicList::erase(): Passed bad value node");
519         
520         std::vector<ListEntry>::iterator iter;
521         for(iter=list.begin();iter!=list.end();++iter)
522                 if(iter->value_node==value_node)
523                 {
524                         list.erase(iter);
525                         if(value_node)
526                         {
527                                 remove_child(value_node.get());
528                                 if(get_parent_canvas())
529                                         get_parent_canvas()->signal_value_node_child_removed()(this,value_node);
530                                 else if(get_root_canvas() && get_parent_canvas())
531                                         get_root_canvas()->signal_value_node_child_removed()(this,value_node);
532                         }
533                         break;
534                 }
535         reindex();
536 }
537
538
539 ValueNode_DynamicList::ValueNode_DynamicList(ValueBase::Type container_type):
540         LinkableValueNode(ValueBase::TYPE_LIST),
541         container_type  (container_type),
542         loop_(false)
543 {
544         DCAST_HACK_ENABLE();
545 }
546
547 ValueNode_DynamicList::Handle
548 ValueNode_DynamicList::create(ValueBase::Type id)
549 {
550         return new ValueNode_DynamicList(id);
551 }
552
553 ValueNode_DynamicList::~ValueNode_DynamicList()
554 {
555         unlink_all();
556 }
557
558 ValueNode_DynamicList*
559 ValueNode_DynamicList::create_from(const ValueBase &value)
560 {
561         //vector<ValueBase> value_list(value.operator vector<ValueBase>());
562         vector<ValueBase> value_list(value.get_list());
563
564         vector<ValueBase>::iterator iter;
565
566         if(value_list.empty())
567                 return 0;
568         
569         ValueNode_DynamicList* value_node(new ValueNode_DynamicList(value_list.front().get_type()));
570         
571         for(iter=value_list.begin();iter!=value_list.end();++iter)
572         {
573                 ValueNode::Handle item(ValueNode_Const::create(*iter));
574                 value_node->add(ListEntry(item));
575                 assert(value_node->list.back().value_node);
576         }
577         return value_node;
578 }
579
580 ValueBase
581 ValueNode_DynamicList::operator()(Time t)const
582 {
583         std::vector<ValueBase> ret_list;
584         std::vector<ListEntry>::const_iterator iter;
585
586         assert(container_type);
587
588         for(iter=list.begin();iter!=list.end();++iter)
589         {
590                 bool state(iter->status_at_time(t));
591                 
592                 if(state)
593                 {
594                         if(iter->value_node->get_type()==container_type)
595                                 ret_list.push_back((*iter->value_node)(t));
596                         else
597                         {
598                                 synfig::warning(string("ValueNode_DynamicList::operator()():")+_("List type/item type mismatch, throwing away mismatch"));
599                         }
600                 }
601         }
602         
603         if(list.empty())
604                 synfig::warning(string("ValueNode_DynamicList::operator()():")+_("No entries in list"));
605         else
606         if(ret_list.empty())
607                 synfig::warning(string("ValueNode_DynamicList::operator()():")+_("No entries in ret_list"));
608
609         return ret_list;
610 }
611
612 bool
613 ValueNode_DynamicList::set_link_vfunc(int i,ValueNode::Handle x)
614 {
615         assert(i>=0);
616         if((unsigned)i>=list.size())
617                 return false;
618         if(x->get_type()!=container_type)
619                 return false;
620         list[i].value_node=x;
621         return true;
622 }
623
624 ValueNode::LooseHandle
625 ValueNode_DynamicList::get_link_vfunc(int i)const
626 {
627         assert(i>=0);
628         if((unsigned)i>=list.size())
629                 return 0;
630         return list[i].value_node;
631 }
632
633 int
634 ValueNode_DynamicList::link_count()const
635 {
636         return list.size();
637 }
638
639 String
640 ValueNode_DynamicList::link_local_name(int i)const
641 {
642         assert(i>=0 && (unsigned)i<list.size());
643         return etl::strprintf(_("Item %03d"),i+1);
644 }       
645
646 ValueNode*
647 ValueNode_DynamicList::clone(const GUID& deriv_guid)const
648 {
649         { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
650
651         ValueNode_DynamicList* ret=new ValueNode_DynamicList(container_type);
652         ret->set_guid(get_guid()^deriv_guid);
653
654         std::vector<ListEntry>::const_iterator iter;
655
656         for(iter=list.begin();iter!=list.end();++iter)
657         {
658                 if(iter->value_node->is_exported())
659                         ret->add(*iter);
660                 else
661                 {               
662                         ListEntry list_entry(*iter);
663                         //list_entry.value_node=find_value_node(iter->value_node->get_guid()^deriv_guid).get();
664                         //if(!list_entry.value_node)
665                                 list_entry.value_node=iter->value_node->clone(deriv_guid);
666                         ret->add(list_entry);
667                         //ret->list.back().value_node=iter->value_node.clone();
668                 }
669         }
670         ret->set_loop(get_loop());
671         return ret;
672 }
673
674 String
675 ValueNode_DynamicList::link_name(int i)const
676 {
677         return strprintf("item%04d",i);
678 }
679
680 int
681 ValueNode_DynamicList::get_link_index_from_name(const String &name)const
682 {
683         throw Exception::BadLinkName(name);
684 }
685
686 String
687 ValueNode_DynamicList::get_name()const
688 {
689         return "dynamic_list";
690 }
691
692 String
693 ValueNode_DynamicList::get_local_name()const
694 {
695         return _("Dynamic List");
696 }
697
698 bool
699 ValueNode_DynamicList::check_type(ValueBase::Type type)
700 {
701         return type==ValueBase::TYPE_LIST;
702 }
703
704 ValueBase::Type
705 ValueNode_DynamicList::get_contained_type()const
706 {
707         return container_type;
708 }
709
710 LinkableValueNode*
711 ValueNode_DynamicList::create_new()const
712 {
713         assert(0);
714         return 0;
715 }
716
717 int
718 ValueNode_DynamicList::find_next_valid_entry(int orig_item, Time t)const
719 {
720         int curr_item;
721         
722         for(curr_item=orig_item+1;curr_item!=orig_item;curr_item++)
723         {
724                 if(curr_item==(int)list.size())
725                 {
726                         curr_item=0;
727                         continue;
728                 }
729                 if(list[curr_item].status_at_time(t))
730                         return curr_item;
731         }
732         return curr_item;
733 }
734
735 int
736 ValueNode_DynamicList::find_prev_valid_entry(int orig_item, Time t)const
737 {
738         int curr_item;
739         
740         for(curr_item=orig_item-1;curr_item!=orig_item;curr_item--)
741         {
742                 if(curr_item==-1)
743                 {
744                         curr_item=list.size();
745                         continue;
746                 }
747                 if(list[curr_item].status_at_time(t))
748                         return curr_item;
749         }
750         return curr_item;
751 }
752
753 const synfig::Node::time_set    & ValueNode_DynamicList::ListEntry::get_times() const
754 {
755         synfig::ActivepointList::const_iterator         j = timing_info.begin(),
756                                                                                         end = timing_info.end();
757                 
758         //must remerge with all the other values because we don't know if we've changed...
759         times = value_node->get_times();
760         
761         for(; j != end; ++j)
762         {
763                 TimePoint t;
764                 t.set_time(j->get_time());
765                 t.set_guid(j->get_guid());
766
767                 times.insert(t);
768         }
769         
770         return times;
771 }
772
773 void ValueNode_DynamicList::get_times_vfunc(Node::time_set &set) const
774 {
775         //add in the active points
776         int size = list.size();
777         
778         //rebuild all the info...
779         for(int i = 0; i < size; ++i)
780         {
781                 const Node::time_set & tset= list[i].get_times();
782                 set.insert(tset.begin(),tset.end());
783         }
784 }
785
786
787 //new find functions that don't throw
788 struct timecmp
789 {
790         Time t;
791
792         timecmp(const Time &c) :t(c) {}
793
794         bool operator()(const Activepoint &rhs) const
795         {
796                 return t.is_equal(rhs.get_time());
797         }
798 };
799
800 ValueNode_DynamicList::ListEntry::findresult ValueNode_DynamicList::ListEntry::find_uid(const UniqueID& x)
801 {
802         findresult f;
803         f.second = false;
804         
805         f.first = std::find(timing_info.begin(),timing_info.end(),x);
806         
807         if(f.first != timing_info.end())
808         {
809                 f.second = true;
810         }
811         
812         return f;
813 }
814
815 ValueNode_DynamicList::ListEntry::const_findresult ValueNode_DynamicList::ListEntry::find_uid(const UniqueID& x) const
816 {
817         const_findresult f;
818         f.second = false;
819         
820         f.first = std::find(timing_info.begin(),timing_info.end(),x);
821         
822         if(f.first != timing_info.end())
823         {
824                 f.second = true;
825         }
826         
827         return f;
828 }
829
830 ValueNode_DynamicList::ListEntry::findresult ValueNode_DynamicList::ListEntry::find_time(const Time& x)
831 {
832         findresult f;
833         f.second = false;
834         
835         f.first = std::find_if(timing_info.begin(),timing_info.end(),timecmp(x));
836         
837         if(f.first != timing_info.end())
838         {
839                 f.second = true;
840         }
841         
842         return f;
843 }
844
845 ValueNode_DynamicList::ListEntry::const_findresult ValueNode_DynamicList::ListEntry::find_time(const Time& x)const
846 {
847         const_findresult f;
848         f.second = false;
849         
850         f.first = std::find_if(timing_info.begin(),timing_info.end(),timecmp(x));
851         
852         if(f.first != timing_info.end())
853         {
854                 f.second = true;
855         }
856         
857         return f;
858 }
859
860 void
861 ValueNode_DynamicList::insert_time(const Time& location, const Time& delta)
862 {
863         if(!delta)
864                 return;
865
866         std::vector<ListEntry>::iterator iter(list.begin());
867         for(;iter!=list.end();++iter)
868         {
869                 try
870                 {
871                         ListEntry& item(*iter);
872                         
873                         ActivepointList::iterator iter(item.find_next(location));
874                         for(;iter!=item.timing_info.end();++iter)
875                         {
876                                 iter->set_time(iter->get_time()+delta);
877                         }
878                 }
879                 catch(Exception::NotFound) { }
880         }
881         changed();
882 }