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 "iconcontroler.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"
45 /* === U S I N G =========================================================== */
49 using namespace synfig;
50 using namespace studio;
52 /* === M A C R O S ========================================================= */
54 /* === G L O B A L S ======================================================= */
56 /* === P R O C E D U R E S ================================================= */
58 /* === M E T H O D S ======================================================= */
60 static CanvasTreeStore::Model& ModelHack()
62 static CanvasTreeStore::Model* model(0);
63 if(!model)model=new CanvasTreeStore::Model;
67 CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
68 Gtk::TreeStore(ModelHack()),
69 canvas_interface_ (canvas_interface_)
73 CanvasTreeStore::~CanvasTreeStore()
78 CanvasTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
80 if(column==model.value.index())
82 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
84 Glib::Value<synfig::ValueBase> x;
85 g_value_init(x.gobj(),x.value_type());
92 if(value_desc.is_const())
93 x.set(value_desc.get_value());
95 if(value_desc.is_value_node())
96 x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
99 synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
103 g_value_init(value.gobj(),x.value_type());
104 g_value_copy(x.gobj(),value.gobj());
107 if(column==model.is_value_node.index())
109 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
112 g_value_init(x.gobj(),x.value_type());
114 x.set(value_desc && value_desc.is_value_node());
116 g_value_init(value.gobj(),x.value_type());
117 g_value_copy(x.gobj(),value.gobj());
120 if(column==model.is_shared.index())
122 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
125 g_value_init(x.gobj(),x.value_type());
127 x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
129 g_value_init(value.gobj(),x.value_type());
130 g_value_copy(x.gobj(),value.gobj());
133 if(column==model.is_exported.index())
135 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
138 g_value_init(x.gobj(),x.value_type());
140 x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
142 g_value_init(value.gobj(),x.value_type());
143 g_value_copy(x.gobj(),value.gobj());
146 if(column==model.is_canvas.index())
148 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
151 g_value_init(x.gobj(),x.value_type());
153 x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
155 g_value_init(value.gobj(),x.value_type());
156 g_value_copy(x.gobj(),value.gobj());
159 if(column==model.id.index())
161 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
163 Glib::Value<Glib::ustring> x;
164 g_value_init(x.gobj(),x.value_type());
166 if(value_desc && value_desc.is_value_node())
167 x.set(value_desc.get_value_node()->get_id());
168 else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
169 x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
171 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
173 g_value_init(value.gobj(),x.value_type());
174 g_value_copy(x.gobj(),value.gobj());
177 if(column==model.is_editable.index())
179 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
182 g_value_init(x.gobj(),x.value_type());
184 x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
186 g_value_init(value.gobj(),x.value_type());
187 g_value_copy(x.gobj(),value.gobj());
190 if(column==model.type.index())
192 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
194 Glib::Value<Glib::ustring> x;
195 g_value_init(x.gobj(),x.value_type());
200 if((*iter)[model.is_canvas])
205 if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
207 x.set(ValueBase::type_name(value_desc.get_value_type()));
211 x.set(value_desc.get_value_node()->get_local_name());
215 g_value_init(value.gobj(),x.value_type());
216 g_value_copy(x.gobj(),value.gobj());
219 if(column==model.label.index())
221 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
223 Glib::Value<Glib::ustring> x;
224 g_value_init(x.gobj(),x.value_type());
229 Canvas::Handle canvas((*iter)[model.canvas]);
232 if(!canvas->get_id().empty())
233 x.set(canvas->get_id());
235 if(!canvas->get_name().empty())
236 x.set(canvas->get_name());
238 x.set(_("[Unnamed]"));
241 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
245 ValueNode::Handle value_node=value_desc.get_value_node();
247 // Setup the row's label
248 if(value_node->get_id().empty())
249 x.set(Glib::ustring((*iter)[model.name]));
250 else if(Glib::ustring((*iter)[model.name]).empty())
251 x.set(value_node->get_id());
253 x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
256 g_value_init(value.gobj(),x.value_type());
257 g_value_copy(x.gobj(),value.gobj());
260 if(column==model.icon.index())
262 synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
264 return Gtk::TreeStore::get_value_vfunc(iter,column,value);
266 Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
267 g_value_init(x.gobj(),x.value_type());
269 x.set(get_tree_pixbuf(value_desc.get_value_type()));
271 g_value_init(value.gobj(),x.value_type());
272 g_value_copy(x.gobj(),value.gobj());
275 Gtk::TreeStore::get_value_vfunc(iter,column,value);
279 CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
281 iter=children().begin();
282 while(iter && value_desc!=(*iter)[model.value_desc])
284 if(!iter->children().empty())
286 Gtk::TreeIter iter2(iter->children().begin());
287 if(iter2 && value_desc==(*iter2)[model.value_desc] || find_next_value_desc(value_desc, iter2))
293 Gtk::TreeIter iter2(++iter);
295 iter==iter->parent();
299 return (bool)iter && value_desc==(*iter)[model.value_desc];
303 CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
305 if(!iter) return find_first_value_desc(value_desc,iter);
308 if(!iter->children().empty())
310 Gtk::TreeIter iter2(iter->children().begin());
311 if(iter2 && value_desc==(*iter2)[model.value_desc] || find_next_value_desc(value_desc, iter2))
317 Gtk::TreeIter iter2(++iter);
320 iter==iter->parent();
325 } while(iter && value_desc!=(*iter)[model.value_desc]);
326 return (bool)iter && value_desc==(*iter)[model.value_desc];
335 CanvasTreeStore::find_first_value_node(const ValueNode::Handle& value_node, Gtk::TreeIter& iter)
337 iter=children().begin();
338 while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
340 if(!iter->children().empty())
342 Gtk::TreeIter iter2(iter->children().begin());
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 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 if(iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node] || find_next_value_node(value_node, iter2))
373 Gtk::TreeIter iter2(++iter);
376 iter==iter->parent();
381 } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
382 return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
386 CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
388 Gtk::TreeModel::Children children = row.children();
389 while(!children.empty() && erase(children.begin()));
391 row[model.value_desc]=value_desc;
394 //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
396 if(value_desc.is_value_node())
398 ValueNode::Handle value_node=value_desc.get_value_node();
402 row[model.value_node] = value_node;
403 //row[model.is_canvas] = false;
404 //row[model.is_value_node] = true;
405 //row[model.is_editable] = synfigapp::is_editable(value_node);
406 //row[model.id]=value_node->get_id();
409 if(value_desc.parent_is_canvas())
410 row[model.canvas]=value_desc.get_canvas();
412 row[model.canvas]=canvas_interface()->get_canvas();
414 LinkableValueNode::Handle linkable;
415 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
417 if(linkable && do_children)
419 row[model.link_count] = linkable->link_count();
420 for(int i=0;i<linkable->link_count();i++)
422 Gtk::TreeRow child_row=*(append(row.children()));
423 child_row[model.link_id] = i;
424 child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
425 child_row[model.name] = linkable->link_local_name(i);
426 set_row(child_row,synfigapp::ValueDesc(linkable,i));
433 //row[model.is_value_node] = false;
434 //row[model.is_editable] = true;
435 //row[model.label] = Glib::ustring(row[model.name]);
439 catch(synfig::Exception::IDNotFound x)
441 synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
446 // We should never get to this point
451 CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
453 synfigapp::ValueDesc value_desc=row[model.value_desc];
457 if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
458 (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
460 set_row(row,value_desc,do_children);
464 if(row[model.is_value_node])
466 ValueNode::Handle value_node(value_desc.get_value_node());
468 if(ValueNode::Handle(row[model.value_node])!=value_node)
470 rebuild_row(row,do_children);
474 //row[model.id]=value_node->get_id();
476 // Setup the row's label
478 if(value_node->get_id().empty())
479 row[model.label] = Glib::ustring(row[model.name]);
480 else if(Glib::ustring(row[model.name]).empty())
481 row[model.label] = value_node->get_id();
483 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
486 LinkableValueNode::Handle linkable;
487 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
488 if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
490 // Gtk::TreeModel::Children children = row.children();
491 // while(!children.empty() && erase(children.begin()));
493 set_row(row,value_desc);
499 //row[model.label] = Glib::ustring(row[model.name]);
500 //row[model.is_value_node] = false;
501 //row[model.is_editable] = true;
507 Gtk::TreeModel::Children children = row.children();
508 Gtk::TreeModel::Children::iterator iter;
510 if(!children.empty())
511 for(iter = children.begin(); iter != children.end(); ++iter)
513 Gtk::TreeRow row=*iter;
519 CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
521 synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
523 if(value_desc && value_desc.get_value_node())
525 ValueNode::Handle value_node;
526 value_node=value_desc.get_value_node();
528 assert(value_node);if(!value_node)return;
530 if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
532 // Gtk::TreeModel::Children children = row.children();
533 // while(!children.empty() && erase(children.begin()));
535 set_row(row,value_desc,do_children);
539 LinkableValueNode::Handle linkable;
540 linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
542 if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
544 // Gtk::TreeModel::Children children = row.children();
545 // while(!children.empty() && erase(children.begin()));
547 set_row(row,value_desc);
552 // value_node=row[model.value_node];
554 row[model.id]=value_node->get_id();
556 // Setup the row's label
557 if(value_node->get_id().empty())
558 row[model.label] = Glib::ustring(row[model.name]);
559 else if(Glib::ustring(row[model.name]).empty())
560 row[model.label] = value_node->get_id();
562 row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
566 row[model.label] = Glib::ustring(row[model.name]);
567 row[model.is_value_node] = false;
568 row[model.is_editable] = true;
569 Gtk::TreeModel::Children children = row.children();
570 while(!children.empty() && erase(children.begin()));
575 Gtk::TreeModel::Children children = row.children();
576 Gtk::TreeModel::Children::iterator iter;
577 if(!children.empty())
578 for(iter = children.begin(); iter != children.end(); ++iter)
580 Gtk::TreeRow row=*iter;
585 CellRenderer_ValueBase*
586 CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
588 const CanvasTreeStore::Model model;
590 CellRenderer_ValueBase* ret;
592 ret=Gtk::manage( new CellRenderer_ValueBase() );
594 column->pack_start(*ret,true);
595 column->add_attribute(ret->property_value(), model.value);
596 column->add_attribute(ret->property_editable(), model.is_editable);
597 column->add_attribute(ret->property_canvas(), model.canvas);
602 CellRenderer_TimeTrack*
603 CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
605 const CanvasTreeStore::Model model;
607 CellRenderer_TimeTrack* ret;
609 ret = Gtk::manage( new CellRenderer_TimeTrack() );
611 column->pack_start(*ret,true);
612 //column->add_attribute(ret->property_visible(), model.is_value_node);
613 column->add_attribute(ret->property_value_desc(), model.value_desc);
614 column->add_attribute(ret->property_canvas(), model.canvas);