1 /* === S Y N F I G ========================================================= */
2 /*! \file canvastreestore.cpp
3 ** \brief Template File
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2008 Chris Moore
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.
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.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
33 #include "trees/canvastreestore.h"
34 #include <synfig/valuenode.h>
35 #include "iconcontroller.h"
36 #include <synfig/valuenode_timedswap.h>
37 #include <synfig/valuenode_animated.h>
38 #include <gtkmm/button.h>
39 #include <synfigapp/instance.h>
40 #include "cellrenderer/cellrenderer_value.h"
41 #include "cellrenderer/cellrenderer_timetrack.h"
48 /* === U S I N G =========================================================== */
52 using namespace synfig;
53 using namespace studio;
55 /* === M A C R O S ========================================================= */
57 /* === G L O B A L S ======================================================= */
59 /* === P R O C E D U R E S ================================================= */
61 /* === M E T H O D S ======================================================= */
63 static CanvasTreeStore::Model& ModelHack()
65 static CanvasTreeStore::Model* model(0);
66 if(!model)model=new CanvasTreeStore::Model;
70 CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
71 Gtk::TreeStore(ModelHack()),
72 canvas_interface_ (canvas_interface_)
76 CanvasTreeStore::~CanvasTreeStore()
81 CanvasTreeStore::get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
83 if(column==model.value.index())
85 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
87 Glib::Value<synfig::ValueBase> x;
88 g_value_init(x.gobj(),x.value_type());
95 if(value_desc.is_const())
96 x.set(value_desc.get_value());
98 if(value_desc.is_value_node())
99 x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
102 synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
106 g_value_init(value.gobj(),x.value_type());
107 g_value_copy(x.gobj(),value.gobj());
110 if(column==model.is_value_node.index())
112 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
115 g_value_init(x.gobj(),x.value_type());
117 x.set(value_desc && value_desc.is_value_node());
119 g_value_init(value.gobj(),x.value_type());
120 g_value_copy(x.gobj(),value.gobj());
123 if(column==model.is_shared.index())
125 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
128 g_value_init(x.gobj(),x.value_type());
130 x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
132 g_value_init(value.gobj(),x.value_type());
133 g_value_copy(x.gobj(),value.gobj());
136 if(column==model.is_exported.index())
138 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
141 g_value_init(x.gobj(),x.value_type());
143 x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
145 g_value_init(value.gobj(),x.value_type());
146 g_value_copy(x.gobj(),value.gobj());
149 if(column==model.is_canvas.index())
151 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
154 g_value_init(x.gobj(),x.value_type());
156 x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
158 g_value_init(value.gobj(),x.value_type());
159 g_value_copy(x.gobj(),value.gobj());
162 if(column==model.id.index())
164 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
166 Glib::Value<Glib::ustring> x;
167 g_value_init(x.gobj(),x.value_type());
169 if(value_desc && value_desc.is_value_node())
170 x.set(value_desc.get_value_node()->get_id());
171 else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
172 x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
174 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
176 g_value_init(value.gobj(),x.value_type());
177 g_value_copy(x.gobj(),value.gobj());
180 if(column==model.is_editable.index())
182 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
185 g_value_init(x.gobj(),x.value_type());
187 x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
189 g_value_init(value.gobj(),x.value_type());
190 g_value_copy(x.gobj(),value.gobj());
193 if(column==model.type.index())
195 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
198 Glib::Value<Glib::ustring> x;
199 g_value_init(x.gobj(),x.value_type());
204 if((*iter)[model.is_canvas])
209 stype=ValueBase::type_local_name(value_desc.get_value_type());
210 if(value_desc.get_value_node())
212 lname=value_desc.get_value_node()->get_name();
213 if (lname=="animated" || lname=="static" ||
214 synfig::LinkableValueNode::Handle::cast_dynamic(value_desc.get_value_node())
216 stype+=" (" + value_desc.get_value_node()->get_local_name() + ")";
218 else if(value_desc.parent_is_layer_param())
220 if(value_desc.get_value().get_static())
221 stype+=_(" (Static)");
224 x.set(stype.c_str());
225 g_value_init(value.gobj(),x.value_type());
226 g_value_copy(x.gobj(),value.gobj());
229 if(column==model.label.index())
231 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
233 Glib::Value<Glib::ustring> x;
234 g_value_init(x.gobj(),x.value_type());
239 Canvas::Handle canvas((*iter)[model.canvas]);
242 if(!canvas->get_id().empty())
243 x.set(canvas->get_id());
245 if(!canvas->get_name().empty())
246 x.set(canvas->get_name());
248 x.set(_("[Unnamed]"));
251 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
255 ValueNode::Handle value_node=value_desc.get_value_node();
257 // Setup the row's label
258 if(value_node->get_id().empty())
259 x.set(Glib::ustring((*iter)[model.name]));
260 else if(Glib::ustring((*iter)[model.name]).empty())
261 x.set(value_node->get_id());
263 x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
266 g_value_init(value.gobj(),x.value_type());
267 g_value_copy(x.gobj(),value.gobj());
270 if(column==model.icon.index())
272 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
274 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
276 Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
277 g_value_init(x.gobj(),x.value_type());
279 x.set(get_tree_pixbuf(value_desc.get_value_type()));
281 g_value_init(value.gobj(),x.value_type());
282 g_value_copy(x.gobj(),value.gobj());
285 Gtk::TreeStore::get_value_vfunc(iter,column,value);
289 CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
291 iter=children().begin();
292 while(iter && value_desc!=(*iter)[model.value_desc])
294 if(!iter->children().empty())
296 Gtk::TreeIter iter2(iter->children().begin());
297 //! \todo confirm that the && should be done before the ||
298 if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
304 Gtk::TreeIter iter2(++iter);
306 iter==iter->parent();
310 return (bool)iter && value_desc==(*iter)[model.value_desc];
314 CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
316 if(!iter) return find_first_value_desc(value_desc,iter);
319 if(!iter->children().empty())
321 Gtk::TreeIter iter2(iter->children().begin());
322 //! \todo confirm that the && should be done before the ||
323 if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
329 Gtk::TreeIter iter2(++iter);
332 iter==iter->parent();
337 } while(iter && value_desc!=(*iter)[model.value_desc]);
338 return (bool)iter && value_desc==(*iter)[model.value_desc];
342 CanvasTreeStore::find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
344 iter=children().begin();
345 while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
347 if(!iter->children().empty())
349 Gtk::TreeIter iter2(iter->children().begin());
350 //! \todo confirm that the && should be done before the ||
351 if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
357 Gtk::TreeIter iter2(++iter);
359 iter==iter->parent();
363 return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
367 CanvasTreeStore::find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
369 if(!iter) return find_first_value_node(value_node,iter);
372 if(!iter->children().empty())
374 Gtk::TreeIter iter2(iter->children().begin());
375 //! \todo confirm that the && should be done before the ||
376 if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
382 Gtk::TreeIter iter2(++iter);
385 iter==iter->parent();
390 } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
391 return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
395 CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
397 Gtk::TreeModel::Children children = row.children();
398 while(!children.empty() && erase(children.begin()))
401 row[model.value_desc]=value_desc;
404 //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
406 if(value_desc.is_value_node())
408 ValueNode::Handle value_node=value_desc.get_value_node();
412 row[model.value_node] = value_node;
413 //row[model.is_canvas] = false;
414 //row[model.is_value_node] = true;
415 //row[model.is_editable] = synfigapp::is_editable(value_node);
416 //row[model.id]=value_node->get_id();
419 if(value_desc.parent_is_canvas())
420 row[model.canvas]=value_desc.get_canvas();
422 row[model.canvas]=canvas_interface()->get_canvas();
424 LinkableValueNode::Handle linkable;
425 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
427 if(linkable && do_children)
429 row[model.link_count] = linkable->link_count();
430 for(int i=0;i<linkable->link_count();i++)
432 Gtk::TreeRow child_row=*(append(row.children()));
433 child_row[model.link_id] = i;
434 child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
435 child_row[model.name] = linkable->link_local_name(i);
436 set_row(child_row,synfigapp::ValueDesc(linkable,i));
443 //row[model.is_value_node] = false;
444 //row[model.is_editable] = true;
445 //row[model.label] = Glib::ustring(row[model.name]);
449 catch(synfig::Exception::IDNotFound x)
451 synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
456 // We should never get to this point
461 CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
463 synfigapp::ValueDesc value_desc=row[model.value_desc];
467 if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
468 (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
470 set_row(row,value_desc,do_children);
474 if(row[model.is_value_node])
476 ValueNode::Handle value_node(value_desc.get_value_node());
478 if(ValueNode::Handle(row[model.value_node])!=value_node)
480 rebuild_row(row,do_children);
484 //row[model.id]=value_node->get_id();
486 // Setup the row's label
488 if(value_node->get_id().empty())
489 row[model.label] = Glib::ustring(row[model.name]);
490 else if(Glib::ustring(row[model.name]).empty())
491 row[model.label] = value_node->get_id();
493 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
496 LinkableValueNode::Handle linkable;
497 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
498 if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
500 // Gtk::TreeModel::Children children = row.children();
501 // while(!children.empty() && erase(children.begin()));
503 set_row(row,value_desc);
509 //row[model.label] = Glib::ustring(row[model.name]);
510 //row[model.is_value_node] = false;
511 //row[model.is_editable] = true;
517 Gtk::TreeModel::Children children = row.children();
518 Gtk::TreeModel::Children::iterator iter;
520 if(!children.empty())
521 for(iter = children.begin(); iter != children.end(); ++iter)
523 Gtk::TreeRow row=*iter;
529 CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
531 synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
533 if(value_desc && value_desc.get_value_node())
535 ValueNode::Handle value_node;
536 value_node=value_desc.get_value_node();
538 assert(value_node);if(!value_node)return;
540 if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
542 // Gtk::TreeModel::Children children = row.children();
543 // while(!children.empty() && erase(children.begin()));
545 set_row(row,value_desc,do_children);
549 LinkableValueNode::Handle linkable;
550 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
552 if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
554 // Gtk::TreeModel::Children children = row.children();
555 // while(!children.empty() && erase(children.begin()));
557 set_row(row,value_desc);
562 // value_node=row[model.value_node];
564 row[model.id]=value_node->get_id();
566 // Setup the row's label
567 if(value_node->get_id().empty())
568 row[model.label] = Glib::ustring(row[model.name]);
569 else if(Glib::ustring(row[model.name]).empty())
570 row[model.label] = value_node->get_id();
572 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
576 row[model.label] = Glib::ustring(row[model.name]);
577 row[model.is_value_node] = false;
578 row[model.is_editable] = true;
579 Gtk::TreeModel::Children children = row.children();
580 while(!children.empty() && erase(children.begin()))
586 Gtk::TreeModel::Children children = row.children();
587 Gtk::TreeModel::Children::iterator iter;
588 if(!children.empty())
589 for(iter = children.begin(); iter != children.end(); ++iter)
591 Gtk::TreeRow row=*iter;
596 CellRenderer_ValueBase*
597 CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
599 const CanvasTreeStore::Model model;
601 CellRenderer_ValueBase* ret;
603 ret=Gtk::manage( new CellRenderer_ValueBase() );
605 column->pack_start(*ret,true);
606 column->add_attribute(ret->property_value(), model.value);
607 column->add_attribute(ret->property_editable(), model.is_editable);
608 column->add_attribute(ret->property_canvas(), model.canvas);
613 CellRenderer_TimeTrack*
614 CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
616 const CanvasTreeStore::Model model;
618 CellRenderer_TimeTrack* ret;
620 ret = Gtk::manage( new CellRenderer_TimeTrack() );
622 column->pack_start(*ret,true);
623 //column->add_attribute(ret->property_visible(), model.is_value_node);
624 column->add_attribute(ret->property_value_desc(), model.value_desc);
625 column->add_attribute(ret->property_canvas(), model.canvas);