1 /* === S Y N F I G ========================================================= */
2 /*!	\file layertreestore.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 <synfig/general.h>
34 
35 #include <glibmm/main.h>
36 
37 #include "layertreestore.h"
38 #include "iconcontroller.h"
39 #include <gtkmm/button.h>
40 #include <synfig/paramdesc.h>
41 #include <synfigapp/action.h>
42 #include <synfigapp/instance.h>
43 #include "app.h"
44 #include "instance.h"
45 #include <synfig/layers/layer_pastecanvas.h>
46 #include <synfig/layers/layer_group.h>
47 #include <synfig/layers/layer_switch.h>
48 #include <synfigapp/action_system.h>
49 #include <synfig/context.h>
50 
51 #include <gtk/gtk.h>
52 #include <ETL/clock>
53 #include <gui/localization.h>
54 
55 #endif
56 
57 /* === U S I N G =========================================================== */
58 
59 using namespace std;
60 using namespace etl;
61 using namespace synfig;
62 using namespace studio;
63 
64 /* === M A C R O S ========================================================= */
65 
66 /* === G L O B A L S ======================================================= */
67 
68 /* === P R O C E D U R E S ================================================= */
69 
70 /* === M E T H O D S ======================================================= */
71 
ModelHack()72 static LayerTreeStore::Model& ModelHack()
73 {
74 	static LayerTreeStore::Model* model(0);
75 	if(!model)model=new LayerTreeStore::Model;
76 	return *model;
77 }
78 
LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)79 LayerTreeStore::LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
80 	Gtk::TreeStore			(ModelHack()),
81 	queued					(false),
82 	canvas_interface_		(canvas_interface_)
83 {
84 	layer_icon=Gtk::Button().render_icon_pixbuf(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
85 
86 	// Connect Signals to Terminals
87 	canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_status_changed));
88 	canvas_interface()->signal_layer_exclude_from_rendering_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_exclude_from_rendering_changed));
89 	canvas_interface()->signal_layer_z_range_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_z_range_changed));
90 	canvas_interface()->signal_layer_lowered().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_lowered));
91 	canvas_interface()->signal_layer_raised().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_raised));
92 	canvas_interface()->signal_layer_removed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_removed));
93 	canvas_interface()->signal_layer_inserted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_inserted));
94 	canvas_interface()->signal_layer_moved().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_moved));
95 	//canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_param_changed));
96 	canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_new_description));
97 
98 	canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::refresh));
99 
100 	//canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_changed));
101 	//canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_added));
102 	//canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_deleted));
103 	//canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_replaced));
104 
105 	set_default_sort_func(sigc::ptr_fun(index_sorter));
106 
107 //	rebuild();
108 }
109 
~LayerTreeStore()110 LayerTreeStore::~LayerTreeStore()
111 {
112 	if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
113 		synfig::info("LayerTreeStore::~LayerTreeStore(): Deleted");
114 }
115 
116 int
z_sorter(const Gtk::TreeModel::iterator & rhs,const Gtk::TreeModel::iterator & lhs)117 LayerTreeStore::z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
118 {
119 	const Model model;
120 
121 	float diff((float)(*rhs)[model.z_depth]-(float)(*lhs)[model.z_depth]);
122 
123 	if(diff<0)
124 		return -1;
125 	if(diff>0)
126 		return 1;
127 	return 0;
128 }
129 
130 int
index_sorter(const Gtk::TreeModel::iterator & rhs,const Gtk::TreeModel::iterator & lhs)131 LayerTreeStore::index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
132 {
133 	const Model model;
134 
135 	return ((int)(*rhs)[model.index]-(int)(*lhs)[model.index]);
136 }
137 
138 bool
search_func(const Glib::RefPtr<TreeModel> &,int,const Glib::ustring & x,const TreeModel::iterator & iter)139 LayerTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
140 {
141 	const Model model;
142 
143 	Glib::ustring substr(x.uppercase());
144 	Glib::ustring label((*iter)[model.label]);
145 	label=label.uppercase();
146 
147 	return label.find(substr)==Glib::ustring::npos;
148 }
149 
150 
151 Glib::RefPtr<LayerTreeStore>
create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)152 LayerTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
153 {
154 	return Glib::RefPtr<LayerTreeStore>(new LayerTreeStore(canvas_interface_));
155 }
156 
157 template<typename T>
set_gvalue_tpl(Glib::ValueBase & value,const T & v,bool use_assign_operator) const158 void LayerTreeStore::set_gvalue_tpl(Glib::ValueBase& value, const T &v, bool use_assign_operator) const
159 {
160 	Glib::Value<T> x;
161 	g_value_init(x.gobj(), x.value_type());
162 
163 	x.set(v);
164 
165 	g_value_init(value.gobj(), x.value_type());
166 	if (use_assign_operator)
167 		value = x;
168 	else
169 		g_value_copy(x.gobj(), value.gobj());
170 }
171 
172 void
get_value_vfunc(const Gtk::TreeModel::iterator & iter,int column,Glib::ValueBase & value) const173 LayerTreeStore::get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
174 {
175 	if ( column != model.record_type.index()
176 	  && column != model.layer.index()
177 	  && column != model.layer_impossible.index()
178 	  && column != model.ghost_label.index() )
179 	{
180 		RecordType record_type((*iter)[model.record_type]);
181 		Layer::Handle layer((*iter)[model.layer]);
182 		bool layer_impossible((*iter)[model.layer_impossible]);
183 		Glib::ustring ghost_label((*iter)[model.ghost_label]);
184 
185 		if (record_type == RECORD_TYPE_LAYER && layer)
186 		{
187 			// Real layer
188 
189 			if (column == model.index.index())
190 				set_gvalue_tpl<int>(value, layer->get_depth());
191 			else
192 			if (column == model.z_depth.index())
193 				set_gvalue_tpl<float>(value, layer->get_true_z_depth(canvas_interface()->get_time()));
194 			else
195 			if (column == model.children_lock.index())
196 			{
197 				ValueBase v(layer->get_param("children_lock"));
198 				set_gvalue_tpl<bool>(value, v.same_type_as(bool()) && v.get(bool()));
199 			}
200 			else
201 			if (column == model.label.index())
202 				set_gvalue_tpl<Glib::ustring>(value, layer->get_non_empty_description(), true);
203 			else
204 			if (column == model.tooltip.index())
205 				set_gvalue_tpl<Glib::ustring>(value, layer->get_local_name(), true);
206 			else
207 			if (column == model.canvas.index())
208 				set_gvalue_tpl<Canvas::Handle>(value, layer->get_canvas(), true);
209 			else
210 			if (column == model.active.index())
211 				set_gvalue_tpl<bool>(value, layer->active());
212 			else
213 			if (column == model.exclude_from_rendering.index())
214 			{
215 				set_gvalue_tpl<bool>(value, layer->get_exclude_from_rendering());
216 			}
217 			else
218 			if (column == model.style.index())
219 			{
220 				//Change style to italic for current layer in treeview in case of excluded from rendering
221 				Pango::Style style = layer->get_exclude_from_rendering()
222 					               ? Pango::STYLE_ITALIC : Pango::STYLE_NORMAL;
223 				set_gvalue_tpl<Pango::Style>(value, style);
224 			}
225 			else
226 			if (column == model.weight.index())
227 			{
228 				Pango::Weight weight = Pango::WEIGHT_NORMAL;
229 
230 				etl::handle<Layer_PasteCanvas> paste=
231 					etl::handle<Layer_PasteCanvas>::cast_dynamic(
232 						layer->get_parent_paste_canvas_layer() );
233 				if(paste)
234 				{
235 					etl::handle<synfig::Canvas> sub_canvas=paste->get_param("canvas").get(sub_canvas);
236 					if(sub_canvas && !sub_canvas->is_inline())
237 					{
238 						Gtk::TreeRow row=*iter;
239 						if(*row.parent() && RECORD_TYPE_LAYER == (RecordType)(*row.parent())[model.record_type])
240 						{
241 							paste = etl::handle<Layer_PasteCanvas>::cast_dynamic(
242 									Layer::Handle((*row.parent())[model.layer]) );
243 						}
244 					}
245 				}
246 				if(paste)
247 				{
248 					//Change style to bold for current layer in treeview in case of visible in z_depth_visibility
249 					synfig::ContextParams cp;
250 					paste->apply_z_range_to_params(cp);
251 					float visibility=synfig::Context::z_depth_visibility(cp, *layer);
252 					weight = visibility==1.0 && cp.z_range ? Pango::WEIGHT_BOLD : Pango::WEIGHT_NORMAL;
253 				}
254 
255 				set_gvalue_tpl<Pango::Weight>(value, weight);
256 			}
257 			else
258 			if (column == model.underline.index())
259 				set_gvalue_tpl<Pango::Underline>(value, layer_impossible ? Pango::UNDERLINE_SINGLE : Pango::UNDERLINE_NONE);
260 			else
261 			if (column == model.strikethrough.index())
262 				set_gvalue_tpl<bool>(value, false);
263 			else
264 			if (column == model.icon.index())
265 				set_gvalue_tpl< Glib::RefPtr<Gdk::Pixbuf> >(value, get_tree_pixbuf_layer(layer->get_name()));
266 			else
267 				Gtk::TreeStore::get_value_vfunc(iter,column,value);
268 
269 			return;
270 		}
271 		else
272 		if (record_type == RECORD_TYPE_GHOST)
273 		{
274 			// Placeholder for new layer (ghost)
275 
276 			if (column == model.z_depth.index())
277 				set_gvalue_tpl<float>(value, (*iter)[model.index]);
278 			else
279 			if (column == model.label.index())
280 				set_gvalue_tpl<Glib::ustring>(value, ghost_label, true);
281 			else
282 			if (column == model.weight.index())
283 			{
284 				Pango::Weight weight = Pango::WEIGHT_NORMAL;
285 				if (iter->parent())
286 				{
287 					RecordType parent_record_type((*iter->parent())[model.record_type]);
288 					Layer::Handle parent_layer((*iter->parent())[model.layer]);
289 
290 					etl::handle<Layer_Switch> layer_switch=
291 						etl::handle<Layer_Switch>::cast_dynamic(parent_layer);
292 					if (parent_record_type == RECORD_TYPE_LAYER && layer_switch)
293 						if (ghost_label == layer_switch->get_param("layer_name").get(String()))
294 							weight = Pango::WEIGHT_BOLD;
295 				}
296 				set_gvalue_tpl<Pango::Weight>(value, weight);
297 			}
298 			else
299 			if (column == model.icon.index())
300 				set_gvalue_tpl< Glib::RefPtr<Gdk::Pixbuf> >(value, get_tree_pixbuf_layer("ghost_group"));
301 			else
302 				Gtk::TreeStore::get_value_vfunc(iter,column,value);
303 
304 			return;
305 		}
306 	}
307 
308 	Gtk::TreeStore::get_value_vfunc(iter,column,value);
309 }
310 
311 void
set_value_impl(const Gtk::TreeModel::iterator & iter,int column,const Glib::ValueBase & value)312 LayerTreeStore::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("LayerTreeStore::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("LayerTreeStore::set_value_impl: Bad value type");
326 		return;
327 	}
328 
329 	try
330 	{
331 		RecordType record_type((*iter)[model.record_type]);
332 		synfig::Layer::Handle layer((*iter)[model.layer]);
333 		Glib::ustring ghost_label((*iter)[model.ghost_label]);
334 
335 		if (record_type == RECORD_TYPE_LAYER)
336 		{
337 			// Edit real layer
338 
339 			if (column == model.label.index())
340 			{
341 				if (!layer) return;
342 
343 				Glib::Value<Glib::ustring> x;
344 				g_value_init(x.gobj(),model.label.type());
345 				g_value_copy(value.gobj(),x.gobj());
346 
347 				synfig::String new_desc(x.get());
348 
349 				if (new_desc == layer->get_local_name())
350 					new_desc = synfig::String();
351 				if (new_desc == layer->get_description())
352 					return;
353 
354 				synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
355 				if (!action) return;
356 
357 				action->set_param("canvas",canvas_interface()->get_canvas());
358 				action->set_param("canvas_interface",canvas_interface());
359 				action->set_param("layer",layer);
360 				action->set_param("new_description",synfig::String(x.get()));
361 
362 				canvas_interface()->get_instance()->perform_action(action);
363 				return;
364 			}
365 			else
366 			if (column == model.active.index())
367 			{
368 				if (!layer) return;
369 
370 				Glib::Value<bool> x;
371 				g_value_init(x.gobj(),model.active.type());
372 				g_value_copy(value.gobj(),x.gobj());
373 
374 				synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
375 				if (!action) return;
376 
377 				action->set_param("canvas",canvas_interface()->get_canvas());
378 				action->set_param("canvas_interface",canvas_interface());
379 				action->set_param("layer",layer);
380 				action->set_param("new_status",bool(x.get()));
381 
382 				canvas_interface()->get_instance()->perform_action(action);
383 				return;
384 			}
385 			else
386 			if (column == model.exclude_from_rendering.index())
387 			{
388 				if (!layer) return;
389 
390 				Glib::Value<bool> x;
391 				g_value_init(x.gobj(),model.exclude_from_rendering.type());
392 				g_value_copy(value.gobj(),x.gobj());
393 
394 				synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetExcludeFromRendering"));
395 				if (!action) return;
396 
397 				action->set_param("canvas",canvas_interface()->get_canvas());
398 				action->set_param("canvas_interface",canvas_interface());
399 				action->set_param("layer",layer);
400 				action->set_param("new_state",bool(x.get()));
401 
402 				canvas_interface()->get_instance()->perform_action(action);
403 				return;
404 			}
405 		}
406 		else
407 		if (record_type == RECORD_TYPE_GHOST)
408 		{
409 			// Edit placeholder for new layer (ghost)
410 
411 			if ( column == model.label.index()
412 			  || column == model.exclude_from_rendering.index() )
413 			{
414 				return;
415 			}
416 			else
417 			if (column == model.active.index())
418 			{
419 				Glib::Value<bool> x;
420 				g_value_init(x.gobj(),model.active.type());
421 				g_value_copy(value.gobj(),x.gobj());
422 
423 				if (x.get())
424 				{
425 					Canvas::Handle canvas = iter->parent()
426 							              ? (*iter->parent())[model.contained_canvas]
427 										  : canvas_interface()->get_canvas();
428 					if (canvas)
429 					{
430 						int depth = canvas->size();
431 						if (Layer::Handle layer = canvas_interface()->layer_create("group", canvas))
432 						{
433 							synfigapp::Action::PassiveGrouper group(
434 								canvas_interface()->get_instance().get(), _("Create Group from Ghost"));
435 							canvas_interface()->layer_set_defaults(layer);
436 							layer->set_description(ghost_label.c_str());
437 							canvas_interface()->layer_add_action(layer);
438 							canvas_interface()->layer_move_action(layer, depth);
439 						}
440 					}
441 				}
442 
443 				return;
444 			}
445 		}
446 
447 		Gtk::TreeStore::set_value_impl(iter,column,value);
448 
449 	}
450 	catch(std::exception x)
451 	{
452 		g_warning("%s", x.what());
453 	}
454 }
455 
456 bool
row_draggable_vfunc(const TreeModel::Path & path) const457 LayerTreeStore::row_draggable_vfunc(const TreeModel::Path& path)const
458 {
459 	Gtk::TreeIter iter = const_cast<LayerTreeStore*>(this)->get_iter(path);
460 	if (!iter) return false;
461 
462 	RecordType record_type((*iter)[model.record_type]);
463 	synfig::Layer::Handle layer((*iter)[model.layer]);
464 
465 	return record_type == RECORD_TYPE_LAYER && layer;
466 }
467 
468 bool
drag_data_get_vfunc(const TreeModel::Path & path,Gtk::SelectionData & selection_data) const469 LayerTreeStore::drag_data_get_vfunc(const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
470 {
471 	if(!const_cast<LayerTreeStore*>(this)->get_iter(path)) return false;
472 	//synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
473 	//synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
474 	//synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
475 
476 	Gtk::TreeModel::Row row(*const_cast<LayerTreeStore*>(this)->get_iter(path));
477 
478 	if((bool)true)
479 	{
480 		Layer* layer = (RecordType)row[model.record_type] == RECORD_TYPE_LAYER
481 				     ? ((Layer::Handle)row[model.layer]).get()
482 		             : NULL;
483 		bool included(false);
484 
485 		std::vector<Layer*> layers;
486 		// The following is a hack for multiple row DND
487 		{
488 			synfigapp::SelectionManager::LayerList bleh(get_canvas_interface()->get_selection_manager()->get_selected_layers());
489 			if(bleh.empty())
490 			{
491 				selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
492 				return true;
493 			}
494 			if (layer) while(!bleh.empty())
495 			{
496 				if(bleh.back().get()==layer)
497 					included=true;
498 				layers.push_back(bleh.back().get());
499 				bleh.pop_back();
500 			}
501 		}
502 		if(layer && !included)
503 			layers.push_back(layer);
504 		selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
505 
506 		return true;
507 	}
508 	return false;
509 }
510 
511 bool
drag_data_delete_vfunc(const TreeModel::Path &)512 LayerTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
513 {
514 	return true;
515 }
516 
517 bool
row_drop_possible_vfunc(const TreeModel::Path & dest,const Gtk::SelectionData & selection_data) const518 LayerTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
519 {
520 	//synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
521 	//synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
522 	//synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
523 
524 	if (synfig::String(selection_data.get_data_type())=="LAYER")
525 	{
526 		TreeModel::Path dest_parent(dest);
527 		if (!dest_parent.up() || dest.size()==1)
528 		{
529 			return true;
530 		}
531 		else
532 		if ((bool)const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))
533 		{
534 			TreeModel::Row row = *const_cast<LayerTreeStore*>(this)->get_iter(dest_parent);
535 			return RECORD_TYPE_LAYER == (RecordType)row[model.record_type]
536 				&& (bool)(Canvas::Handle)row[model.contained_canvas];
537 		}
538 	}
539 	return false;
540 }
541 
542 bool
drag_data_received_vfunc(const TreeModel::Path & dest,const Gtk::SelectionData & selection_data)543 LayerTreeStore::drag_data_received_vfunc(const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
544 {
545 
546 	//if(!dest_parent.up() || !get_iter(dest)) return false;
547 
548 	bool ret=false;
549 	int i(0);
550 
551 
552 	//synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
553 	//synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
554 	//synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
555 	synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Move Layers"));
556 
557 	// Save the selection data
558 	synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
559 
560 	if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
561 	{
562 		synfigapp::SelectionManager::LayerList dropped_layers;
563 		if(synfig::String(selection_data.get_data_type())=="LAYER")
564 			for(unsigned int i=0; i<selection_data.get_length()/sizeof(void*); i++)
565 			{
566 				Layer::Handle l(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
567 				if (l) dropped_layers.push_back(l);
568 			}
569 		if (dropped_layers.empty())
570 			return false;
571 
572 		Gtk::TreeModel::Row row(*get_iter(dest));
573 		if (!row)
574 			{ TreeModel::Path p(dest); p.up(); row = *get_iter(p); }
575 
576 		Canvas::Handle dest_canvas;
577 		Layer::Handle dest_layer;
578 		int dest_layer_depth = dest.back();
579 
580 		if (!row)
581 		{
582 			dest_canvas = get_canvas_interface()->get_canvas();
583 			if (!dest_canvas->empty())
584 				dest_layer = dest_canvas->back();
585 			dest_layer_depth = dest_layer ? dest_layer->get_depth() + 1 : 0;
586 		}
587 		else
588 		if (RECORD_TYPE_LAYER == (RecordType)row[model.record_type])
589 		{
590 			// TODO: check RecordType for parent
591 			TreeModel::Path dest_parent(dest);
592 			if(!dest_parent.up() || !get_iter(dest_parent))
593 			{
594 				TreeModel::Path dest_(dest);
595 				if(!get_iter(dest_))
596 					dest_.prev();
597 				if(!get_iter(dest_))
598 					return false;
599 				{
600 					row=(*get_iter(dest_));
601 					dest_canvas=(Canvas::Handle)(row[model.canvas]);
602 				}
603 			}
604 			else
605 			{
606 				row=(*get_iter(dest_parent));
607 				dest_canvas=row[model.contained_canvas];
608 			}
609 			assert(dest_canvas);
610 			dest_layer = row[model.layer];
611 		}
612 		else
613 		if (RECORD_TYPE_GHOST == (RecordType)row[model.record_type] && row.parent())
614 		{
615 			// TODO: check RecordType for parent
616 			dest_canvas = (Canvas::Handle)(*row.parent())[model.contained_canvas];
617 			dest_layer_depth = dest_canvas->size();
618 			if (dropped_layers.size() == 1 && etl::handle<Layer_Group>::cast_dynamic(dropped_layers.front()))
619 			{
620 				Layer::Handle src = dropped_layers.front();
621 				synfigapp::Action::Handle action;
622 
623 				action = synfigapp::Action::create("LayerMove");
624 				action->set_param("canvas", dest_canvas);
625 				action->set_param("canvas_interface", canvas_interface());
626 				action->set_param("layer", src);
627 				action->set_param("new_index", dest_layer_depth);
628 				action->set_param("dest_canvas", dest_canvas);
629 				if (!canvas_interface()->get_instance()->perform_action(action))
630 					{ passive_grouper.cancel(); return false; }
631 
632 				action = synfigapp::Action::create("LayerSetDesc");
633 				action->set_param("canvas", canvas_interface()->get_canvas());
634 				action->set_param("canvas_interface", canvas_interface());
635 				action->set_param("layer", dropped_layers.front());
636 				action->set_param("new_description", synfig::String(((Glib::ustring)row[model.ghost_label]).c_str()));
637 				if (!canvas_interface()->get_instance()->perform_action(action))
638 					{ passive_grouper.cancel(); return false; }
639 
640 				dropped_layers.clear();
641 				ret = true;
642 			}
643 			else
644 			{
645 				dest_layer = canvas_interface()->layer_create("group", dest_canvas);
646 				if (!dest_layer) return false;
647 				canvas_interface()->layer_set_defaults(dest_layer);
648 				dest_layer->set_description( ((Glib::ustring)row[model.ghost_label]).c_str() );
649 				canvas_interface()->layer_add_action(dest_layer);
650 				canvas_interface()->layer_move_action(dest_layer, dest_layer_depth);
651 				dest_canvas = dest_layer->get_param("canvas").get(Canvas::Handle());
652 			}
653 			dest_layer_depth = 0;
654 		}
655 		else
656 		{
657 			return false;
658 		}
659 
660 		for(synfigapp::SelectionManager::LayerList::const_iterator i = dropped_layers.begin(); i != dropped_layers.end(); ++i)
661 		{
662 			Layer::Handle src(*i);
663 			if(!src || dest_layer == src) continue;
664 
665 			if(dest_canvas==src->get_canvas() && src->get_depth()<dest_layer_depth)
666 				dest_layer_depth--;
667 
668 			if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
669 				continue;
670 
671 			synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
672 			action->set_param("canvas",dest_canvas);
673 			action->set_param("canvas_interface",canvas_interface());
674 			action->set_param("layer",src);
675 			action->set_param("new_index",dest_layer_depth);
676 			action->set_param("dest_canvas",dest_canvas);
677 			if (canvas_interface()->get_instance()->perform_action(action))
678 				{ ret=true; }
679 			else
680 				{ passive_grouper.cancel(); return false; }
681 		}
682 	}
683 	synfig::info("I supposedly moved %d layers",i);
684 
685 	// Reselect the previously selected layers
686 	canvas_interface()->get_selection_manager()->clear_selected_layers();
687 	canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
688 
689 	return ret;
690 }
691 
692 void
queue_rebuild()693 LayerTreeStore::queue_rebuild()
694 {
695 	if (queued) return;
696 	queued = false;
697 	queue_connection.disconnect();
698 	queue_connection=Glib::signal_timeout().connect(
699 		sigc::bind_return(
700 			sigc::mem_fun(*this,&LayerTreeStore::rebuild),
701 			false
702 		)
703 	,150);
704 }
705 
706 void
rebuild()707 LayerTreeStore::rebuild()
708 {
709 	if (queued) queued = false;
710 
711 	// disconnect any subcanvas_changed connections
712 	std::map<synfig::Layer::Handle, sigc::connection>::iterator iter;
713 	for (iter = subcanvas_changed_connections.begin(); iter != subcanvas_changed_connections.end(); iter++)
714 		iter->second.disconnect();
715 	subcanvas_changed_connections.clear();
716 
717 	for (iter = switch_changed_connections.begin(); iter != switch_changed_connections.end(); iter++)
718 		iter->second.disconnect();
719 	switch_changed_connections.clear();
720 
721 	//etl::clock timer;timer.reset();
722 
723 	//synfig::warning("---------rebuilding layer table---------");
724 	// Save the selection data
725 	synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
726 	synfigapp::SelectionManager::LayerList expanded_layer_list=canvas_interface()->get_selection_manager()->get_expanded_layers();
727 
728 	// Clear out the current list
729 	clear();
730 
731 	// Go ahead and add all the layers
732 	for(Canvas::reverse_iterator iter = canvas_interface()->get_canvas()->rbegin(); iter != canvas_interface()->get_canvas()->rend(); ++iter)
733 	{
734 		Gtk::TreeRow row_(*(prepend(children())));
735 		row_[model.layer_impossible] = false;
736 		set_row_layer(row_,*iter);
737 	}
738 
739 	// Reselect the previously selected layers
740 	if(!expanded_layer_list.empty())
741 		canvas_interface()->get_selection_manager()->set_expanded_layers(expanded_layer_list);
742 	if(!layer_list.empty())
743 		canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
744 
745 	//synfig::info("LayerTreeStore::rebuild() took %f seconds",float(timer()));
746 }
747 
748 void
refresh()749 LayerTreeStore::refresh()
750 {
751 	etl::clock timer;
752 	timer.reset();
753 
754 	Gtk::TreeModel::Children children_(children());
755 	Gtk::TreeModel::Children::iterator iter;
756 
757 	if(!children_.empty())
758 		for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
759 		{
760 			Gtk::TreeRow row=*iter;
761 			refresh_row(row);
762 			row_changed(get_path(iter), iter);
763 		}
764 
765 	//synfig::info("LayerTreeStore::refresh() took %f seconds",float(timer()));
766 }
767 
768 void
refresh_row(Gtk::TreeModel::Row & row)769 LayerTreeStore::refresh_row(Gtk::TreeModel::Row &row)
770 {
771 	RecordType record_type = row[model.record_type];
772 	Layer::Handle layer = row[model.layer];
773 
774 	if (record_type == RECORD_TYPE_LAYER && layer)
775 	{
776 		/*
777 		{
778 			row[model.name] = layer->get_local_name();
779 			if(layer->get_description().empty())
780 			{
781 				row[model.label] = layer->get_local_name();
782 				row[model.tooltip] = Glib::ustring("Layer");
783 			}
784 			else
785 			{
786 				row[model.label] = layer->get_description();
787 				row[model.tooltip] = layer->get_local_name();
788 			}
789 		}
790 		*/
791 
792 		if(layer->dynamic_param_list().count("z_depth"))
793 			row[model.z_depth]=Time::begin();
794 		//	row_changed(get_path(row),row);
795 
796 		Gtk::TreeModel::Children children = row.children();
797 		Gtk::TreeModel::Children::iterator iter;
798 
799 		if(!children.empty())
800 			for(iter = children.begin(); iter && iter != children.end(); ++iter)
801 			{
802 				Gtk::TreeRow row=*iter;
803 				refresh_row(row);
804 				row_changed(get_path(iter), iter);
805 			}
806 	}
807 }
808 
809 void
set_row_layer(Gtk::TreeRow & row,const synfig::Layer::Handle & handle)810 LayerTreeStore::set_row_layer(Gtk::TreeRow &row, const synfig::Layer::Handle &handle)
811 {
812 	if (etl::handle<Layer_PasteCanvas> layer_paste = etl::handle<Layer_PasteCanvas>::cast_dynamic(handle))
813 	{
814 		subcanvas_changed_connections[layer_paste].disconnect();
815 		subcanvas_changed_connections[layer_paste] =
816 			layer_paste->signal_subcanvas_changed().connect(
817 				sigc::mem_fun(*this,&studio::LayerTreeStore::queue_rebuild) );
818 	}
819 	if (etl::handle<Layer_Switch> layer_switch = etl::handle<Layer_Switch>::cast_dynamic(handle))
820 	{
821 		switch_changed_connections[layer_switch].disconnect();
822 		switch_changed_connections[layer_switch] =
823 			layer_switch->signal_possible_layers_changed().connect(
824 				sigc::mem_fun(*this,&studio::LayerTreeStore::queue_rebuild) );
825 	}
826 
827 	//row[model.id] = handle->get_name();
828 	//row[model.name] = handle->get_local_name();
829 	/*if(handle->get_description().empty())
830 	{
831 		//row[model.label] = handle->get_local_name();
832 		row[model.tooltip] = Glib::ustring("Layer");
833 	}
834 	else
835 	{
836 		//row[model.label] = handle->get_description();
837 		row[model.tooltip] = handle->get_local_name();
838 	}*/
839 
840 	//row[model.active] = handle->active();
841 	row[model.record_type] = RECORD_TYPE_LAYER;
842 	row[model.layer] = handle;
843 	//row[model.canvas] = handle->get_canvas();
844 	//row[model.icon] = layer_icon;
845 
846 	synfig::Layer::ParamList paramlist=handle->get_param_list();
847 
848 	synfig::Layer::Vocab vocab=handle->get_param_vocab();
849 	synfig::Layer::Vocab::iterator iter;
850 
851 	for(iter=vocab.begin();iter!=vocab.end();++iter)
852 	{
853 		if(iter->get_hidden())
854 			continue;
855 		if(handle->get_param(iter->get_name()).get_type()!=type_canvas)
856 			continue;
857 
858 		{
859 			Canvas::Handle canvas;
860 			canvas=handle->get_param(iter->get_name()).get(canvas);
861 			if(!canvas)
862 				continue;
863 
864 			row[model.contained_canvas]=canvas;
865 
866 			std::set<String> possible_new_layers;
867 			std::set<String> impossible_existant_layers;
868 			if (etl::handle<Layer_Switch> layer_switch = etl::handle<Layer_Switch>::cast_dynamic(handle))
869 			{
870 				layer_switch->get_possible_new_layers(possible_new_layers);
871 				layer_switch->get_impossible_existant_layers(impossible_existant_layers);
872 			}
873 
874 			int index = canvas->size() + possible_new_layers.size();
875 			for(std::set<String>::const_reverse_iterator i = possible_new_layers.rbegin(); i != possible_new_layers.rend(); ++i)
876 			{
877 				Gtk::TreeRow row_(*(prepend(row.children())));
878 				set_row_ghost(row_, *i, --index);
879 			}
880 
881 			for(Canvas::reverse_iterator iter = canvas->rbegin(); iter != canvas->rend(); ++iter)
882 			{
883 				Gtk::TreeRow row_(*(prepend(row.children())));
884 				bool xx = (bool)impossible_existant_layers.count((*iter)->get_description());
885 				row_[model.layer_impossible] = xx;
886 				set_row_layer(row_,*iter);
887 			}
888 
889 			continue;
890 		}
891 
892 		/*
893 		etl::handle<ValueNode> value_node;
894 		if(handle.constant()->dynamic_param_list().count(iter->get_name()))
895 			value_node=handle->dynamic_param_list()[iter->get_name()];
896 
897 		Gtk::TreeRow child_row = *(append(row.children()));
898 		set_row_param(
899 			child_row,
900 			handle,
901 			iter->get_name(),
902 			iter->get_local_name(),
903 			paramlist[iter->get_name()],
904 			value_node,
905 			&*iter
906 		);
907 		*/
908 	}
909 }
910 
911 void
set_row_ghost(Gtk::TreeRow & row,const synfig::String & label,int depth)912 LayerTreeStore::set_row_ghost(Gtk::TreeRow &row, const synfig::String &label, int depth)
913 {
914 	row[model.index] = depth;
915 	row[model.record_type] = RECORD_TYPE_GHOST;
916 	row[model.ghost_label] = label;
917 }
918 
919 void
on_layer_added(synfig::Layer::Handle layer)920 LayerTreeStore::on_layer_added(synfig::Layer::Handle layer)
921 {
922 	assert(layer);
923 	Gtk::TreeRow row;
924 	if(canvas_interface()->get_canvas()==layer->get_canvas())
925 	{
926 		row=*(prepend());
927 	}
928 	else
929 	{
930 		Gtk::TreeModel::Children::iterator iter;
931 		if(!find_canvas_row(layer->get_canvas(),iter))
932 		{
933 			rebuild();
934 			return;
935 		}
936 		row=*(prepend(iter->children()));
937 	}
938 	set_row_layer(row,layer);
939 }
940 
941 void
on_layer_removed(synfig::Layer::Handle handle)942 LayerTreeStore::on_layer_removed(synfig::Layer::Handle handle)
943 {
944 	if (etl::handle<Layer_PasteCanvas>::cast_dynamic(handle))
945 	{
946 		subcanvas_changed_connections[handle].disconnect();
947 		subcanvas_changed_connections.erase(handle);
948 	}
949 	if (etl::handle<Layer_Switch>::cast_dynamic(handle))
950 	{
951 		switch_changed_connections[handle].disconnect();
952 		switch_changed_connections.erase(handle);
953 	}
954 	Gtk::TreeModel::Children::iterator iter;
955 	if(find_layer_row(handle,iter))
956 		erase(iter);
957 	else
958 	{
959 		synfig::error("LayerTreeStore::on_layer_removed():Unable to find layer to be removed, forced to rebuild...");
960 		rebuild();
961 	}
962 }
963 
964 void
on_layer_inserted(synfig::Layer::Handle handle,int depth)965 LayerTreeStore::on_layer_inserted(synfig::Layer::Handle handle,int depth)
966 {
967 	if(depth==0)
968 	{
969 		on_layer_added(handle);
970 		return;
971 	}
972 
973 	Gtk::TreeModel::Children children_(children());
974 	if(canvas_interface()->get_canvas()!=handle->get_canvas())
975 	{
976 		Gtk::TreeModel::Children::iterator iter;
977 		if(!find_canvas_row(handle->get_canvas(),iter))
978 		{
979 			synfig::error("LayerTreeStore::on_layer_inserted():Unable to find canvas row, forced to rebuild...");
980 			rebuild();
981 			return;
982 		}
983 		children_=iter->children();
984 	}
985 
986 	Gtk::TreeModel::Children::iterator iter(children_.begin());
987 	while(depth-- && iter)
988 	{
989 		++iter;
990 		if(!iter || iter==children_.end())
991 		{
992 			synfig::error("LayerTreeStore::on_layer_inserted():Unable to achieve desired depth, forced to rebuild...");
993 			rebuild();
994 			return;
995 		}
996 	}
997 
998 	Gtk::TreeModel::Row row(*insert(iter));
999 	set_row_layer(row,handle);
1000 }
1001 
1002 void
on_layer_status_changed(synfig::Layer::Handle handle,bool)1003 LayerTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
1004 {
1005 	Gtk::TreeModel::Children::iterator iter;
1006 	if(find_layer_row(handle,iter))
1007 		(*iter)[model.layer]=handle;
1008 	else
1009 	{
1010 		synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
1011 		rebuild();
1012 	}
1013 }
1014 
1015 void
on_layer_exclude_from_rendering_changed(synfig::Layer::Handle handle,bool)1016 LayerTreeStore::on_layer_exclude_from_rendering_changed(synfig::Layer::Handle handle,bool /*x*/)
1017 {
1018 	Gtk::TreeModel::Children::iterator iter;
1019 	if(find_layer_row(handle,iter))
1020 		(*iter)[model.layer]=handle;
1021 	else
1022 	{
1023 		synfig::warning("Couldn't find layer to be excluded/included from/to rendering in layer list. Rebuilding index...");
1024 		rebuild();
1025 	}
1026 }
1027 
1028 void
on_layer_z_range_changed(synfig::Layer::Handle handle,bool)1029 LayerTreeStore::on_layer_z_range_changed(synfig::Layer::Handle handle,bool /*x*/)
1030 {
1031 	// Seems to not work. Need to do something different like call row_changed
1032 	// for this layer row or all its children.
1033 	Gtk::TreeModel::Children::iterator iter;
1034 	if(find_layer_row(handle,iter))
1035 		(*iter)[model.layer]=handle;
1036 	else
1037 	{
1038 		synfig::warning("Couldn't find layer to be change the z_depth range in layer list. Rebuilding index...");
1039 		rebuild();
1040 	}
1041 }
1042 
1043 
1044 void
on_layer_lowered(synfig::Layer::Handle layer)1045 LayerTreeStore::on_layer_lowered(synfig::Layer::Handle layer)
1046 {
1047 	Gtk::TreeModel::Children::iterator iter, iter2;
1048 	if(find_layer_row(layer,iter))
1049 	{
1050 		// Save the selection data
1051 		//synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
1052 		iter2=iter;
1053 		iter2++;
1054 		if(!iter2 || RECORD_TYPE_LAYER != (*iter2)[model.record_type])
1055 		{
1056 			rebuild();
1057 			return;
1058 		}
1059 
1060 		//Gtk::TreeModel::Row row(*iter);
1061 		Gtk::TreeModel::Row row2 = *iter2;
1062 		synfig::Layer::Handle layer2=row2[model.layer];
1063 
1064 		erase(iter2);
1065 		row2=*insert(iter);
1066 		set_row_layer(row2,layer2);
1067 
1068 	}
1069 	else
1070 		rebuild();
1071 }
1072 
1073 void
on_layer_raised(synfig::Layer::Handle layer)1074 LayerTreeStore::on_layer_raised(synfig::Layer::Handle layer)
1075 {
1076 	Gtk::TreeModel::Children::iterator iter, iter2;
1077 
1078 	Gtk::TreeModel::Children children_(children());
1079 
1080 	if(find_layer_row_(layer, canvas_interface()->get_canvas(), children_, iter,iter2))
1081 	{
1082 		if(iter!=iter2 && RECORD_TYPE_LAYER==(*iter2)[model.record_type])
1083 		{
1084 			//Gtk::TreeModel::Row row = *iter;
1085 			Gtk::TreeModel::Row row2 = *iter2;
1086 			synfig::Layer::Handle layer2=row2[model.layer];
1087 
1088 			erase(iter2);
1089 			iter++;
1090 			row2=*insert(iter);
1091 			set_row_layer(row2,layer2);
1092 
1093 			return;
1094 		}
1095 	}
1096 
1097 	rebuild();
1098 }
1099 
1100 void
on_layer_moved(synfig::Layer::Handle layer,int depth,synfig::Canvas::Handle)1101 LayerTreeStore::on_layer_moved(synfig::Layer::Handle layer,int depth, synfig::Canvas::Handle /*canvas*/)
1102 {
1103 	on_layer_removed(layer);
1104 	on_layer_inserted(layer,depth);
1105 }
1106 
1107 void
on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)1108 LayerTreeStore::on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)
1109 {
1110 	if(param_name=="z_depth")
1111 	{
1112 		Gtk::TreeModel::Children::iterator iter;
1113 		if(find_layer_row(handle,iter))
1114 		{
1115 			(*iter)[model.z_depth]=Time::begin();
1116 		}
1117 	}
1118 
1119 	/*
1120 	Gtk::TreeModel::Children::iterator iter;
1121 	if(find_layer_row(handle,iter))
1122 	{
1123 		Gtk::TreeModel::Children children(iter->children());
1124 
1125 		for(iter = children.begin(); iter && iter != children.end(); ++iter)
1126 		{
1127 			if((Glib::ustring)(*iter)[model.param_name]==param_name)
1128 			{
1129 				Gtk::TreeRow row=*iter;
1130 				refresh_row(row);
1131 				return;
1132 			}
1133 		}
1134 	}
1135 	rebuild();
1136 	*/
1137 }
1138 
1139 void
on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)1140 LayerTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
1141 {
1142 	Gtk::TreeModel::Children::iterator iter;
1143 	if(find_layer_row(handle,iter))
1144 	{
1145 		Gtk::TreeRow row(*iter);
1146 
1147 		Layer::Handle layer(row[model.layer]);
1148 
1149 		if(desc.empty())
1150 		{
1151 			//row[model.label]=layer->get_local_name();
1152 			row[model.tooltip]=Glib::ustring(_("Layer"));
1153 		}
1154 		else
1155 			//row[model.label]=layer->get_description();
1156 			row[model.tooltip]=layer->get_local_name();
1157 	}
1158 	else
1159 	{
1160 		rebuild();
1161 	}
1162 }
1163 
1164 bool
find_canvas_row_(synfig::Canvas::Handle canvas,synfig::Canvas::Handle parent,Gtk::TreeModel::Children layers,Gtk::TreeModel::Children::iterator & iter)1165 LayerTreeStore::find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter)
1166 {
1167 	if(canvas==parent)
1168 		return false;
1169 
1170 	{
1171 		for(iter=layers.begin(); iter && iter != layers.end(); ++iter)
1172 		{
1173 			Gtk::TreeModel::Row row = *iter;
1174 			if(canvas==(synfig::Canvas::Handle)row[model.contained_canvas])
1175 				return true;
1176 		}
1177 
1178 		iter=children().end();
1179 		//return false;
1180 	}
1181 
1182 	Gtk::TreeModel::Children::iterator iter2;
1183 	//Gtk::TreeModel::Children::iterator iter3;
1184 
1185 	for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
1186 	{
1187 		Gtk::TreeModel::Row row = *iter2;
1188 		assert((bool)true);
1189 
1190 		if(row.children().empty())
1191 			continue;
1192 
1193 		Canvas::Handle sub_canvas((*row.children().begin())[model.canvas]);
1194 		if(!sub_canvas)
1195 			continue;
1196 
1197 		if(find_canvas_row_(canvas,sub_canvas,iter2->children(),iter))
1198 			return true;
1199 	}
1200 
1201 	iter=children().end();
1202 	return false;
1203 }
1204 
1205 bool
find_canvas_row(synfig::Canvas::Handle canvas,Gtk::TreeModel::Children::iterator & iter)1206 LayerTreeStore::find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter)
1207 {
1208 	return find_canvas_row_(canvas,canvas_interface()->get_canvas(),children(),iter);
1209 }
1210 
1211 
1212 bool
find_layer_row_(const synfig::Layer::Handle & layer,synfig::Canvas::Handle,Gtk::TreeModel::Children layers,Gtk::TreeModel::Children::iterator & iter,Gtk::TreeModel::Children::iterator & prev)1213 LayerTreeStore::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)
1214 {
1215 	assert(layer);
1216 
1217 	//if(layer->get_canvas()==canvas)
1218 	{
1219 		for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
1220 		{
1221 			Gtk::TreeModel::Row row = *iter;
1222 			if ( RECORD_TYPE_LAYER == (RecordType)row[model.record_type]
1223 			  && layer == (synfig::Layer::Handle)row[model.layer] )
1224 				return true;
1225 		}
1226 
1227 		iter=children().end();
1228 		//return false;
1229 	}
1230 
1231 	Gtk::TreeModel::Children::iterator iter2;
1232 
1233 	for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
1234 	{
1235 		Gtk::TreeModel::Row row = *iter2;
1236 		assert((bool)true);
1237 
1238 		if(row.children().empty())
1239 			continue;
1240 
1241 		if (RECORD_TYPE_LAYER != (RecordType)row[model.record_type])
1242 			continue;
1243 
1244 		Canvas::Handle canvas((*row.children().begin())[model.canvas]);
1245 		if(!canvas)
1246 			continue;
1247 
1248 		if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
1249 			return true;
1250 	}
1251 
1252 	iter=children().end();
1253 	return false;
1254 }
1255 
1256 bool
find_layer_row(const synfig::Layer::Handle & layer,Gtk::TreeModel::Children::iterator & iter)1257 LayerTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
1258 {
1259 	Gtk::TreeModel::Children::iterator prev;
1260 	return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
1261 }
1262 
1263 bool
find_prev_layer_row(const synfig::Layer::Handle & layer,Gtk::TreeModel::Children::iterator & prev)1264 LayerTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
1265 {
1266 	Gtk::TreeModel::Children::iterator iter;
1267 	if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
1268 		return false;
1269 	if(iter==children().begin())
1270 		return false;
1271 	return true;
1272 }
1273