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