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