Move treeviews/treestores into subfolder
[synfig.git] / synfig-studio / src / gui / trees / 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 **      Copyright (c) 2008 Chris Moore
10 **
11 **      This package is free software; you can redistribute it and/or
12 **      modify it under the terms of the GNU General Public License as
13 **      published by the Free Software Foundation; either version 2 of
14 **      the License, or (at your option) any later version.
15 **
16 **      This package is distributed in the hope that it will be useful,
17 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 **      General Public License for more details.
20 **      \endlegal
21 */
22 /* ========================================================================= */
23
24 /* === H E A D E R S ======================================================= */
25
26 #ifdef USING_PCH
27 #       include "pch.h"
28 #else
29 #ifdef HAVE_CONFIG_H
30 #       include <config.h>
31 #endif
32
33 #include "trees/layergrouptreestore.h"
34 #include "iconcontroller.h"
35 #include <gtkmm/button.h>
36 #include <synfig/paramdesc.h>
37 #include <synfigapp/action.h>
38 #include <synfigapp/instance.h>
39 #include "app.h"
40 #include "instance.h"
41 #include <synfigapp/action_system.h>
42 #include "docks/dockmanager.h"
43 #include "docks/dockable.h"
44
45 #include <gtk/gtkversion.h>
46 #include <ETL/clock>
47 #include "general.h"
48
49 #endif
50
51 /* === U S I N G =========================================================== */
52
53 using namespace std;
54 using namespace etl;
55 using namespace synfig;
56 using namespace studio;
57
58 /* === M A C R O S ========================================================= */
59
60 #define GROUP_NEST_CHAR '.'
61
62 /* === G L O B A L S ======================================================= */
63
64 /* === P R O C E D U R E S ================================================= */
65
66 /* === M E T H O D S ======================================================= */
67
68 static LayerGroupTreeStore::Model& ModelHack()
69 {
70         static LayerGroupTreeStore::Model* model(0);
71         if(!model)model=new LayerGroupTreeStore::Model;
72         return *model;
73 }
74
75 LayerGroupTreeStore::LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
76         Gtk::TreeStore                  (ModelHack()),
77         canvas_interface_               (canvas_interface_)
78 {
79         layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
80         group_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-group"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
81
82         // Connect Signals to Terminals
83         canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_status_changed));
84         canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_new_description));
85
86         canvas_interface()->get_canvas()->signal_group_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_added)));
87         canvas_interface()->get_canvas()->signal_group_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_removed)));
88         canvas_interface()->get_canvas()->signal_group_changed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_changed)));
89
90         canvas_interface()->get_canvas()->signal_group_pair_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_added)));
91         canvas_interface()->get_canvas()->signal_group_pair_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_removed)));
92
93         rebuild();
94 }
95
96 LayerGroupTreeStore::~LayerGroupTreeStore()
97 {
98         //clear();
99
100         if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
101                 synfig::info("LayerGroupTreeStore::~LayerGroupTreeStore(): Deleted");
102 }
103
104 bool
105 LayerGroupTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
106 {
107         const Model model;
108
109         Glib::ustring substr(x.uppercase());
110         Glib::ustring label((*iter)[model.label]);
111         label=label.uppercase();
112
113         return label.find(substr)==Glib::ustring::npos;
114 }
115
116
117 Glib::RefPtr<LayerGroupTreeStore>
118 LayerGroupTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
119 {
120         return Glib::RefPtr<LayerGroupTreeStore>(new LayerGroupTreeStore(canvas_interface_));
121 }
122
123 void
124 LayerGroupTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
125 {
126         if(column==model.child_layers.index())
127         {
128                 Glib::Value<LayerList> x;
129                 g_value_init(x.gobj(),x.value_type());
130
131                 if((bool)(*iter)[model.is_group])
132                 {
133                         set<Layer::Handle> layer_set(canvas_interface()->get_canvas()->get_layers_in_group((Glib::ustring)(*iter)[model.group_name]));
134
135                         x.set(LayerList(layer_set.begin(),layer_set.end()));
136                 }
137                 else if((bool)(*iter)[model.is_layer])
138                 {
139                         LayerList layer_list;
140                         layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
141                         x.set(layer_list);
142                 }
143
144                 g_value_init(value.gobj(),x.value_type());
145                 value=x;
146         }
147         else if(column==model.all_layers.index())
148         {
149                 Glib::Value<LayerList> x;
150                 g_value_init(x.gobj(),x.value_type());
151
152                 if((bool)(*iter)[model.is_group])
153                 {
154                         LayerList layer_list;
155                         Gtk::TreeModel::iterator child_iter(iter->children().begin());
156                         for(;child_iter;++child_iter)
157                         {
158                                 LayerList layer_list2((LayerList)(*child_iter)[model.all_layers]);
159                                 for(;layer_list2.size();layer_list2.pop_front())
160                                         layer_list.push_back(layer_list2.front());
161                         }
162                         x.set(layer_list);
163                 }
164                 else if((bool)(*iter)[model.is_layer])
165                 {
166                         LayerList layer_list;
167                         layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
168                         x.set(layer_list);
169                 }
170
171                 g_value_init(value.gobj(),x.value_type());
172                 value=x;
173         }
174         else if(column==model.group_name.index())
175         {
176                 if((bool)(*iter)[model.is_group])
177                         return Gtk::TreeStore::get_value_vfunc(iter,column,value);
178                 return get_value_vfunc(iter->parent(),column,value);
179         }
180         else if(column==model.parent_group_name.index())
181         {
182                 if(iter->parent())
183                         return get_value_vfunc(iter->parent(),model.group_name.index(),value);
184                 Glib::Value<Glib::ustring> x;
185                 g_value_init(x.gobj(),x.value_type());
186                 x.set(Glib::ustring());
187                 g_value_init(value.gobj(),x.value_type());
188                 value=x;
189         }
190         else if(column==model.label.index())
191         {
192                 if((bool)(*iter)[model.is_group])
193                 {
194                         Glib::Value<Glib::ustring> x;
195                         g_value_init(x.gobj(),x.value_type());
196
197                         Glib::ustring group_name((*iter)[model.group_name]);
198
199                         // Get rid of any parent group crap
200                         while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
201                                 group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
202
203                         x.set(group_name);
204
205                         g_value_init(value.gobj(),x.value_type());
206
207                         value=x;
208                 }
209                 else if((bool)(*iter)[model.is_layer])
210                 {
211                         synfig::Layer::Handle layer((*iter)[model.layer]);
212
213                         if(!layer)return;
214
215                         Glib::Value<Glib::ustring> x;
216                         g_value_init(x.gobj(),x.value_type());
217
218                         x.set(layer->get_non_empty_description());
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("LayerSetDesc"));
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("GroupRename"));
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("LayerActivate"));
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("%s", 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 }
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("GroupAddLayers"));
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("GroupRename"));
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("LayerMove"));
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 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                 // Not need to send a warning when a layer changes its status and
901                 // it is not found in any group.
902                 //synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
903                 rebuild();
904         }
905 }
906
907
908 void
909 LayerGroupTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
910 {
911         Gtk::TreeModel::Children::iterator iter;
912         if(find_layer_row(handle,iter))
913         {
914                 Gtk::TreeRow row(*iter);
915
916                 Layer::Handle layer(row[model.layer]);
917
918                 if(desc.empty())
919                 {
920                         //row[model.label]=layer->get_local_name();
921                         row[model.tooltip]=Glib::ustring(_("Layer"));
922                 }
923                 else
924                         //row[model.label]=layer->get_description();
925                         row[model.tooltip]=layer->get_local_name();
926         }
927         else
928         {
929                 rebuild();
930         }
931 }
932
933 bool
934 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)
935 {
936         assert(layer);
937
938         //if(layer->get_canvas()==canvas)
939         {
940                 for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
941                 {
942                         Gtk::TreeModel::Row row = *iter;
943                         if((bool)row[model.is_layer] && layer==(synfig::Layer::Handle)row[model.layer])
944                                 return true;
945                 }
946
947                 iter=children().end();
948                 //return false;
949         }
950
951         Gtk::TreeModel::Children::iterator iter2;
952
953         for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
954         {
955                 Gtk::TreeModel::Row row = *iter2;
956                 assert((bool)true);
957
958                 if(row.children().empty())
959                         continue;
960
961                 /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
962                 if(!canvas)
963                         continue;
964                 */
965
966                 if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
967                         return true;
968         }
969
970         iter=children().end();
971         return false;
972 }
973
974 bool
975 LayerGroupTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
976 {
977         Gtk::TreeModel::Children::iterator prev;
978         return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
979 }
980
981 bool
982 LayerGroupTreeStore::find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter)
983 {
984         Gtk::TreeModel::Children::iterator prev;
985         return find_group_row_(group,children(),iter,prev);
986 }
987
988 bool
989 LayerGroupTreeStore::find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
990 {
991         //if(layer->get_canvas()==canvas)
992         {
993                 for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
994                 {
995                         Gtk::TreeModel::Row row = *iter;
996                         if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
997                                 return true;
998                 }
999
1000                 iter=children().end();
1001                 //return false;
1002         }
1003
1004         Gtk::TreeModel::Children::iterator iter2;
1005
1006         for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
1007         {
1008                 Gtk::TreeModel::Row row = *iter2;
1009                 assert((bool)true);
1010
1011                 if(row.children().empty())
1012                         continue;
1013
1014                 if(find_group_row_(group,iter2->children(),iter,prev))
1015                         return true;
1016         }
1017
1018         iter=children().end();
1019         return false;
1020 }
1021
1022 bool
1023 LayerGroupTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
1024 {
1025         Gtk::TreeModel::Children::iterator iter;
1026         if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
1027                 return false;
1028         if(iter==children().begin())
1029                 return false;
1030         return true;
1031 }