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