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