Extract translatable strings from some more files
[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 **      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 "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 "dockmanager.h"
43 #include "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("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                                         ret=true;
674                                 }
675                                 else
676                                 {
677                                         passive_grouper.cancel();
678                                         return false;
679                                 }
680                                 continue;
681                         }
682                 }
683         }
684         synfig::info("I supposedly moved %d layers",i);
685
686         // Reselect the previously selected layers
687         canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
688
689         return ret;
690         */
691         return false;
692 }
693
694
695
696
697
698
699
700 void
701 LayerGroupTreeStore::rebuild()
702 {
703         rebuilding=true;
704         // etl::clock timer;timer.reset();
705         try {
706
707                 // Clear out the current list
708                 clear();
709                 Canvas::Handle canvas(canvas_interface()->get_canvas());
710                 std::set<String> groups(canvas->get_groups());
711                 for(;groups.size();groups.erase(groups.begin()))
712                 {
713                         String group(*groups.begin());
714                         Gtk::TreeRow row(on_group_added(group));
715                         std::set<Layer::Handle> layers(canvas->get_layers_in_group(group));
716
717                         for(;layers.size();layers.erase(layers.begin()))
718                         {
719                                 Gtk::TreeRow layer_row(*(prepend(row.children())));
720                                 Layer::Handle layer(*layers.begin());
721                                 set_row_layer(layer_row,layer);
722                         }
723                 }
724
725                 // Go ahead and and add all the layers
726                 /*std::for_each(
727                         canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
728                         sigc::mem_fun(*this, &studio::LayerGroupTreeStore::on_layer_added)
729                 );*/
730         }
731         catch(...)
732         {
733                 rebuilding=false;
734                 throw;
735         }
736         rebuilding=false;
737         // synfig::info("LayerGroupTreeStore::rebuild() took %f seconds",float(timer()));
738 }
739
740 void
741 LayerGroupTreeStore::refresh()
742 {
743         rebuild();
744 }
745
746 void
747 LayerGroupTreeStore::refresh_row(Gtk::TreeModel::Row &row)
748 {
749         if((bool)row[model.is_layer])
750         {
751                 Layer::Handle layer=row[model.layer];
752
753
754                 //if(layer->dynamic_param_list().count("z_depth"))
755                 //      row[model.z_depth]=Time::begin();
756         }
757
758         Gtk::TreeModel::Children children = row.children();
759         Gtk::TreeModel::Children::iterator iter;
760
761         if(!children.empty())
762                 for(iter = children.begin(); iter && iter != children.end(); ++iter)
763                 {
764                         Gtk::TreeRow row=*iter;
765                         refresh_row(row);
766                 }
767 }
768
769
770 void
771 LayerGroupTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
772 {
773         row[model.is_layer] = true;
774         row[model.is_group] = false;
775         row[model.layer] = handle;
776 }
777
778 Gtk::TreeRow
779 LayerGroupTreeStore::on_group_added(synfig::String group)
780 {
781         // Check to see if this group perhaps already
782         // exists
783         {
784                 Gtk::TreeModel::Children::iterator iter;
785                 if(find_group_row(group,  iter))
786                         return *iter;
787         }
788
789         if(group.find(GROUP_NEST_CHAR)!=String::npos)
790         {
791                 Gtk::TreeModel::Children::iterator iter;
792                 String parent_name;
793                 do
794                 {
795                         if(parent_name.size())
796                                 parent_name+=GROUP_NEST_CHAR;
797                         parent_name+=string(group,0,group.find(GROUP_NEST_CHAR));
798
799                         if(!find_group_row(parent_name, iter))
800                                 iter=on_group_added(parent_name);
801
802                         group=String(group,group.find(GROUP_NEST_CHAR)+1,String::npos);
803                 }while(group.find(GROUP_NEST_CHAR)!=String::npos);
804
805                 if(parent_name.size())
806                         parent_name+=GROUP_NEST_CHAR;
807                 parent_name+=group;
808
809                 if(iter)
810                 {
811                         Gtk::TreeRow row(*(prepend(iter->children())));
812                         row[model.group_name]=parent_name;
813                         row[model.is_layer]=false;
814                         row[model.is_group]=true;
815                         on_activity();
816                         return row;
817                 }
818         }
819
820         Gtk::TreeRow row(*(append()));
821         row[model.group_name]=group;
822         row[model.is_layer]=false;
823         row[model.is_group]=true;
824         on_activity();
825         return row;
826 }
827
828 bool
829 LayerGroupTreeStore::on_group_removed(synfig::String group)
830 {
831         Gtk::TreeModel::Children::iterator iter;
832         if(find_group_row(group,iter) && iter->children().size()==0)
833                 erase(iter);
834         else
835                 return false;
836
837         return true;
838 }
839
840 bool
841 LayerGroupTreeStore::on_group_changed(synfig::String /*group*/)
842 {
843         return true;
844 }
845
846 void
847 LayerGroupTreeStore::on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer)
848 {
849         if(!layer->get_canvas())
850                 return;
851         Gtk::TreeModel::Children::iterator iter;
852         if(!find_group_row(group, iter))
853                 iter=on_group_added(group);
854
855         Gtk::TreeRow layer_row(*(append(iter->children())));
856         set_row_layer(layer_row,layer);
857         on_activity();
858 }
859
860 void
861 LayerGroupTreeStore::on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer)
862 {
863         if(!layer->get_canvas())
864                 return;
865         Gtk::TreeModel::Children::iterator iter;
866         if(!find_group_row(group, iter))
867                 return;
868
869         Gtk::TreeModel::Children::iterator prev,layer_iter;
870
871         if(!find_layer_row_(layer, layer->get_canvas(), iter->children(), layer_iter, prev))
872                 return;
873
874         erase(layer_iter);
875
876         on_activity();
877 }
878
879 void
880 LayerGroupTreeStore::on_activity()
881 {
882         // If we aren't rebuilding and the last action
883         // had something to do with groups, then go
884         // a head and present the groups dialog.
885         if(!rebuilding && canvas_interface()->get_instance()->get_most_recent_action() && canvas_interface()->get_instance()->get_most_recent_action()->get_name().find("group")!=String::npos)
886         try
887         {
888                 App::dock_manager->find_dockable("groups").present();
889         }
890         catch(...) { }
891 }
892
893 void
894 LayerGroupTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
895 {
896         Gtk::TreeModel::Children::iterator iter;
897         if(find_layer_row(handle,iter))
898                 (*iter)[model.layer]=handle;
899         else
900         {
901                 synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
902                 rebuild();
903         }
904 }
905
906
907 void
908 LayerGroupTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
909 {
910         Gtk::TreeModel::Children::iterator iter;
911         if(find_layer_row(handle,iter))
912         {
913                 Gtk::TreeRow row(*iter);
914
915                 Layer::Handle layer(row[model.layer]);
916
917                 if(desc.empty())
918                 {
919                         //row[model.label]=layer->get_local_name();
920                         row[model.tooltip]=Glib::ustring(_("Layer"));
921                 }
922                 else
923                         //row[model.label]=layer->get_description();
924                         row[model.tooltip]=layer->get_local_name();
925         }
926         else
927         {
928                 rebuild();
929         }
930 }
931
932 bool
933 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)
934 {
935         assert(layer);
936
937         //if(layer->get_canvas()==canvas)
938         {
939                 for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
940                 {
941                         Gtk::TreeModel::Row row = *iter;
942                         if((bool)row[model.is_layer] && layer==(synfig::Layer::Handle)row[model.layer])
943                                 return true;
944                 }
945
946                 iter=children().end();
947                 //return false;
948         }
949
950         Gtk::TreeModel::Children::iterator iter2;
951
952         for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
953         {
954                 Gtk::TreeModel::Row row = *iter2;
955                 assert((bool)true);
956
957                 if(row.children().empty())
958                         continue;
959
960                 /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
961                 if(!canvas)
962                         continue;
963                 */
964
965                 if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
966                         return true;
967         }
968
969         iter=children().end();
970         return false;
971 }
972
973 bool
974 LayerGroupTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
975 {
976         Gtk::TreeModel::Children::iterator prev;
977         return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
978 }
979
980 bool
981 LayerGroupTreeStore::find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter)
982 {
983         Gtk::TreeModel::Children::iterator prev;
984         return find_group_row_(group,children(),iter,prev);
985 }
986
987 bool
988 LayerGroupTreeStore::find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
989 {
990         //if(layer->get_canvas()==canvas)
991         {
992                 for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
993                 {
994                         Gtk::TreeModel::Row row = *iter;
995                         if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
996                                 return true;
997                 }
998
999                 iter=children().end();
1000                 //return false;
1001         }
1002
1003         Gtk::TreeModel::Children::iterator iter2;
1004
1005         for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
1006         {
1007                 Gtk::TreeModel::Row row = *iter2;
1008                 assert((bool)true);
1009
1010                 if(row.children().empty())
1011                         continue;
1012
1013                 if(find_group_row_(group,iter2->children(),iter,prev))
1014                         return true;
1015         }
1016
1017         iter=children().end();
1018         return false;
1019 }
1020
1021 bool
1022 LayerGroupTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
1023 {
1024         Gtk::TreeModel::Children::iterator iter;
1025         if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
1026                 return false;
1027         if(iter==children().begin())
1028                 return false;
1029         return true;
1030 }