1 /* === S Y N F I G ========================================================= */
2 /*! \file canvastreestore.cpp
3 ** \brief Template File
5 ** $Id: canvastreestore.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
8 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
10 ** This software and associated documentation
11 ** are CONFIDENTIAL and PROPRIETARY property of
12 ** the above-mentioned copyright holder.
14 ** You may not copy, print, publish, or in any
15 ** other way distribute this software without
16 ** a prior written agreement with
17 ** the copyright holder.
20 /* ========================================================================= */
22 /* === H E A D E R S ======================================================= */
31 #include "canvastreestore.h"
32 #include <synfig/valuenode.h>
33 #include "iconcontroler.h"
34 #include <synfig/valuenode_timedswap.h>
35 #include <synfig/valuenode_animated.h>
36 #include <gtkmm/button.h>
37 #include <synfigapp/instance.h>
38 #include "cellrenderer_value.h"
39 #include "cellrenderer_timetrack.h"
44 /* === U S I N G =========================================================== */
48 using namespace synfig;
49 using namespace studio;
51 /* === M A C R O S ========================================================= */
53 /* === G L O B A L S ======================================================= */
55 /* === P R O C E D U R E S ================================================= */
57 /* === M E T H O D S ======================================================= */
59 static CanvasTreeStore::Model& ModelHack()
61 static CanvasTreeStore::Model* model(0);
62 if(!model)model=new CanvasTreeStore::Model;
66 CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
67 Gtk::TreeStore(ModelHack()),
68 canvas_interface_ (canvas_interface_)
72 CanvasTreeStore::~CanvasTreeStore()
77 CanvasTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
79 if(column==model.value.index())
81 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
83 Glib::Value<synfig::ValueBase> x;
84 g_value_init(x.gobj(),x.value_type());
91 if(value_desc.is_const())
92 x.set(value_desc.get_value());
94 if(value_desc.is_value_node())
95 x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
98 synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
102 g_value_init(value.gobj(),x.value_type());
103 g_value_copy(x.gobj(),value.gobj());
106 if(column==model.is_value_node.index())
108 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
111 g_value_init(x.gobj(),x.value_type());
113 x.set(value_desc && value_desc.is_value_node());
115 g_value_init(value.gobj(),x.value_type());
116 g_value_copy(x.gobj(),value.gobj());
119 if(column==model.is_shared.index())
121 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
124 g_value_init(x.gobj(),x.value_type());
126 x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
128 g_value_init(value.gobj(),x.value_type());
129 g_value_copy(x.gobj(),value.gobj());
132 if(column==model.is_exported.index())
134 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
137 g_value_init(x.gobj(),x.value_type());
139 x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
141 g_value_init(value.gobj(),x.value_type());
142 g_value_copy(x.gobj(),value.gobj());
145 if(column==model.is_canvas.index())
147 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
150 g_value_init(x.gobj(),x.value_type());
152 x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
154 g_value_init(value.gobj(),x.value_type());
155 g_value_copy(x.gobj(),value.gobj());
158 if(column==model.id.index())
160 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
162 Glib::Value<Glib::ustring> x;
163 g_value_init(x.gobj(),x.value_type());
165 if(value_desc && value_desc.is_value_node())
166 x.set(value_desc.get_value_node()->get_id());
167 else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
168 x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
170 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
172 g_value_init(value.gobj(),x.value_type());
173 g_value_copy(x.gobj(),value.gobj());
176 if(column==model.is_editable.index())
178 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
181 g_value_init(x.gobj(),x.value_type());
183 x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
185 g_value_init(value.gobj(),x.value_type());
186 g_value_copy(x.gobj(),value.gobj());
189 if(column==model.type.index())
191 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
193 Glib::Value<Glib::ustring> x;
194 g_value_init(x.gobj(),x.value_type());
199 if((*iter)[model.is_canvas])
204 if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
206 x.set(ValueBase::type_name(value_desc.get_value_type()));
210 x.set(value_desc.get_value_node()->get_local_name());
214 g_value_init(value.gobj(),x.value_type());
215 g_value_copy(x.gobj(),value.gobj());
218 if(column==model.label.index())
220 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
222 Glib::Value<Glib::ustring> x;
223 g_value_init(x.gobj(),x.value_type());
228 Canvas::Handle canvas((*iter)[model.canvas]);
231 if(!canvas->get_id().empty())
232 x.set(canvas->get_id());
234 if(!canvas->get_name().empty())
235 x.set(canvas->get_name());
237 x.set(_("[Unnamed]"));
240 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
244 ValueNode::Handle value_node=value_desc.get_value_node();
246 // Setup the row's label
247 if(value_node->get_id().empty())
248 x.set(Glib::ustring((*iter)[model.name]));
249 else if(Glib::ustring((*iter)[model.name]).empty())
250 x.set(value_node->get_id());
252 x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
255 g_value_init(value.gobj(),x.value_type());
256 g_value_copy(x.gobj(),value.gobj());
259 if(column==model.icon.index())
261 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
263 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
265 Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
266 g_value_init(x.gobj(),x.value_type());
268 x.set(get_tree_pixbuf(value_desc.get_value_type()));
270 g_value_init(value.gobj(),x.value_type());
271 g_value_copy(x.gobj(),value.gobj());
274 Gtk::TreeStore::get_value_vfunc(iter,column,value);
278 CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
280 iter=children().begin();
281 while(iter && value_desc!=(*iter)[model.value_desc])
283 if(!iter->children().empty())
285 Gtk::TreeIter iter2(iter->children().begin());
286 if(iter2 && value_desc==(*iter2)[model.value_desc] || find_next_value_desc(value_desc, iter2))
292 Gtk::TreeIter iter2(++iter);
294 iter==iter->parent();
298 return (bool)iter && value_desc==(*iter)[model.value_desc];
302 CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
304 if(!iter) return find_first_value_desc(value_desc,iter);
307 if(!iter->children().empty())
309 Gtk::TreeIter iter2(iter->children().begin());
310 if(iter2 && value_desc==(*iter2)[model.value_desc] || find_next_value_desc(value_desc, iter2))
316 Gtk::TreeIter iter2(++iter);
319 iter==iter->parent();
324 } while(iter && value_desc!=(*iter)[model.value_desc]);
325 return (bool)iter && value_desc==(*iter)[model.value_desc];
334 CanvasTreeStore::find_first_value_node(const 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 if(iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node] || find_next_value_node(value_node, iter2))
348 Gtk::TreeIter iter2(++iter);
350 iter==iter->parent();
354 return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
358 CanvasTreeStore::find_next_value_node(const ValueNode::Handle& value_node, Gtk::TreeIter& iter)
360 if(!iter) return find_first_value_node(value_node,iter);
363 if(!iter->children().empty())
365 Gtk::TreeIter iter2(iter->children().begin());
366 if(iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node] || find_next_value_node(value_node, iter2))
372 Gtk::TreeIter iter2(++iter);
375 iter==iter->parent();
380 } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
381 return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
385 CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
387 Gtk::TreeModel::Children children = row.children();
388 while(!children.empty() && erase(children.begin()));
390 row[model.value_desc]=value_desc;
393 //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
395 if(value_desc.is_value_node())
397 ValueNode::Handle value_node=value_desc.get_value_node();
401 row[model.value_node] = value_node;
402 //row[model.is_canvas] = false;
403 //row[model.is_value_node] = true;
404 //row[model.is_editable] = synfigapp::is_editable(value_node);
405 //row[model.id]=value_node->get_id();
408 if(value_desc.parent_is_canvas())
409 row[model.canvas]=value_desc.get_canvas();
411 row[model.canvas]=canvas_interface()->get_canvas();
413 LinkableValueNode::Handle linkable;
414 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
416 if(linkable && do_children)
418 row[model.link_count] = linkable->link_count();
419 for(int i=0;i<linkable->link_count();i++)
421 Gtk::TreeRow child_row=*(append(row.children()));
422 child_row[model.link_id] = i;
423 child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
424 child_row[model.name] = linkable->link_local_name(i);
425 set_row(child_row,synfigapp::ValueDesc(linkable,i));
432 //row[model.is_value_node] = false;
433 //row[model.is_editable] = true;
434 //row[model.label] = Glib::ustring(row[model.name]);
438 catch(synfig::Exception::IDNotFound x)
440 synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
445 // We should never get to this point
450 CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
452 synfigapp::ValueDesc value_desc=row[model.value_desc];
456 if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
457 (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
459 set_row(row,value_desc,do_children);
463 if(row[model.is_value_node])
465 ValueNode::Handle value_node(value_desc.get_value_node());
467 if(ValueNode::Handle(row[model.value_node])!=value_node)
469 rebuild_row(row,do_children);
473 //row[model.id]=value_node->get_id();
475 // Setup the row's label
477 if(value_node->get_id().empty())
478 row[model.label] = Glib::ustring(row[model.name]);
479 else if(Glib::ustring(row[model.name]).empty())
480 row[model.label] = value_node->get_id();
482 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
485 LinkableValueNode::Handle linkable;
486 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
487 if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
489 // Gtk::TreeModel::Children children = row.children();
490 // while(!children.empty() && erase(children.begin()));
492 set_row(row,value_desc);
498 //row[model.label] = Glib::ustring(row[model.name]);
499 //row[model.is_value_node] = false;
500 //row[model.is_editable] = true;
506 Gtk::TreeModel::Children children = row.children();
507 Gtk::TreeModel::Children::iterator iter;
509 if(!children.empty())
510 for(iter = children.begin(); iter != children.end(); ++iter)
512 Gtk::TreeRow row=*iter;
518 CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
520 synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
522 if(value_desc && value_desc.get_value_node())
524 ValueNode::Handle value_node;
525 value_node=value_desc.get_value_node();
527 assert(value_node);if(!value_node)return;
529 if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
531 // Gtk::TreeModel::Children children = row.children();
532 // while(!children.empty() && erase(children.begin()));
534 set_row(row,value_desc,do_children);
538 LinkableValueNode::Handle linkable;
539 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
541 if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
543 // Gtk::TreeModel::Children children = row.children();
544 // while(!children.empty() && erase(children.begin()));
546 set_row(row,value_desc);
551 // value_node=row[model.value_node];
553 row[model.id]=value_node->get_id();
555 // Setup the row's label
556 if(value_node->get_id().empty())
557 row[model.label] = Glib::ustring(row[model.name]);
558 else if(Glib::ustring(row[model.name]).empty())
559 row[model.label] = value_node->get_id();
561 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
565 row[model.label] = Glib::ustring(row[model.name]);
566 row[model.is_value_node] = false;
567 row[model.is_editable] = true;
568 Gtk::TreeModel::Children children = row.children();
569 while(!children.empty() && erase(children.begin()));
574 Gtk::TreeModel::Children children = row.children();
575 Gtk::TreeModel::Children::iterator iter;
576 if(!children.empty())
577 for(iter = children.begin(); iter != children.end(); ++iter)
579 Gtk::TreeRow row=*iter;
584 CellRenderer_ValueBase*
585 CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
587 const CanvasTreeStore::Model model;
589 CellRenderer_ValueBase* ret;
591 ret=Gtk::manage( new CellRenderer_ValueBase() );
593 column->pack_start(*ret,true);
594 column->add_attribute(ret->property_value(), model.value);
595 column->add_attribute(ret->property_editable(), model.is_editable);
596 column->add_attribute(ret->property_canvas(), model.canvas);
601 CellRenderer_TimeTrack*
602 CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
604 const CanvasTreeStore::Model model;
606 CellRenderer_TimeTrack* ret;
608 ret = Gtk::manage( new CellRenderer_TimeTrack() );
610 column->pack_start(*ret,true);
611 //column->add_attribute(ret->property_visible(), model.is_value_node);
612 column->add_attribute(ret->property_value_desc(), model.value_desc);
613 column->add_attribute(ret->property_canvas(), model.canvas);