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