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