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