Fix a crash when running single-threaded and dragging the time slider.
[synfig.git] / synfig-studio / trunk / src / gtkmm / layertreestore.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file layertreestore.cpp
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 /* === 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 "layertreestore.h"
33 #include "iconcontroler.h"
34 #include <gtkmm/button.h>
35 #include <synfig/paramdesc.h>
36 #include <synfigapp/action.h>
37 #include <synfigapp/instance.h>
38 #include "app.h"
39 #include "instance.h"
40 #include "iconcontroler.h"
41 #include <synfigapp/action_system.h>
42
43 #include <gtk/gtkversion.h>
44 #include <ETL/clock>
45 #endif
46
47 /* === U S I N G =========================================================== */
48
49 using namespace std;
50 using namespace etl;
51 using namespace synfig;
52 using namespace studio;
53
54 /* === M A C R O S ========================================================= */
55
56 /* === G L O B A L S ======================================================= */
57
58 /* === P R O C E D U R E S ================================================= */
59
60 /* === M E T H O D S ======================================================= */
61
62 static LayerTreeStore::Model& ModelHack()
63 {
64         static LayerTreeStore::Model* model(0);
65         if(!model)model=new LayerTreeStore::Model;
66         return *model;
67 }
68
69 LayerTreeStore::LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
70         Gtk::TreeStore                  (ModelHack()),
71         canvas_interface_               (canvas_interface_)
72 {
73         layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
74
75         // Connect Signals to Terminals
76         canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_status_changed));
77         canvas_interface()->signal_layer_lowered().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_lowered));
78         canvas_interface()->signal_layer_raised().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_raised));
79         canvas_interface()->signal_layer_removed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_removed));
80         canvas_interface()->signal_layer_inserted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_inserted));
81         canvas_interface()->signal_layer_moved().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_moved));
82         //canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_param_changed));
83         canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_new_description));
84
85         canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::refresh));
86
87         //canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_changed));
88         //canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_added));
89         //canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_deleted));
90         //canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_replaced));
91
92         set_default_sort_func(sigc::ptr_fun(index_sorter));
93
94 //      rebuild();
95 }
96
97 LayerTreeStore::~LayerTreeStore()
98 {
99         synfig::info("LayerTreeStore::~LayerTreeStore(): Deleted");
100 }
101
102 int
103 LayerTreeStore::z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
104 {
105         const Model model;
106
107         float diff((float)(*rhs)[model.z_depth]-(float)(*lhs)[model.z_depth]);
108
109         if(diff<0)
110                 return -1;
111         if(diff>0)
112                 return 1;
113         return 0;
114 }
115
116 int
117 LayerTreeStore::index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
118 {
119         const Model model;
120
121         return ((int)(*rhs)[model.index]-(int)(*lhs)[model.index]);
122 }
123
124 bool
125 LayerTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
126 {
127         const Model model;
128
129         Glib::ustring substr(x.uppercase());
130         Glib::ustring label((*iter)[model.label]);
131         label=label.uppercase();
132
133         return label.find(substr)==Glib::ustring::npos;
134 }
135
136
137 Glib::RefPtr<LayerTreeStore>
138 LayerTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
139 {
140         return Glib::RefPtr<LayerTreeStore>(new LayerTreeStore(canvas_interface_));
141 }
142
143 void
144 LayerTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
145 {
146         if(column==model.index.index())
147         {
148                 synfig::Layer::Handle layer((*iter)[model.layer]);
149
150                 if(!layer)return;
151
152                 Glib::Value<int> x;
153                 g_value_init(x.gobj(),x.value_type());
154
155                 x.set(layer->get_depth());
156
157                 g_value_init(value.gobj(),x.value_type());
158                 g_value_copy(x.gobj(),value.gobj());
159         }
160         else if(column==model.z_depth.index())
161         {
162                 synfig::Layer::Handle layer((*iter)[model.layer]);
163
164                 if(!layer)return;
165
166                 Glib::Value<float> x;
167                 g_value_init(x.gobj(),x.value_type());
168
169                 x.set(layer->get_z_depth(canvas_interface()->get_time())*1.0001+layer->get_depth());
170
171                 g_value_init(value.gobj(),x.value_type());
172                 g_value_copy(x.gobj(),value.gobj());
173         }
174         else if(column==model.children_lock.index())
175         {
176                 synfig::Layer::Handle layer((*iter)[model.layer]);
177
178                 if(!layer)return;
179
180                 Glib::Value<bool> x;
181                 g_value_init(x.gobj(),x.value_type());
182                 x.set(false);
183
184                 ValueBase v(layer->get_param("children_lock"));
185                 if(v.same_type_as(bool()))
186                         x.set(v.get(bool()));
187
188                 g_value_init(value.gobj(),x.value_type());
189                 g_value_copy(x.gobj(),value.gobj());
190         }
191         else if(column==model.label.index())
192         {
193                 synfig::Layer::Handle layer((*iter)[model.layer]);
194
195                 if(!layer)return;
196
197                 Glib::Value<Glib::ustring> x;
198                 g_value_init(x.gobj(),x.value_type());
199
200
201                 if(!layer->get_description().empty())
202                         x.set(layer->get_description());
203                 else
204                         x.set(layer->get_local_name());
205
206                 g_value_init(value.gobj(),x.value_type());
207                 //g_value_copy(x.gobj(),value.gobj());
208                 value=x;
209         }
210         else if(column==model.tooltip.index())
211         {
212                 synfig::Layer::Handle layer((*iter)[model.layer]);
213
214                 if(!layer)return;
215
216                 Glib::Value<Glib::ustring> x;
217                 g_value_init(x.gobj(),x.value_type());
218
219
220                 x.set(layer->get_local_name());
221
222                 g_value_init(value.gobj(),x.value_type());
223                 //g_value_copy(x.gobj(),value.gobj());
224                 value=x;
225         }
226         else if(column==model.canvas.index())
227         {
228                 synfig::Layer::Handle layer((*iter)[model.layer]);
229
230                 if(!layer)return;
231
232                 Glib::Value<Canvas::Handle> x;
233                 g_value_init(x.gobj(),x.value_type());
234
235
236                 x.set(layer->get_canvas());
237
238                 g_value_init(value.gobj(),x.value_type());
239                 //g_value_copy(x.gobj(),value.gobj());
240                 value=x;
241         }
242         else if(column==model.active.index())
243         {
244                 synfig::Layer::Handle layer((*iter)[model.layer]);
245
246                 if(!layer)return;
247
248                 Glib::Value<bool> x;
249                 g_value_init(x.gobj(),x.value_type());
250
251                 x.set(layer->active());
252
253                 g_value_init(value.gobj(),x.value_type());
254                 g_value_copy(x.gobj(),value.gobj());
255         }
256         else if(column==model.icon.index())
257         {
258                 synfig::Layer::Handle layer((*iter)[model.layer]);
259                 if(!layer)return;
260
261                 Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
262                 g_value_init(x.gobj(),x.value_type());
263
264                 //x.set(layer_icon);
265                 x.set(get_tree_pixbuf_layer(layer->get_name()));
266
267                 g_value_init(value.gobj(),x.value_type());
268                 g_value_copy(x.gobj(),value.gobj());
269         }
270         else
271                 Gtk::TreeStore::get_value_vfunc(iter,column,value);
272 }
273
274 void
275 LayerTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
276 {
277         //if(!iterator_sane(row))
278         //      return;
279
280         if(column>=get_n_columns_vfunc())
281         {
282                 g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
283                 return;
284         }
285
286         if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
287         {
288                 g_warning("LayerTreeStore::set_value_impl: Bad value type");
289                 return;
290         }
291
292         try
293         {
294                 if(column==model.label.index())
295                 {
296                         Glib::Value<Glib::ustring> x;
297                         g_value_init(x.gobj(),model.label.type());
298                         g_value_copy(value.gobj(),x.gobj());
299
300                         synfig::Layer::Handle layer((*iter)[model.layer]);
301                         if(!layer)
302                                 return;
303                         synfig::String new_desc(x.get());
304
305                         if(new_desc==layer->get_local_name())
306                                 new_desc=synfig::String();
307
308                         if(new_desc==layer->get_description())
309                                 return;
310
311                         synfigapp::Action::Handle action(synfigapp::Action::create("layer_set_desc"));
312
313                         if(!action)
314                                 return;
315
316                         action->set_param("canvas",canvas_interface()->get_canvas());
317                         action->set_param("canvas_interface",canvas_interface());
318                         action->set_param("layer",layer);
319                         action->set_param("new_description",synfig::String(x.get()));
320
321                         canvas_interface()->get_instance()->perform_action(action);
322                         return;
323                 }
324                 else if(column==model.active.index())
325                 {
326                         synfig::Layer::Handle layer((*iter)[model.layer]);
327
328                         if(!layer)return;
329
330                         Glib::Value<bool> x;
331                         g_value_init(x.gobj(),model.active.type());
332                         g_value_copy(value.gobj(),x.gobj());
333
334                         synfigapp::Action::Handle action(synfigapp::Action::create("layer_activate"));
335
336                         if(!action)
337                                 return;
338
339                         action->set_param("canvas",canvas_interface()->get_canvas());
340                         action->set_param("canvas_interface",canvas_interface());
341                         action->set_param("layer",layer);
342                         action->set_param("new_status",bool(x.get()));
343
344                         canvas_interface()->get_instance()->perform_action(action);
345                         return;
346                 }
347                 else
348                         Gtk::TreeStore::set_value_impl(iter,column, value);
349
350         }
351         catch(std::exception x)
352         {
353                 g_warning(x.what());
354         }
355 }
356
357
358
359
360 bool
361 LayerTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
362 {
363         //if(!get_iter(path)) return false;
364 //      Gtk::TreeModel::Row row(*get_iter(path));
365
366         return true;
367 //      return (bool)true;
368 }
369
370 bool
371 LayerTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
372 {
373         if(!const_cast<LayerTreeStore*>(this)->get_iter(path)) return false;
374         //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
375         //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
376         //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
377
378         Gtk::TreeModel::Row row(*const_cast<LayerTreeStore*>(this)->get_iter(path));
379
380         if((bool)true)
381         {
382                 Layer* layer(((Layer::Handle)row[model.layer]).get());
383                 assert(layer);
384                 bool included(false);
385
386                 //gtk_selection_data_set (selection_data, gdk_atom_intern("LAYER",false), 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
387
388                 std::vector<Layer*> layers;
389                 // The following is a hack for multiple row DND
390                 {
391                         synfigapp::SelectionManager::LayerList bleh(get_canvas_interface()->get_selection_manager()->get_selected_layers());
392                         if(bleh.empty())
393                         {
394                                 selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
395                                 return true;
396                         }
397                         while(!bleh.empty())
398                         {
399                                 if(bleh.back().get()==layer)
400                                         included=true;
401                                 layers.push_back(bleh.back().get());
402                                 bleh.pop_back();
403                         }
404                 }
405                 if(!included)
406                         layers.push_back(layer);
407                 selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
408
409                 return true;
410         }
411         return false;
412 }
413
414 bool
415 LayerTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
416 {
417         return true;
418 }
419
420 bool
421 LayerTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
422 {
423         //if(!const_cast<LayerTreeStore*>(this)->get_iter(dest)) return false;
424
425         //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
426         //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
427         //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
428
429         //Gtk::TreeModel::Row row(*get_iter(dest));
430
431         if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
432         {
433                 //Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
434                 //assert(src);
435
436                 //return true;
437                 TreeModel::Path dest_parent(dest);
438                 if(!dest_parent.up() || dest.get_depth()==1)
439                 {
440                         //row=(*get_iter(dest));
441                         //dest_canvas=(Canvas::Handle)(row[model.canvas]);
442                         return true;
443                 }
444                 else if((bool)const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))
445                         return (bool)(Canvas::Handle)(*const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))[model.contained_canvas];
446         }
447         return false;
448 }
449
450 bool
451 LayerTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
452 {
453
454         //if(!dest_parent.up() || !get_iter(dest)) return false;
455
456         bool ret=false;
457         int i(0);
458
459
460         //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
461         //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
462         //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
463         synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Move Layers"));
464
465         // Save the selection data
466         synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
467
468         if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
469         {
470                 Gtk::TreeModel::Row row;
471                 Canvas::Handle dest_canvas;
472
473                 int dest_layer_depth=dest.back();
474
475                 TreeModel::Path dest_parent(dest);
476                 if(!dest_parent.up() || !get_iter(dest_parent))
477                 {
478                         TreeModel::Path dest_(dest);
479                         if(!get_iter(dest_))
480                                 dest_.prev();
481
482                         if(!get_iter(dest_))
483                                 return false;
484
485                         {
486                                 row=(*get_iter(dest_));
487                                 dest_canvas=(Canvas::Handle)(row[model.canvas]);
488                         }
489                 }
490                 else
491                 {
492                         row=(*get_iter(dest_parent));
493                         dest_canvas=row[model.contained_canvas];
494                 }
495
496                 assert(dest_canvas);
497
498                 Layer::Handle dest_layer(row[model.layer]);
499
500                 if(synfig::String(selection_data.get_data_type())=="LAYER")for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
501                 {
502                         //synfig::info("dest_layer_depth=%d",dest_layer_depth);
503
504                         Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
505                         assert(src);
506                         if(dest_layer==src)
507                                 continue;
508
509                         if(dest_canvas==src->get_canvas() && src->get_depth()<dest_layer_depth)
510                                 dest_layer_depth--;
511
512                         // In this case, we are just moving.
513 //                      if(dest_canvas==src->get_canvas())
514                         {
515                                 //if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
516                                 //      dest_layer_depth--;
517                                 if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
518                                         continue;
519
520                                 synfigapp::Action::Handle action(synfigapp::Action::create("layer_move"));
521                                 action->set_param("canvas",dest_canvas);
522                                 action->set_param("canvas_interface",canvas_interface());
523                                 action->set_param("layer",src);
524                                 action->set_param("new_index",dest_layer_depth);
525                                 action->set_param("dest_canvas",dest_canvas);
526                                 if(canvas_interface()->get_instance()->perform_action(action))
527                                         ret=true;
528                                 else
529                                 {
530                                         passive_grouper.cancel();
531                                         return false;
532                                 }
533                                 continue;
534                         }
535                         /*else // In this case we need to remove and then add
536                         {
537
538                                 synfigapp::Action::Handle action;
539                                 action=synfigapp::Action::create("layer_remove");
540                                 action->set_param("canvas",Canvas::Handle(src->get_canvas()));
541                                 if(!action->set_param("canvas_interface",App::get_instance(src->get_canvas())->find_canvas_interface(src->get_canvas())))
542                                         action->set_param("canvas_interface",canvas_interface());
543                                 action->set_param("layer",src);
544                                 if(!canvas_interface()->get_instance()->perform_action(action))
545                                 {
546                                         passive_grouper.cancel();
547                                         ret=false;
548                                         return false;
549                                 }
550
551                                 action=synfigapp::Action::create("layer_add");
552                                 action->set_param("canvas",dest_canvas);
553                                 action->set_param("canvas_interface",canvas_interface());
554                                 action->set_param("new",src);
555                                 if(!canvas_interface()->get_instance()->perform_action(action))
556                                 {
557                                         passive_grouper.cancel();
558                                         ret=false;
559                                         return false;
560                                 }
561
562                                 if(dest_layer_depth!=0)
563                                 {
564                                         action=synfigapp::Action::create("layer_move");
565                                         action->set_param("canvas",dest_canvas);
566                                         action->set_param("canvas_interface",canvas_interface());
567                                         action->set_param("layer",src);
568                                         action->set_param("new_index",dest_layer_depth);
569                                         if(!canvas_interface()->get_instance()->perform_action(action))
570                                         {
571                                                 passive_grouper.cancel();
572                                                 ret=false;
573                                                 return false;
574                                         }
575                                 }
576                                 ret=true;
577                         }
578                         */
579                 }
580         }
581         synfig::info("I suposidly moved %d layers",i);
582
583         // Reselect the previously selected layers
584         canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
585
586         return ret;
587 }
588
589 void
590 LayerTreeStore::rebuild()
591 {
592         //etl::clock timer;timer.reset();
593
594         //synfig::warning("---------rebuilding layer table---------");
595         // Save the selection data
596         synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
597
598         // Clear out the current list
599         clear();
600
601         // Go ahead and and add all the layers
602         std::for_each(
603                 canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
604                 sigc::mem_fun(*this, &studio::LayerTreeStore::on_layer_added)
605         );
606
607         // Reselect the previously selected layers
608         if(!layer_list.empty())
609                 canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
610
611         //synfig::info("LayerTreeStore::rebuild() took %f seconds",float(timer()));
612 }
613
614 void
615 LayerTreeStore::refresh()
616 {
617         etl::clock timer;timer.reset();
618
619         Gtk::TreeModel::Children children_(children());
620
621         Gtk::TreeModel::Children::iterator iter;
622
623         if(!children_.empty())
624                 for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
625                 {
626                         Gtk::TreeRow row=*iter;
627                         refresh_row(row);
628                 }
629         //synfig::info("LayerTreeStore::refresh() took %f seconds",float(timer()));
630 }
631
632 void
633 LayerTreeStore::refresh_row(Gtk::TreeModel::Row &row)
634 {
635         Layer::Handle layer=row[model.layer];
636         /*
637         {
638                 row[model.name] = layer->get_local_name();
639                 if(layer->get_description().empty())
640                 {
641                         row[model.label] = layer->get_local_name();
642                         row[model.tooltip] = Glib::ustring("Layer");
643                 }
644                 else
645                 {
646                         row[model.label] = layer->get_description();
647                         row[model.tooltip] = layer->get_local_name();
648                 }
649         }
650         */
651
652         if(layer->dynamic_param_list().count("z_depth"))
653                 row[model.z_depth]=Time::begin();
654         //      row_changed(get_path(row),row);
655
656         Gtk::TreeModel::Children children = row.children();
657         Gtk::TreeModel::Children::iterator iter;
658
659         if(!children.empty())
660                 for(iter = children.begin(); iter && iter != children.end(); ++iter)
661                 {
662                         Gtk::TreeRow row=*iter;
663                         refresh_row(row);
664                 }
665 }
666
667
668 void
669 LayerTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
670 {
671         //row[model.id] = handle->get_name();
672         //row[model.name] = handle->get_local_name();
673         /*if(handle->get_description().empty())
674         {
675                 //row[model.label] = handle->get_local_name();
676                 row[model.tooltip] = Glib::ustring("Layer");
677         }
678         else
679         {
680                 //row[model.label] = handle->get_description();
681                 row[model.tooltip] = handle->get_local_name();
682         }*/
683
684         //row[model.active] = handle->active();
685         row[model.layer] = handle;
686         //row[model.canvas] = handle->get_canvas();
687         //row[model.icon] = layer_icon;
688
689         synfig::Layer::ParamList paramlist=handle->get_param_list();
690
691         synfig::Layer::Vocab vocab=handle->get_param_vocab();
692         synfig::Layer::Vocab::iterator iter;
693
694         for(iter=vocab.begin();iter!=vocab.end();++iter)
695         {
696                 if(iter->get_hidden())
697                         continue;
698                 if(handle->get_param(iter->get_name()).get_type()!=ValueBase::TYPE_CANVAS)
699                         continue;
700
701                 {
702                         Canvas::Handle canvas;
703                         canvas=handle->get_param(iter->get_name()).get(canvas);
704                         if(!canvas)
705                                 continue;
706
707                         Canvas::reverse_iterator iter;
708                         row[model.contained_canvas]=canvas;
709
710                         for(iter=canvas->rbegin();iter!=canvas->rend();++iter)
711                         {
712                                 Gtk::TreeRow row_(*(prepend(row.children())));
713                                 set_row_layer(row_,*iter);
714                         }
715                         continue;
716                 }
717
718                 /*
719                 etl::handle<ValueNode> value_node;
720                 if(handle.constant()->dynamic_param_list().count(iter->get_name()))
721                         value_node=handle->dynamic_param_list()[iter->get_name()];
722
723                 Gtk::TreeRow child_row = *(append(row.children()));
724                 set_row_param(
725                         child_row,
726                         handle,
727                         iter->get_name(),
728                         iter->get_local_name(),
729                         paramlist[iter->get_name()],
730                         value_node,
731                         &*iter
732                 );
733                 */
734         }
735 }
736
737 void
738 LayerTreeStore::on_layer_added(synfig::Layer::Handle layer)
739 {
740         assert(layer);
741         Gtk::TreeRow row;
742         if(canvas_interface()->get_canvas()==layer->get_canvas())
743         {
744                 row=*(prepend());
745         }
746         else
747         {
748                 Gtk::TreeModel::Children::iterator iter;
749                 if(!find_canvas_row(layer->get_canvas(),iter))
750                 {
751                         rebuild();
752                         return;
753                 }
754                 row=*(prepend(iter->children()));
755         }
756         set_row_layer(row,layer);
757 }
758
759 void
760 LayerTreeStore::on_layer_removed(synfig::Layer::Handle handle)
761 {
762         Gtk::TreeModel::Children::iterator iter;
763         if(find_layer_row(handle,iter))
764                 erase(iter);
765         else
766         {
767                 synfig::error("LayerTreeStore::on_layer_removed():Unable to find layer to be removed, forced to rebuild...");
768                 rebuild();
769         }
770 }
771
772 void
773 LayerTreeStore::on_layer_inserted(synfig::Layer::Handle handle,int depth)
774 {
775         if(depth==0)
776         {
777                 on_layer_added(handle);
778                 return;
779         }
780
781         Gtk::TreeModel::Children children_(children());
782         if(canvas_interface()->get_canvas()!=handle->get_canvas())
783         {
784                 Gtk::TreeModel::Children::iterator iter;
785                 if(!find_canvas_row(handle->get_canvas(),iter))
786                 {
787                         synfig::error("LayerTreeStore::on_layer_inserted():Unable to find canvas row, forced to rebuild...");
788                         rebuild();
789                         return;
790                 }
791                 children_=iter->children();
792         }
793
794         Gtk::TreeModel::Children::iterator iter(children_.begin());
795         while(depth-- && iter)
796         {
797                 ++iter;
798                 if(!iter || iter==children_.end())
799                 {
800                         synfig::error("LayerTreeStore::on_layer_inserted():Unable to achieve desired depth, forced to rebuild...");
801                         rebuild();
802                         return;
803                 }
804         }
805
806         Gtk::TreeModel::Row row(*insert(iter));
807         set_row_layer(row,handle);
808 }
809
810 void
811 LayerTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
812 {
813         Gtk::TreeModel::Children::iterator iter;
814         if(find_layer_row(handle,iter))
815                 (*iter)[model.layer]=handle;
816         else
817         {
818                 synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
819                 rebuild();
820         }
821 }
822
823 void
824 LayerTreeStore::on_layer_lowered(synfig::Layer::Handle layer)
825 {
826         Gtk::TreeModel::Children::iterator iter, iter2;
827         if(find_layer_row(layer,iter))
828         {
829                 // Save the selection data
830                 //synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
831                 iter2=iter;
832                 iter2++;
833                 if(!iter2)
834                 {
835                         rebuild();
836                         return;
837                 }
838
839                 //Gtk::TreeModel::Row row(*iter);
840                 Gtk::TreeModel::Row row2 = *iter2;
841                 synfig::Layer::Handle layer2=row2[model.layer];
842
843                 erase(iter2);
844                 row2=*insert(iter);
845                 set_row_layer(row2,layer2);
846
847         }
848         else
849                 rebuild();
850 }
851
852 void
853 LayerTreeStore::on_layer_raised(synfig::Layer::Handle layer)
854 {
855         Gtk::TreeModel::Children::iterator iter, iter2;
856
857         Gtk::TreeModel::Children children_(children());
858
859         if(find_layer_row_(layer, canvas_interface()->get_canvas(), children_, iter,iter2))
860         {
861                 if(iter!=iter2)
862                 {
863                         //Gtk::TreeModel::Row row = *iter;
864                         Gtk::TreeModel::Row row2 = *iter2;
865                         synfig::Layer::Handle layer2=row2[model.layer];
866
867                         erase(iter2);
868                         iter++;
869                         row2=*insert(iter);
870                         set_row_layer(row2,layer2);
871
872                         return;
873                 }
874         }
875
876         rebuild();
877 }
878
879 void
880 LayerTreeStore::on_layer_moved(synfig::Layer::Handle layer,int depth, synfig::Canvas::Handle /*canvas*/)
881 {
882         on_layer_removed(layer);
883         on_layer_inserted(layer,depth);
884 }
885
886 void
887 LayerTreeStore::on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)
888 {
889         if(param_name=="z_depth")
890         {
891                 Gtk::TreeModel::Children::iterator iter;
892                 if(find_layer_row(handle,iter))
893                 {
894                         (*iter)[model.z_depth]=Time::begin();
895                 }
896         }
897
898         /*
899         //DEBUGPOINT();
900         Gtk::TreeModel::Children::iterator iter;
901         if(find_layer_row(handle,iter))
902         {
903                 //DEBUGPOINT();
904                 Gtk::TreeModel::Children children(iter->children());
905
906                 for(iter = children.begin(); iter && iter != children.end(); ++iter)
907                 {
908                         if((Glib::ustring)(*iter)[model.param_name]==param_name)
909                         {
910                                 //DEBUGPOINT();
911                                 Gtk::TreeRow row=*iter;
912                                 refresh_row(row);
913                                 return;
914                         }
915                 }
916         }
917         //DEBUGPOINT();
918         rebuild();
919         */
920 }
921
922 void
923 LayerTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
924 {
925         Gtk::TreeModel::Children::iterator iter;
926         if(find_layer_row(handle,iter))
927         {
928                 Gtk::TreeRow row(*iter);
929
930                 Layer::Handle layer(row[model.layer]);
931
932                 if(desc.empty())
933                 {
934                         //row[model.label]=layer->get_local_name();
935                         row[model.tooltip]=Glib::ustring(_("Layer"));
936                 }
937                 else
938                         //row[model.label]=layer->get_description();
939                         row[model.tooltip]=layer->get_local_name();
940         }
941         else
942         {
943                 rebuild();
944         }
945 }
946
947 bool
948 LayerTreeStore::find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter)
949 {
950         if(canvas==parent)
951                 return false;
952
953         {
954                 for(iter=layers.begin(); iter && iter != layers.end(); ++iter)
955                 {
956                         Gtk::TreeModel::Row row = *iter;
957                         if(canvas==(synfig::Canvas::Handle)row[model.contained_canvas])
958                                 return true;
959                 }
960
961                 iter=children().end();
962                 //return false;
963         }
964
965         Gtk::TreeModel::Children::iterator iter2;
966         //Gtk::TreeModel::Children::iterator iter3;
967
968         for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
969         {
970                 Gtk::TreeModel::Row row = *iter2;
971                 assert((bool)true);
972
973                 if(row.children().empty())
974                         continue;
975
976                 Canvas::Handle sub_canvas((*row.children().begin())[model.canvas]);
977                 if(!sub_canvas)
978                         continue;
979
980                 if(find_canvas_row_(canvas,sub_canvas,iter2->children(),iter))
981                         return true;
982         }
983
984         iter=children().end();
985         return false;
986 }
987
988 bool
989 LayerTreeStore::find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter)
990 {
991         return find_canvas_row_(canvas,canvas_interface()->get_canvas(),children(),iter);
992 }
993
994
995 bool
996 LayerTreeStore::find_layer_row_(const synfig::Layer::Handle &layer, synfig::Canvas::Handle /*canvas*/, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
997 {
998         assert(layer);
999
1000         //if(layer->get_canvas()==canvas)
1001         {
1002                 for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
1003                 {
1004                         Gtk::TreeModel::Row row = *iter;
1005                         if(layer==(synfig::Layer::Handle)row[model.layer])
1006                                 return true;
1007                 }
1008
1009                 iter=children().end();
1010                 //DEBUGPOINT();
1011                 //return false;
1012         }
1013
1014         Gtk::TreeModel::Children::iterator iter2;
1015
1016         for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
1017         {
1018                 Gtk::TreeModel::Row row = *iter2;
1019                 assert((bool)true);
1020
1021                 if(row.children().empty())
1022                         continue;
1023
1024                 Canvas::Handle canvas((*row.children().begin())[model.canvas]);
1025                 if(!canvas)
1026                         continue;
1027
1028                 if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
1029                         return true;
1030         }
1031
1032         iter=children().end();
1033         return false;
1034 }
1035
1036 bool
1037 LayerTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
1038 {
1039         Gtk::TreeModel::Children::iterator prev;
1040         return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
1041 }
1042
1043 bool
1044 LayerTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
1045 {
1046         Gtk::TreeModel::Children::iterator iter;
1047         if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
1048                 return false;
1049         if(iter==children().begin())
1050                 return false;
1051         return true;
1052 }