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
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.
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.
21 /* ========================================================================= */
23 /* === H E A D E R S ======================================================= */
32 #include "canvastreestore.h"
33 #include <synfig/valuenode.h>
34 #include "iconcontroller.h"
35 #include <synfig/valuenode_timedswap.h>
36 #include <synfig/valuenode_animated.h>
37 #include <gtkmm/button.h>
38 #include <synfigapp/instance.h>
39 #include "cellrenderer_value.h"
40 #include "cellrenderer_timetrack.h"
47 /* === U S I N G =========================================================== */
51 using namespace synfig;
52 using namespace studio;
54 /* === M A C R O S ========================================================= */
56 /* === G L O B A L S ======================================================= */
58 /* === P R O C E D U R E S ================================================= */
60 /* === M E T H O D S ======================================================= */
62 static CanvasTreeStore::Model& ModelHack()
64 static CanvasTreeStore::Model* model(0);
65 if(!model)model=new CanvasTreeStore::Model;
69 CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
70 Gtk::TreeStore(ModelHack()),
71 canvas_interface_ (canvas_interface_)
75 CanvasTreeStore::~CanvasTreeStore()
80 CanvasTreeStore::get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
82 if(column==model.value.index())
84 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
86 Glib::Value<synfig::ValueBase> x;
87 g_value_init(x.gobj(),x.value_type());
94 if(value_desc.is_const())
95 x.set(value_desc.get_value());
97 if(value_desc.is_value_node())
98 x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
101 synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
105 g_value_init(value.gobj(),x.value_type());
106 g_value_copy(x.gobj(),value.gobj());
109 if(column==model.is_value_node.index())
111 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
114 g_value_init(x.gobj(),x.value_type());
116 x.set(value_desc && value_desc.is_value_node());
118 g_value_init(value.gobj(),x.value_type());
119 g_value_copy(x.gobj(),value.gobj());
122 if(column==model.is_shared.index())
124 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
127 g_value_init(x.gobj(),x.value_type());
129 x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
131 g_value_init(value.gobj(),x.value_type());
132 g_value_copy(x.gobj(),value.gobj());
135 if(column==model.is_exported.index())
137 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
140 g_value_init(x.gobj(),x.value_type());
142 x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
144 g_value_init(value.gobj(),x.value_type());
145 g_value_copy(x.gobj(),value.gobj());
148 if(column==model.is_canvas.index())
150 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
153 g_value_init(x.gobj(),x.value_type());
155 x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
157 g_value_init(value.gobj(),x.value_type());
158 g_value_copy(x.gobj(),value.gobj());
161 if(column==model.id.index())
163 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
165 Glib::Value<Glib::ustring> x;
166 g_value_init(x.gobj(),x.value_type());
168 if(value_desc && value_desc.is_value_node())
169 x.set(value_desc.get_value_node()->get_id());
170 else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
171 x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
173 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
175 g_value_init(value.gobj(),x.value_type());
176 g_value_copy(x.gobj(),value.gobj());
179 if(column==model.is_editable.index())
181 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
184 g_value_init(x.gobj(),x.value_type());
186 x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
188 g_value_init(value.gobj(),x.value_type());
189 g_value_copy(x.gobj(),value.gobj());
192 if(column==model.type.index())
194 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
196 Glib::Value<Glib::ustring> x;
197 g_value_init(x.gobj(),x.value_type());
202 if((*iter)[model.is_canvas])
207 if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
209 x.set(ValueBase::type_local_name(value_desc.get_value_type()));
213 x.set(value_desc.get_value_node()->get_local_name());
217 g_value_init(value.gobj(),x.value_type());
218 g_value_copy(x.gobj(),value.gobj());
221 if(column==model.label.index())
223 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
225 Glib::Value<Glib::ustring> x;
226 g_value_init(x.gobj(),x.value_type());
231 Canvas::Handle canvas((*iter)[model.canvas]);
234 if(!canvas->get_id().empty())
235 x.set(canvas->get_id());
237 if(!canvas->get_name().empty())
238 x.set(canvas->get_name());
240 x.set(_("[Unnamed]"));
243 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
247 ValueNode::Handle value_node=value_desc.get_value_node();
249 // Setup the row's label
250 if(value_node->get_id().empty())
251 x.set(Glib::ustring((*iter)[model.name]));
252 else if(Glib::ustring((*iter)[model.name]).empty())
253 x.set(value_node->get_id());
255 x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
258 g_value_init(value.gobj(),x.value_type());
259 g_value_copy(x.gobj(),value.gobj());
262 if(column==model.icon.index())
264 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
266 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
268 Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
269 g_value_init(x.gobj(),x.value_type());
271 x.set(get_tree_pixbuf(value_desc.get_value_type()));
273 g_value_init(value.gobj(),x.value_type());
274 g_value_copy(x.gobj(),value.gobj());
277 Gtk::TreeStore::get_value_vfunc(iter,column,value);
281 CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
283 iter=children().begin();
284 while(iter && value_desc!=(*iter)[model.value_desc])
286 if(!iter->children().empty())
288 Gtk::TreeIter iter2(iter->children().begin());
289 //! \todo confirm that the && should be done before the ||
290 if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
296 Gtk::TreeIter iter2(++iter);
298 iter==iter->parent();
302 return (bool)iter && value_desc==(*iter)[model.value_desc];
306 CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
308 if(!iter) return find_first_value_desc(value_desc,iter);
311 if(!iter->children().empty())
313 Gtk::TreeIter iter2(iter->children().begin());
314 //! \todo confirm that the && should be done before the ||
315 if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
321 Gtk::TreeIter iter2(++iter);
324 iter==iter->parent();
329 } while(iter && value_desc!=(*iter)[model.value_desc]);
330 return (bool)iter && value_desc==(*iter)[model.value_desc];
334 CanvasTreeStore::find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
336 iter=children().begin();
337 while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
339 if(!iter->children().empty())
341 Gtk::TreeIter iter2(iter->children().begin());
342 //! \todo confirm that the && should be done before the ||
343 if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
349 Gtk::TreeIter iter2(++iter);
351 iter==iter->parent();
355 return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
359 CanvasTreeStore::find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
361 if(!iter) return find_first_value_node(value_node,iter);
364 if(!iter->children().empty())
366 Gtk::TreeIter iter2(iter->children().begin());
367 //! \todo confirm that the && should be done before the ||
368 if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
374 Gtk::TreeIter iter2(++iter);
377 iter==iter->parent();
382 } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
383 return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
387 CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
389 Gtk::TreeModel::Children children = row.children();
390 while(!children.empty() && erase(children.begin()))
393 row[model.value_desc]=value_desc;
396 //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
398 if(value_desc.is_value_node())
400 ValueNode::Handle value_node=value_desc.get_value_node();
404 row[model.value_node] = value_node;
405 //row[model.is_canvas] = false;
406 //row[model.is_value_node] = true;
407 //row[model.is_editable] = synfigapp::is_editable(value_node);
408 //row[model.id]=value_node->get_id();
411 if(value_desc.parent_is_canvas())
412 row[model.canvas]=value_desc.get_canvas();
414 row[model.canvas]=canvas_interface()->get_canvas();
416 LinkableValueNode::Handle linkable;
417 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
419 if(linkable && do_children)
421 row[model.link_count] = linkable->link_count();
422 for(int i=0;i<linkable->link_count();i++)
424 Gtk::TreeRow child_row=*(append(row.children()));
425 child_row[model.link_id] = i;
426 child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
427 child_row[model.name] = linkable->link_local_name(i);
428 set_row(child_row,synfigapp::ValueDesc(linkable,i));
435 //row[model.is_value_node] = false;
436 //row[model.is_editable] = true;
437 //row[model.label] = Glib::ustring(row[model.name]);
441 catch(synfig::Exception::IDNotFound x)
443 synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
448 // We should never get to this point
453 CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
455 synfigapp::ValueDesc value_desc=row[model.value_desc];
459 if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
460 (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
462 set_row(row,value_desc,do_children);
466 if(row[model.is_value_node])
468 ValueNode::Handle value_node(value_desc.get_value_node());
470 if(ValueNode::Handle(row[model.value_node])!=value_node)
472 rebuild_row(row,do_children);
476 //row[model.id]=value_node->get_id();
478 // Setup the row's label
480 if(value_node->get_id().empty())
481 row[model.label] = Glib::ustring(row[model.name]);
482 else if(Glib::ustring(row[model.name]).empty())
483 row[model.label] = value_node->get_id();
485 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
488 LinkableValueNode::Handle linkable;
489 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
490 if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
492 // Gtk::TreeModel::Children children = row.children();
493 // while(!children.empty() && erase(children.begin()));
495 set_row(row,value_desc);
501 //row[model.label] = Glib::ustring(row[model.name]);
502 //row[model.is_value_node] = false;
503 //row[model.is_editable] = true;
509 Gtk::TreeModel::Children children = row.children();
510 Gtk::TreeModel::Children::iterator iter;
512 if(!children.empty())
513 for(iter = children.begin(); iter != children.end(); ++iter)
515 Gtk::TreeRow row=*iter;
521 CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
523 synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
525 if(value_desc && value_desc.get_value_node())
527 ValueNode::Handle value_node;
528 value_node=value_desc.get_value_node();
530 assert(value_node);if(!value_node)return;
532 if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
534 // Gtk::TreeModel::Children children = row.children();
535 // while(!children.empty() && erase(children.begin()));
537 set_row(row,value_desc,do_children);
541 LinkableValueNode::Handle linkable;
542 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
544 if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
546 // Gtk::TreeModel::Children children = row.children();
547 // while(!children.empty() && erase(children.begin()));
549 set_row(row,value_desc);
554 // value_node=row[model.value_node];
556 row[model.id]=value_node->get_id();
558 // Setup the row's label
559 if(value_node->get_id().empty())
560 row[model.label] = Glib::ustring(row[model.name]);
561 else if(Glib::ustring(row[model.name]).empty())
562 row[model.label] = value_node->get_id();
564 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
568 row[model.label] = Glib::ustring(row[model.name]);
569 row[model.is_value_node] = false;
570 row[model.is_editable] = true;
571 Gtk::TreeModel::Children children = row.children();
572 while(!children.empty() && erase(children.begin()))
578 Gtk::TreeModel::Children children = row.children();
579 Gtk::TreeModel::Children::iterator iter;
580 if(!children.empty())
581 for(iter = children.begin(); iter != children.end(); ++iter)
583 Gtk::TreeRow row=*iter;
588 CellRenderer_ValueBase*
589 CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
591 const CanvasTreeStore::Model model;
593 CellRenderer_ValueBase* ret;
595 ret=Gtk::manage( new CellRenderer_ValueBase() );
597 column->pack_start(*ret,true);
598 column->add_attribute(ret->property_value(), model.value);
599 column->add_attribute(ret->property_editable(), model.is_editable);
600 column->add_attribute(ret->property_canvas(), model.canvas);
605 CellRenderer_TimeTrack*
606 CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
608 const CanvasTreeStore::Model model;
610 CellRenderer_TimeTrack* ret;
612 ret = Gtk::manage( new CellRenderer_TimeTrack() );
614 column->pack_start(*ret,true);
615 //column->add_attribute(ret->property_visible(), model.is_value_node);
616 column->add_attribute(ret->property_value_desc(), model.value_desc);
617 column->add_attribute(ret->property_canvas(), model.canvas);