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