source: synfigstudio/trunk/fuentes/src/gui/trees/layergrouptreestore.cpp @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 27.1 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file layergrouptreestore.cpp
3**      \brief Template File
4**
5**      $Id$
6**
7**      \legal
8**      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9**      Copyright (c) 2008 Chris Moore
10**
11**      This package is free software; you can redistribute it and/or
12**      modify it under the terms of the GNU General Public License as
13**      published by the Free Software Foundation; either version 2 of
14**      the License, or (at your option) any later version.
15**
16**      This package is distributed in the hope that it will be useful,
17**      but WITHOUT ANY WARRANTY; without even the implied warranty of
18**      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19**      General Public License for more details.
20**      \endlegal
21*/
22/* ========================================================================= */
23
24/* === H E A D E R S ======================================================= */
25
26#ifdef USING_PCH
27#       include "pch.h"
28#else
29#ifdef HAVE_CONFIG_H
30#       include <config.h>
31#endif
32
33#include "trees/layergrouptreestore.h"
34#include "iconcontroller.h"
35#include <gtkmm/button.h>
36#include <synfig/paramdesc.h>
37#include <synfigapp/action.h>
38#include <synfigapp/instance.h>
39#include "app.h"
40#include "instance.h"
41#include <synfigapp/action_system.h>
42#include "docks/dockmanager.h"
43#include "docks/dockable.h"
44
45#include <gtk/gtk.h>
46#include <ETL/clock>
47#include "general.h"
48
49#endif
50
51/* === U S I N G =========================================================== */
52
53using namespace std;
54using namespace etl;
55using namespace synfig;
56using namespace studio;
57
58/* === M A C R O S ========================================================= */
59
60#define GROUP_NEST_CHAR '.'
61
62/* === G L O B A L S ======================================================= */
63
64/* === P R O C E D U R E S ================================================= */
65
66/* === M E T H O D S ======================================================= */
67
68static LayerGroupTreeStore::Model& ModelHack()
69{
70        static LayerGroupTreeStore::Model* model(0);
71        if(!model)model=new LayerGroupTreeStore::Model;
72        return *model;
73}
74
75LayerGroupTreeStore::LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
76        Gtk::TreeStore                  (ModelHack()),
77        canvas_interface_               (canvas_interface_)
78{
79        layer_icon=Gtk::Button().render_icon_pixbuf(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
80        group_icon=Gtk::Button().render_icon_pixbuf(Gtk::StockID("synfig-group"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
81
82        // Connect Signals to Terminals
83        canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_status_changed));
84        canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_new_description));
85
86        canvas_interface()->get_canvas()->signal_group_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_added)));
87        canvas_interface()->get_canvas()->signal_group_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_removed)));
88        canvas_interface()->get_canvas()->signal_group_changed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_changed)));
89
90        canvas_interface()->get_canvas()->signal_group_pair_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_added)));
91        canvas_interface()->get_canvas()->signal_group_pair_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_removed)));
92
93        rebuild();
94}
95
96LayerGroupTreeStore::~LayerGroupTreeStore()
97{
98        //clear();
99
100        if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
101                synfig::info("LayerGroupTreeStore::~LayerGroupTreeStore(): Deleted");
102}
103
104bool
105LayerGroupTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
106{
107        const Model model;
108
109        Glib::ustring substr(x.uppercase());
110        Glib::ustring label((*iter)[model.label]);
111        label=label.uppercase();
112
113        return label.find(substr)==Glib::ustring::npos;
114}
115
116
117Glib::RefPtr<LayerGroupTreeStore>
118LayerGroupTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
119{
120        return Glib::RefPtr<LayerGroupTreeStore>(new LayerGroupTreeStore(canvas_interface_));
121}
122
123void
124LayerGroupTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
125{
126        if(column==model.child_layers.index())
127        {
128                Glib::Value<LayerList> x;
129                g_value_init(x.gobj(),x.value_type());
130
131                if((bool)(*iter)[model.is_group])
132                {
133                        set<Layer::Handle> layer_set(canvas_interface()->get_canvas()->get_layers_in_group((Glib::ustring)(*iter)[model.group_name]));
134
135                        x.set(LayerList(layer_set.begin(),layer_set.end()));
136                }
137                else if((bool)(*iter)[model.is_layer])
138                {
139                        LayerList layer_list;
140                        layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
141                        x.set(layer_list);
142                }
143
144                g_value_init(value.gobj(),x.value_type());
145                value=x;
146        }
147        else if(column==model.all_layers.index())
148        {
149                Glib::Value<LayerList> x;
150                g_value_init(x.gobj(),x.value_type());
151
152                if((bool)(*iter)[model.is_group])
153                {
154                        LayerList layer_list;
155                        Gtk::TreeModel::iterator child_iter(iter->children().begin());
156                        for(;child_iter;++child_iter)
157                        {
158                                LayerList layer_list2((LayerList)(*child_iter)[model.all_layers]);
159                                for(;layer_list2.size();layer_list2.pop_front())
160                                        layer_list.push_back(layer_list2.front());
161                        }
162                        x.set(layer_list);
163                }
164                else if((bool)(*iter)[model.is_layer])
165                {
166                        LayerList layer_list;
167                        layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
168                        x.set(layer_list);
169                }
170
171                g_value_init(value.gobj(),x.value_type());
172                value=x;
173        }
174        else if(column==model.group_name.index())
175        {
176                if((bool)(*iter)[model.is_group])
177                        return Gtk::TreeStore::get_value_vfunc(iter,column,value);
178                return get_value_vfunc(iter->parent(),column,value);
179        }
180        else if(column==model.parent_group_name.index())
181        {
182                if(iter->parent())
183                        return get_value_vfunc(iter->parent(),model.group_name.index(),value);
184                Glib::Value<Glib::ustring> x;
185                g_value_init(x.gobj(),x.value_type());
186                x.set(Glib::ustring());
187                g_value_init(value.gobj(),x.value_type());
188                value=x;
189        }
190        else if(column==model.label.index())
191        {
192                if((bool)(*iter)[model.is_group])
193                {
194                        Glib::Value<Glib::ustring> x;
195                        g_value_init(x.gobj(),x.value_type());
196
197                        Glib::ustring group_name((*iter)[model.group_name]);
198
199                        // Get rid of any parent group crap
200                        while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
201                                group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
202
203                        x.set(group_name);
204
205                        g_value_init(value.gobj(),x.value_type());
206
207                        value=x;
208                }
209                else if((bool)(*iter)[model.is_layer])
210                {
211                        synfig::Layer::Handle layer((*iter)[model.layer]);
212
213                        if(!layer)return;
214
215                        Glib::Value<Glib::ustring> x;
216                        g_value_init(x.gobj(),x.value_type());
217
218                        x.set(layer->get_non_empty_description());
219
220                        g_value_init(value.gobj(),x.value_type());
221                        //g_value_copy(x.gobj(),value.gobj());
222                        value=x;
223                }
224        }
225        else
226        if(column==model.tooltip.index())
227        {
228                synfig::Layer::Handle layer((*iter)[model.layer]);
229
230                if(!layer)return;
231
232                Glib::Value<Glib::ustring> x;
233                g_value_init(x.gobj(),x.value_type());
234
235
236                x.set(layer->get_local_name());
237
238                g_value_init(value.gobj(),x.value_type());
239                //g_value_copy(x.gobj(),value.gobj());
240                value=x;
241        }
242        else
243        if(column==model.canvas.index())
244        {
245                synfig::Layer::Handle layer((*iter)[model.layer]);
246
247                if(!layer)return;
248
249                Glib::Value<Canvas::Handle> x;
250                g_value_init(x.gobj(),x.value_type());
251
252
253                x.set(layer->get_canvas());
254
255                g_value_init(value.gobj(),x.value_type());
256                //g_value_copy(x.gobj(),value.gobj());
257                value=x;
258        }
259        else
260        if(column==model.active.index())
261        {
262                Glib::Value<bool> x;
263                g_value_init(x.gobj(),x.value_type());
264
265                if((bool)(*iter)[model.is_layer])
266                {
267                        synfig::Layer::Handle layer((*iter)[model.layer]);
268                        x.set(layer->active());
269                }
270                else if((bool)(*iter)[model.is_group])
271                {
272                        int activecount(0),total(0);
273                        Gtk::TreeModel::iterator child_iter(iter->children().begin());
274                        for(;child_iter;++child_iter)
275                        {
276                                total++;
277                                if((*child_iter)[model.active])
278                                        activecount++;
279                        }
280                        x.set(activecount>0);
281                }
282                else
283                        x.set(false);
284
285                g_value_init(value.gobj(),x.value_type());
286                g_value_copy(x.gobj(),value.gobj());
287        }
288        else
289        if(column==model.icon.index())
290        {
291                Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
292                g_value_init(x.gobj(),x.value_type());
293
294                if((bool)(*iter)[model.is_layer])
295                {
296                        synfig::Layer::Handle layer((*iter)[model.layer]);
297                        if(!layer)return;
298                        //x.set(layer_icon);
299                        x.set(get_tree_pixbuf_layer(layer->get_name()));
300                }
301                if((bool)(*iter)[model.is_group])
302                        x.set(group_icon);
303
304                g_value_init(value.gobj(),x.value_type());
305                g_value_copy(x.gobj(),value.gobj());
306        }
307        else
308                Gtk::TreeStore::get_value_vfunc(iter,column,value);
309}
310
311void
312LayerGroupTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
313{
314        //if(!iterator_sane(row))
315        //      return;
316
317        if(column>=get_n_columns_vfunc())
318        {
319                g_warning("LayerGroupTreeStore::set_value_impl: Bad column (%d)",column);
320                return;
321        }
322
323        if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
324        {
325                g_warning("LayerGroupTreeStore::set_value_impl: Bad value type");
326                return;
327        }
328
329        try
330        {
331                if(column==model.label.index())
332                {
333                        Glib::Value<Glib::ustring> x;
334                        g_value_init(x.gobj(),model.label.type());
335                        g_value_copy(value.gobj(),x.gobj());
336
337                        if((bool)(*iter)[model.is_layer])
338                        {
339                                synfig::Layer::Handle layer((*iter)[model.layer]);
340                                if(!layer)
341                                        return;
342                                synfig::String new_desc(x.get());
343
344                                if(new_desc==layer->get_local_name())
345                                        new_desc=synfig::String();
346
347                                if(new_desc==layer->get_description())
348                                        return;
349
350                                synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
351
352                                if(!action)
353                                        return;
354
355                                action->set_param("canvas",canvas_interface()->get_canvas());
356                                action->set_param("canvas_interface",canvas_interface());
357                                action->set_param("layer",layer);
358                                action->set_param("new_description",synfig::String(x.get()));
359
360                                canvas_interface()->get_instance()->perform_action(action);
361                                return;
362                        }
363                        else if((bool)(*iter)[model.is_group])
364                        {
365                                synfig::String group((Glib::ustring)(*iter)[model.label]);
366                                synfig::String new_group(x.get());
367
368                                if(x.get()==group)
369                                        return;
370
371                                Glib::ustring group_name((*iter)[model.group_name]);
372                                group=group_name;
373                                new_group.clear();
374
375                                // Get rid of any parent group crap
376                                while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
377                                {
378                                        new_group+=Glib::ustring(group_name,0,group_name.find(GROUP_NEST_CHAR)+1);
379                                        group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
380                                }
381                                new_group+=x.get();
382
383                                // Check to see if this group is real or not.
384                                // If it isn't real, then renaming it is a cinch.
385                                // We know it isn't real if it doesn't have any
386                                // children yet.
387                                if(iter->children().empty())
388                                {
389                                        (*iter)[model.group_name]=new_group;
390                                }
391                                else
392                                {
393                                        synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
394
395                                        if(!action)
396                                                return;
397
398                                        action->set_param("canvas",canvas_interface()->get_canvas());
399                                        action->set_param("canvas_interface",canvas_interface());
400                                        action->set_param("group",group);
401                                        action->set_param("new_group",new_group);
402
403                                        canvas_interface()->get_instance()->perform_action(action);
404                                }
405                                return;
406                        }
407                        return;
408                }
409                else
410                if(column==model.active.index())
411                {
412                        Glib::Value<bool> x;
413                        g_value_init(x.gobj(),model.active.type());
414                        g_value_copy(value.gobj(),x.gobj());
415
416                        if((bool)(*iter)[model.is_layer])
417                        {
418                                synfig::Layer::Handle layer((*iter)[model.layer]);
419                                if(!layer)return;
420
421                                synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
422
423                                if(!action)
424                                        return;
425
426                                action->set_param("canvas",canvas_interface()->get_canvas());
427                                action->set_param("canvas_interface",canvas_interface());
428                                action->set_param("layer",layer);
429                                action->set_param("new_status",bool(x.get()));
430
431
432                                canvas_interface()->get_instance()->perform_action(action);
433                                return;
434                        }
435                        else if(!iter->children().empty())
436                        {
437                                synfigapp::Action::PassiveGrouper group(
438                                        get_canvas_interface()->get_instance().get(),
439                                        String(
440                                                x.get()?_("Activate "):_("Deactivate ")
441                                        )+(Glib::ustring)(*iter)[model.label]
442                                );
443
444                                Gtk::TreeModel::iterator child_iter(iter->children().begin());
445
446                                for(;child_iter;++child_iter)
447                                        (*child_iter)[model.active]=x.get();
448
449                                Gtk::TreeStore::set_value_impl(iter,column, value);
450                        }
451                }
452                else
453                        Gtk::TreeStore::set_value_impl(iter,column, value);
454
455        }
456        catch(std::exception x)
457        {
458                g_warning("%s", x.what());
459        }
460}
461
462
463
464
465bool
466LayerGroupTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
467{
468        //if(!get_iter(path)) return false;
469//      Gtk::TreeModel::Row row(*get_iter(path));
470
471        return true;
472}
473
474bool
475LayerGroupTreeStore::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
511bool
512LayerGroupTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
513{
514        return true;
515}
516
517bool
518LayerGroupTreeStore::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
551bool
552LayerGroupTreeStore::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(),_("Reset"));
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("GroupAddLayers"));
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("GroupRename"));
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("LayerMove"));
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
697void
698LayerGroupTreeStore::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 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
737void
738LayerGroupTreeStore::refresh()
739{
740        rebuild();
741}
742
743void
744LayerGroupTreeStore::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
767void
768LayerGroupTreeStore::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
775Gtk::TreeRow
776LayerGroupTreeStore::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
825bool
826LayerGroupTreeStore::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
837bool
838LayerGroupTreeStore::on_group_changed(synfig::String /*group*/)
839{
840        return true;
841}
842
843void
844LayerGroupTreeStore::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
857void
858LayerGroupTreeStore::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
876void
877LayerGroupTreeStore::on_activity()
878{
879        // If we aren't rebuilding and the last action
880        // had something to do with groups, then go
881        // ahead and present the groups dialog.
882        if(!rebuilding && canvas_interface()->get_instance()->get_most_recent_action_name().find("Group")!=String::npos)
883        try
884        {
885                App::dock_manager->find_dockable("groups").present();
886        }
887        catch(...) { }
888}
889
890void
891LayerGroupTreeStore::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                // Not need to send a warning when a layer changes its status and
899                // it is not found in any group.
900                //synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
901                rebuild();
902        }
903}
904
905
906void
907LayerGroupTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
908{
909        Gtk::TreeModel::Children::iterator iter;
910        if(find_layer_row(handle,iter))
911        {
912                Gtk::TreeRow row(*iter);
913
914                Layer::Handle layer(row[model.layer]);
915
916                if(desc.empty())
917                {
918                        //row[model.label]=layer->get_local_name();
919                        row[model.tooltip]=Glib::ustring(_("Layer"));
920                }
921                else
922                        //row[model.label]=layer->get_description();
923                        row[model.tooltip]=layer->get_local_name();
924        }
925        else
926        {
927                rebuild();
928        }
929}
930
931bool
932LayerGroupTreeStore::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)
933{
934        assert(layer);
935
936        //if(layer->get_canvas()==canvas)
937        {
938                for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
939                {
940                        Gtk::TreeModel::Row row = *iter;
941                        if((bool)row[model.is_layer] && layer==(synfig::Layer::Handle)row[model.layer])
942                                return true;
943                }
944
945                iter=children().end();
946                //return false;
947        }
948
949        Gtk::TreeModel::Children::iterator iter2;
950
951        for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
952        {
953                Gtk::TreeModel::Row row = *iter2;
954                assert((bool)true);
955
956                if(row.children().empty())
957                        continue;
958
959                /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
960                if(!canvas)
961                        continue;
962                */
963
964                if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
965                        return true;
966        }
967
968        iter=children().end();
969        return false;
970}
971
972bool
973LayerGroupTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
974{
975        Gtk::TreeModel::Children::iterator prev;
976        return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
977}
978
979bool
980LayerGroupTreeStore::find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter)
981{
982        Gtk::TreeModel::Children::iterator prev;
983        return find_group_row_(group,children(),iter,prev);
984}
985
986bool
987LayerGroupTreeStore::find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
988{
989        //if(layer->get_canvas()==canvas)
990        {
991                for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
992                {
993                        Gtk::TreeModel::Row row = *iter;
994                        if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
995                                return true;
996                }
997
998                iter=children().end();
999                //return false;
1000        }
1001
1002        Gtk::TreeModel::Children::iterator iter2;
1003
1004        for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
1005        {
1006                Gtk::TreeModel::Row row = *iter2;
1007                assert((bool)true);
1008
1009                if(row.children().empty())
1010                        continue;
1011
1012                if(find_group_row_(group,iter2->children(),iter,prev))
1013                        return true;
1014        }
1015
1016        iter=children().end();
1017        return false;
1018}
1019
1020bool
1021LayerGroupTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
1022{
1023        Gtk::TreeModel::Children::iterator iter;
1024        if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
1025                return false;
1026        if(iter==children().begin())
1027                return false;
1028        return true;
1029}
Note: See TracBrowser for help on using the repository browser.