Move treeviews/treestores into subfolder
authorNikita Kitaev <nikitakit@gmail.com>
Sat, 17 Apr 2010 06:13:46 +0000 (23:13 -0700)
committerNikita Kitaev <nikitakit@gmail.com>
Sat, 17 Apr 2010 06:14:01 +0000 (23:14 -0700)
65 files changed:
synfig-studio/src/gui/Makefile.am
synfig-studio/src/gui/canvastreestore.cpp [deleted file]
synfig-studio/src/gui/canvastreestore.h [deleted file]
synfig-studio/src/gui/canvasview.h
synfig-studio/src/gui/childrentree.cpp [deleted file]
synfig-studio/src/gui/childrentree.h [deleted file]
synfig-studio/src/gui/childrentreestore.cpp [deleted file]
synfig-studio/src/gui/childrentreestore.h [deleted file]
synfig-studio/src/gui/dialogs/canvasproperties.cpp
synfig-studio/src/gui/docks/dock_canvasspecific.cpp
synfig-studio/src/gui/docks/dock_children.cpp
synfig-studio/src/gui/docks/dock_curves.cpp
synfig-studio/src/gui/docks/dock_history.cpp
synfig-studio/src/gui/docks/dock_keyframes.cpp
synfig-studio/src/gui/docks/dock_layergroups.cpp
synfig-studio/src/gui/docks/dock_layers.cpp
synfig-studio/src/gui/docks/dock_metadata.cpp
synfig-studio/src/gui/docks/dock_params.cpp
synfig-studio/src/gui/docks/dock_timetrack.cpp
synfig-studio/src/gui/groupactionmanager.cpp
synfig-studio/src/gui/historytreestore.cpp [deleted file]
synfig-studio/src/gui/historytreestore.h [deleted file]
synfig-studio/src/gui/instance.h
synfig-studio/src/gui/keyframeactionmanager.cpp
synfig-studio/src/gui/keyframetree.cpp [deleted file]
synfig-studio/src/gui/keyframetree.h [deleted file]
synfig-studio/src/gui/keyframetreestore.cpp [deleted file]
synfig-studio/src/gui/keyframetreestore.h [deleted file]
synfig-studio/src/gui/layeractionmanager.cpp
synfig-studio/src/gui/layergrouptree.cpp [deleted file]
synfig-studio/src/gui/layergrouptree.h [deleted file]
synfig-studio/src/gui/layergrouptreestore.cpp [deleted file]
synfig-studio/src/gui/layergrouptreestore.h [deleted file]
synfig-studio/src/gui/layerparamtreestore.cpp [deleted file]
synfig-studio/src/gui/layerparamtreestore.h [deleted file]
synfig-studio/src/gui/layertree.cpp [deleted file]
synfig-studio/src/gui/layertree.h [deleted file]
synfig-studio/src/gui/layertreestore.cpp [deleted file]
synfig-studio/src/gui/layertreestore.h [deleted file]
synfig-studio/src/gui/metadatatreestore.cpp [deleted file]
synfig-studio/src/gui/metadatatreestore.h [deleted file]
synfig-studio/src/gui/trees/canvastreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/canvastreestore.h [new file with mode: 0644]
synfig-studio/src/gui/trees/childrentree.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/childrentree.h [new file with mode: 0644]
synfig-studio/src/gui/trees/childrentreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/childrentreestore.h [new file with mode: 0644]
synfig-studio/src/gui/trees/historytreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/historytreestore.h [new file with mode: 0644]
synfig-studio/src/gui/trees/keyframetree.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/keyframetree.h [new file with mode: 0644]
synfig-studio/src/gui/trees/keyframetreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/keyframetreestore.h [new file with mode: 0644]
synfig-studio/src/gui/trees/layergrouptree.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/layergrouptree.h [new file with mode: 0644]
synfig-studio/src/gui/trees/layergrouptreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/layergrouptreestore.h [new file with mode: 0644]
synfig-studio/src/gui/trees/layerparamtreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/layerparamtreestore.h [new file with mode: 0644]
synfig-studio/src/gui/trees/layertree.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/layertree.h [new file with mode: 0644]
synfig-studio/src/gui/trees/layertreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/layertreestore.h [new file with mode: 0644]
synfig-studio/src/gui/trees/metadatatreestore.cpp [new file with mode: 0644]
synfig-studio/src/gui/trees/metadatatreestore.h [new file with mode: 0644]

index caeb8e1..c6ba46d 100644 (file)
@@ -199,37 +199,37 @@ STATE_CC = \
 
 
 TREEVIEW_HH = \
-       childrentree.h \
-       keyframetree.h \
-       layergrouptree.h \
-       layertree.h
+       trees/childrentree.h \
+       trees/keyframetree.h \
+       trees/layergrouptree.h \
+       trees/layertree.h
 
 TREEVIEW_CC = \
-       childrentree.cpp \
-       keyframetree.cpp \
-       layergrouptree.cpp \
-       layertree.cpp
+       trees/childrentree.cpp \
+       trees/keyframetree.cpp \
+       trees/layergrouptree.cpp \
+       trees/layertree.cpp
 
 
 TREESTORE_HH = \
-       canvastreestore.h \
-       childrentreestore.h \
-       historytreestore.h \
-       keyframetreestore.h \
-       layergrouptreestore.h \
-       layerparamtreestore.h \
-       layertreestore.h \
-       metadatatreestore.h
+       trees/canvastreestore.h \
+       trees/childrentreestore.h \
+       trees/historytreestore.h \
+       trees/keyframetreestore.h \
+       trees/layergrouptreestore.h \
+       trees/layerparamtreestore.h \
+       trees/layertreestore.h \
+       trees/metadatatreestore.h
 
 TREESTORE_CC = \
-       canvastreestore.cpp \
-       childrentreestore.cpp \
-       historytreestore.cpp \
-       keyframetreestore.cpp \
-       layergrouptreestore.cpp \
-       layerparamtreestore.cpp \
-       layertreestore.cpp \
-       metadatatreestore.cpp
+       trees/canvastreestore.cpp \
+       trees/childrentreestore.cpp \
+       trees/historytreestore.cpp \
+       trees/keyframetreestore.cpp \
+       trees/layergrouptreestore.cpp \
+       trees/layerparamtreestore.cpp \
+       trees/layertreestore.cpp \
+       trees/metadatatreestore.cpp
 
 
 DUCKTRANSFORM_HH = \
diff --git a/synfig-studio/src/gui/canvastreestore.cpp b/synfig-studio/src/gui/canvastreestore.cpp
deleted file mode 100644 (file)
index f49d7a3..0000000
+++ /dev/null
@@ -1,622 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file canvastreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "canvastreestore.h"
-#include <synfig/valuenode.h>
-#include "iconcontroller.h"
-#include <synfig/valuenode_timedswap.h>
-#include <synfig/valuenode_animated.h>
-#include <gtkmm/button.h>
-#include <synfigapp/instance.h>
-#include "cellrenderer_value.h"
-#include "cellrenderer_timetrack.h"
-#include <ETL/clock>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static CanvasTreeStore::Model& ModelHack()
-{
-       static CanvasTreeStore::Model* model(0);
-       if(!model)model=new CanvasTreeStore::Model;
-       return *model;
-}
-
-CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
-       Gtk::TreeStore(ModelHack()),
-       canvas_interface_               (canvas_interface_)
-{
-}
-
-CanvasTreeStore::~CanvasTreeStore()
-{
-}
-
-void
-CanvasTreeStore::get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
-       if(column==model.value.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<synfig::ValueBase> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               if(!value_desc)
-               {
-                       x.set(ValueBase());
-               }
-               else
-               if(value_desc.is_const())
-                       x.set(value_desc.get_value());
-               else
-               if(value_desc.is_value_node())
-                       x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
-               else
-               {
-                       synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
-                       return;
-               }
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.is_value_node.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(value_desc && value_desc.is_value_node());
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.is_shared.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.is_exported.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.is_canvas.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.id.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               if(value_desc && value_desc.is_value_node())
-                       x.set(value_desc.get_value_node()->get_id());
-               else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
-                       x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
-               else
-                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.is_editable.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.type.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               // Set the type
-               if(!value_desc)
-               {
-                       if((*iter)[model.is_canvas])
-                               x.set(_("Canvas"));
-               }
-               else
-               {
-                       if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
-                       {
-                               x.set(ValueBase::type_local_name(value_desc.get_value_type()));
-                       }
-                       else
-                       {
-                               x.set(value_desc.get_value_node()->get_local_name());
-                       }
-               }
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.label.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               // Set the type
-               if(!value_desc)
-               {
-                       Canvas::Handle canvas((*iter)[model.canvas]);
-                       if(canvas)
-                       {
-                               if(!canvas->get_id().empty())
-                                       x.set(canvas->get_id());
-                               else
-                               if(!canvas->get_name().empty())
-                                       x.set(canvas->get_name());
-                               else
-                                       x.set(_("[Unnamed]"));
-                               x.set(_("Canvas"));
-                       }
-                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
-               }
-               else
-               {
-                       ValueNode::Handle value_node=value_desc.get_value_node();
-
-                       // Setup the row's label
-                       if(value_node->get_id().empty())
-                               x.set(Glib::ustring((*iter)[model.name]));
-                       else if(Glib::ustring((*iter)[model.name]).empty())
-                               x.set(value_node->get_id());
-                       else
-                               x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
-               }
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.icon.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-               if(!value_desc)
-                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
-
-               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(get_tree_pixbuf(value_desc.get_value_type()));
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-               Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-bool
-CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
-{
-       iter=children().begin();
-       while(iter && value_desc!=(*iter)[model.value_desc])
-       {
-               if(!iter->children().empty())
-               {
-                       Gtk::TreeIter iter2(iter->children().begin());
-                       //! \todo confirm that the && should be done before the ||
-                       if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
-                       {
-                               iter=iter2;
-                               return true;
-                       }
-               }
-               Gtk::TreeIter iter2(++iter);
-               if(!iter2)
-                       iter==iter->parent();
-               else
-                       iter=iter2;
-       }
-       return (bool)iter && value_desc==(*iter)[model.value_desc];
-}
-
-bool
-CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
-{
-       if(!iter) return find_first_value_desc(value_desc,iter);
-
-       if(iter) do {
-               if(!iter->children().empty())
-               {
-                       Gtk::TreeIter iter2(iter->children().begin());
-                       //! \todo confirm that the && should be done before the ||
-                       if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
-                       {
-                               iter=iter2;
-                               return true;
-                       }
-               }
-               Gtk::TreeIter iter2(++iter);
-               if(!iter2)
-               {
-                       iter==iter->parent();
-                       if(iter)++iter;
-               }
-               else
-                       iter=iter2;
-       } while(iter && value_desc!=(*iter)[model.value_desc]);
-       return (bool)iter && value_desc==(*iter)[model.value_desc];
-}
-
-bool
-CanvasTreeStore::find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
-{
-       iter=children().begin();
-       while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
-       {
-               if(!iter->children().empty())
-               {
-                       Gtk::TreeIter iter2(iter->children().begin());
-                       //! \todo confirm that the && should be done before the ||
-                       if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
-                       {
-                               iter=iter2;
-                               return true;
-                       }
-               }
-               Gtk::TreeIter iter2(++iter);
-               if(!iter2)
-                       iter==iter->parent();
-               else
-                       iter=iter2;
-       }
-       return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
-}
-
-bool
-CanvasTreeStore::find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
-{
-       if(!iter) return find_first_value_node(value_node,iter);
-
-       if(iter) do {
-               if(!iter->children().empty())
-               {
-                       Gtk::TreeIter iter2(iter->children().begin());
-                       //! \todo confirm that the && should be done before the ||
-                       if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
-                       {
-                               iter=iter2;
-                               return true;
-                       }
-               }
-               Gtk::TreeIter iter2(++iter);
-               if(!iter2)
-               {
-                       iter==iter->parent();
-                       if(iter)++iter;
-               }
-               else
-                       iter=iter2;
-       } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
-       return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
-}
-
-void
-CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
-{
-       Gtk::TreeModel::Children children = row.children();
-       while(!children.empty() && erase(children.begin()))
-               ;
-
-       row[model.value_desc]=value_desc;
-       try
-       {
-               //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
-
-               if(value_desc.is_value_node())
-               {
-                       ValueNode::Handle value_node=value_desc.get_value_node();
-
-                       assert(value_node);
-
-                       row[model.value_node] = value_node;
-                       //row[model.is_canvas] = false;
-                       //row[model.is_value_node] = true;
-                       //row[model.is_editable] = synfigapp::is_editable(value_node);
-                       //row[model.id]=value_node->get_id();
-
-                       // Set the canvas
-                       if(value_desc.parent_is_canvas())
-                               row[model.canvas]=value_desc.get_canvas();
-                       else
-                               row[model.canvas]=canvas_interface()->get_canvas();
-
-                       LinkableValueNode::Handle linkable;
-                       linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
-
-                       if(linkable && do_children)
-                       {
-                               row[model.link_count] = linkable->link_count();
-                               for(int i=0;i<linkable->link_count();i++)
-                               {
-                                       Gtk::TreeRow child_row=*(append(row.children()));
-                                       child_row[model.link_id] = i;
-                                       child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
-                                       child_row[model.name] = linkable->link_local_name(i);
-                                       set_row(child_row,synfigapp::ValueDesc(linkable,i));
-                               }
-                       }
-                       return;
-               }
-               else
-               {
-                       //row[model.is_value_node] = false;
-                       //row[model.is_editable] = true;
-                       //row[model.label] = Glib::ustring(row[model.name]);
-                       return;
-               }
-       }
-       catch(synfig::Exception::IDNotFound x)
-       {
-               synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
-               erase(row);
-               return;
-       }
-
-       // We should never get to this point
-       assert(0);
-}
-
-void
-CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
-{
-       synfigapp::ValueDesc value_desc=row[model.value_desc];
-
-       if(value_desc)
-       {
-               if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
-                       (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
-               {
-                       set_row(row,value_desc,do_children);
-                       return;
-               }
-
-               if(row[model.is_value_node])
-               {
-                       ValueNode::Handle value_node(value_desc.get_value_node());
-
-                       if(ValueNode::Handle(row[model.value_node])!=value_node)
-                       {
-                               rebuild_row(row,do_children);
-                               return;
-                       }
-
-                       //row[model.id]=value_node->get_id();
-
-                       // Setup the row's label
-                       /*
-                       if(value_node->get_id().empty())
-                               row[model.label] = Glib::ustring(row[model.name]);
-                       else if(Glib::ustring(row[model.name]).empty())
-                               row[model.label] = value_node->get_id();
-                       else
-                               row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
-                       */
-
-                       LinkableValueNode::Handle linkable;
-                       linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
-                       if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
-                       {
-       //                      Gtk::TreeModel::Children children = row.children();
-       //                      while(!children.empty() && erase(children.begin()));
-
-                               set_row(row,value_desc);
-                               return;
-                       }
-               }
-               else
-               {
-                       //row[model.label] = Glib::ustring(row[model.name]);
-                       //row[model.is_value_node] = false;
-                       //row[model.is_editable] = true;
-               }
-       }
-       if(!do_children)
-               return;
-
-       Gtk::TreeModel::Children children = row.children();
-       Gtk::TreeModel::Children::iterator iter;
-
-       if(!children.empty())
-       for(iter = children.begin(); iter != children.end(); ++iter)
-       {
-               Gtk::TreeRow row=*iter;
-               refresh_row(row);
-       }
-}
-
-void
-CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
-{
-       synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
-
-       if(value_desc && value_desc.get_value_node())
-       {
-               ValueNode::Handle value_node;
-               value_node=value_desc.get_value_node();
-
-               assert(value_node);if(!value_node)return;
-
-               if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
-               {
-//                     Gtk::TreeModel::Children children = row.children();
-//                     while(!children.empty() && erase(children.begin()));
-
-                       set_row(row,value_desc,do_children);
-                       return;
-               }
-
-               LinkableValueNode::Handle linkable;
-               linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
-
-               if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
-               {
-//                     Gtk::TreeModel::Children children = row.children();
-//                     while(!children.empty() && erase(children.begin()));
-
-                       set_row(row,value_desc);
-                       return;
-               }
-
-               //if(!value_node)
-               //      value_node=row[model.value_node];
-
-               row[model.id]=value_node->get_id();
-
-               // Setup the row's label
-               if(value_node->get_id().empty())
-                       row[model.label] = Glib::ustring(row[model.name]);
-               else if(Glib::ustring(row[model.name]).empty())
-                       row[model.label] = value_node->get_id();
-               else
-                       row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
-       }
-       else
-       {
-               row[model.label] = Glib::ustring(row[model.name]);
-               row[model.is_value_node] = false;
-               row[model.is_editable] = true;
-               Gtk::TreeModel::Children children = row.children();
-               while(!children.empty() && erase(children.begin()))
-                       ;
-       }
-       if(!do_children)
-               return;
-
-       Gtk::TreeModel::Children children = row.children();
-       Gtk::TreeModel::Children::iterator iter;
-       if(!children.empty())
-       for(iter = children.begin(); iter != children.end(); ++iter)
-       {
-               Gtk::TreeRow row=*iter;
-               rebuild_row(row);
-       }
-}
-
-CellRenderer_ValueBase*
-CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
-{
-       const CanvasTreeStore::Model model;
-
-       CellRenderer_ValueBase* ret;
-
-       ret=Gtk::manage( new CellRenderer_ValueBase() );
-
-       column->pack_start(*ret,true);
-       column->add_attribute(ret->property_value(), model.value);
-       column->add_attribute(ret->property_editable(), model.is_editable);
-       column->add_attribute(ret->property_canvas(), model.canvas);
-
-       return ret;
-}
-
-CellRenderer_TimeTrack*
-CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
-{
-       const CanvasTreeStore::Model model;
-
-       CellRenderer_TimeTrack* ret;
-
-       ret = Gtk::manage( new CellRenderer_TimeTrack() );
-
-       column->pack_start(*ret,true);
-       //column->add_attribute(ret->property_visible(), model.is_value_node);
-       column->add_attribute(ret->property_value_desc(), model.value_desc);
-       column->add_attribute(ret->property_canvas(), model.canvas);
-
-
-       return ret;
-}
diff --git a/synfig-studio/src/gui/canvastreestore.h b/synfig-studio/src/gui/canvastreestore.h
deleted file mode 100644 (file)
index faed8b6..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file canvastreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_CANVASTREESTORE_H
-#define __SYNFIG_STUDIO_CANVASTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfigapp/value_desc.h>
-#include <gtkmm/treeview.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class CellRenderer_TimeTrack;
-class CellRenderer_ValueBase;
-
-       enum ColumnID
-       {
-               COLUMNID_ID,
-               COLUMNID_VALUE,
-               COLUMNID_TIME_TRACK,
-               COLUMNID_TYPE,
-
-               COLUMNID_END                    //!< \internal
-       };
-#define        COLUMNID_NAME COLUMNID_ID
-
-class CanvasTreeStore : virtual public Gtk::TreeStore
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       class Model : public Gtk::TreeModel::ColumnRecord
-       {
-       public:
-               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
-               Gtk::TreeModelColumn<Glib::ustring> label;
-               Gtk::TreeModelColumn<Glib::ustring> name;
-               Gtk::TreeModelColumn<Glib::ustring> id;
-
-               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
-               Gtk::TreeModelColumn<bool> is_canvas;
-
-               Gtk::TreeModelColumn<synfig::ValueNode::Handle> value_node;
-               Gtk::TreeModelColumn<bool> is_value_node;
-               Gtk::TreeModelColumn<synfig::ValueBase> value;
-               Gtk::TreeModelColumn<Glib::ustring> type;
-               Gtk::TreeModelColumn<int> link_id;
-               Gtk::TreeModelColumn<int> link_count;
-
-               Gtk::TreeModelColumn<bool> is_editable;
-
-               Gtk::TreeModelColumn<bool> is_shared;
-               Gtk::TreeModelColumn<bool> is_exported;
-
-               Gtk::TreeModelColumn<synfigapp::ValueDesc> value_desc;
-
-               Gtk::TreeModelColumn<Glib::ustring> tooltip;
-
-               Model()
-               {
-                       add(value);
-                       add(name);
-                       add(label);
-                       add(icon);
-                       add(type);
-                       add(id);
-                       add(canvas);
-                       add(value_node);
-                       add(is_canvas);
-                       add(is_value_node);
-
-                       add(is_shared);
-                       add(is_exported);
-                       add(is_editable);
-                       add(value_desc);
-                       add(link_count);
-                       add(link_id);
-
-                       add(tooltip);
-               }
-       };
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       const Model model;
-
-       //std::multimap<etl::handle<ValueNode>, sigc::connection> connection_map;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-protected:
-       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-       ~CanvasTreeStore();
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
-       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
-
-       virtual void rebuild_row(Gtk::TreeModel::Row &row, bool do_children=true);
-
-       virtual void refresh_row(Gtk::TreeModel::Row &row, bool do_children=true);
-
-       virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children=true);
-
-       bool find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
-       bool find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
-
-       bool find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
-       bool find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
-
-
-       static CellRenderer_ValueBase* add_cell_renderer_value(Gtk::TreeView::Column* column);
-
-       static CellRenderer_TimeTrack* add_cell_renderer_value_node(Gtk::TreeView::Column* column);
-
-       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
-
-       virtual void on_value_node_changed(synfig::ValueNode::Handle value_node)=0;
-
-       /*
- -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
-       */
-
-public:
-
-}; // END of class CanvasTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
index d877c33..21a7f1d 100644 (file)
 #include "cellrenderer_timetrack.h"
 #include "app.h"
 
-#include "layertreestore.h"
-#include "layertree.h"
-#include "childrentreestore.h"
-#include "childrentree.h"
-#include "keyframetreestore.h"
-#include "keyframetree.h"
+#include "trees/layertreestore.h"
+#include "trees/layertree.h"
+#include "trees/childrentreestore.h"
+#include "trees/childrentree.h"
+#include "trees/keyframetreestore.h"
+#include "trees/keyframetree.h"
 
 #include "dialogs/dialog_waypoint.h"
 #include "dialogs/dialog_keyframe.h"
diff --git a/synfig-studio/src/gui/childrentree.cpp b/synfig-studio/src/gui/childrentree.cpp
deleted file mode 100644 (file)
index 01ef95e..0000000
+++ /dev/null
@@ -1,439 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file childrentree.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "childrentree.h"
-#include "cellrenderer_value.h"
-#include "cellrenderer_timetrack.h"
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include <gtkmm/scrolledwindow.h>
-#include <synfig/timepointcollect.h>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-#ifndef SMALL_BUTTON
-#define SMALL_BUTTON(button,stockid,tooltip)   \
-       button = manage(new class Gtk::Button());       \
-       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
-       button->add(*icon);     \
-       tooltips_.set_tip(*button,tooltip);     \
-       icon->set_padding(0,0);\
-       icon->show();   \
-       button->set_relief(Gtk::RELIEF_NONE); \
-       button->show()
-#endif
-
-#ifndef NORMAL_BUTTON
-#define NORMAL_BUTTON(button,stockid,tooltip)  \
-       button = manage(new class Gtk::Button());       \
-       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
-       button->add(*icon);     \
-       tooltips_.set_tip(*button,tooltip);     \
-       icon->set_padding(0,0);\
-       icon->show();   \
-       /*button->set_relief(Gtk::RELIEF_NONE);*/ \
-       button->show()
-#endif
-
-#define NEW_SMALL_BUTTON(x,y,z)        Gtk::Button *SMALL_BUTTON(x,y,z)
-
-#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-ChildrenTree::ChildrenTree()
-{
-       const ChildrenTreeStore::Model model;
-
-       {       // --- N A M E --------------------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ID")) );
-
-               // Set up the icon cell-renderer
-               Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
-               column->pack_start(*icon_cellrenderer,false);
-               column->add_attribute(icon_cellrenderer->property_pixbuf(), model.icon);
-
-               // Pack the label into the column
-               column->pack_start(model.label,true);
-
-               // Finish setting up the column
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable();
-               column->set_min_width(150);
-               column->set_sort_column(model.label);
-               tree_view.append_column(*column);
-
-       }
-       {       // --- T Y P E --------------------------------------------------------
-               int cols_count = tree_view.append_column(_("Type"),model.type);
-               Gtk::TreeViewColumn* column = tree_view.get_column(cols_count-1);
-               if(column)
-               {
-                       column->set_reorderable();
-                       column->set_resizable();
-                       column->set_clickable();
-                       column->set_sort_column(model.type);
-               }
-       }
-       {       // --- V A L U E  -----------------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
-
-               // Set up the value cell-renderer
-               cellrenderer_value=ChildrenTreeStore::add_cell_renderer_value(column);
-               cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_edited_value));
-               cellrenderer_value->property_value()=synfig::ValueBase();
-
-               // Finish setting up the column
-               tree_view.append_column(*column);
-               column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
-               column->set_min_width(150);
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable(false);
-       }
-       {       // --- T I M E   T R A C K --------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
-               column_time_track=column;
-
-               // Set up the value-node cell-renderer
-               cellrenderer_time_track=ChildrenTreeStore::add_cell_renderer_value_node(column);
-               cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
-               cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_waypoint_clicked_childrentree) );
-               column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
-               column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
-
-               //column->pack_start(*cellrenderer_time_track);
-
-               // Finish setting up the column
-               column->set_reorderable();
-               column->set_resizable();
-               tree_view.append_column(*column);
-       }
-
-       // This makes things easier to read.
-       tree_view.set_rules_hint();
-
-       // Make us more sensitive to several events
-       tree_view.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
-       tree_view.signal_event().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_event));
-
-       // Create a scrolled window for that tree
-       Gtk::ScrolledWindow *scroll_children_tree = manage(new class Gtk::ScrolledWindow());
-       scroll_children_tree->set_flags(Gtk::CAN_FOCUS);
-       scroll_children_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
-       scroll_children_tree->add(tree_view);
-       scroll_children_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
-       scroll_children_tree->show();
-
-       attach(*scroll_children_tree, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
-
-       hbox=manage(new Gtk::HBox());
-
-       attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-
-       tree_view.set_enable_search(true);
-       tree_view.set_search_column(model.label);
-
-/*  // Buttons to raise/lower/duplicate/delete children valuenodes
-       //   Commented out because these functions are not implemented
-    //   and children sort themselves alphabetically
-
-       Gtk::Image *icon;
-       //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
-       Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
-       SMALL_BUTTON(button_raise,"gtk-go-up",_("Raise"));
-       SMALL_BUTTON(button_lower,"gtk-go-down",_("Lower"));
-       SMALL_BUTTON(button_duplicate,"synfig-duplicate",_("Duplicate"));
-       SMALL_BUTTON(button_delete,"gtk-delete",_("Delete"));
-
-       hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
-       hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
-       hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
-       hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
-
-       button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_raise_pressed));
-       button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_lower_pressed));
-       button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_duplicate_pressed));
-       button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_delete_pressed));
-
-       button_raise->set_sensitive(false);
-       button_lower->set_sensitive(false);
-       button_duplicate->set_sensitive(false);
-       button_delete->set_sensitive(false);
-*/
-
-       get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_selection_changed));
-
-       tree_view.set_reorderable(true);
-
-       hbox->show();
-       tree_view.show();
-
-       tooltips_.enable();
-
-       //get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
-}
-
-ChildrenTree::~ChildrenTree()
-{
-}
-
-void
-ChildrenTree::set_show_timetrack(bool x)
-{
-       column_time_track->set_visible(x);
-}
-
-void
-ChildrenTree::set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store)
-{
-       children_tree_store_=children_tree_store;
-       tree_view.set_model(children_tree_store_);
-       cellrenderer_time_track->set_canvas_interface(children_tree_store_->canvas_interface()); // am I smart people?  (cellrenderer_timetrack.h:176)
-       children_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::ChildrenTree::on_dirty_preview));
-}
-
-void
-ChildrenTree::set_time_adjustment(Gtk::Adjustment &adjustment)
-{
-       cellrenderer_time_track->set_adjustment(adjustment);
-}
-
-void
-ChildrenTree::on_dirty_preview()
-{
-}
-
-void
-ChildrenTree::on_selection_changed()
-{
-       if(0)
-               {
-               button_raise->set_sensitive(false);
-               button_lower->set_sensitive(false);
-               button_duplicate->set_sensitive(false);
-               button_delete->set_sensitive(false);
-               return;
-       }
-}
-
-void
-ChildrenTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
-       row[model.value]=value;
-//     signal_edited_value()(row[model.value_desc],value);
-}
-
-void
-ChildrenTree::on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
-                                                                                          const synfig::Time& time __attribute__ ((unused)),
-                                                                                          const synfig::Time& time_offset __attribute__ ((unused)),
-                                                                                          int button __attribute__ ((unused)))
-{
-       std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
-       synfig::waypoint_collect(waypoint_set,time,node);
-
-       synfigapp::ValueDesc value_desc;
-
-       if (waypoint_set.size() == 1)
-       {
-               ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
-               assert(value_node);
-
-               Gtk::TreeRow row;
-               if (children_tree_store_->find_first_value_node(value_node, row) && row)
-                       value_desc = static_cast<synfigapp::ValueDesc>(row[model.value_desc]);
-       }
-
-       if (!waypoint_set.empty())
-               signal_waypoint_clicked_childrentree()(value_desc,waypoint_set,button);
-}
-
-bool
-ChildrenTree::on_tree_event(GdkEvent *event)
-{
-    switch(event->type)
-    {
-       case GDK_BUTTON_PRESS:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!tree_view.get_path_at_pos(
-                               int(event->button.x),int(event->button.y),      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-                       const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
-                       if(column->get_first_cell_renderer()==cellrenderer_time_track)
-                       {
-                               Gdk::Rectangle rect;
-                               tree_view.get_cell_area(path,*column,rect);
-                               cellrenderer_time_track->property_value_desc()=row[model.value_desc];
-                               cellrenderer_time_track->property_canvas()=row[model.canvas];
-                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
-                               queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
-                               return true;
-                       }
-                       else if(column->get_first_cell_renderer()==cellrenderer_value)
-                               return signal_user_click()(event->button.button,row,COLUMNID_VALUE);
-                       else
-                               return signal_user_click()(event->button.button,row,COLUMNID_ID);
-
-               }
-               break;
-
-       case GDK_MOTION_NOTIFY:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!tree_view.get_path_at_pos(
-                               (int)event->button.x,(int)event->button.y,      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-
-                       if(!tree_view.get_model()->get_iter(path))
-                               break;
-
-                       Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
-                       if(cellrenderer_time_track==column->get_first_cell_renderer())
-                       {
-                               // Movement on TimeLine
-                               Gdk::Rectangle rect;
-                               tree_view.get_cell_area(path,*column,rect);
-                               cellrenderer_time_track->property_value_desc()=row[model.value_desc];
-                               cellrenderer_time_track->property_canvas()=row[model.canvas];
-                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
-                               queue_draw();
-                               //queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
-                               return true;
-                       }
-                       else
-                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
-                       {
-                               tooltips_.unset_tip(*this);
-                               Glib::ustring tooltips_string(row[model.tooltip]);
-                               last_tooltip_path=path;
-                               if(!tooltips_string.empty())
-                               {
-                                       tooltips_.set_tip(*this,tooltips_string);
-                                       tooltips_.force_window();
-                               }
-                       }
-               }
-               break;
-       case GDK_BUTTON_RELEASE:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!tree_view.get_path_at_pos(
-                                  (int)event->button.x,(int)event->button.y,   // x, y
-                                  path, // TreeModel::Path&
-                                  column, //TreeViewColumn*&
-                                  cell_x,cell_y //int&cell_x,int&cell_y
-                                  )
-                               ) break;
-
-                       if(!tree_view.get_model()->get_iter(path))
-                               break;
-
-                       Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
-
-                       if(column && cellrenderer_time_track == column->get_first_cell_renderer())
-                       {
-                               Gdk::Rectangle rect;
-                               tree_view.get_cell_area(path,*column,rect);
-                               cellrenderer_time_track->property_value_desc()=row[model.value_desc];
-                               cellrenderer_time_track->property_canvas()=row[model.canvas];
-                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
-                               queue_draw();
-                               queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
-                               return true;
-                       }
-               }
-               break;
-       default:
-               break;
-       }
-       return false;
-}
-
-void
-ChildrenTree::on_raise_pressed()
-{
-}
-
-void
-ChildrenTree::on_lower_pressed()
-{
-}
-
-void
-ChildrenTree::on_duplicate_pressed()
-{
-}
-
-void
-ChildrenTree::on_delete_pressed()
-{
-}
diff --git a/synfig-studio/src/gui/childrentree.h b/synfig-studio/src/gui/childrentree.h
deleted file mode 100644 (file)
index 8584ed7..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file childrentree.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_CHILDRENTREE_H
-#define __SYNFIG_STUDIO_CHILDRENTREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <gtkmm/tooltips.h>
-#include <gtkmm/table.h>
-#include <gtkmm/box.h>
-#include <gtkmm/adjustment.h>
-#include <gtkmm/scale.h>
-#include <gtkmm/button.h>
-
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "childrentreestore.h"
-#include <synfig/valuenode_animated.h>
-
-#include "widgets/widget_value.h"
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class CellRenderer_TimeTrack;
-class CellRenderer_ValueBase;
-
-class ChildrenTree : public Gtk::Table
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       typedef studio::ColumnID ColumnID;
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       ChildrenTreeStore::Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       Gtk::Tooltips tooltips_;
-
-       Gtk::TreePath last_tooltip_path;
-
-       Gtk::TreeView tree_view;
-
-       Gtk::HBox *hbox;
-
-       Glib::RefPtr<ChildrenTreeStore> children_tree_store_;
-
-       CellRenderer_TimeTrack *cellrenderer_time_track;
-
-       Gtk::TreeView::Column* column_time_track;
-
-       CellRenderer_ValueBase *cellrenderer_value;
-
-       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
-
-       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_user_click_;
-
-       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_childrentree_;
-
-       Gtk::Button *button_raise;
-       Gtk::Button *button_lower;
-       Gtk::Button *button_duplicate;
-       Gtk::Button *button_delete;
-
-       Widget_ValueBase blend_method_widget;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
-
-       void on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node,const synfig::Time&,const synfig::Time&,int button);
-
-       bool on_tree_event(GdkEvent *event);
-
-       void on_selection_changed();
-
-       void on_dirty_preview();
-
-       //! \todo Implement raise/lower/duplicate/delete functions
-       void on_raise_pressed();
-
-       void on_lower_pressed();
-
-       void on_duplicate_pressed();
-
-       void on_delete_pressed();
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       Gtk::HBox& get_hbox() { return *hbox; }
-
-       Gtk::TreeView& get_tree_view() { return tree_view; }
-
-       Glib::RefPtr<Gtk::TreeSelection> get_selection() { return tree_view.get_selection(); }
-       Glib::SignalProxy1< bool,GdkEvent* >  signal_event () { return tree_view.signal_event(); }
-
-       ChildrenTree();
-       ~ChildrenTree();
-
-       void set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store_);
-
-       void set_time_adjustment(Gtk::Adjustment &adjustment);
-
-       void set_show_timetrack(bool x=true);
-
-       //! Signal called with a value has been edited.
-       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
-
-       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
-
-       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_childrentree() { return signal_waypoint_clicked_childrentree_; }
-
-       etl::handle<synfigapp::SelectionManager> get_selection_manager() { return children_tree_store_->canvas_interface()->get_selection_manager(); }
-
-}; // END of ChildrenTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/childrentreestore.cpp b/synfig-studio/src/gui/childrentreestore.cpp
deleted file mode 100644 (file)
index cf8798f..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file childrentreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "childrentreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include <ETL/clock>
-
-#include "general.h"
-
-class Profiler : private etl::clock
-{
-       const std::string name;
-public:
-       Profiler(const std::string& name):name(name) { reset(); }
-       ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
-};
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static ChildrenTreeStore::Model& ModelHack()
-{
-       static ChildrenTreeStore::Model* model(0);
-       if(!model)model=new ChildrenTreeStore::Model;
-       return *model;
-}
-
-ChildrenTreeStore::ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
-       Gtk::TreeStore                  (ModelHack()),
-       CanvasTreeStore                 (canvas_interface_)
-{
-       canvas_row=*append();
-       canvas_row[model.label]=_("Canvases");
-       canvas_row[model.is_canvas] = false;
-       canvas_row[model.is_value_node] = false;
-
-       value_node_row=*append();
-       value_node_row[model.label]=_("ValueBase Nodes");
-       value_node_row[model.is_canvas] = false;
-       value_node_row[model.is_value_node] = false;
-
-       // Connect all the signals
-       canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_changed));
-       canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_renamed));
-       canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_added));
-       canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_deleted));
-       canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_replaced));
-       canvas_interface()->signal_canvas_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_added));
-       canvas_interface()->signal_canvas_removed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_removed));
-
-       rebuild();
-}
-
-ChildrenTreeStore::~ChildrenTreeStore()
-{
-}
-
-Glib::RefPtr<ChildrenTreeStore>
-ChildrenTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
-       return Glib::RefPtr<ChildrenTreeStore>(new ChildrenTreeStore(canvas_interface_));
-}
-
-void
-ChildrenTreeStore::rebuild()
-{
-       // Profiler profiler("ChildrenTreeStore::rebuild()");
-       rebuild_value_nodes();
-       rebuild_canvases();
-}
-
-void
-ChildrenTreeStore::refresh()
-{
-       // Profiler profiler("ChildrenTreeStore::refresh()");
-       refresh_value_nodes();
-       refresh_canvases();
-}
-
-void
-ChildrenTreeStore::rebuild_value_nodes()
-{
-       Gtk::TreeModel::Children children(value_node_row.children());
-
-       while(!children.empty())erase(children.begin());
-
-       clear_changed_queue();
-
-       std::for_each(
-               canvas_interface()->get_canvas()->value_node_list().rbegin(), canvas_interface()->get_canvas()->value_node_list().rend(),
-               sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_value_node_added)
-       );
-}
-
-void
-ChildrenTreeStore::refresh_value_nodes()
-{
-       Gtk::TreeModel::Children children(value_node_row.children());
-
-       Gtk::TreeModel::Children::iterator iter;
-
-       if(!children.empty())
-               for(iter = children.begin(); iter != children.end(); ++iter)
-               {
-                       Gtk::TreeRow row=*iter;
-                       refresh_row(row);
-               }
-}
-
-void
-ChildrenTreeStore::rebuild_canvases()
-{
-       Gtk::TreeModel::Children children(canvas_row.children());
-
-       while(!children.empty())erase(children.begin());
-
-       std::for_each(
-               canvas_interface()->get_canvas()->children().rbegin(), canvas_interface()->get_canvas()->children().rend(),
-               sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_canvas_added)
-       );
-}
-
-void
-ChildrenTreeStore::refresh_canvases()
-{
-       rebuild_canvases();
-}
-
-void
-ChildrenTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool /*do_children*/)
-{
-       CanvasTreeStore::refresh_row(row,false);
-
-       if((bool)row[model.is_value_node])
-       {
-               changed_set_.erase(row[model.value_node]);
-       }
-
-}
-
-void
-ChildrenTreeStore::on_canvas_added(synfig::Canvas::Handle canvas)
-{
-       Gtk::TreeRow row = *(prepend(canvas_row.children()));
-
-       row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-       row[model.id] = canvas->get_id();
-       row[model.name] = canvas->get_name();
-
-       if(!canvas->get_id().empty())
-               row[model.label] = canvas->get_id();
-       else
-       if(!canvas->get_name().empty())
-               row[model.label] = canvas->get_name();
-       else
-               row[model.label] = _("[Unnamed]");
-
-       row[model.canvas] = canvas;
-       row[model.type] = _("Canvas");
-       //row[model.is_canvas] = true;
-       //row[model.is_value_node] = false;
-}
-
-void
-ChildrenTreeStore::on_canvas_removed(synfig::Canvas::Handle /*canvas*/)
-{
-       rebuild_canvases();
-}
-
-void
-ChildrenTreeStore::on_value_node_added(synfig::ValueNode::Handle value_node)
-{
-//     if(value_node->get_id().find("Unnamed")!=String::npos)
-//             return;
-
-       Gtk::TreeRow row = *prepend(value_node_row.children());
-
-       set_row(row,synfigapp::ValueDesc(canvas_interface()->get_canvas(),value_node->get_id()),false);
-}
-
-void
-ChildrenTreeStore::on_value_node_deleted(synfig::ValueNode::Handle value_node)
-{
-       Gtk::TreeIter iter;
-       //int i(0);
-
-       if(find_first_value_node(value_node,iter))
-       {
-               erase(iter);
-       }
-       //rebuild_value_nodes();
-}
-
-bool
-ChildrenTreeStore::execute_changed_value_nodes()
-{
-       // Profiler profiler("ChildrenTreeStore::execute_changed_value_nodes()");
-       if(!replaced_set_.empty())
-               rebuild_value_nodes();
-
-       etl::clock timer;
-       timer.reset();
-
-       while(!changed_set_.empty())
-       {
-               ValueNode::Handle value_node(*changed_set_.begin());
-               changed_set_.erase(value_node);
-
-               Gtk::TreeIter iter;
-
-               try
-               {
-                       Gtk::TreeIter iter;
-                       int i(0);
-
-                       if(!value_node->is_exported() && find_first_value_node(value_node,iter))
-                       {
-                               rebuild_value_nodes();
-                               continue;
-                       }
-
-                       if(value_node->is_exported() && find_first_value_node(value_node,iter)) do
-                       {
-                               Gtk::TreeRow row(*iter);
-                               i++;
-                               refresh_row(row);
-                       }while(find_next_value_node(value_node,iter));
-
-                       if(!i)
-                       {
-                               refresh_value_nodes();
-                               return false;
-                       }
-
-               }
-               catch(...)
-               {
-                       rebuild_value_nodes();
-                       return false;
-               }
-
-               // If we are taking too long...
-               if(timer()>4)
-               {
-                       refresh_value_nodes();
-                       return false;
-               }
-       }
-
-       return false;
-}
-
-void
-ChildrenTreeStore::on_value_node_changed(synfig::ValueNode::Handle value_node)
-{
-
-       if(!value_node->is_exported())
-               return;
-       changed_connection.disconnect();
-//     if(!execute_changed_queued())
-//             changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
-       changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
-
-       changed_set_.insert(value_node);
-       /*
-       try
-       {
-               Gtk::TreeIter iter;
-               int i(0);
-               while(find_next_value_node(value_node,iter))
-               {
-                       Gtk::TreeRow row(*iter);
-                       i++;
-                       refresh_row(row);
-               }
-               if(!i)
-               {
-                       refresh_value_nodes();
-               }
-       }
-       catch(...)
-       {
-               rebuild_value_nodes();
-       }
-       */
-}
-
-void
-ChildrenTreeStore::on_value_node_renamed(synfig::ValueNode::Handle value_node __attribute__ ((unused)))
-{
-       rebuild_value_nodes();
-}
-
-void
-ChildrenTreeStore::on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle /*new_value_node*/)
-{
-       changed_connection.disconnect();
-       //if(!execute_changed_queued())
-//             changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
-               changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
-
-       replaced_set_.insert(replaced_value_node);
-}
-
-void
-ChildrenTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
-       if(column>=get_n_columns_vfunc())
-       {
-               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
-               return;
-       }
-
-       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
-       {
-               g_warning("LayerTreeStore::set_value_impl: Bad value type");
-               return;
-       }
-
-       try
-       {
-               if(column==model.value.index())
-               {
-                       Glib::Value<synfig::ValueBase> x;
-                       g_value_init(x.gobj(),model.value.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-                       if(value_desc)
-                       {
-                               canvas_interface()->change_value(value_desc,x.get());
-                               row_changed(get_path(*iter),*iter);
-                       }
-
-                       return;
-               }
-               else
-                       CanvasTreeStore::set_value_impl(iter,column, value);
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
diff --git a/synfig-studio/src/gui/childrentreestore.h b/synfig-studio/src/gui/childrentreestore.h
deleted file mode 100644 (file)
index 5d0412a..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file childrentreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_CHILDRENTREESTORE_H
-#define __SYNFIG_STUDIO_CHILDRENTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include "canvastreestore.h"
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <set>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class ChildrenTreeStore : public CanvasTreeStore
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       //! TreeModel for the layers
-       const Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       Gtk::TreeModel::Row value_node_row;
-       Gtk::TreeModel::Row canvas_row;
-
-       std::set<synfig::ValueNode::Handle> changed_set_;
-
-       std::set<synfig::ValueNode::Handle> replaced_set_;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       sigc::connection changed_connection;
-       bool execute_changed_queued()const { return !changed_set_.empty() || !replaced_set_.empty(); }
-       bool execute_changed_value_nodes();
-       void clear_changed_queue() { changed_set_.clear(); replaced_set_.clear(); }
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       void on_value_node_added(synfig::ValueNode::Handle value_node);
-       void on_value_node_deleted(synfig::ValueNode::Handle value_node);
-       void on_value_node_changed(synfig::ValueNode::Handle value_node);
-       void on_value_node_renamed(synfig::ValueNode::Handle value_node);
-       void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
-       void on_canvas_added(synfig::Canvas::Handle canvas);
-       void on_canvas_removed(synfig::Canvas::Handle canvas);
-
-       void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-       ~ChildrenTreeStore();
-
-       void rebuild();
-
-       void refresh();
-
-       void rebuild_value_nodes();
-
-       void refresh_value_nodes();
-
-       void rebuild_canvases();
-
-       void refresh_canvases();
-
-       void refresh_row(Gtk::TreeModel::Row &row, bool do_children=false);
-
-       Gtk::TreeModel::Row get_canvas_row()const { return canvas_row; }
-
-       Gtk::TreeModel::Row get_value_node_row()const { return value_node_row; }
-
-       /*
- -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
-       */
-
-public:
-
-       static Glib::RefPtr<ChildrenTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-}; // END of class ChildrenTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
index 25e48eb..434b6bf 100644 (file)
@@ -36,7 +36,7 @@
 #include <gtkmm/label.h>
 #include <gtkmm/alignment.h>
 #include <synfigapp/canvasinterface.h>
-#include "metadatatreestore.h"
+#include "trees/metadatatreestore.h"
 #include <gtkmm/treeview.h>
 #include <gtkmm/scrolledwindow.h>
 #include "app.h"
index 1ef3a47..64f81e5 100644 (file)
@@ -39,7 +39,6 @@
 #include <sigc++/adaptors/hide.h>
 //#include <sigc++/hide.h>
 #include <sigc++/slot.h>
-#include "metadatatreestore.h"
 #include "canvasview.h"
 #include <ETL/clock>
 
index eaa6365..798049c 100644 (file)
@@ -40,8 +40,8 @@
 #include <sigc++/hide.h>
 #include <sigc++/retype_return.h>
 #include <sigc++/slot.h>
-#include "childrentreestore.h"
-#include "childrentree.h"
+#include "trees/childrentreestore.h"
+#include "trees/childrentree.h"
 #include "canvasview.h"
 
 #include "general.h"
index 4d1d97d..a436b68 100644 (file)
 #include <sigc++/hide.h>
 #include <sigc++/slot.h>
 #include "canvasview.h"
-#include "layerparamtreestore.h"
+#include "trees/layerparamtreestore.h"
 #include "workarea.h"
 #include "widgets/widget_curves.h"
-#include "layerparamtreestore.h"
 #include <gtkmm/table.h>
 #include <gtkmm/scrollbar.h>
 #include "widgets/widget_timeslider.h"
index 6ee6e51..5d477c6 100644 (file)
@@ -42,7 +42,7 @@
 #include <sigc++/hide.h>
 #include <sigc++/slot.h>
 #include <synfigapp/action.h>
-#include "historytreestore.h"
+#include "trees/historytreestore.h"
 
 #include "general.h"
 
index e741bbf..c05b92c 100644 (file)
@@ -38,8 +38,8 @@
 #include <sigc++/signal.h>
 #include <sigc++/hide.h>
 #include <sigc++/slot.h>
-#include "keyframetreestore.h"
-#include "keyframetree.h"
+#include "trees/keyframetreestore.h"
+#include "trees/keyframetree.h"
 #include "canvasview.h"
 #include "keyframeactionmanager.h"
 
index 8306a8e..03daeaf 100644 (file)
@@ -41,8 +41,8 @@
 #include <sigc++/slot.h>
 #include "canvasview.h"
 
-#include "layergrouptreestore.h"
-#include "layergrouptree.h"
+#include "trees/layergrouptreestore.h"
+#include "trees/layergrouptree.h"
 #include "groupactionmanager.h"
 
 #include "general.h"
index 152ffb1..df0e4af 100644 (file)
@@ -40,8 +40,8 @@
 #include <sigc++/hide.h>
 #include <sigc++/retype_return.h>
 #include <sigc++/slot.h>
-#include "layertreestore.h"
-#include "layertree.h"
+#include "trees/layertreestore.h"
+#include "trees/layertree.h"
 #include "canvasview.h"
 #include "layeractionmanager.h"
 //#include <ETL/ref_count>
index 5fe09f9..69dad23 100644 (file)
@@ -38,7 +38,7 @@
 #include <sigc++/signal.h>
 #include <sigc++/hide.h>
 #include <sigc++/slot.h>
-#include "metadatatreestore.h"
+#include "trees/metadatatreestore.h"
 #include "canvasview.h"
 
 #include "general.h"
index 79b965e..7494ca7 100644 (file)
@@ -39,7 +39,7 @@
 #include <sigc++/hide.h>
 #include <sigc++/slot.h>
 #include "canvasview.h"
-#include "layerparamtreestore.h"
+#include "trees/layerparamtreestore.h"
 #include "workarea.h"
 
 #include "general.h"
index 61ba14d..adb8998 100644 (file)
 #include <sigc++/hide.h>
 #include <sigc++/slot.h>
 #include "canvasview.h"
-#include "layerparamtreestore.h"
+#include "trees/layerparamtreestore.h"
 #include "workarea.h"
 #include "widgets/widget_timeslider.h"
 #include "widgets/widget_keyframe_list.h"
-#include "layerparamtreestore.h"
 #include "general.h"
 #include <synfig/timepointcollect.h>
 
index 54eab18..2d77407 100644 (file)
@@ -31,7 +31,7 @@
 #endif
 
 #include "groupactionmanager.h"
-#include "layergrouptree.h"
+#include "trees/layergrouptree.h"
 #include <synfigapp/action_param.h>
 #include "instance.h"
 #include <gtkmm/stock.h>
diff --git a/synfig-studio/src/gui/historytreestore.cpp b/synfig-studio/src/gui/historytreestore.cpp
deleted file mode 100644 (file)
index 1f0eb9c..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file historytreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "historytreestore.h"
-#include <synfig/valuenode.h>
-#include "iconcontroller.h"
-#include <synfig/valuenode_timedswap.h>
-#include <gtkmm/button.h>
-#include <synfigapp/action.h>
-#include "instance.h"
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static HistoryTreeStore::Model& ModelHack()
-{
-       static HistoryTreeStore::Model* model(0);
-       if(!model)model=new HistoryTreeStore::Model;
-       return *model;
-}
-
-HistoryTreeStore::HistoryTreeStore(etl::loose_handle<studio::Instance> instance_):
-       Gtk::TreeStore  (ModelHack()),
-       instance_               (instance_)
-{
-       instance_->signal_undo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo));
-       instance_->signal_redo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo));
-       instance_->signal_undo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo_stack_cleared));
-       instance_->signal_redo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo_stack_cleared));
-       instance_->signal_new_action().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_new_action));
-       instance_->signal_action_status_changed().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_action_status_changed));
-}
-
-HistoryTreeStore::~HistoryTreeStore()
-{
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("HistoryTreeStore::~HistoryTreeStore(): Deleted");
-}
-
-Glib::RefPtr<HistoryTreeStore>
-HistoryTreeStore::create(etl::loose_handle<studio::Instance> instance_)
-{
-       return Glib::RefPtr<HistoryTreeStore>(new HistoryTreeStore(instance_));
-}
-
-void
-HistoryTreeStore::rebuild()
-{
-       synfigapp::Action::Stack::const_iterator iter;
-
-       clear();
-
-       for(iter=instance()->undo_action_stack().begin();iter!=instance()->undo_action_stack().end();++iter)
-       {
-               insert_action(*(prepend()),*iter,true,true,false);
-       }
-       curr_row=*children().end();
-       for(iter=instance()->redo_action_stack().begin();iter!=instance()->redo_action_stack().end();++iter)
-       {
-               insert_action(*(append()),*iter,true,false,true);
-       }
-
-       signal_undo_tree_changed()();
-}
-
-void
-HistoryTreeStore::insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool /*is_active*/, bool is_undo, bool is_redo)
-{
-       assert(action);
-
-       row[model.action] = action;
-       row[model.name] = static_cast<Glib::ustring>(action->get_local_name());
-       row[model.is_active] = action->is_active();
-       row[model.is_undo] = is_undo;
-       row[model.is_redo] = is_redo;
-
-       synfigapp::Action::CanvasSpecific *specific_action;
-       specific_action=dynamic_cast<synfigapp::Action::CanvasSpecific*>(action.get());
-       if(specific_action)
-       {
-               row[model.canvas] = specific_action->get_canvas();
-               row[model.canvas_id] = specific_action->get_canvas()->get_id();
-       }
-
-       etl::handle<synfigapp::Action::Group> group;
-       group=etl::handle<synfigapp::Action::Group>::cast_dynamic(action);
-       if(group)
-       {
-               synfigapp::Action::ActionList::const_iterator iter;
-               for(iter=group->action_list().begin();iter!=group->action_list().end();++iter)
-               {
-                       Gtk::TreeRow child_row = *(append(row.children()));
-                       insert_action(child_row,*iter,true,is_undo,is_redo);
-               }
-       }
-
-       //row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-}
-
-
-void
-HistoryTreeStore::on_undo()
-{
-       refresh();
-}
-
-void
-HistoryTreeStore::on_redo()
-{
-       refresh();
-}
-
-void
-HistoryTreeStore::on_undo_stack_cleared()
-{
-       Gtk::TreeModel::Children::iterator iter,next;
-       Gtk::TreeModel::Children children_(children());
-
-       for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
-       {
-               Gtk::TreeModel::Row row = *iter;
-               if(row[model.is_undo])
-                       erase(iter);
-       }
-}
-
-void
-HistoryTreeStore::on_redo_stack_cleared()
-{
-       Gtk::TreeModel::Children::iterator iter,next;
-       Gtk::TreeModel::Children children_(children());
-
-       for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
-       {
-               Gtk::TreeModel::Row row = *iter;
-               if(row[model.is_redo])
-                       erase(iter);
-       }
-}
-
-void
-HistoryTreeStore::on_new_action(etl::handle<synfigapp::Action::Undoable> action)
-{
-//     Gtk::TreeRow row = *(append());
-       Gtk::TreeRow row;
-       Gtk::TreeModel::Children::iterator iter;
-       for(iter=children().begin(); iter != children().end(); ++iter)
-       {
-               Gtk::TreeModel::Row row = *iter;
-               if(row[model.is_redo])
-               {
-                       break;
-               }
-       }
-
-       row=*insert(iter);
-
-       insert_action(row,action);
-
-       signal_undo_tree_changed()();
-}
-
-void
-HistoryTreeStore::on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       Gtk::TreeModel::Children children_(children());
-
-       for(iter=children_.begin(); iter != children_.end(); ++iter)
-       {
-               Gtk::TreeModel::Row row = *iter;
-               if(action == (etl::handle<synfigapp::Action::Undoable>)row[model.action])
-               {
-                       row[model.is_active]=action->is_active();
-                       return;
-               }
-       }
-}
-
-bool
-HistoryTreeStore::search_func(const Glib::RefPtr<Gtk::TreeModel>&,int,const Glib::ustring& x,const Gtk::TreeModel::iterator& iter)
-{
-       const Model model;
-
-       Glib::ustring substr(x.uppercase());
-       Glib::ustring name((*iter)[model.name]);
-       name=name.uppercase();
-
-       return name.find(substr)==Glib::ustring::npos;
-}
diff --git a/synfig-studio/src/gui/historytreestore.h b/synfig-studio/src/gui/historytreestore.h
deleted file mode 100644 (file)
index 31a4b13..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file historytreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_HISTORYTREESTORE_H
-#define __SYNFIG_STUDIO_HISTORYTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfigapp/action.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class Instance;
-
-class HistoryTreeStore : virtual public Gtk::TreeStore
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       class Model : public Gtk::TreeModel::ColumnRecord
-       {
-       public:
-       public:
-               Gtk::TreeModelColumn<etl::handle<synfigapp::Action::Undoable> > action;
-               Gtk::TreeModelColumn<Glib::ustring> name;
-               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
-               Gtk::TreeModelColumn<bool> is_active;
-               Gtk::TreeModelColumn<bool> is_undo;
-               Gtk::TreeModelColumn<bool> is_redo;
-
-               Gtk::TreeModelColumn<Glib::ustring> canvas_id;
-               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
-
-               Model()
-               {
-                       add(action);
-                       add(name);
-                       add(icon);
-                       add(is_active);
-                       add(is_undo);
-                       add(is_redo);
-                       add(canvas_id);
-                       add(canvas);
-               }
-       };
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       const Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       etl::loose_handle<studio::Instance> instance_;
-       Gtk::TreeIter curr_row;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       sigc::signal<void> signal_undo_tree_changed_;
-
-       /*
- -- ** -- S I G N A L   I N T E R F A C E S -----------------------------------
-       */
-
-public:
-
-       sigc::signal<void>& signal_undo_tree_changed() { return signal_undo_tree_changed_; }
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       void on_undo();
-
-       void on_redo();
-
-       void on_undo_stack_cleared();
-
-       void on_redo_stack_cleared();
-
-       void on_new_action(etl::handle<synfigapp::Action::Undoable> action);
-
-       void on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action);
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       HistoryTreeStore(etl::loose_handle<studio::Instance> instance_);
-       ~HistoryTreeStore();
-
-       etl::loose_handle<studio::Instance> instance() { return instance_; }
-       etl::loose_handle<const studio::Instance> instance()const { return instance_; }
-
-       void rebuild();
-
-       void refresh() { rebuild(); }
-
-       void insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool is_active=true, bool is_undo=true, bool is_redo=false);
-
-       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
-
-       /*
- -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
-       */
-
-public:
-
-       static Glib::RefPtr<HistoryTreeStore> create(etl::loose_handle<studio::Instance> instance);
-
-}; // END of class HistoryTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
index 16842c1..6536c86 100644 (file)
@@ -34,7 +34,7 @@
 #include <synfigapp/instance.h>
 #include <sigc++/object.h>
 #include <synfigapp/value_desc.h>
-#include "historytreestore.h"
+#include "trees/historytreestore.h"
 #include <synfig/canvas.h>
 
 /* === M A C R O S ========================================================= */
index aaddf1f..906591b 100644 (file)
@@ -31,7 +31,7 @@
 #endif
 
 #include "keyframeactionmanager.h"
-#include "keyframetree.h"
+#include "trees/keyframetree.h"
 #include <synfigapp/action_param.h>
 #include "instance.h"
 
diff --git a/synfig-studio/src/gui/keyframetree.cpp b/synfig-studio/src/gui/keyframetree.cpp
deleted file mode 100644 (file)
index e480292..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file keyframetree.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "keyframetree.h"
-#include "cellrenderer_time.h"
-#include <gtkmm/treemodelsort.h>
-#include <ETL/misc>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-KeyframeTree::KeyframeTree()
-{
-       const KeyframeTreeStore::Model model;
-
-       {
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time")) );
-
-               cell_renderer_time = Gtk::manage( new CellRenderer_Time() );
-               column->pack_start(*cell_renderer_time,true);
-               column->add_attribute(cell_renderer_time->property_time(), model.time);
-               cell_renderer_time->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time));
-
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable();
-               column->set_sort_column(model.time);
-
-               append_column(*column);
-       }
-       {
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Length")) );
-
-               cell_renderer_time_delta = Gtk::manage( new CellRenderer_Time() );
-               column->pack_start(*cell_renderer_time_delta,true);
-               column->add_attribute(cell_renderer_time_delta->property_time(), model.time_delta);
-               cell_renderer_time_delta->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time_delta));
-
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable(false);
-               // column->set_sort_column(model.time_delta);
-
-               append_column(*column);
-       }
-       {
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Jump")) );
-
-               Gtk::CellRendererText* cell_renderer_jump=Gtk::manage(new Gtk::CellRendererText());
-               column->pack_start(*cell_renderer_jump,true);
-               cell_renderer_jump->property_text()=_("(JMP)");
-               cell_renderer_jump->property_foreground()="#003a7f";
-
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable(false);
-               column->set_sort_column(COLUMNID_JUMP); // without this, (JMP) needs a double click?!
-
-               append_column(*column);
-       }
-       {
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Description")) );
-
-               cell_renderer_description=Gtk::manage(new Gtk::CellRendererText());
-               column->pack_start(*cell_renderer_description,true);
-               column->add_attribute(cell_renderer_description->property_text(), model.description);
-               cell_renderer_description->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_description));
-
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable();
-               column->set_sort_column(model.description);
-
-               append_column(*column);
-       }
-
-       set_enable_search(true);
-       set_search_column(model.description);
-
-       // This makes things easier to read.
-       set_rules_hint();
-
-       // Make us more sensitive to several events
-       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
-}
-
-KeyframeTree::~KeyframeTree()
-{
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("KeyframeTree::~KeyframeTree(): Deleted");
-}
-
-void
-KeyframeTree::on_rend_desc_changed()
-{
-       cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
-       queue_draw();
-}
-
-void
-KeyframeTree::set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store)
-{
-       keyframe_tree_store_=keyframe_tree_store;
-       KeyframeTreeStore::Model model;
-
-       if(true)
-       {
-               Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(keyframe_tree_store_));
-               sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
-               sorted_store->set_sort_func(model.time,                 sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
-               sorted_store->set_sort_func(model.description,  sigc::ptr_fun(&studio::KeyframeTreeStore::description_sorter));
-               Gtk::TreeView::set_model(sorted_store);
-       }
-       else
-               Gtk::TreeView::set_model(keyframe_tree_store);
-
-       keyframe_tree_store_->canvas_interface()->signal_rend_desc_changed().connect(
-               sigc::mem_fun(
-                       *this,
-                       &studio::KeyframeTree::on_rend_desc_changed
-               )
-       );
-       cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
-       cell_renderer_time_delta->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
-}
-
-void
-KeyframeTree::set_editable(bool x)
-{
-       editable_=x;
-
-       if(editable_)
-       {
-               cell_renderer_time->property_editable()=true;
-               cell_renderer_time_delta->property_editable()=true;
-               cell_renderer_description->property_editable()=true;
-       }
-       else
-       {
-               cell_renderer_time->property_editable()=false;
-               cell_renderer_time_delta->property_editable()=false;
-               cell_renderer_description->property_editable()=false;
-       }
-}
-
-void
-KeyframeTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
-       synfig::Keyframe keyframe(row[model.keyframe]);
-       if(time!=keyframe.get_time())
-       {
-               row[model.time]=time;
-               //keyframe.set_time(time);
-               //signal_edited_time()(keyframe,time);
-               //signal_edited()(keyframe);
-       }
-}
-
-void
-KeyframeTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
-       if(row)row[model.time_delta]=time;
-}
-
-void
-KeyframeTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
-       const synfig::String description(desc);
-       synfig::Keyframe keyframe(row[model.keyframe]);
-       if(description!=keyframe.get_description())
-       {
-               row[model.description]=desc;
-               keyframe.set_description(description);
-               signal_edited_description()(keyframe,description);
-               signal_edited()(keyframe);
-       }
-}
-
-bool
-KeyframeTree::on_event(GdkEvent *event)
-{
-    switch(event->type)
-    {
-       case GDK_BUTTON_PRESS:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
-                       //tree_to_widget_coords (,, wx, wy);
-                       if(!get_path_at_pos(
-                               wx,wy,  // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
-                       signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
-                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
-                       {
-                               keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
-                       }
-               }
-               break;
-       case GDK_2BUTTON_PRESS:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!get_path_at_pos(
-                               int(event->button.x),int(event->button.y),      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
-                       {
-                               keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
-                               return true;
-                       }
-               }
-               break;
-
-       case GDK_BUTTON_RELEASE:
-               break;
-       default:
-               break;
-       }
-       return false;
-}
diff --git a/synfig-studio/src/gui/keyframetree.h b/synfig-studio/src/gui/keyframetree.h
deleted file mode 100644 (file)
index 31d820e..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file keyframetree.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_KEYFRAMETREE_H
-#define __SYNFIG_STUDIO_KEYFRAMETREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "keyframetreestore.h"
-#include <synfig/keyframe.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class CellRenderer_Time;
-
-class KeyframeTree : public Gtk::TreeView
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       enum ColumnID
-       {
-               COLUMNID_TIME,
-               COLUMNID_DESCRIPTION,
-               COLUMNID_JUMP,
-
-               COLUMNID_END                    //!< \internal
-       };
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       KeyframeTreeStore::Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_;
-
-       CellRenderer_Time *cell_renderer_time;
-
-       CellRenderer_Time *cell_renderer_time_delta;
-
-       Gtk::CellRendererText *cell_renderer_description;
-
-       sigc::signal<void,synfig::Keyframe> signal_edited_;
-
-       sigc::signal<void,synfig::Keyframe,synfig::Time> signal_edited_time_;
-
-       sigc::signal<void,synfig::Keyframe,synfig::String> signal_edited_description_;
-
-       sigc::signal<void, int, Gtk::TreeRow, ColumnID> signal_user_click_;
-
-       bool editable_;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       void on_edited_time(const Glib::ustring&path_string,synfig::Time time);
-
-       void on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time);
-
-       void on_edited_description(const Glib::ustring&path_string,const Glib::ustring &description);
-
-       bool on_event(GdkEvent *event);
-
-       void on_rend_desc_changed();
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       KeyframeTree();
-       ~KeyframeTree();
-
-       void set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_);
-
-       void set_editable(bool x=true);
-
-       bool get_editable()const { return editable_; }
-
-       //! Signal called when a keyframe has been edited in any way
-       sigc::signal<void,synfig::Keyframe>& signal_edited() { return signal_edited_; }
-
-       //! Signal called when a time has been edited.
-       sigc::signal<void,synfig::Keyframe,synfig::Time>& signal_edited_time() { return signal_edited_time_; }
-
-       //! Signal called when a description has been edited.
-       sigc::signal<void,synfig::Keyframe,synfig::String>& signal_edited_description() { return signal_edited_description_; }
-
-       sigc::signal<void,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
-}; // END of KeyframeTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/keyframetreestore.cpp b/synfig-studio/src/gui/keyframetreestore.cpp
deleted file mode 100644 (file)
index 4e84001..0000000
+++ /dev/null
@@ -1,901 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file keyframetreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007, 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "keyframetreestore.h"
-#include <synfig/valuenode.h>
-#include "iconcontroller.h"
-#include <synfig/valuenode_timedswap.h>
-#include <gtkmm/button.h>
-#include <gtkmm/treerowreference.h>
-#include <synfig/canvas.h>
-#include <synfig/keyframe.h>
-#include <time.h>
-#include <cstdlib>
-#include <ETL/smart_ptr>
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include "onemoment.h"
-#include <synfig/exception.h>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-// KeyframeTreeStore_Class KeyframeTreeStore::keyframe_tree_store_class_;
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-struct _keyframe_iterator
-{
-       synfig::KeyframeList::iterator iter;
-       int ref_count;
-       int index;
-};
-
-/*
-Gtk::TreeModel::iterator keyframe_iter_2_model_iter(synfig::KeyframeList::iterator iter,int index)
-{
-       Gtk::TreeModel::iterator ret;
-
-       _keyframe_iterator*& data(static_cast<_keyframe_iterator*&>(ret->gobj()->user_data));
-       data=new _keyframe_iterator();
-       data->ref_count=1;
-       data->iter=iter;
-       data->index=index;
-
-       return ret;
-}
-*/
-
-synfig::KeyframeList::iterator model_iter_2_keyframe_iter(Gtk::TreeModel::iterator iter)
-{
-       _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
-       if(!data)
-               throw std::runtime_error("bad data");
-       return data->iter;
-}
-
-int get_index_from_model_iter(Gtk::TreeModel::iterator iter)
-{
-       _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
-       if(!data)
-               throw std::runtime_error("bad data");
-       return data->index;
-}
-
-
-/*
-#ifndef TreeRowReferenceHack
-class TreeRowReferenceHack
-{
-       GtkTreeRowReference *gobject_;
-public:
-       TreeRowReferenceHack():
-               gobject_(0)
-       {
-       }
-
-       TreeRowReferenceHack(const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path):
-               gobject_ ( gtk_tree_row_reference_new(model->gobj(), const_cast<GtkTreePath*>(path.gobj())) )
-       {
-       }
-
-       TreeRowReferenceHack(const TreeRowReferenceHack &x):
-               gobject_ ( x.gobject_?gtk_tree_row_reference_copy(x.gobject_):0 )
-       {
-
-       }
-
-       void swap(TreeRowReferenceHack & other)
-       {
-               GtkTreeRowReference *const temp = gobject_;
-               gobject_ = other.gobject_;
-               other.gobject_ = temp;
-       }
-
-       const TreeRowReferenceHack &
-       operator=(const TreeRowReferenceHack &rhs)
-       {
-               TreeRowReferenceHack temp (rhs);
-               swap(temp);
-               return *this;
-       }
-
-       ~TreeRowReferenceHack()
-       {
-               if(gobject_)
-                       gtk_tree_row_reference_free(gobject_);
-       }
-
-       Gtk::TreeModel::Path get_path() { return Gtk::TreeModel::Path(gtk_tree_row_reference_get_path(gobject_),false); }
-       GtkTreeRowReference *gobj() { return gobject_; }
-};
-#endif
-*/
-
-/* === P R O C E D U R E S ================================================= */
-
-void clear_iterator(GtkTreeIter* iter)
-{
-       iter->stamp=0;
-       iter->user_data=iter->user_data2=iter->user_data3=0;
-}
-
-/* === M E T H O D S ======================================================= */
-
-const Glib::Class&
-KeyframeTreeStore_Class::init()
-{
-       if(!gtype_)
-       {
-               class_init_func_ = &KeyframeTreeStore_Class::class_init_function;
-
-               const GTypeInfo derived_info =
-               {
-                       sizeof(GObjectClass),
-                       NULL,
-                       NULL,
-                       class_init_func_,
-                       NULL,
-                       NULL,
-                       sizeof(GObject),
-                       0,
-                       0,
-                       NULL
-               };
-
-               gtype_ = g_type_register_static(G_TYPE_OBJECT, "KeyframeTreeStore", &derived_info, GTypeFlags(0));
-               Gtk::TreeModel::add_interface(get_type());
-       }
-       return *this;
-}
-
-void
-KeyframeTreeStore_Class::class_init_function(gpointer /*g_class*/, gpointer /*class_data*/)
-{
-       // ???
-}
-
-KeyframeTreeStore::KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
-       Glib::ObjectBase        ("KeyframeTreeStore"),
-       //! \todo what is going on here?  why the need for this KeyframeTreeStore_Class at all?
-       // Glib::Object         (Glib::ConstructParams(keyframe_tree_store_class_.init(), (char*) 0, (char*) 0)),
-       canvas_interface_       (canvas_interface_)
-{
-       reset_stamp();
-       //reset_path_table();
-
-       canvas_interface()->signal_keyframe_added().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::add_keyframe));
-       canvas_interface()->signal_keyframe_removed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::remove_keyframe));
-       canvas_interface()->signal_keyframe_changed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::change_keyframe));
-}
-
-KeyframeTreeStore::~KeyframeTreeStore()
-{
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("KeyframeTreeStore::~KeyframeTreeStore(): Deleted");
-}
-
-Glib::RefPtr<KeyframeTreeStore>
-KeyframeTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
-       KeyframeTreeStore *store(new KeyframeTreeStore(canvas_interface_));
-       Glib::RefPtr<KeyframeTreeStore> ret(store);
-       assert(ret);
-       return ret;
-}
-
-void
-KeyframeTreeStore::reset_stamp()
-{
-       stamp_=time(0)+reinterpret_cast<long>(this);
-}
-
-/*
-void
-KeyframeTreeStore::reset_path_table()
-{
-       Gtk::TreeModel::Children::iterator iter;
-       const Gtk::TreeModel::Children children(children());
-       path_table_.clear();
-       for(iter = children.begin(); iter != children.end(); ++iter)
-       {
-               Gtk::TreeModel::Row row(*iter);
-               path_table_[(Keyframe)row[model.keyframe]]=TreeRowReferenceHack(Glib::RefPtr<KeyframeTreeStore>(this),Gtk::TreePath(row));
-       }
-}
-*/
-
-
-inline bool
-KeyframeTreeStore::iterator_sane(const GtkTreeIter* iter)const
-{
-       if(iter && iter->stamp==stamp_)
-               return true;
-       g_warning("KeyframeTreeStore::iterator_sane(): Bad iterator stamp");
-       return false;
-}
-
-inline bool
-KeyframeTreeStore::iterator_sane(const Gtk::TreeModel::iterator& iter)const
-{
-       return iterator_sane(iter->gobj());
-}
-
-inline void
-KeyframeTreeStore::dump_iterator(const GtkTreeIter* /*gtk_iter*/, const Glib::ustring &/*name*/)const
-{
-#if 0
-       if(!gtk_iter)
-       {
-               g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is NULL (Root?)",name.c_str());
-               return;
-       }
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-
-       if(gtk_iter->stamp!=stamp_ || !iter)
-       {
-               g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is INVALID",name.c_str());
-               return;
-       }
-
-       if((unsigned)iter->index>=canvas_interface()->get_canvas()->keyframe_list().size())
-               g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) has bad index(index:%d)",name.c_str(),gtk_iter,iter->index);
-
-       g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) ref:%d, index:%d, time:%s",name.c_str(),gtk_iter,iter->ref_count,iter->index,iter->iter->get_time().get_string().c_str());
-#endif
-}
-
-inline void
-KeyframeTreeStore::dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const
-{
-       dump_iterator(iter->gobj(),name);
-}
-
-int
-KeyframeTreeStore::time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
-       const Model model;
-
-       _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
-       _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
-
-       Time diff(rhs_iter->iter->get_time()-lhs_iter->iter->get_time());
-       if(diff<0)
-               return -1;
-       if(diff>0)
-               return 1;
-       return 0;
-}
-
-int
-KeyframeTreeStore::description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
-       const Model model;
-
-       _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
-       _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
-
-       int comp = rhs_iter->iter->get_description().compare(lhs_iter->iter->get_description());
-       if (comp > 0) return 1;
-       if (comp < 0) return -1;
-       return 0;
-}
-
-void
-KeyframeTreeStore::set_value_impl(const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value)
-{
-       if(!iterator_sane(row))
-               return;
-
-       if(column>=get_n_columns_vfunc())
-       {
-               g_warning("KeyframeTreeStore::set_value_impl: Bad column (%d)",column);
-               return;
-       }
-
-       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
-       {
-               g_warning("KeyframeTreeStore::set_value_impl: Bad value type");
-               return;
-       }
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(row.gobj()->user_data));
-
-       try
-       {
-               if(column==model.time_delta.index())
-               {
-                       Glib::Value<synfig::Time> x;
-                       g_value_init(x.gobj(),model.time.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       Time new_delta(x.get());
-                       if(new_delta<=Time::zero()+Time::epsilon())
-                       {
-                               // Bad value
-                               return;
-                       }
-
-                       Time old_delta((*row)[model.time_delta]);
-                       if(old_delta<=Time::zero()+Time::epsilon())
-                       {
-                               // Bad old delta
-                               return;
-                       }
-                       // row(row) on the next line is bad - don't use it, because it leaves 'row' uninitialized
-                       //Gtk::TreeModel::iterator row(row);
-                       //row++;
-                       //if(!row)return;
-
-                       Time change_delta(new_delta-old_delta);
-
-                       if(change_delta<=Time::zero()+Time::epsilon() &&change_delta>=Time::zero()-Time::epsilon())
-                       {
-                               // Not an error, just no change
-                               return;
-                       }
-
-                       {
-                               Keyframe keyframe((*row)[model.keyframe]);
-                               synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSetDelta"));
-
-                               if(!action)return;
-
-                               action->set_param("canvas",canvas_interface()->get_canvas());
-                               action->set_param("canvas_interface",canvas_interface());
-                               action->set_param("keyframe",keyframe);
-                               action->set_param("delta",change_delta);
-
-                               canvas_interface()->get_instance()->perform_action(action);
-                       }
-
-                       return;
-               }
-               else
-               if(column==model.time.index())
-               {
-                       OneMoment one_moment;
-
-                       Glib::Value<synfig::Time> x;
-                       g_value_init(x.gobj(),model.time.type());
-                       g_value_copy(value.gobj(),x.gobj());
-                       synfig::Keyframe keyframe(*iter->iter);
-
-                       synfig::info("KeyframeTreeStore::set_value_impl():old_time=%s",keyframe.get_time().get_string().c_str());
-                       keyframe.set_time(x.get());
-                       synfig::info("KeyframeTreeStore::set_value_impl():new_time=%s",keyframe.get_time().get_string().c_str());
-
-                       synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
-
-                       if(!action)
-                               return;
-
-                       action->set_param("canvas",canvas_interface()->get_canvas());
-                       action->set_param("canvas_interface",canvas_interface());
-                       action->set_param("keyframe",keyframe);
-
-                       canvas_interface()->get_instance()->perform_action(action);
-               }
-               else if(column==model.description.index())
-               {
-                       Glib::Value<Glib::ustring> x;
-                       g_value_init(x.gobj(),model.description.type());
-                       g_value_copy(value.gobj(),x.gobj());
-                       synfig::Keyframe keyframe(*iter->iter);
-                       keyframe.set_description(x.get());
-
-                       synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
-
-                       if(!action)
-                               return;
-
-                       action->set_param("canvas",canvas_interface()->get_canvas());
-                       action->set_param("canvas_interface",canvas_interface());
-                       action->set_param("keyframe",keyframe);
-
-                       canvas_interface()->get_instance()->perform_action(action);
-               }
-               else if(column==model.keyframe.index())
-               {
-                       g_warning("KeyframeTreeStore::set_value_impl: This column is read-only");
-               }
-               else
-               {
-                       assert(0);
-               }
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
-
-Gtk::TreeModelFlags
-KeyframeTreeStore::get_flags_vfunc ()
-{
-       return Gtk::TREE_MODEL_LIST_ONLY;
-}
-
-int
-KeyframeTreeStore::get_n_columns_vfunc ()
-{
-       return model.size();
-}
-
-GType
-KeyframeTreeStore::get_column_type_vfunc (int index)
-{
-       return model.types()[index];
-}
-
-bool
-KeyframeTreeStore::iter_next_vfunc (const iterator& xiter, iterator& iter_next) const
-{
-       if(!iterator_sane(xiter)) return false;
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(xiter.gobj()->user_data));
-
-       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
-               return false;
-
-       _keyframe_iterator *next(new _keyframe_iterator());
-       iter_next.gobj()->user_data=static_cast<gpointer>(next);
-       next->ref_count=1;
-       next->index=iter->index+1;
-       next->iter=iter->iter;
-       ++next->iter;
-
-       if(next->iter==canvas_interface()->get_canvas()->keyframe_list().end())
-               return false;
-
-       iter_next.gobj()->stamp=stamp_;
-
-       return true;
-}
-
-/*
-bool
-KeyframeTreeStore::iter_next_vfunc (GtkTreeIter* gtk_iter)
-{
-       if(!iterator_sane(gtk_iter)) return false;
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-
-       // If we are already at the end, then we are very invalid
-       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
-               return false;
-
-       ++(iter->iter);
-
-       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
-       {
-               --(iter->iter);
-               return false;
-       }
-       (iter->index)++;
-       return true;
-}
-
-bool
-KeyframeTreeStore::iter_children_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent)
-{
-       dump_iterator(gtk_iter,"gtk_iter");
-       dump_iterator(parent,"parent");
-
-       if(!parent || !iterator_sane(parent))
-       {
-               clear_iterator(gtk_iter);
-               return false;
-       }
-
-       _keyframe_iterator *iter(new _keyframe_iterator());
-       iter->ref_count=1;
-       iter->index=0;
-       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
-
-       gtk_iter->user_data=static_cast<gpointer>(iter);
-       gtk_iter->stamp=stamp_;
-
-       return true;
-}
-
-bool
-KeyframeTreeStore::iter_has_child_vfunc (const GtkTreeIter*parent)
-{
-       dump_iterator(parent,"parent");
-
-       if(parent)
-               return false;
-
-       return true;
-}
-
-int
-KeyframeTreeStore::iter_n_children_vfunc (const GtkTreeIter* parent)
-{
-       dump_iterator(parent,"parent");
-
-       if(parent)
-               return 0;
-
-       return canvas_interface()->get_canvas()->keyframe_list().size();
-}
-*/
-
-int
-KeyframeTreeStore::iter_n_root_children_vfunc () const
-{
-       return canvas_interface()->get_canvas()->keyframe_list().size();
-}
-
-bool
-KeyframeTreeStore::iter_nth_root_child_vfunc (int n, iterator& xiter)const
-{
-       if(canvas_interface()->get_canvas()->keyframe_list().size()==0)
-       {
-               return false;
-       }
-
-       if(n<0)
-       {
-               g_warning("KeyframeTreeStore::iter_nth_root_child_vfunc: Out of range (negative index)");
-               return false;
-       }
-       if(n && (unsigned)n>=canvas_interface()->get_canvas()->keyframe_list().size())
-       {
-               g_warning("KeyframeTreeStore::iter_nth_child_vfunc: Out of range (large index)");
-               return false;
-       }
-
-       _keyframe_iterator *iter(new _keyframe_iterator());
-       iter->ref_count=1;
-       iter->index=n;
-       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
-       while(n--)
-       {
-               if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
-               {
-                       g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
-                       delete iter;
-                       return false;
-               }
-               ++iter->iter;
-       }
-       xiter.gobj()->user_data=static_cast<gpointer>(iter);
-       xiter.gobj()->stamp=stamp_;
-       return true;
-}
-
-/*
-bool
-KeyframeTreeStore::iter_nth_child_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent, int n)
-{
-       dump_iterator(parent,"parent");
-
-       if(parent)
-       {
-               g_warning("KeyframeTreeStore::iter_nth_child_vfunc: I am a list");
-               clear_iterator(gtk_iter);
-               return false;
-       }
-
-
-
-       _keyframe_iterator *iter(new _keyframe_iterator());
-       iter->ref_count=1;
-       iter->index=n;
-       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
-       while(n--)
-       {
-               if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
-               {
-                       g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
-                       delete iter;
-                       clear_iterator(gtk_iter);
-                       return false;
-               }
-               ++iter->iter;
-       }
-
-       gtk_iter->user_data=static_cast<gpointer>(iter);
-       gtk_iter->stamp=stamp_;
-       return true;
-}
-
-bool
-KeyframeTreeStore::iter_parent_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* child)
-{
-       dump_iterator(child,"child");
-       iterator_sane(child);
-       clear_iterator(gtk_iter);
-       return false;
-}
-*/
-
-void
-KeyframeTreeStore::ref_node_vfunc (iterator& xiter)const
-{
-       GtkTreeIter* gtk_iter(xiter.gobj());
-       if(!gtk_iter || !iterator_sane(gtk_iter)) return;
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-       iter->ref_count++;
-}
-
-void
-KeyframeTreeStore::unref_node_vfunc (iterator& xiter)const
-{
-       GtkTreeIter* gtk_iter(xiter.gobj());
-       if(!gtk_iter || !iterator_sane(gtk_iter)) return;
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-       iter->ref_count--;
-       if(!iter->ref_count)
-       {
-               delete iter;
-
-               // Make this iterator invalid
-               gtk_iter->stamp=0;
-       }
-}
-
-Gtk::TreeModel::Path
-KeyframeTreeStore::get_path_vfunc (const iterator& gtk_iter)const
-{
-       Gtk::TreeModel::Path path;
-
-       // If this is the root node, then return
-       // a root path
-       if(!iterator_sane(gtk_iter))
-               return path;
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
-
-       path.append_index(iter->index);
-
-       return path;
-}
-
-bool
-KeyframeTreeStore::get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter)const
-{
-       if(path.get_depth()>=1)
-               return iter_nth_root_child_vfunc(path.front(),iter);
-
-       // Error case
-       g_warning("KeyframeTreeStore::get_iter_vfunc(): Bad path \"%s\"",path.to_string().c_str());
-       //clear_iterator(iter);
-       return false;
-}
-
-bool
-KeyframeTreeStore::iter_is_valid (const iterator& iter) const
-{
-       return iterator_sane(iter);
-}
-
-void
-KeyframeTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& gtk_iter, int column, Glib::ValueBase& value)const
-{
-       dump_iterator(gtk_iter,"gtk_iter");
-       if(!iterator_sane(gtk_iter))
-               return;
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
-
-       switch(column)
-       {
-       case 0:         // Time
-       {
-               Glib::Value<synfig::Time> x;
-               g_value_init(x.gobj(),x.value_type());
-               x.set(iter->iter->get_time());
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-               return;
-       }
-       case 3:         // Time Delta
-       {
-               Glib::Value<synfig::Time> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               synfig::Keyframe prev_keyframe(*iter->iter);
-               synfig::Keyframe keyframe;
-               {
-                       KeyframeList::iterator tmp(iter->iter);
-                       tmp++;
-                       if(tmp==get_canvas()->keyframe_list().end())
-                       {
-                               x.set(Time(0));
-                               g_value_init(value.gobj(),x.value_type());
-                               g_value_copy(x.gobj(),value.gobj());
-                               return;
-                       }
-                       keyframe=*tmp;
-               }
-
-               Time delta(0);
-               try {
-                       delta=keyframe.get_time()-prev_keyframe.get_time();
-               }catch(...) { }
-               x.set(delta);
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-               return;
-       }
-       case 1:         // Description
-       {
-               g_value_init(value.gobj(),G_TYPE_STRING);
-               g_value_set_string(value.gobj(),iter->iter->get_description().c_str());
-               return;
-       }
-       case 2:         // Keyframe
-       {
-               Glib::Value<synfig::Keyframe> x;
-               g_value_init(x.gobj(),x.value_type());
-               x.set(*iter->iter);
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-               return;
-       }
-       default:
-               break;
-       }
-}
-
-Gtk::TreeModel::Row
-KeyframeTreeStore::find_row(const synfig::Keyframe &keyframe)
-{
-       Gtk::TreeModel::Row row(*(children().begin()));
-       dump_iterator(row,"find_row,begin");
-       const GtkTreeIter *gtk_iter(row.gobj());
-       if(!iterator_sane(gtk_iter))
-               throw std::runtime_error(_("Unable to find Keyframe in table"));
-
-       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
-
-       synfig::KeyframeList &keyframe_list(canvas_interface()->get_canvas()->keyframe_list());
-       if(keyframe_list.empty())
-               throw std::runtime_error(_("There are no keyframes n this canvas"));
-
-       iter->index=0;
-
-       for(iter->iter=keyframe_list.begin();iter->iter!=keyframe_list.end() && *iter->iter!=keyframe;++iter->iter)
-       {
-               iter->index++;
-       }
-       if(iter->iter==keyframe_list.end())
-               throw std::runtime_error(_("Unable to find Keyframe in table"));
-       return row;
-}
-
-void
-KeyframeTreeStore::add_keyframe(synfig::Keyframe keyframe)
-{
-       try
-       {
-               Gtk::TreeRow row(find_row(keyframe));
-               dump_iterator(row.gobj(),"add_keyframe,row");
-               Gtk::TreePath path(get_path(row));
-
-               row_inserted(path,row);
-
-               old_keyframe_list=get_canvas()->keyframe_list();
-               //old_keyframe_list.add(keyframe);
-               //old_keyframe_list.sort();
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
-
-void
-KeyframeTreeStore::remove_keyframe(synfig::Keyframe keyframe)
-{
-       try
-       {
-               if(1)
-               {
-                       Gtk::TreeRow row(find_row(keyframe));
-                       dump_iterator(row,"remove_keyframe,row");
-                       Gtk::TreePath path(get_path(row));
-                       row_deleted(path);
-
-                       old_keyframe_list.erase(keyframe);
-               }
-               else
-               {
-                       g_warning("KeyframeTreeStore::remove_keyframe: Keyframe not in table");
-               }
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
-
-void
-KeyframeTreeStore::change_keyframe(synfig::Keyframe keyframe)
-{
-       try
-       {
-               Gtk::TreeRow row(find_row(keyframe));
-
-               unsigned int new_index(get_index_from_model_iter(row));
-               unsigned int old_index(0);
-               synfig::KeyframeList::iterator iter;
-               for(old_index=0,iter=old_keyframe_list.begin();iter!=old_keyframe_list.end() && (UniqueID)*iter!=(UniqueID)keyframe;++iter,old_index++)
-                       ;
-
-               if(iter!=old_keyframe_list.end() && new_index!=old_index)
-               {
-                       std::vector<int> new_order;
-                       for(unsigned int i=0;i<old_keyframe_list.size();i++)
-                       {
-                               new_order.push_back(i);
-                       }
-                       if(new_order.size()>new_index)
-                       {
-                               new_order.erase(new_order.begin()+new_index);
-                               new_order.insert(new_order.begin()+old_index,new_index);
-
-                               //new_order[old_index]=
-
-                               rows_reordered (Path(), iterator(), &new_order[0]);
-                       }
-                       old_keyframe_list=get_canvas()->keyframe_list();
-
-                       row=find_row(keyframe);
-               }
-
-               dump_iterator(row,"change_keyframe,row");
-               row_changed(get_path(row),row);
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
diff --git a/synfig-studio/src/gui/keyframetreestore.h b/synfig-studio/src/gui/keyframetreestore.h
deleted file mode 100644 (file)
index c3efccf..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file keyframetreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
-#define __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/liststore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfig/keyframe.h>
-#include <map>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-//class TreeRowReferenceHack;
-//#define TreeRowReferenceHack Gtk::TreeRowReference
-
-namespace studio {
-
-class KeyframeTreeStore_Class;
-
-class KeyframeTreeStore :
-       public Glib::Object,
-       public Gtk::TreeModel,
-       public Gtk::TreeDragSource,
-       public Gtk::TreeDragDest
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       class Model : public Gtk::TreeModel::ColumnRecord
-       {
-       public:
-               Gtk::TreeModelColumn<synfig::Time> time;
-               Gtk::TreeModelColumn<Glib::ustring> description;
-               Gtk::TreeModelColumn<synfig::Keyframe> keyframe;
-               Gtk::TreeModelColumn<synfig::Time> time_delta;
-
-               Model()
-               {
-                       add(time);
-                       add(description);
-                       add(keyframe);
-                       add(time_delta);
-               }
-       };
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       const Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
-       //! Unique stamp for this TreeModel.
-       int stamp_;
-
-       static KeyframeTreeStore_Class keyframe_tree_store_class_;
-
-       //std::map<synfig::Keyframe,TreeRowReferenceHack> path_table_;
-
-       synfig::KeyframeList old_keyframe_list;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       void add_keyframe(synfig::Keyframe);
-
-       void remove_keyframe(synfig::Keyframe);
-
-       void change_keyframe(synfig::Keyframe);
-
-       static int sorter(const Gtk::TreeModel::iterator &,const Gtk::TreeModel::iterator &);
-
-       bool iterator_sane(const GtkTreeIter* iter)const;
-
-       bool iterator_sane(const Gtk::TreeModel::iterator& iter)const;
-
-       void dump_iterator(const GtkTreeIter* iter, const Glib::ustring &name)const;
-
-       void dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const;
-
-       //! Resets the iterator stamp for this model.
-       /*!     This should be called whenever the class is
-       **      constructed     or when large numbers of
-       **      iterators become invalid. */
-       void reset_stamp();
-
-       //void reset_path_table();
-
-       /*
- -- ** -- V I R T U A L   F U N C T I O N S -----------------------------------
-       */
-
-protected:
-
-       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
-       virtual Gtk::TreeModelFlags  get_flags_vfunc ();
-       virtual int  get_n_columns_vfunc ();
-       virtual GType  get_column_type_vfunc (int index);
-       virtual bool iter_next_vfunc (const iterator& iter, iterator& iter_next) const;
-       virtual bool  get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter_next)const;
-       virtual bool  iter_nth_root_child_vfunc (int n, iterator& iter)const;
-       virtual Gtk::TreeModel::Path  get_path_vfunc (const iterator& iter)const;
-       virtual void  ref_node_vfunc (iterator& iter)const;
-       virtual void  unref_node_vfunc (iterator& iter)const;
-       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-       virtual bool    iter_is_valid (const iterator& iter) const;
-       virtual int     iter_n_root_children_vfunc () const;
-
-       //virtual bool  iter_nth_child_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent, int n);
-       //virtual bool  iter_children_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent);
-       //virtual bool  iter_has_child_vfunc (const GtkTreeIter* iter);
-       //virtual int  iter_n_children_vfunc (const GtkTreeIter* iter);
-       //virtual bool  iter_parent_vfunc (GtkTreeIter* iter, const GtkTreeIter* child);
-
-       /*
-       virtual bool  get_sort_column_id_vfunc (int* sort_column_id, Gtk::SortType* order);
-       virtual void  set_sort_column_id_vfunc (int sort_column_id, Gtk::SortType order);
-       virtual void  set_sort_func_vfunc (int sort_column_id, GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
-       virtual void  set_default_sort_func_vfunc (GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
-       virtual bool  has_default_sort_func_vfunc ();
-       */
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-       ~KeyframeTreeStore();
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
-       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
-
-       synfig::Canvas::Handle get_canvas() { return canvas_interface()->get_canvas(); }
-       synfig::Canvas::Handle get_canvas()const { return canvas_interface()->get_canvas(); }
-
-       Gtk::TreeModel::Row find_row(const synfig::Keyframe &keyframe);
-
-       /*
- -- ** -- S T A T I C  M E T H O D S ------------------------------------------
-       */
-
-public:
-
-       static Glib::RefPtr<KeyframeTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-
-       static int time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
-       static int description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
-
-}; // END of class KeyframeTreeStore
-
-//! \internal
-class KeyframeTreeStore_Class : public Glib::Class
-{
-public:
-       struct KeyframeTreeStoreClass
-       {
-               GObjectClass parent_class;
-       };
-
-       friend class KeyframeTreeStore;
-
-       const Glib::Class& init();
-
-       static void class_init_function(gpointer g_blass, gpointer class_data);
-}; // END of CustomTreeStore_Class
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
index c3a3be4..5f0538f 100644 (file)
@@ -31,7 +31,7 @@
 #endif
 
 #include "layeractionmanager.h"
-#include "layertree.h"
+#include "trees/layertree.h"
 #include <synfig/context.h>
 #include <synfig/layer_pastecanvas.h>
 #include <synfigapp/action_param.h>
diff --git a/synfig-studio/src/gui/layergrouptree.cpp b/synfig-studio/src/gui/layergrouptree.cpp
deleted file mode 100644 (file)
index 3dd323e..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layergrouptree.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include <synfig/layer.h>
-#include "layergrouptree.h"
-#include <gtkmm/treemodelsort.h>
-#include <ETL/misc>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-LayerGroupTree::LayerGroupTree()
-{
-       const LayerGroupTreeStore::Model model;
-
-
-       {       // --- O N / O F F ----------------------------------------------------
-               int index;
-               index=append_column_editable(_(" "),model.active);
-               //Gtk::TreeView::Column* column = get_column(index-1);
-       }
-       {       // --- I C O N --------------------------------------------------------
-               int index;
-               index=append_column(_(" "),model.icon);
-               Gtk::TreeView::Column* column = get_column(index-1);
-               set_expander_column(*column);
-       }
-       {       // --- N A M E --------------------------------------------------------
-               int index;
-               index=append_column_editable(_("Name"),model.label);
-               label_column = get_column(index-1);
-
-               //column->set_sort_column(layer_model.index);
-
-               //set_expander_column(*column);
-               //column->set_reorderable();
-               //column->set_resizable();
-               //column->set_clickable(false);
-
-               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
-               //column->pack_start(*icon_cellrenderer,false);
-               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
-       }
-
-       set_enable_search(true);
-       set_search_column(model.label);
-       set_search_equal_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::search_func));
-
-       // This makes things easier to read.
-       set_rules_hint();
-
-       // Make us more sensitive to several events
-       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
-       set_reorderable(true);
-
-       get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
-
-       //set_flags(get_flags()|Gtk::RECEIVES_DEFAULT|Gtk::HAS_GRAB);
-
-       //std::list<Gtk::TargetEntry> listTargets;
-       //listTargets.push_back( Gtk::TargetEntry("LAYER") );
-       //listTargets.push_back( Gtk::TargetEntry("GROUP") );
-       //drag_dest_set(listTargets);
-}
-
-LayerGroupTree::~LayerGroupTree()
-{
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("LayerGroupTree::~LayerGroupTree(): Deleted");
-}
-
-void
-LayerGroupTree::set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store)
-{
-       layer_group_tree_store_=layer_group_tree_store;
-       LayerGroupTreeStore::Model model;
-
-#if 0
-       {
-               Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(layer_group_tree_store_));
-               sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
-               sorted_store->set_sort_func(model.time.index(),sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
-               sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
-               Gtk::TreeView::set_model(sorted_store);
-       }
-#else
-               Gtk::TreeView::set_model(layer_group_tree_store);
-#endif
-}
-
-void
-LayerGroupTree::set_editable(bool x)
-{
-       editable_=x;
-/*
-       if(editable_)
-       {
-               cell_renderer_time->property_editable()=true;
-               cell_renderer_time_delta->property_editable()=true;
-               cell_renderer_description->property_editable()=true;
-       }
-       else
-       {
-               cell_renderer_time->property_editable()=false;
-               cell_renderer_time_delta->property_editable()=false;
-               cell_renderer_description->property_editable()=false;
-       }
-*/
-}
-/*
-void
-LayerGroupTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
-       synfig::Keyframe keyframe(row[model.keyframe]);
-       if(time!=keyframe.get_time())
-       {
-               row[model.time]=time;
-               //keyframe.set_time(time);
-               //signal_edited_time()(keyframe,time);
-               //signal_edited()(keyframe);
-       }
-}
-
-void
-LayerGroupTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
-
-       if(row)row[model.time_delta]=time;
-}
-
-void
-LayerGroupTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
-       const synfig::String description(desc);
-       synfig::Keyframe keyframe(row[model.keyframe]);
-       if(description!=keyframe.get_description())
-       {
-               row[model.description]=desc;
-               keyframe.set_description(description);
-               signal_edited_description()(keyframe,description);
-               signal_edited()(keyframe);
-       }
-}
-*/
-
-bool
-LayerGroupTree::on_event(GdkEvent *event)
-{
-    switch(event->type)
-    {
-       case GDK_BUTTON_PRESS:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
-                       //tree_to_widget_coords (,, wx, wy);
-                       if(!get_path_at_pos(
-                               wx,wy,  // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
-                       if(row[model.is_layer] && event->button.button==3)
-                       {
-                               signal_popup_layer_menu()((Layer::Handle)row[model.layer]);
-                               return true;
-                       }
-
-                       /*signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
-                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
-                       {
-                               layer_group_tree_store_->canvas_interface()->set_time(row[model.time]);
-                       }*/
-               }
-               break;
-       case GDK_2BUTTON_PRESS:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!get_path_at_pos(
-                               int(event->button.x),int(event->button.y),      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
-
-                       LayerList layer_list(row[model.all_layers]);
-                       if(!layer_list.empty())
-                       {
-                               if(!(event->button.state&GDK_CONTROL_MASK))
-                               {
-                                       layer_group_tree_store_->canvas_interface()->get_selection_manager()->clear_selected_layers();
-                               }
-                               layer_group_tree_store_->canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
-                               return true;
-                       }
-               }
-               break;
-       case GDK_BUTTON_RELEASE:
-               break;
-       default:
-               break;
-       }
-       return Gtk::TreeView::on_event(event);
-       //return false;
-}
-
-static inline void __group_grabber(const Gtk::TreeModel::iterator& iter, std::list<synfig::String>* ret)
-{
-       const LayerGroupTreeStore::Model model;
-       if((bool)(*iter)[model.is_group])
-               ret->push_back((Glib::ustring)(*iter)[model.group_name]);
-}
-
-std::list<synfig::String>
-LayerGroupTree::get_selected_groups()const
-{
-       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
-
-       if(!selection)
-               return std::list<synfig::String>();
-
-       std::list<synfig::String> ret;
-
-       selection->selected_foreach_iter(
-               sigc::bind(
-                       sigc::ptr_fun(
-                               &__group_grabber
-                       ),
-                       &ret
-               )
-       );
-
-       return ret;
-}
-
-static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerGroupTree::LayerList* ret)
-{
-       const LayerGroupTreeStore::Model model;
-       if((bool)(*iter)[model.is_layer])
-               ret->push_back((Layer::Handle)(*iter)[model.layer]);
-}
-
-LayerGroupTree::LayerList
-LayerGroupTree::get_selected_layers()const
-{
-       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
-
-       if(!selection)
-               return LayerList();
-
-       LayerList ret;
-
-       selection->selected_foreach_iter(
-               sigc::bind(
-                       sigc::ptr_fun(
-                               &__layer_grabber
-                       ),
-                       &ret
-               )
-       );
-
-       return ret;
-}
-
-void
-LayerGroupTree::set_cursor(const Gtk::TreeModel::Path& path, bool start_editing)
-{
-       Gtk::TreeView::set_cursor(path, *label_column, start_editing);
-}
diff --git a/synfig-studio/src/gui/layergrouptree.h b/synfig-studio/src/gui/layergrouptree.h
deleted file mode 100644 (file)
index a17c470..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layergrouptree.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERGROUPTREE_H
-#define __SYNFIG_STUDIO_LAYERGROUPTREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "layergrouptreestore.h"
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace synfig { class Layer; }
-
-namespace studio {
-
-class LayerGroupTree : public Gtk::TreeView
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       typedef std::list<synfig::Layer::Handle> LayerList;
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       LayerGroupTreeStore::Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_;
-
-       Gtk::CellRendererText *cell_renderer_description;
-
-       bool editable_;
-
-
-       sigc::signal<void,etl::handle<synfig::Layer> > signal_popup_layer_menu_;
-
-//     sigc::signal<void,LayerList> signal_select_layers_;
-       Gtk::TreeView::Column* label_column;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       bool on_event(GdkEvent *event);
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       LayerGroupTree();
-       ~LayerGroupTree();
-       void set_cursor(const Gtk::TreeModel::Path& path, bool start_editing=false);
-
-       Glib::RefPtr<LayerGroupTreeStore> get_model() { return layer_group_tree_store_; }
-
-       sigc::signal<void,etl::handle<synfig::Layer> >& signal_popup_layer_menu() { return signal_popup_layer_menu_; }
-
-//     sigc::signal<void,LayerList>& signal_select_layers() { return signal_select_layers_; }
-
-       void set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_);
-
-       void set_editable(bool x=true);
-
-       bool get_editable()const { return editable_; }
-
-       std::list<synfig::String> get_selected_groups()const;
-
-       LayerList get_selected_layers()const;
-}; // END of LayerGroupTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/layergrouptreestore.cpp b/synfig-studio/src/gui/layergrouptreestore.cpp
deleted file mode 100644 (file)
index 332994f..0000000
+++ /dev/null
@@ -1,1031 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layergrouptreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "layergrouptreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include "app.h"
-#include "instance.h"
-#include <synfigapp/action_system.h>
-#include "docks/dockmanager.h"
-#include "docks/dockable.h"
-
-#include <gtk/gtkversion.h>
-#include <ETL/clock>
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-#define GROUP_NEST_CHAR        '.'
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static LayerGroupTreeStore::Model& ModelHack()
-{
-       static LayerGroupTreeStore::Model* model(0);
-       if(!model)model=new LayerGroupTreeStore::Model;
-       return *model;
-}
-
-LayerGroupTreeStore::LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
-       Gtk::TreeStore                  (ModelHack()),
-       canvas_interface_               (canvas_interface_)
-{
-       layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-       group_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-group"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
-       // Connect Signals to Terminals
-       canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_status_changed));
-       canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_new_description));
-
-       canvas_interface()->get_canvas()->signal_group_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_added)));
-       canvas_interface()->get_canvas()->signal_group_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_removed)));
-       canvas_interface()->get_canvas()->signal_group_changed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_changed)));
-
-       canvas_interface()->get_canvas()->signal_group_pair_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_added)));
-       canvas_interface()->get_canvas()->signal_group_pair_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_removed)));
-
-       rebuild();
-}
-
-LayerGroupTreeStore::~LayerGroupTreeStore()
-{
-       //clear();
-
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("LayerGroupTreeStore::~LayerGroupTreeStore(): Deleted");
-}
-
-bool
-LayerGroupTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
-{
-       const Model model;
-
-       Glib::ustring substr(x.uppercase());
-       Glib::ustring label((*iter)[model.label]);
-       label=label.uppercase();
-
-       return label.find(substr)==Glib::ustring::npos;
-}
-
-
-Glib::RefPtr<LayerGroupTreeStore>
-LayerGroupTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
-       return Glib::RefPtr<LayerGroupTreeStore>(new LayerGroupTreeStore(canvas_interface_));
-}
-
-void
-LayerGroupTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
-       if(column==model.child_layers.index())
-       {
-               Glib::Value<LayerList> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               if((bool)(*iter)[model.is_group])
-               {
-                       set<Layer::Handle> layer_set(canvas_interface()->get_canvas()->get_layers_in_group((Glib::ustring)(*iter)[model.group_name]));
-
-                       x.set(LayerList(layer_set.begin(),layer_set.end()));
-               }
-               else if((bool)(*iter)[model.is_layer])
-               {
-                       LayerList layer_list;
-                       layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
-                       x.set(layer_list);
-               }
-
-               g_value_init(value.gobj(),x.value_type());
-               value=x;
-       }
-       else if(column==model.all_layers.index())
-       {
-               Glib::Value<LayerList> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               if((bool)(*iter)[model.is_group])
-               {
-                       LayerList layer_list;
-                       Gtk::TreeModel::iterator child_iter(iter->children().begin());
-                       for(;child_iter;++child_iter)
-                       {
-                               LayerList layer_list2((LayerList)(*child_iter)[model.all_layers]);
-                               for(;layer_list2.size();layer_list2.pop_front())
-                                       layer_list.push_back(layer_list2.front());
-                       }
-                       x.set(layer_list);
-               }
-               else if((bool)(*iter)[model.is_layer])
-               {
-                       LayerList layer_list;
-                       layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
-                       x.set(layer_list);
-               }
-
-               g_value_init(value.gobj(),x.value_type());
-               value=x;
-       }
-       else if(column==model.group_name.index())
-       {
-               if((bool)(*iter)[model.is_group])
-                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
-               return get_value_vfunc(iter->parent(),column,value);
-       }
-       else if(column==model.parent_group_name.index())
-       {
-               if(iter->parent())
-                       return get_value_vfunc(iter->parent(),model.group_name.index(),value);
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-               x.set(Glib::ustring());
-               g_value_init(value.gobj(),x.value_type());
-               value=x;
-       }
-       else if(column==model.label.index())
-       {
-               if((bool)(*iter)[model.is_group])
-               {
-                       Glib::Value<Glib::ustring> x;
-                       g_value_init(x.gobj(),x.value_type());
-
-                       Glib::ustring group_name((*iter)[model.group_name]);
-
-                       // Get rid of any parent group crap
-                       while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
-                               group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
-
-                       x.set(group_name);
-
-                       g_value_init(value.gobj(),x.value_type());
-
-                       value=x;
-               }
-               else if((bool)(*iter)[model.is_layer])
-               {
-                       synfig::Layer::Handle layer((*iter)[model.layer]);
-
-                       if(!layer)return;
-
-                       Glib::Value<Glib::ustring> x;
-                       g_value_init(x.gobj(),x.value_type());
-
-                       x.set(layer->get_non_empty_description());
-
-                       g_value_init(value.gobj(),x.value_type());
-                       //g_value_copy(x.gobj(),value.gobj());
-                       value=x;
-               }
-       }
-       else
-       if(column==model.tooltip.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-
-               x.set(layer->get_local_name());
-
-               g_value_init(value.gobj(),x.value_type());
-               //g_value_copy(x.gobj(),value.gobj());
-               value=x;
-       }
-       else
-       if(column==model.canvas.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<Canvas::Handle> x;
-               g_value_init(x.gobj(),x.value_type());
-
-
-               x.set(layer->get_canvas());
-
-               g_value_init(value.gobj(),x.value_type());
-               //g_value_copy(x.gobj(),value.gobj());
-               value=x;
-       }
-       else
-       if(column==model.active.index())
-       {
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               if((bool)(*iter)[model.is_layer])
-               {
-                       synfig::Layer::Handle layer((*iter)[model.layer]);
-                       x.set(layer->active());
-               }
-               else if((bool)(*iter)[model.is_group])
-               {
-                       int activecount(0),total(0);
-                       Gtk::TreeModel::iterator child_iter(iter->children().begin());
-                       for(;child_iter;++child_iter)
-                       {
-                               total++;
-                               if((*child_iter)[model.active])
-                                       activecount++;
-                       }
-                       x.set(activecount>total/2);
-               }
-               else
-                       x.set(false);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.icon.index())
-       {
-               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
-               g_value_init(x.gobj(),x.value_type());
-
-               if((bool)(*iter)[model.is_layer])
-               {
-                       synfig::Layer::Handle layer((*iter)[model.layer]);
-                       if(!layer)return;
-                       //x.set(layer_icon);
-                       x.set(get_tree_pixbuf_layer(layer->get_name()));
-               }
-               if((bool)(*iter)[model.is_group])
-                       x.set(group_icon);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-               Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-void
-LayerGroupTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
-       //if(!iterator_sane(row))
-       //      return;
-
-       if(column>=get_n_columns_vfunc())
-       {
-               g_warning("LayerGroupTreeStore::set_value_impl: Bad column (%d)",column);
-               return;
-       }
-
-       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
-       {
-               g_warning("LayerGroupTreeStore::set_value_impl: Bad value type");
-               return;
-       }
-
-       try
-       {
-               if(column==model.label.index())
-               {
-                       Glib::Value<Glib::ustring> x;
-                       g_value_init(x.gobj(),model.label.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       if((bool)(*iter)[model.is_layer])
-                       {
-                               synfig::Layer::Handle layer((*iter)[model.layer]);
-                               if(!layer)
-                                       return;
-                               synfig::String new_desc(x.get());
-
-                               if(new_desc==layer->get_local_name())
-                                       new_desc=synfig::String();
-
-                               if(new_desc==layer->get_description())
-                                       return;
-
-                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
-
-                               if(!action)
-                                       return;
-
-                               action->set_param("canvas",canvas_interface()->get_canvas());
-                               action->set_param("canvas_interface",canvas_interface());
-                               action->set_param("layer",layer);
-                               action->set_param("new_description",synfig::String(x.get()));
-
-                               canvas_interface()->get_instance()->perform_action(action);
-                               return;
-                       }
-                       else if((bool)(*iter)[model.is_group])
-                       {
-                               synfig::String group((Glib::ustring)(*iter)[model.label]);
-                               synfig::String new_group(x.get());
-
-                               if(x.get()==group)
-                                       return;
-
-                               Glib::ustring group_name((*iter)[model.group_name]);
-                               group=group_name;
-                               new_group.clear();
-
-                               // Get rid of any parent group crap
-                               while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
-                               {
-                                       new_group+=Glib::ustring(group_name,0,group_name.find(GROUP_NEST_CHAR)+1);
-                                       group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
-                               }
-                               new_group+=x.get();
-
-                               synfig::info("Renaming group \"%s\" to \"%s\"...",group.c_str(),new_group.c_str());
-
-                               // Check to see if this group is real or not.
-                               // If it isn't real, then renaming it is a cinch.
-                               // We know it isn't real if it doesn't have any
-                               // children yet.
-                               if(iter->children().empty())
-                               {
-                                       (*iter)[model.group_name]=new_group;
-                               }
-                               else
-                               {
-                                       synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
-
-                                       if(!action)
-                                               return;
-
-                                       action->set_param("canvas",canvas_interface()->get_canvas());
-                                       action->set_param("canvas_interface",canvas_interface());
-                                       action->set_param("group",group);
-                                       action->set_param("new_group",new_group);
-
-                                       canvas_interface()->get_instance()->perform_action(action);
-                               }
-                               return;
-                       }
-                       return;
-               }
-               else
-               if(column==model.active.index())
-               {
-                       Glib::Value<bool> x;
-                       g_value_init(x.gobj(),model.active.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       if((bool)(*iter)[model.is_layer])
-                       {
-                               synfig::Layer::Handle layer((*iter)[model.layer]);
-                               if(!layer)return;
-
-                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
-
-                               if(!action)
-                                       return;
-
-                               action->set_param("canvas",canvas_interface()->get_canvas());
-                               action->set_param("canvas_interface",canvas_interface());
-                               action->set_param("layer",layer);
-                               action->set_param("new_status",bool(x.get()));
-
-
-                               canvas_interface()->get_instance()->perform_action(action);
-                               return;
-                       }
-                       else if(!iter->children().empty())
-                       {
-                               synfigapp::Action::PassiveGrouper group(
-                                       get_canvas_interface()->get_instance().get(),
-                                       String(
-                                               x.get()?_("Activate "):_("Deactivate ")
-                                       )+(Glib::ustring)(*iter)[model.label]
-                               );
-
-                               Gtk::TreeModel::iterator child_iter(iter->children().begin());
-
-                               for(;child_iter;++child_iter)
-                                       (*child_iter)[model.active]=x.get();
-
-                               Gtk::TreeStore::set_value_impl(iter,column, value);
-                       }
-               }
-               else
-                       Gtk::TreeStore::set_value_impl(iter,column, value);
-
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
-
-
-
-
-bool
-LayerGroupTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
-{
-       //if(!get_iter(path)) return false;
-//     Gtk::TreeModel::Row row(*get_iter(path));
-
-       return true;
-}
-
-bool
-LayerGroupTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
-{
-       if(!const_cast<LayerGroupTreeStore*>(this)->get_iter(path)) return false;
-       //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
-       //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
-       //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
-       Gtk::TreeModel::Row row(*const_cast<LayerGroupTreeStore*>(this)->get_iter(path));
-
-       if((bool)row[model.is_layer])
-       {
-               Layer* layer(((Layer::Handle)row[model.layer]).get());
-               assert(layer);
-
-               std::vector<Layer*> layers;
-
-               layers.push_back(layer);
-
-               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
-
-               return true;
-       }
-       else if((bool)row[model.is_group])
-       {
-               synfig::String group((Glib::ustring)row[model.group_name]);
-               if(group.empty())
-                       return false;
-
-               selection_data.set("GROUP", 8, reinterpret_cast<const guchar*>(&*group.begin()), sizeof(void*)*group.size());
-
-               return true;
-       }
-
-       return false;
-}
-
-bool
-LayerGroupTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
-{
-       return true;
-}
-
-bool
-LayerGroupTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
-{
-       Gtk::TreeIter iter(const_cast<LayerGroupTreeStore*>(this)->get_iter(dest));
-       if(!iter) return false;
-
-       if(synfig::String(selection_data.get_data_type())=="LAYER")
-               return true;
-
-       if(synfig::String(selection_data.get_data_type())=="GROUP")
-       {
-               synfig::String dest_group((Glib::ustring)(*iter)[model.group_name]);
-               synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
-               //synfig::String src_group(const_cast<gchar*>(selection_data.get_data()));
-
-               // Avoid putting a group inside of itself
-               if(dest_group.size()>src_group.size() && src_group==String(dest_group,0,src_group.size()))
-                       return false;
-               return true;
-       }
-
-       return false;
-       //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
-       //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
-       //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
-       //Gtk::TreeModel::Row row(*get_iter(dest));
-
-/*     if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
-               return true;
-*/
-       return false;
-}
-
-bool
-LayerGroupTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
-{
-       if(!get_iter(dest)) return false;
-//     bool ret=false;
-       //int i(0);
-
-       Gtk::TreeModel::Row row(*get_iter(dest));
-
-       //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
-       //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
-       //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
-       synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Regroup"));
-
-       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
-       {
-               synfig::String dest_group;
-
-               dest_group=(Glib::ustring)row[model.group_name];
-
-               if(dest_group.empty())
-                       return false;
-
-               if(synfig::String(selection_data.get_data_type())=="LAYER")
-               {
-                       synfigapp::Action::Handle action(synfigapp::Action::create("GroupAddLayers"));
-
-                       if(!action)
-                               return false;
-
-                       action->set_param("canvas",canvas_interface()->get_canvas());
-                       action->set_param("canvas_interface",canvas_interface());
-                       action->set_param("group",dest_group);
-
-                       for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
-                       {
-                               Layer::Handle layer(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
-                               assert(layer);
-
-                               action->set_param("layer",layer);
-                       }
-                       if(!canvas_interface()->get_instance()->perform_action(action))
-                       {
-                               passive_grouper.cancel();
-                               return false;
-                       }
-                       return true;
-               }
-               if(synfig::String(selection_data.get_data_type())=="GROUP")
-               {
-                       synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
-                       synfig::String group(src_group);
-
-                       // Get rid of any parent group crap
-                       while(group.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
-                               group=Glib::ustring(group,group.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
-
-                       group=dest_group+GROUP_NEST_CHAR+group;
-
-                       synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
-
-                       if(!action)
-                               return false;
-
-                       action->set_param("canvas",canvas_interface()->get_canvas());
-                       action->set_param("canvas_interface",canvas_interface());
-                       action->set_param("group",src_group);
-                       action->set_param("new_group",group);
-
-                       if(!canvas_interface()->get_instance()->perform_action(action))
-                       {
-                               passive_grouper.cancel();
-                               return false;
-                       }
-                       return true;
-               }
-       }
-/*     // Save the selection data
-       synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
-
-       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
-       {
-               Canvas::Handle dest_canvas;
-               Layer::Handle dest_layer;
-
-               dest_canvas=(Canvas::Handle)(row[model.canvas]);
-               dest_layer=(Layer::Handle)(row[model.layer]);
-               assert(dest_canvas);
-
-               if(!dest_layer)
-                       return false;
-
-               int dest_layer_depth=dest_layer->get_depth();
-
-               if(synfig::String(selection_data.get_data_type())=="LAYER")for(i=0;i<selection_data.get_length()/sizeof(void*);i++)
-               {
-                       //synfig::info("dest_layer_depth=%d",dest_layer_depth);
-
-                       Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
-                       assert(src);
-                       if(dest_layer==src)
-                               continue;
-
-                       // In this case, we are just moving.
-//                     if(dest_canvas==src->get_canvas())
-                       {
-                               if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
-                                       dest_layer_depth--;
-                               if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
-                                       continue;
-
-                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
-                               action->set_param("canvas",dest_canvas);
-                               action->set_param("canvas_interface",canvas_interface());
-                               action->set_param("layer",src);
-                               action->set_param("new_index",dest_layer_depth);
-                               action->set_param("dest_canvas",dest_canvas);
-                               if(canvas_interface()->get_instance()->perform_action(action))
-                               {
-                                       ret=true;
-                               }
-                               else
-                               {
-                                       passive_grouper.cancel();
-                                       return false;
-                               }
-                               continue;
-                       }
-               }
-       }
-       synfig::info("I supposedly moved %d layers",i);
-
-       // Reselect the previously selected layers
-       canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
-
-       return ret;
-       */
-       return false;
-}
-
-
-
-
-
-
-
-void
-LayerGroupTreeStore::rebuild()
-{
-       rebuilding=true;
-       // etl::clock timer;timer.reset();
-       try {
-
-               // Clear out the current list
-               clear();
-               Canvas::Handle canvas(canvas_interface()->get_canvas());
-               std::set<String> groups(canvas->get_groups());
-               for(;groups.size();groups.erase(groups.begin()))
-               {
-                       String group(*groups.begin());
-                       Gtk::TreeRow row(on_group_added(group));
-                       std::set<Layer::Handle> layers(canvas->get_layers_in_group(group));
-
-                       for(;layers.size();layers.erase(layers.begin()))
-                       {
-                               Gtk::TreeRow layer_row(*(prepend(row.children())));
-                               Layer::Handle layer(*layers.begin());
-                               set_row_layer(layer_row,layer);
-                       }
-               }
-
-               // Go ahead and add all the layers
-               /*std::for_each(
-                       canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
-                       sigc::mem_fun(*this, &studio::LayerGroupTreeStore::on_layer_added)
-               );*/
-       }
-       catch(...)
-       {
-               rebuilding=false;
-               throw;
-       }
-       rebuilding=false;
-       // synfig::info("LayerGroupTreeStore::rebuild() took %f seconds",float(timer()));
-}
-
-void
-LayerGroupTreeStore::refresh()
-{
-       rebuild();
-}
-
-void
-LayerGroupTreeStore::refresh_row(Gtk::TreeModel::Row &row)
-{
-       if((bool)row[model.is_layer])
-       {
-               Layer::Handle layer=row[model.layer];
-
-
-               //if(layer->dynamic_param_list().count("z_depth"))
-               //      row[model.z_depth]=Time::begin();
-       }
-
-       Gtk::TreeModel::Children children = row.children();
-       Gtk::TreeModel::Children::iterator iter;
-
-       if(!children.empty())
-               for(iter = children.begin(); iter && iter != children.end(); ++iter)
-               {
-                       Gtk::TreeRow row=*iter;
-                       refresh_row(row);
-               }
-}
-
-
-void
-LayerGroupTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
-{
-       row[model.is_layer] = true;
-       row[model.is_group] = false;
-       row[model.layer] = handle;
-}
-
-Gtk::TreeRow
-LayerGroupTreeStore::on_group_added(synfig::String group)
-{
-       // Check to see if this group perhaps already
-       // exists
-       {
-               Gtk::TreeModel::Children::iterator iter;
-               if(find_group_row(group,  iter))
-                       return *iter;
-       }
-
-       if(group.find(GROUP_NEST_CHAR)!=String::npos)
-       {
-               Gtk::TreeModel::Children::iterator iter;
-               String parent_name;
-               do
-               {
-                       if(parent_name.size())
-                               parent_name+=GROUP_NEST_CHAR;
-                       parent_name+=string(group,0,group.find(GROUP_NEST_CHAR));
-
-                       if(!find_group_row(parent_name, iter))
-                               iter=on_group_added(parent_name);
-
-                       group=String(group,group.find(GROUP_NEST_CHAR)+1,String::npos);
-               }while(group.find(GROUP_NEST_CHAR)!=String::npos);
-
-               if(parent_name.size())
-                       parent_name+=GROUP_NEST_CHAR;
-               parent_name+=group;
-
-               if(iter)
-               {
-                       Gtk::TreeRow row(*(prepend(iter->children())));
-                       row[model.group_name]=parent_name;
-                       row[model.is_layer]=false;
-                       row[model.is_group]=true;
-                       on_activity();
-                       return row;
-               }
-       }
-
-       Gtk::TreeRow row(*(append()));
-       row[model.group_name]=group;
-       row[model.is_layer]=false;
-       row[model.is_group]=true;
-       on_activity();
-       return row;
-}
-
-bool
-LayerGroupTreeStore::on_group_removed(synfig::String group)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(find_group_row(group,iter) && iter->children().size()==0)
-               erase(iter);
-       else
-               return false;
-
-       return true;
-}
-
-bool
-LayerGroupTreeStore::on_group_changed(synfig::String /*group*/)
-{
-       return true;
-}
-
-void
-LayerGroupTreeStore::on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer)
-{
-       if(!layer->get_canvas())
-               return;
-       Gtk::TreeModel::Children::iterator iter;
-       if(!find_group_row(group, iter))
-               iter=on_group_added(group);
-
-       Gtk::TreeRow layer_row(*(append(iter->children())));
-       set_row_layer(layer_row,layer);
-       on_activity();
-}
-
-void
-LayerGroupTreeStore::on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer)
-{
-       if(!layer->get_canvas())
-               return;
-       Gtk::TreeModel::Children::iterator iter;
-       if(!find_group_row(group, iter))
-               return;
-
-       Gtk::TreeModel::Children::iterator prev,layer_iter;
-
-       if(!find_layer_row_(layer, layer->get_canvas(), iter->children(), layer_iter, prev))
-               return;
-
-       erase(layer_iter);
-
-       on_activity();
-}
-
-void
-LayerGroupTreeStore::on_activity()
-{
-       // If we aren't rebuilding and the last action
-       // had something to do with groups, then go
-       // a head and present the groups dialog.
-       if(!rebuilding && canvas_interface()->get_instance()->get_most_recent_action() && canvas_interface()->get_instance()->get_most_recent_action()->get_name().find("Group")!=String::npos)
-       try
-       {
-               App::dock_manager->find_dockable("groups").present();
-       }
-       catch(...) { }
-}
-
-void
-LayerGroupTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(find_layer_row(handle,iter))
-               (*iter)[model.layer]=handle;
-       else
-       {
-               // Not need to send a warning when a layer changes its status and
-               // it is not found in any group.
-               //synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
-               rebuild();
-       }
-}
-
-
-void
-LayerGroupTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(find_layer_row(handle,iter))
-       {
-               Gtk::TreeRow row(*iter);
-
-               Layer::Handle layer(row[model.layer]);
-
-               if(desc.empty())
-               {
-                       //row[model.label]=layer->get_local_name();
-                       row[model.tooltip]=Glib::ustring(_("Layer"));
-               }
-               else
-                       //row[model.label]=layer->get_description();
-                       row[model.tooltip]=layer->get_local_name();
-       }
-       else
-       {
-               rebuild();
-       }
-}
-
-bool
-LayerGroupTreeStore::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)
-{
-       assert(layer);
-
-       //if(layer->get_canvas()==canvas)
-       {
-               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
-               {
-                       Gtk::TreeModel::Row row = *iter;
-                       if((bool)row[model.is_layer] && layer==(synfig::Layer::Handle)row[model.layer])
-                               return true;
-               }
-
-               iter=children().end();
-               //return false;
-       }
-
-       Gtk::TreeModel::Children::iterator iter2;
-
-       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
-       {
-               Gtk::TreeModel::Row row = *iter2;
-               assert((bool)true);
-
-               if(row.children().empty())
-                       continue;
-
-               /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
-               if(!canvas)
-                       continue;
-               */
-
-               if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
-                       return true;
-       }
-
-       iter=children().end();
-       return false;
-}
-
-bool
-LayerGroupTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
-{
-       Gtk::TreeModel::Children::iterator prev;
-       return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
-}
-
-bool
-LayerGroupTreeStore::find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter)
-{
-       Gtk::TreeModel::Children::iterator prev;
-       return find_group_row_(group,children(),iter,prev);
-}
-
-bool
-LayerGroupTreeStore::find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
-{
-       //if(layer->get_canvas()==canvas)
-       {
-               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
-               {
-                       Gtk::TreeModel::Row row = *iter;
-                       if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
-                               return true;
-               }
-
-               iter=children().end();
-               //return false;
-       }
-
-       Gtk::TreeModel::Children::iterator iter2;
-
-       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
-       {
-               Gtk::TreeModel::Row row = *iter2;
-               assert((bool)true);
-
-               if(row.children().empty())
-                       continue;
-
-               if(find_group_row_(group,iter2->children(),iter,prev))
-                       return true;
-       }
-
-       iter=children().end();
-       return false;
-}
-
-bool
-LayerGroupTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
-               return false;
-       if(iter==children().begin())
-               return false;
-       return true;
-}
diff --git a/synfig-studio/src/gui/layergrouptreestore.h b/synfig-studio/src/gui/layergrouptreestore.h
deleted file mode 100644 (file)
index cd0c196..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layergrouptreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
-#define __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <gtkmm/treeview.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class LayerGroupTreeStore :  public Gtk::TreeStore
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-       typedef std::list<synfig::Layer::Handle> LayerList;
-
-       class Model : public Gtk::TreeModel::ColumnRecord
-       {
-       public:
-               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
-               Gtk::TreeModelColumn<Glib::ustring> label;
-               Gtk::TreeModelColumn<Glib::ustring> tooltip;
-
-               Gtk::TreeModelColumn<Glib::ustring> group_name;
-               Gtk::TreeModelColumn<Glib::ustring> parent_group_name;
-
-               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
-
-               Gtk::TreeModelColumn<bool>                                              active;
-               Gtk::TreeModelColumn<bool>                                              is_layer;
-               Gtk::TreeModelColumn<bool>                                              is_group;
-               Gtk::TreeModelColumn<synfig::Layer::Handle>             layer;
-
-               Gtk::TreeModelColumn<LayerList>         all_layers;
-               Gtk::TreeModelColumn<LayerList>         child_layers;
-
-               Model()
-               {
-                       add(icon);
-                       add(label);
-                       add(group_name);
-                       add(parent_group_name);
-                       add(canvas);
-                       add(tooltip);
-                       add(active);
-                       add(layer);
-                       add(is_layer);
-                       add(is_group);
-                       add(all_layers);
-                       add(child_layers);
-               }
-       };
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       //! TreeModel for the layers
-       const Model model;
-
-       bool rebuilding;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
-       Glib::RefPtr<Gdk::Pixbuf> layer_icon;
-       Glib::RefPtr<Gdk::Pixbuf> group_icon;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
-       */
-
-private:
-
-       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
-       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-
-       virtual bool  row_draggable_vfunc (const TreeModel::Path& path)const;
-       virtual bool  drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
-       virtual bool  drag_data_delete_vfunc (const TreeModel::Path& path);
-       virtual bool  drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
-       virtual bool  row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
-
-
-       void on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer);
-       void on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer);
-
-       void on_activity();
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       bool on_layer_tree_event(GdkEvent *event);
-
-       void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
-
-       void on_layer_status_changed(synfig::Layer::Handle handle,bool);
-
-       bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
-
-       bool find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
-
-       bool on_group_removed(synfig::String group);
-       bool on_group_changed(synfig::String group);
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-       ~LayerGroupTreeStore();
-
-       Gtk::TreeRow on_group_added(synfig::String group);
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
-       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
-       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
-
-       bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
-       bool find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter);
-
-       bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
-       void rebuild();
-
-       void refresh();
-
-       void refresh_row(Gtk::TreeModel::Row &row);
-
-       void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
-
-       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
-
-       /*
- -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
-       */
-
-public:
-
-       static Glib::RefPtr<LayerGroupTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-
-}; // END of class LayerGroupTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/layerparamtreestore.cpp b/synfig-studio/src/gui/layerparamtreestore.cpp
deleted file mode 100644 (file)
index 8fe850a..0000000
+++ /dev/null
@@ -1,577 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layerparamtreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007, 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "layerparamtreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include "layertree.h"
-#include <synfigapp/action_system.h>
-#include <synfigapp/instance.h>
-#include "app.h"
-#include <ETL/clock>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-class Profiler : private etl::clock
-{
-       const std::string name;
-public:
-       Profiler(const std::string& name):name(name) { reset(); }
-       ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
-};
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static LayerParamTreeStore::Model& ModelHack()
-{
-       static LayerParamTreeStore::Model* model(0);
-       if(!model)model=new LayerParamTreeStore::Model;
-       return *model;
-}
-
-LayerParamTreeStore::LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,LayerTree* layer_tree):
-       Gtk::TreeStore                  (ModelHack()),
-       CanvasTreeStore                 (canvas_interface_),
-       layer_tree                              (layer_tree)
-{
-       queued=0;
-       // Connect all the signals
-       canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_changed));
-       canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_renamed));
-       canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_added));
-       canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_deleted));
-       canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_replaced));
-       canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_layer_param_changed));
-
-       canvas_interface()->signal_value_node_child_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_added));
-       canvas_interface()->signal_value_node_child_removed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_removed));
-
-
-       layer_tree->get_selection()->signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_rebuild));
-
-       signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_refresh));
-       rebuild();
-}
-
-LayerParamTreeStore::~LayerParamTreeStore()
-{
-       while(!changed_connection_list.empty())
-       {
-               changed_connection_list.back().disconnect();
-               changed_connection_list.pop_back();
-       }
-
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("LayerParamTreeStore::~LayerParamTreeStore(): Deleted");
-}
-
-Glib::RefPtr<LayerParamTreeStore>
-LayerParamTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree)
-{
-       return Glib::RefPtr<LayerParamTreeStore>(new LayerParamTreeStore(canvas_interface_,layer_tree));
-}
-
-
-
-void
-LayerParamTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
-       if(column<0)
-       {
-               synfig::error("LayerParamTreeStore::get_value_vfunc(): Bad column!");
-               return;
-       }
-
-/*     if(column==model.label.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(layer->get_non_empty_description());
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-*/
-       if(column==model.label.index())
-       {
-               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
-               Glib::ustring label;
-
-               if(!(*iter)[model.is_toplevel])
-                       return CanvasTreeStore::get_value_vfunc(iter,column,value);
-               synfig::ParamDesc param_desc((*iter)[model.param_desc]);
-               label=param_desc.get_local_name();
-
-               if(!(*iter)[model.is_inconsistent])
-               if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
-               {
-                       label+=strprintf(" (%s)",value_desc.get_value_node()->get_id().c_str());
-               }
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(label);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.is_toplevel.index())
-       {
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               TreeModel::Path path(get_path(iter));
-
-               x.set(path.get_depth()<=1);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       if(column==model.is_inconsistent.index())
-       {
-               if((*iter)[model.is_toplevel])
-               {
-                       CanvasTreeStore::get_value_vfunc(iter,column,value);
-                       return;
-               }
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(false);
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-       CanvasTreeStore::get_value_vfunc(iter,column,value);
-}
-
-
-
-void
-LayerParamTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
-       //if(!iterator_sane(row))
-       //      return;
-
-       if(column>=get_n_columns_vfunc())
-       {
-               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
-               return;
-       }
-
-       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
-       {
-               g_warning("LayerTreeStore::set_value_impl: Bad value type");
-               return;
-       }
-
-       try
-       {
-               if(column==model.value.index())
-               {
-                       Glib::Value<synfig::ValueBase> x;
-                       g_value_init(x.gobj(),model.value.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       if((bool)(*iter)[model.is_toplevel])
-                       {
-                               synfigapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Set Layer Params"));
-
-                               synfig::ParamDesc param_desc((*iter)[model.param_desc]);
-
-                               LayerList::iterator iter2(layer_list.begin());
-
-                               for(;iter2!=layer_list.end();++iter2)
-                               {
-                                       if(!canvas_interface()->change_value(synfigapp::ValueDesc(*iter2,param_desc.get_name()),x.get()))
-                                       {
-                                               // ERROR!
-                                               group.cancel();
-                                               App::dialog_error_blocking(_("Error"),_("Unable to set all layer parameters."));
-
-                                               return;
-                                       }
-                               }
-                       }
-                       else
-                       {
-                               canvas_interface()->change_value((*iter)[model.value_desc],x.get());
-                       }
-                       return;
-               }
-               else
-/*
-               if(column==model.active.index())
-               {
-                       synfig::Layer::Handle layer((*iter)[model.layer]);
-
-                       if(!layer)return;
-
-                       Glib::Value<bool> x;
-                       g_value_init(x.gobj(),model.active.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
-
-                       if(!action)
-                               return;
-
-                       action->set_param("canvas",canvas_interface()->get_canvas());
-                       action->set_param("canvas_interface",canvas_interface());
-                       action->set_param("layer",layer);
-                       action->set_param("new_status",bool(x.get()));
-
-                       canvas_interface()->get_instance()->perform_action(action);
-                       return;
-               }
-               else
-*/
-               CanvasTreeStore::set_value_impl(iter,column, value);
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
-
-
-
-
-
-
-
-
-
-
-void
-LayerParamTreeStore::rebuild()
-{
-       // Profiler profiler("LayerParamTreeStore::rebuild()");
-       if(queued)queued=0;
-       clear();
-       layer_list=layer_tree->get_selected_layers();
-
-       if(layer_list.size()<=0)
-               return;
-
-       // Get rid of all the connections,
-       // and clear the connection map.
-       //while(!connection_map.empty())connection_map.begin()->second.disconnect(),connection_map.erase(connection_map.begin());
-       while(!changed_connection_list.empty())
-       {
-               changed_connection_list.back().disconnect();
-               changed_connection_list.pop_back();
-       }
-
-       struct REBUILD_HELPER
-       {
-               ParamVocab vocab;
-               Layer::Handle layer_0;
-
-               static ParamVocab::iterator find_param_desc(ParamVocab& vocab, const synfig::String& x)
-               {
-                       ParamVocab::iterator iter;
-
-                       for(iter=vocab.begin();iter!=vocab.end();++iter)
-                               if(iter->get_name()==x)
-                                       break;
-                       return iter;
-               }
-
-               void process_vocab(synfig::Layer::Handle layer_n)
-               {
-                       ParamVocab x = layer_n->get_param_vocab();
-                       ParamVocab::iterator iter;
-
-                       for(iter=vocab.begin();iter!=vocab.end();++iter)
-                       {
-                               String name(iter->get_name());
-                               ParamVocab::iterator iter2(find_param_desc(x,name));
-                               if(iter2==x.end() ||
-                                  layer_0->get_param(name).get_type() != layer_n->get_param(name).get_type())
-                               {
-                                       // remove it and start over
-                                       vocab.erase(iter);
-                                       iter=vocab.begin();
-                                       iter--;
-                                       continue;
-                               }
-                       }
-               }
-
-       } rebuild_helper;
-
-
-       {
-               LayerList::iterator iter(layer_list.begin());
-               rebuild_helper.vocab=(*iter)->get_param_vocab();
-               rebuild_helper.layer_0=*iter;
-
-               for(++iter;iter!=layer_list.end();++iter)
-               {
-                       rebuild_helper.process_vocab(*iter);
-                       changed_connection_list.push_back(
-                               (*iter)->signal_changed().connect(
-                                       sigc::mem_fun(
-                                               *this,
-                                               &LayerParamTreeStore::changed
-                                       )
-                               )
-                       );
-               }
-       }
-
-       ParamVocab::iterator iter;
-       for(iter=rebuild_helper.vocab.begin();iter!=rebuild_helper.vocab.end();++iter)
-       {
-               if(iter->get_hidden())
-                       continue;
-
-               /*
-               if(iter->get_animation_only())
-               {
-                       int length(layer_list.front()->get_canvas()->rend_desc().get_frame_end()-layer_list.front()->get_canvas()->rend_desc().get_frame_start());
-                       if(!length)
-                               continue;
-               }
-               */
-               Gtk::TreeRow row(*(append()));
-               synfigapp::ValueDesc value_desc(layer_list.front(),iter->get_name());
-               CanvasTreeStore::set_row(row,value_desc);
-               if(value_desc.is_value_node())
-               {
-                       changed_connection_list.push_back(
-                               value_desc.get_value_node()->signal_changed().connect(
-                                       sigc::mem_fun(
-                                               this,
-                                               &LayerParamTreeStore::changed
-                                       )
-                               )
-                       );
-               }
-               if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
-               {
-                       Canvas::Handle canvas_handle = value_desc.get_value().get(Canvas::Handle());
-                       if(canvas_handle) changed_connection_list.push_back(
-                               canvas_handle->signal_changed().connect(
-                                       sigc::mem_fun(
-                                               this,
-                                               &LayerParamTreeStore::changed
-                                       )
-                               )
-                       );
-               }
-               //row[model.label] = iter->get_local_name();
-               row[model.param_desc] = *iter;
-               row[model.canvas] = layer_list.front()->get_canvas();
-               row[model.is_inconsistent] = false;
-               //row[model.is_toplevel] = true;
-
-
-               LayerList::iterator iter2(layer_list.begin());
-               ValueBase value((*iter2)->get_param(iter->get_name()));
-               for(++iter2;iter2!=layer_list.end();++iter2)
-               {
-                       if(value!=((*iter2)->get_param(iter->get_name())))
-                       {
-                               row[model.is_inconsistent] = true;
-                               while(!row.children().empty() && erase(row.children().begin()))
-                                       ;
-                               break;
-                       }
-               }
-       }
-}
-
-void
-LayerParamTreeStore::queue_refresh()
-{
-       if(queued)
-               return;
-       queued=1;
-       queue_connection.disconnect();
-       queue_connection=Glib::signal_timeout().connect(
-               sigc::bind_return(
-                       sigc::mem_fun(*this,&LayerParamTreeStore::refresh),
-                       false
-               )
-       ,150);
-
-}
-
-void
-LayerParamTreeStore::queue_rebuild()
-{
-       if(queued==2)
-               return;
-       queued=2;
-       queue_connection.disconnect();
-       queue_connection=Glib::signal_timeout().connect(
-               sigc::bind_return(
-                       sigc::mem_fun(*this,&LayerParamTreeStore::rebuild),
-                       false
-               )
-       ,150);
-
-}
-
-void
-LayerParamTreeStore::refresh()
-{
-       if(queued)queued=0;
-
-       Gtk::TreeModel::Children children_(children());
-
-       Gtk::TreeModel::Children::iterator iter;
-
-       if(!children_.empty())
-               for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
-               {
-                       Gtk::TreeRow row=*iter;
-                       refresh_row(row);
-               }
-}
-
-void
-LayerParamTreeStore::refresh_row(Gtk::TreeModel::Row &row)
-{
-       if(row[model.is_toplevel])
-       {
-               row[model.is_inconsistent] = false;
-               ParamDesc param_desc(row[model.param_desc]);
-
-               LayerList::iterator iter2(layer_list.begin());
-               ValueBase value((*iter2)->get_param(param_desc.get_name()));
-               for(++iter2;iter2!=layer_list.end();++iter2)
-               {
-                       if(value!=((*iter2)->get_param(param_desc.get_name())))
-                       {
-                               row[model.is_inconsistent] = true;
-                               while(!row.children().empty() && erase(row.children().begin()))
-                                       ;
-                               return;
-                       }
-               }
-       }
-
-       //handle<ValueNode> value_node=row[model.value_node];
-       //if(value_node)
-       {
-               CanvasTreeStore::refresh_row(row);
-               return;
-       }
-}
-
-void
-LayerParamTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc)
-{
-       Gtk::TreeModel::Children children = row.children();
-       while(!children.empty() && erase(children.begin()))
-               ;
-
-       CanvasTreeStore::set_row(row,value_desc);
-}
-
-void
-LayerParamTreeStore::on_value_node_added(synfig::ValueNode::Handle /*value_node*/)
-{
-//     queue_refresh();
-}
-
-void
-LayerParamTreeStore::on_value_node_deleted(synfig::ValueNode::Handle /*value_node*/)
-{
-//     queue_refresh();
-}
-
-void
-LayerParamTreeStore::on_value_node_child_added(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
-{
-       queue_rebuild();
-}
-
-void
-LayerParamTreeStore::on_value_node_child_removed(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
-{
-       rebuild();
-}
-
-void
-LayerParamTreeStore::on_value_node_changed(synfig::ValueNode::Handle /*value_node*/)
-{
-       queue_refresh();
-}
-
-void
-LayerParamTreeStore::on_value_node_renamed(synfig::ValueNode::Handle /*value_node*/)
-{
-       rebuild();
-}
-
-void
-LayerParamTreeStore::on_value_node_replaced(synfig::ValueNode::Handle /*replaced_value_node*/,synfig::ValueNode::Handle /*new_value_node*/)
-{
-       queue_rebuild();
-}
-
-void
-LayerParamTreeStore::on_layer_param_changed(synfig::Layer::Handle /*handle*/,synfig::String /*param_name*/)
-{
-       queue_refresh();
-}
diff --git a/synfig-studio/src/gui/layerparamtreestore.h b/synfig-studio/src/gui/layerparamtreestore.h
deleted file mode 100644 (file)
index ce96cbe..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layerparamtreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
-#define __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include "canvastreestore.h"
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <synfig/paramdesc.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class LayerTree;
-
-class LayerParamTreeStore : public CanvasTreeStore
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-       typedef std::list<synfig::Layer::Handle> LayerList;
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       //! TreeModel for the layer parameters
-       class Model : public CanvasTreeStore::Model
-       {
-       public:
-
-               Gtk::TreeModelColumn<synfig::ParamDesc> param_desc;
-
-               Gtk::TreeModelColumn<bool>      is_inconsistent;
-               Gtk::TreeModelColumn<bool>      is_toplevel;
-
-               Model()
-               {
-                       add(param_desc);
-                       add(is_inconsistent);
-                       add(is_toplevel);
-               }
-       };
-
-       Model model;
-
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       int queued;
-
-       LayerTree* layer_tree;
-
-       LayerList layer_list;
-
-       sigc::connection queue_connection;
-
-       std::list<sigc::connection> changed_connection_list;
-
-       sigc::signal<void> signal_changed_;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-protected:
-       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
-       virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       void on_value_node_child_added(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
-       void on_value_node_child_removed(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
-
-       void on_value_node_added(synfig::ValueNode::Handle value_node);
-       void on_value_node_deleted(synfig::ValueNode::Handle value_node);
-       virtual void on_value_node_changed(synfig::ValueNode::Handle value_node);
-       virtual void on_value_node_renamed(synfig::ValueNode::Handle value_node);
-       void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
-       void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,
-               LayerTree* layer_tree);
-       ~LayerParamTreeStore();
-
-       void rebuild();
-
-       void refresh();
-
-       void queue_refresh();
-
-       void queue_rebuild();
-
-       void refresh_row(Gtk::TreeModel::Row &row);
-
-       sigc::signal<void>& signal_changed() { return signal_changed_; }
-
-       void changed() { signal_changed_(); }
-
-       /*
- -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
-       */
-
-public:
-
-       static Glib::RefPtr<LayerParamTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree);
-}; // END of class LayerParamTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/layertree.cpp b/synfig-studio/src/gui/layertree.cpp
deleted file mode 100644 (file)
index a69f234..0000000
+++ /dev/null
@@ -1,1232 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layertree.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007, 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "layertree.h"
-#include "layerparamtreestore.h"
-#include "cellrenderer_value.h"
-#include "cellrenderer_timetrack.h"
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/paned.h>
-#include "app.h"
-#include "instance.h"
-#include <gtkmm/treemodelsort.h>
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-#  include <synfig/timepointcollect.h>
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-#ifndef SMALL_BUTTON
-#define SMALL_BUTTON(button,stockid,tooltip)   \
-       button = manage(new class Gtk::Button());       \
-       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
-       button->add(*icon);     \
-       tooltips_.set_tip(*button,tooltip);     \
-       icon->set_padding(0,0);\
-       icon->show();   \
-       button->set_relief(Gtk::RELIEF_NONE); \
-       button->show()
-#endif
-
-#ifndef NORMAL_BUTTON
-#define NORMAL_BUTTON(button,stockid,tooltip)  \
-       button = manage(new class Gtk::Button());       \
-       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
-       button->add(*icon);     \
-       tooltips_.set_tip(*button,tooltip);     \
-       icon->set_padding(0,0);\
-       icon->show();   \
-       /*button->set_relief(Gtk::RELIEF_NONE);*/ \
-       button->show()
-#endif
-
-#define NEW_SMALL_BUTTON(x,y,z)        Gtk::Button *SMALL_BUTTON(x,y,z)
-
-#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-LayerTree::LayerTree():
-       layer_amount_adjustment_(1,0,1,0.01,0.01,0)
-{
-       param_tree_view_=new Gtk::TreeView;
-       layer_tree_view_=new Gtk::TreeView;
-
-       //Gtk::HPaned* hpaned(manage(new Gtk::HPaned()));
-       //hpaned->show();
-       //attach(*hpaned, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
-       //attach(*create_layer_tree(), 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
-
-       create_layer_tree();
-       create_param_tree();
-
-       //hpaned->pack1(*create_layer_tree(),false,false);
-       //hpaned->pack2(*create_param_tree(),true,false);
-       //hpaned->set_position(200);
-       hbox=manage(new Gtk::HBox());
-
-       attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       attach(blend_method_widget, 2, 3, 1, 2,Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-
-       layer_amount_hscale=manage(new Gtk::HScale(layer_amount_adjustment_));
-       layer_amount_hscale->set_digits(2);
-       layer_amount_hscale->set_value_pos(Gtk::POS_LEFT);
-       layer_amount_hscale->set_sensitive(false);
-       layer_amount_hscale->set_update_policy( Gtk::UPDATE_DISCONTINUOUS);
-       attach(*layer_amount_hscale, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 1, 1);
-       layer_amount_adjustment_.signal_value_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_amount_value_changed));
-
-       Gtk::Image *icon;
-       //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
-       Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
-       SMALL_BUTTON(button_raise,"gtk-go-up","Raise");
-       SMALL_BUTTON(button_lower,"gtk-go-down","Lower");
-       SMALL_BUTTON(button_duplicate,"synfig-duplicate","Duplicate");
-       SMALL_BUTTON(button_encapsulate,"synfig-encapsulate","Encapsulate");
-       SMALL_BUTTON(button_delete,"gtk-delete","Delete");
-
-       hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
-       hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
-       hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
-       hbox->pack_start(*button_encapsulate,Gtk::PACK_SHRINK);
-       hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
-
-       // button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_raise_pressed));
-       // button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_lower_pressed));
-       // button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_duplicate_pressed));
-       // button_encapsulate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_encapsulate_pressed));
-       // button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_delete_pressed));
-
-       button_raise->set_sensitive(false);
-       button_lower->set_sensitive(false);
-       button_duplicate->set_sensitive(false);
-       button_encapsulate->set_sensitive(false);
-       button_delete->set_sensitive(false);
-
-       get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_selection_changed));
-
-       get_layer_tree_view().set_reorderable(true);
-       get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
-       //get_param_tree_view().get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
-       get_layer_tree_view().show();
-       get_param_tree_view().show();
-
-       hbox->show();
-       layer_amount_hscale->show();
-       blend_method_widget.show();
-
-       tooltips_.enable();
-       disable_amount_changed_signal=false;
-
-       blend_method_widget.set_param_desc(ParamDesc(Color::BlendMethod(),"blend_method"));
-
-       blend_method_widget.set_value((int)Color::BLEND_COMPOSITE);
-       blend_method_widget.set_size_request(150,-1);
-       blend_method_widget.set_sensitive(false);
-       blend_method_widget.signal_activate().connect(sigc::mem_fun(*this, &studio::LayerTree::on_blend_method_changed));
-}
-
-LayerTree::~LayerTree()
-{
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("LayerTree::~LayerTree(): Deleted");
-}
-
-Gtk::Widget*
-LayerTree::create_layer_tree()
-{
-       const LayerTreeStore::Model model;
-
-       {       // --- O N / O F F ----------------------------------------------------
-               //int index;
-               //index=get_layer_tree_view().append_column_editable(_(" "),layer_model.active);
-               //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
-
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_(" ")) );
-
-               // Set up the icon cell-renderer
-               Gtk::CellRendererToggle* cellrenderer = Gtk::manage( new Gtk::CellRendererToggle() );
-               cellrenderer->signal_toggled().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_toggle));
-
-               column->pack_start(*cellrenderer,false);
-               column->add_attribute(cellrenderer->property_active(), layer_model.active);
-               get_layer_tree_view().append_column(*column);
-       }
-
-       {       // --- I C O N --------------------------------------------------------
-               int index;
-               index=get_layer_tree_view().append_column(_("Z"),layer_model.icon);
-               Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
-               get_layer_tree_view().set_expander_column(*column);
-
-               column->set_sort_column(layer_model.z_depth);
-               //column->set_reorderable();
-               //column->set_resizable();
-               //column->set_clickable();
-
-               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
-               //column->pack_start(*icon_cellrenderer,false);
-               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
-       }
-       //get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
-       {       // --- N A M E --------------------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
-
-               // Set up the icon cell-renderer
-               Gtk::CellRendererText* cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
-               column->pack_start(*cellrenderer,false);
-               column->add_attribute(cellrenderer->property_text(), layer_model.label);
-               cellrenderer->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_renamed));
-               cellrenderer->property_editable()=true;
-
-               column->set_reorderable();
-               // column->set_resizable();
-               column->set_clickable(true);
-               column->set_sort_column(layer_model.label);
-
-               get_layer_tree_view().append_column(*column);
-
-               //              int index;
-//             index=get_layer_tree_view().append_column_editable(_("Layer"),layer_model.label);
-               //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
-
-               //get_layer_tree_view().set_expander_column(*column);
-
-               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
-               //column->pack_start(*icon_cellrenderer,false);
-               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
-       }
-       {       // --- Z D E P T H ----------------------------------------------------
-               int index;
-               index=get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
-               column_z_depth=get_layer_tree_view().get_column(index-1);
-
-               column_z_depth->set_reorderable();
-               column_z_depth->set_resizable();
-               column_z_depth->set_clickable();
-
-               column_z_depth->set_sort_column(layer_model.z_depth);
-       }
-
-       get_layer_tree_view().set_enable_search(true);
-       get_layer_tree_view().set_search_column(layer_model.label);
-       get_layer_tree_view().set_search_equal_func(sigc::ptr_fun(&studio::LayerTreeStore::search_func));
-
-       std::list<Gtk::TargetEntry> listTargets;
-       listTargets.push_back( Gtk::TargetEntry("LAYER") );
-       get_layer_tree_view().drag_dest_set(listTargets);
-
-       // This makes things easier to read.
-       get_layer_tree_view().set_rules_hint();
-
-       // Make us more sensitive to several events
-       //get_layer_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
-       get_layer_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_tree_event));
-       get_layer_tree_view().show();
-
-       Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
-       scroll->set_flags(Gtk::CAN_FOCUS);
-       scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
-       //scroll->add(get_layer_tree_view());
-       scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
-       scroll->show();
-
-       return scroll;
-}
-
-Gtk::Widget*
-LayerTree::create_param_tree()
-{
-       Pango::AttrList attr_list;
-       {
-               Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8));
-               pango_size.set_start_index(0);
-               pango_size.set_end_index(64);
-               attr_list.change(pango_size);
-       }
-
-       Gtk::IconSize icon_size(Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
-       {       // --- N A M E --------------------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
-
-               // Set up the icon cell-renderer
-               Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
-               column->pack_start(*icon_cellrenderer,false);
-               column->add_attribute(icon_cellrenderer->property_pixbuf(), param_model.icon);
-
-               // Pack the label into the column
-               //column->pack_start(layer_model.label,true);
-               Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
-               column->pack_start(*text_cellrenderer,false);
-               column->add_attribute(text_cellrenderer->property_text(), param_model.label);
-               text_cellrenderer->property_attributes()=attr_list;
-
-               text_cellrenderer->property_foreground()=Glib::ustring("#7f7f7f");
-               column->add_attribute(text_cellrenderer->property_foreground_set(),param_model.is_inconsistent);
-
-               // Pack the label into the column
-               //column->pack_start(param_model.label,true);
-
-               // Set up the value-node icon cell-renderer to be on the far right
-               Gtk::CellRendererPixbuf* valuenode_icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
-               column->pack_end(*valuenode_icon_cellrenderer,false);
-               valuenode_icon_cellrenderer->property_pixbuf()=Gtk::Button().render_icon(Gtk::StockID("synfig-value_node"),icon_size);
-               column->add_attribute(valuenode_icon_cellrenderer->property_visible(), param_model.is_shared);
-
-               // Finish setting up the column
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable();
-
-               get_param_tree_view().append_column(*column);
-       }
-       {       // --- V A L U E  -----------------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Value")) );
-
-               // Set up the value cell-renderer
-               cellrenderer_value=LayerParamTreeStore::add_cell_renderer_value(column);
-               cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_edited_value));
-               cellrenderer_value->property_value()=synfig::ValueBase();
-               column->add_attribute(cellrenderer_value->property_param_desc(), param_model.param_desc);
-               column->add_attribute(cellrenderer_value->property_inconsistent(),param_model.is_inconsistent);
-               //cellrenderer_value->property_canvas()=canvas_interface->get_canvas(); // Is this line necessary?
-               cellrenderer_value->property_attributes()=attr_list;
-
-               // Finish setting up the column
-               get_param_tree_view().append_column(*column);
-               column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
-               column->set_clickable();
-               column->set_min_width(120);
-               column->set_reorderable();
-               column->set_resizable();
-       }
-       {       // --- T Y P E --------------------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Type")) );
-               Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
-               column->pack_start(*text_cellrenderer,false);
-               column->add_attribute(text_cellrenderer->property_text(), param_model.type);
-               text_cellrenderer->property_attributes()=attr_list;
-               get_param_tree_view().append_column(*column);
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_clickable();
-               column->set_sort_column(param_model.type);
-       }
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-       {       // --- T I M E   T R A C K --------------------------------------------
-               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
-               column_time_track=column;
-
-               // Set up the value-node cell-renderer
-               cellrenderer_time_track=LayerParamTreeStore::add_cell_renderer_value_node(column);
-               cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
-               cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_clicked_layertree) );
-               cellrenderer_time_track->signal_waypoint_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_changed) );
-               column->add_attribute(cellrenderer_time_track->property_value_desc(), param_model.value_desc);
-               column->add_attribute(cellrenderer_time_track->property_canvas(), param_model.canvas);
-               column->add_attribute(cellrenderer_time_track->property_visible(), param_model.is_value_node);
-
-               // Finish setting up the column
-               column->set_reorderable();
-               column->set_resizable();
-               column->set_min_width(200);
-
-               if (!getenv("SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK"))
-                       get_param_tree_view().append_column(*column);
-       }
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
-       // This makes things easier to read.
-       get_param_tree_view().set_rules_hint();
-
-       // Make us more sensitive to several events
-       get_param_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
-
-       get_param_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_param_tree_event));
-       get_param_tree_view().show();
-
-       Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
-       scroll->set_flags(Gtk::CAN_FOCUS);
-       scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
-       //scroll->add(get_param_tree_view());
-       scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
-       scroll->show();
-
-       //column_time_track->set_visible(false);
-
-       return scroll;
-}
-
-void
-LayerTree::on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node)
-{
-       synfigapp::Action::ParamList param_list;
-       param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-       param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-       param_list.add("value_node",value_node);
-       param_list.add("waypoint",waypoint);
-//     param_list.add("time",canvas_interface()->get_time());
-
-       etl::handle<studio::Instance>::cast_static(layer_tree_store_->canvas_interface()->get_instance())->process_action("WaypointSetSmart", param_list);
-}
-
-void
-LayerTree::select_layer(synfig::Layer::Handle layer)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(layer_tree_store_->find_layer_row(layer,iter))
-       {
-               if(sorted_layer_tree_store_)
-                       iter=sorted_layer_tree_store_->convert_child_iter_to_iter(iter);
-
-               Gtk::TreePath path(iter);
-               for(int i=path.get_depth();i;i--)
-               {
-                       int j;
-                       path=Gtk::TreePath(iter);
-                       for(j=i;j;j--)
-                               path.up();
-                       get_layer_tree_view().expand_row(path,false);
-               }
-               get_layer_tree_view().scroll_to_row(Gtk::TreePath(iter));
-               get_layer_tree_view().get_selection()->select(iter);
-       }
-}
-
-void
-LayerTree::select_all_children(Gtk::TreeModel::Children::iterator iter)
-{
-       get_layer_tree_view().get_selection()->select(iter);
-       if((bool)(*iter)[layer_model.children_lock])
-               return;
-       get_layer_tree_view().expand_row(layer_tree_store_->get_path(iter),false);
-       Gtk::TreeModel::Children children(iter->children());
-       for(iter=children.begin();iter!=children.end();++iter)
-               select_all_children(iter);
-}
-
-void
-LayerTree::select_all_children_layers(synfig::Layer::Handle layer)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(layer_tree_store_->find_layer_row(layer,iter))
-               select_all_children(iter);
-}
-
-void
-LayerTree::select_layers(const LayerList &layer_list)
-{
-       LayerList::const_iterator iter;
-       for(iter = layer_list.begin(); iter != layer_list.end(); ++iter)
-               select_layer(*iter);
-}
-
-static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerTree::LayerList* ret)
-{
-       const LayerTreeStore::Model layer_tree_model;
-       ret->push_back((Layer::Handle)(*iter)[layer_tree_model.layer]);
-}
-
-LayerTree::LayerList
-LayerTree::get_selected_layers()const
-{
-       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<Gtk::TreeView&>(get_layer_tree_view()).get_selection();
-
-       if(!selection)
-               return LayerList();
-
-       LayerList ret;
-
-       selection->selected_foreach_iter(
-               sigc::bind(
-                       sigc::ptr_fun(
-                               &__layer_grabber
-                       ),
-                       &ret
-               )
-       );
-
-       return ret;
-}
-
-synfig::Layer::Handle
-LayerTree::get_selected_layer()const
-{
-       LayerList layers(get_selected_layers());
-
-       if(layers.empty())
-               return 0;
-
-       return *layers.begin();
-}
-
-void
-LayerTree::clear_selected_layers()
-{
-       get_layer_tree_view().get_selection()->unselect_all();
-}
-
-void
-LayerTree::set_show_timetrack(bool x)
-{
-       //column_time_track->set_visible(x);
-//     column_time_track->set_visible(false);
-       column_z_depth->set_visible(x);
-}
-
-void
-LayerTree::set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store)
-{
-       layer_tree_store_=layer_tree_store;
-
-       if(false)
-       {
-               sorted_layer_tree_store_=Gtk::TreeModelSort::create(layer_tree_store);
-
-               sorted_layer_tree_store_->set_default_sort_func(sigc::ptr_fun(&studio::LayerTreeStore::z_sorter));
-
-               //sorted_store->set_sort_func(model.time.index(),sigc::mem_fun(&studio::KeyframeTreeStore::time_sorter));
-               //sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
-
-               get_layer_tree_view().set_model(sorted_layer_tree_store_);
-       }
-       else
-               get_layer_tree_view().set_model(layer_tree_store_);
-
-       layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
-
-       //layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
-
-       layer_tree_store_->canvas_interface()->signal_time_changed().connect(
-               sigc::mem_fun(
-                       &get_param_tree_view(),
-                       &Gtk::Widget::queue_draw
-               )
-       );
-       if(!param_tree_store_)
-       {
-               param_tree_store_=LayerParamTreeStore::create(layer_tree_store_->canvas_interface(), this);
-               get_param_tree_view().set_model(param_tree_store_);
-       }
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-       if(cellrenderer_time_track && layer_tree_store_ && layer_tree_store_->canvas_interface())
-               cellrenderer_time_track->set_canvas_interface(layer_tree_store_->canvas_interface());
-#endif // TIMETRACK_IN_PARAMS_PANEL
-}
-
-void
-LayerTree::set_time_adjustment(Gtk::Adjustment &adjustment)
-{
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-       cellrenderer_time_track->set_adjustment(adjustment);
-#endif // TIMETRACK_IN_PARAMS_PANEL
-       adjustment.signal_value_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
-       adjustment.signal_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
-}
-
-void
-LayerTree::on_dirty_preview()
-{
-/*
-       if(quick_layer && !disable_amount_changed_signal)
-       {
-               layer_amount_hscale->set_sensitive(true);
-               disable_amount_changed_signal=true;
-               layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
-               disable_amount_changed_signal=false;
-               if(quick_layer->get_param("blend_method").is_valid())
-               {
-                       blend_method_widget.set_sensitive(true);
-                       disable_amount_changed_signal=true;
-                       blend_method_widget.set_value(quick_layer->get_param("blend_method"));
-                       disable_amount_changed_signal=false;
-               }
-       }
-*/
-}
-
-void
-LayerTree::on_selection_changed()
-{
-       synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-
-       Gtk::TreeIter iter;
-       if(last_top_selected_layer && !layer_tree_store_->find_layer_row(last_top_selected_layer,iter))
-       {
-               if(layer_list.empty())
-               {
-                       last_top_selected_layer=0;
-                       layer_tree_view_->get_selection()->select(last_top_selected_path);
-                       return;
-               }
-       }
-
-       {
-               if(!layer_list.empty())
-               {
-                       last_top_selected_layer=layer_list.front();
-                       last_top_selected_path=*layer_tree_view_->get_selection()->get_selected_rows().begin();
-               }
-               else
-               {
-                       last_top_selected_layer=0;
-               }
-       }
-
-       if(layer_list.empty())
-       {
-               button_raise->set_sensitive(false);
-               button_lower->set_sensitive(false);
-               button_duplicate->set_sensitive(false);
-               button_encapsulate->set_sensitive(false);
-               button_delete->set_sensitive(false);
-               layer_amount_hscale->set_sensitive(false);
-               blend_method_widget.set_sensitive(false);
-               return;
-       }
-
-       button_raise->set_sensitive(true);
-       button_lower->set_sensitive(true);
-       button_duplicate->set_sensitive(true);
-       button_encapsulate->set_sensitive(true);
-       button_delete->set_sensitive(true);
-
-       if(layer_list.size()==1 && (*layer_list.begin())->get_param("amount").is_valid()&& (*layer_list.begin())->get_param("amount").same_type_as(Real()))
-       {
-               quick_layer=*layer_list.begin();
-       }
-       else
-               quick_layer=0;
-
-       if(quick_layer)
-       {
-               layer_amount_hscale->set_sensitive(true);
-               disable_amount_changed_signal=true;
-               layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
-               disable_amount_changed_signal=false;
-               if(quick_layer->get_param("blend_method").is_valid())
-               {
-                       blend_method_widget.set_sensitive(true);
-                       disable_amount_changed_signal=true;
-                       blend_method_widget.set_value(quick_layer->get_param("blend_method"));
-                       disable_amount_changed_signal=false;
-               }
-               else
-                       blend_method_widget.set_sensitive(false);
-       }
-       else
-       {
-               layer_amount_hscale->set_sensitive(false);
-               blend_method_widget.set_sensitive(false);
-       }
-}
-
-void
-LayerTree::on_blend_method_changed()
-{
-       if(disable_amount_changed_signal)
-               return;
-       if(!quick_layer)
-               return;
-
-       if(quick_layer->get_param("blend_method").is_valid())
-       {
-               disable_amount_changed_signal=true;
-               signal_edited_value()(synfigapp::ValueDesc(quick_layer,"blend_method"),blend_method_widget.get_value());
-               disable_amount_changed_signal=false;
-       }
-}
-
-void
-LayerTree::on_amount_value_changed()
-{
-       if(disable_amount_changed_signal)
-               return;
-       if(!quick_layer)
-               return;
-
-       disable_amount_changed_signal=true;
-       signal_edited_value()(synfigapp::ValueDesc(quick_layer,"amount"),synfig::ValueBase(layer_amount_adjustment_.get_value()));
-       disable_amount_changed_signal=false;
-}
-
-void
-LayerTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
-       if(!row)
-               return;
-       row[param_model.value]=value;
-       //signal_edited_value()(row[param_model.value_desc],value);
-}
-
-void
-LayerTree::on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
-       if(!row)
-               return;
-       row[layer_model.label]=value;
-       get_layer_tree_view().columns_autosize();
-}
-
-void
-LayerTree::on_layer_toggle(const Glib::ustring& path_string)
-{
-       Gtk::TreePath path(path_string);
-
-       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
-       bool active=static_cast<bool>(row[layer_model.active]);
-       row[layer_model.active]=!active;
-}
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-void
-LayerTree::on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
-                                                                                const synfig::Time& time __attribute__ ((unused)),
-                                                                                const synfig::Time& time_offset __attribute__ ((unused)),
-                                                                                int button __attribute__ ((unused)))
-{
-       std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
-       synfig::waypoint_collect(waypoint_set,time,node);
-
-       synfigapp::ValueDesc value_desc;
-
-       if (waypoint_set.size() == 1)
-       {
-               ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
-               assert(value_node);
-
-               Gtk::TreeRow row;
-               if (param_tree_store_->find_first_value_node(value_node, row) && row)
-                       value_desc = static_cast<synfigapp::ValueDesc>(row[param_tree_store_->model.value_desc]);
-       }
-
-       if (!waypoint_set.empty())
-               signal_waypoint_clicked_layertree()(value_desc,waypoint_set,button);
-}
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
-bool
-LayerTree::on_layer_tree_event(GdkEvent *event)
-{
-    switch(event->type)
-    {
-       case GDK_BUTTON_PRESS:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!get_layer_tree_view().get_path_at_pos(
-                               int(event->button.x),int(event->button.y),      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-                       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-                       if(column->get_first_cell_renderer()==cellrenderer_time_track)
-                               return signal_layer_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
-                       else
-#endif // TIMETRACK_IN_PARAMS_PANEL
-                       if(column->get_first_cell_renderer()==cellrenderer_value)
-                               return signal_layer_user_click()(event->button.button,row,COLUMNID_VALUE);
-                       else
-                               return signal_layer_user_click()(event->button.button,row,COLUMNID_NAME);
-
-               }
-               break;
-
-       case GDK_MOTION_NOTIFY:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!get_layer_tree_view().get_path_at_pos(
-                               (int)event->button.x,(int)event->button.y,      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-
-                       if(!get_layer_tree_view().get_model()->get_iter(path))
-                               break;
-
-                       Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-                       if(cellrenderer_time_track==column->get_first_cell_renderer())
-                               // Movement on TimeLine
-                               return true;
-                       else
-#endif // TIMETRACK_IN_PARAMS_PANEL
-                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
-                       {
-                               tooltips_.unset_tip(*this);
-                               Glib::ustring tooltips_string(row[layer_model.tooltip]);
-                               last_tooltip_path=path;
-                               if(!tooltips_string.empty())
-                               {
-                                       tooltips_.set_tip(*this,tooltips_string);
-                                       tooltips_.force_window();
-                               }
-                       }
-               }
-               break;
-       case GDK_BUTTON_RELEASE:
-               break;
-       default:
-               break;
-       }
-       return false;
-}
-
-bool
-LayerTree::on_param_tree_event(GdkEvent *event)
-{
-    switch(event->type)
-    {
-       case GDK_BUTTON_PRESS:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!get_param_tree_view().get_path_at_pos(
-                               int(event->button.x),int(event->button.y),      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-                       const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-                       if(column && column->get_first_cell_renderer()==cellrenderer_time_track)
-                       {
-                               Gdk::Rectangle rect;
-                               get_param_tree_view().get_cell_area(path,*column,rect);
-                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
-                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
-                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
-                               get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
-                               return true;
-                               //return signal_param_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
-                       }
-                       else
-#endif // TIMETRACK_IN_PARAMS_PANEL
-                       {
-                               if(event->button.button==3)
-                               {
-                                       LayerList layer_list(get_selected_layers());
-                                       if(layer_list.size()<=1)
-                                       {
-                                               synfigapp::ValueDesc value_desc(row[param_model.value_desc]);
-                                               Gtk::Menu* menu(manage(new Gtk::Menu()));
-                                               menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
-                                               App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc,0.5f);
-                                               menu->popup(event->button.button,gtk_get_current_event_time());
-                                               return true;
-                                       }
-                                       Gtk::Menu* menu(manage(new Gtk::Menu()));
-                                       menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
-                                       std::list<synfigapp::ValueDesc> value_desc_list;
-                                       ParamDesc param_desc(row[param_model.param_desc]);
-                                       for(;!layer_list.empty();layer_list.pop_back())
-                                               value_desc_list.push_back(synfigapp::ValueDesc(layer_list.back(),param_desc.get_name()));
-                                       App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc_list);
-                                       menu->popup(event->button.button,gtk_get_current_event_time());
-                                       return true;
-                               }
-                               else
-                               {
-                                       if(column->get_first_cell_renderer()==cellrenderer_value)
-                                               return signal_param_user_click()(event->button.button,row,COLUMNID_VALUE);
-                                       else
-                                               return signal_param_user_click()(event->button.button,row,COLUMNID_NAME);
-                               }
-                       }
-               }
-               break;
-
-       case GDK_MOTION_NOTIFY:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!get_param_tree_view().get_path_at_pos(
-                               (int)event->motion.x,(int)event->motion.y,      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-
-                       if(!get_param_tree_view().get_model()->get_iter(path))
-                               break;
-
-                       Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-                       if((event->motion.state&GDK_BUTTON1_MASK ||event->motion.state&GDK_BUTTON3_MASK) && column && cellrenderer_time_track==column->get_first_cell_renderer())
-                       {
-                               Gdk::Rectangle rect;
-                               get_param_tree_view().get_cell_area(path,*column,rect);
-                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
-                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
-                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
-                               get_param_tree_view().queue_draw();
-                               //get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
-                               return true;
-                       }
-                       else
-#endif // TIMETRACK_IN_PARAMS_PANEL
-                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
-                       {
-                               tooltips_.unset_tip(*this);
-                               Glib::ustring tooltips_string(row[layer_model.tooltip]);
-                               last_tooltip_path=path;
-                               if(!tooltips_string.empty())
-                               {
-                                       tooltips_.set_tip(*this,tooltips_string);
-                                       tooltips_.force_window();
-                               }
-                       }
-               }
-               break;
-       case GDK_BUTTON_RELEASE:
-               {
-                       Gtk::TreeModel::Path path;
-                       Gtk::TreeViewColumn *column;
-                       int cell_x, cell_y;
-                       if(!get_param_tree_view().get_path_at_pos(
-                               (int)event->button.x,(int)event->button.y,      // x, y
-                               path, // TreeModel::Path&
-                               column, //TreeViewColumn*&
-                               cell_x,cell_y //int&cell_x,int&cell_y
-                               )
-                       ) break;
-
-                       if(!get_param_tree_view().get_model()->get_iter(path))
-                               break;
-
-                       Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-                       if(column && cellrenderer_time_track==column->get_first_cell_renderer())
-                       {
-                               Gdk::Rectangle rect;
-                               get_param_tree_view().get_cell_area(path,*column,rect);
-                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
-                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
-                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
-                               get_param_tree_view().queue_draw();
-                               get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
-                               return true;
-
-                       }
-#endif // TIMETRACK_IN_PARAMS_PANEL
-               }
-               break;
-       default:
-               break;
-       }
-       return false;
-}
-
-// void
-// LayerTree::on_raise_pressed()
-// {
-//     synfigapp::Action::ParamList param_list;
-//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-//     {
-//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-//             synfigapp::SelectionManager::LayerList::iterator iter;
-//
-//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-//                     param_list.add("layer",Layer::Handle(*iter));
-//     }
-//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerRaise"));
-//     action->set_param_list(param_list);
-//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_lower_pressed()
-// {
-//     synfigapp::Action::ParamList param_list;
-//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-//     {
-//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-//             synfigapp::SelectionManager::LayerList::iterator iter;
-//
-//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-//                     param_list.add("layer",Layer::Handle(*iter));
-//     }
-//
-//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerLower"));
-//     action->set_param_list(param_list);
-//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_duplicate_pressed()
-// {
-//     synfigapp::Action::ParamList param_list;
-//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-//     {
-//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-//             synfigapp::SelectionManager::LayerList::iterator iter;
-//
-//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-//                     param_list.add("layer",Layer::Handle(*iter));
-//     }
-//
-//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerDuplicate"));
-//     action->set_param_list(param_list);
-//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_encapsulate_pressed()
-// {
-//     synfigapp::Action::ParamList param_list;
-//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-//     {
-//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-//             synfigapp::SelectionManager::LayerList::iterator iter;
-//
-//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-//                     param_list.add("layer",Layer::Handle(*iter));
-//     }
-//
-//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerEncapsulate"));
-//     action->set_param_list(param_list);
-//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-// void
-// LayerTree::on_delete_pressed()
-// {
-//     synfigapp::Action::ParamList param_list;
-//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
-//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
-//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
-//
-//     {
-//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
-//             synfigapp::SelectionManager::LayerList::iterator iter;
-//
-//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
-//                     param_list.add("layer",Layer::Handle(*iter));
-//     }
-//
-//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerRemove"));
-//     action->set_param_list(param_list);
-//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
-// }
-
-/*
-void
-LayerTree::on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&context, Gtk::SelectionData& selection_data, guint info, guint time)
-{
-       synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
-       synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
-       synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
-       Gtk::TreeModel::Path path;
-       Gtk::TreeViewColumn *column;
-       int cell_x, cell_y;
-       if(get_selection()
-       Gtk::TreeRow row = *(get_selection()->get_selected());
-
-       if(synfig::String(gdk_atom_name(selection_data->target))=="LAYER" && (bool)row[model.is_layer])
-       {
-               Layer* layer(((Layer::Handle)row[model.layer]).get());
-               assert(layer);
-               selection_data.set(8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
-               return;
-       }
-}
-
-void
-LayerTree::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
-{
-       synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
-       synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
-       synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
-       synfig::info("Dropped x=%d, y=%d",x,y);
-       bool success=false;
-       bool dropped_on_specific_row=false;
-
-       Gtk::TreeModel::Path path;
-       Gtk::TreeViewColumn *column;
-       int cell_x, cell_y;
-       if(!get_path_at_pos(
-               x,y,    // x, y
-               path, // TreeModel::Path&
-               column, //TreeViewColumn*&
-               cell_x,cell_y //int&cell_x,int&cell_y
-               )
-       )
-       {
-               dropped_on_specific_row=false;
-       }
-       else
-               dropped_on_specific_row=true;
-
-       Gtk::TreeRow row = *(get_model()->get_iter(path));
-
-       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
-       {
-               if(synfig::String(selection_data.get_data_type())=="LAYER")do
-               {
-                       Layer::Handle src(*reinterpret_cast<Layer**>(selection_data.get_data()));
-                       assert(src);
-
-                       Canvas::Handle dest_canvas;
-                       Layer::Handle dest_layer;
-
-                       if(dropped_on_specific_row)
-                       {
-                               dest_canvas=(Canvas::Handle)(row[model.canvas]);
-                               dest_layer=(Layer::Handle)(row[model.layer]);
-                               assert(dest_canvas);
-                       }
-                       else
-                               dest_canvas=layer_tree_store_->canvas_interface()->get_canvas();
-
-                       // In this case, we are just moving.
-                       if(dest_canvas==src->get_canvas())
-                       {
-                               if(!dest_layer || dest_layer==src)
-                                       break;
-
-                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
-                               action->set_param("canvas",dest_canvas);
-                               action->set_param("canvas_interface",layer_tree_store_->canvas_interface());
-                               action->set_param("layer",src);
-                               action->set_param("new_index",dest_canvas->get_depth(dest_layer));
-                               if(layer_tree_store_->canvas_interface()->get_instance()->perform_action(action))
-                                       success=true;
-                               else
-                                       success=false;
-                               break;
-                       }
-               }while(0);
-       }
-
-       // Finish the drag
-       context->drag_finish(success, false, time);
-}
-*/
-
-/*bool
-LayerTree::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,int x, int    y, guint    time)
-{
-       return get_layer_tree_view().on_drag_motion(context,x,y,time);
-}
-
-void
-LayerTree::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
-{
-       get_layer_tree_view().on_drag_data_received(context,x,y,selection_data,info,time);
-*/
-/*
-       if(context->gobj()->source_window==context->gobj()->dest_window)
-       {
-               Gtk::TreeView::on_drag_data_received(context,x,y,selection_data,info,time);
-               return;
-       }
-
-       Gtk::TreeModel::Path path;
-       Gtk::TreeViewColumn *column;
-       int cell_x, cell_y;
-       if(!get_path_at_pos(
-               x,y,    // x, y
-               path, // TreeModel::Path&
-               column, //TreeViewColumn*&
-               cell_x,cell_y //int&cell_x,int&cell_y
-               )
-       )
-       {
-               context->drag_finish(false, false, time);
-       }
-
-       if(layer_tree_store_->row_drop_possible(path,selection_data))
-       {
-               if(layer_tree_store_->drag_data_received(path,selection_data))
-                       context->drag_finish(true, false, time);
-       }
-       context->drag_finish(false, false, time);
-}
-*/
diff --git a/synfig-studio/src/gui/layertree.h b/synfig-studio/src/gui/layertree.h
deleted file mode 100644 (file)
index cf06899..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layertree.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERTREE_H
-#define __SYNFIG_STUDIO_LAYERTREE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <gtkmm/tooltips.h>
-#include <gtkmm/table.h>
-#include <gtkmm/box.h>
-#include <gtkmm/adjustment.h>
-#include <gtkmm/scale.h>
-#include <gtkmm/button.h>
-
-#include <synfigapp/canvasinterface.h>
-#include <synfigapp/value_desc.h>
-#include "layertreestore.h"
-#include "layerparamtreestore.h"
-#include <synfig/valuenode_animated.h>
-
-#include "widgets/widget_value.h"
-
-/* === M A C R O S ========================================================= */
-
-// comment this out if you don't want the params dialog to have a 'timetrack' column
-// (alternatively, export SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK=1 in environment at runtime)
-#define TIMETRACK_IN_PARAMS_PANEL
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace Gtk { class TreeModelSort; };
-
-namespace studio {
-
-class CellRenderer_TimeTrack;
-class CellRenderer_ValueBase;
-
-class LayerTree : public Gtk::Table
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       typedef studio::ColumnID ColumnID;
-/*     enum ColumnID
-       {
-               COLUMNID_NAME,
-               COLUMNID_VALUE,
-               COLUMNID_TIME_TRACK,
-
-               COLUMNID_END                    //!< \internal
-       };
-*/
-       typedef std::list<synfig::Layer::Handle> LayerList;
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       //LayerTreeStore::Model model;
-
-       LayerTreeStore::Model layer_model;
-       LayerParamTreeStore::Model param_model;
-
-       synfig::Layer::Handle last_top_selected_layer;
-       Gtk::TreePath last_top_selected_path;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       Gtk::Tooltips tooltips_;
-       Gtk::TreePath last_tooltip_path;
-
-       Gtk::TreeView* layer_tree_view_;
-
-       Gtk::TreeView* param_tree_view_;
-
-       Gtk::HBox *hbox;
-
-       Gtk::Adjustment layer_amount_adjustment_;
-
-       Gtk::HScale *layer_amount_hscale;
-
-       synfig::Layer::Handle quick_layer;
-
-       Glib::RefPtr<LayerTreeStore> layer_tree_store_;
-
-       Glib::RefPtr<LayerParamTreeStore> param_tree_store_;
-
-       Glib::RefPtr<Gtk::TreeModelSort> sorted_layer_tree_store_;
-
-#ifdef TIMETRACK_IN_PARAMS_PANEL
-       CellRenderer_TimeTrack *cellrenderer_time_track;
-#endif // TIMETRACK_IN_PARAMS_PANEL
-
-       Gtk::TreeView::Column* column_time_track;
-
-       Gtk::TreeView::Column* column_z_depth;
-
-       CellRenderer_ValueBase *cellrenderer_value;
-
-       sigc::signal<void,synfig::Layer::Handle> signal_layer_toggle_;
-
-       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
-
-       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_layer_user_click_;
-
-       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_param_user_click_;
-
-       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_layertree_;
-
-       bool disable_amount_changed_signal;
-
-       Gtk::Button *button_raise;
-       Gtk::Button *button_lower;
-       Gtk::Button *button_duplicate;
-       Gtk::Button *button_encapsulate;
-       Gtk::Button *button_delete;
-
-       Widget_ValueBase blend_method_widget;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       Gtk::Widget* create_layer_tree();
-       Gtk::Widget* create_param_tree();
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
-
-       void on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value);
-
-       void on_layer_toggle(const Glib::ustring& path_string);
-
-       void on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node, const synfig::Time&, const synfig::Time&, int button);
-
-       void on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node);
-
-       bool on_layer_tree_event(GdkEvent *event);
-
-       bool on_param_tree_event(GdkEvent *event);
-
-       void on_selection_changed();
-
-       void on_dirty_preview();
-
-       void on_amount_value_changed();
-
-       void on_blend_method_changed();
-
-public:
-
-       // void on_raise_pressed();
-
-       // void on_lower_pressed();
-
-       // void on_duplicate_pressed();
-
-       // void on_encapsulate_pressed();
-
-       // void on_delete_pressed();
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       //Gtk::TreeView* get_param_tree_view() { return param_tree_view_; }
-       //Gtk::TreeView& param_tree_view() { return *param_tree_view_; }
-       Gtk::HBox& get_hbox() { return *hbox; }
-
-       Gtk::TreeView& get_layer_tree_view() { return *layer_tree_view_; }
-       Gtk::TreeView& get_param_tree_view() { return *param_tree_view_; }
-
-       const Gtk::TreeView& get_layer_tree_view()const { return *layer_tree_view_; }
-       const Gtk::TreeView& get_param_tree_view()const { return *param_tree_view_; }
-
-       Glib::RefPtr<Gtk::TreeSelection> get_selection() { return get_layer_tree_view().get_selection(); }
-       Glib::SignalProxy1< bool,GdkEvent* >  signal_event () { return get_layer_tree_view().signal_event(); }
-
-       LayerTree();
-       ~LayerTree();
-
-       void set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store_);
-
-       void set_time_adjustment(Gtk::Adjustment &adjustment);
-
-       void set_show_timetrack(bool x=true);
-
-       //! Signal called when layer is toggled.
-       sigc::signal<void,synfig::Layer::Handle>& signal_layer_toggle() { return signal_layer_toggle_; }
-
-       //! Signal called with a value has been edited.
-       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
-
-       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_layer_user_click() { return signal_layer_user_click_; }
-
-       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_param_user_click() { return signal_param_user_click_; }
-
-       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_layertree() { return signal_waypoint_clicked_layertree_; }
-
-       etl::handle<synfigapp::SelectionManager> get_selection_manager() { return layer_tree_store_->canvas_interface()->get_selection_manager(); }
-
-       void select_layer(synfig::Layer::Handle layer);
-       void select_layers(const LayerList& layer_list);
-       void select_all_children_layers(synfig::Layer::Handle layer);
-       void select_all_children(Gtk::TreeModel::Children::iterator iter);
-       LayerList get_selected_layers()const;
-       synfig::Layer::Handle get_selected_layer()const;
-       void clear_selected_layers();
-
-}; // END of LayerTree
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/layertreestore.cpp b/synfig-studio/src/gui/layertreestore.cpp
deleted file mode 100644 (file)
index 16b7fc8..0000000
+++ /dev/null
@@ -1,1081 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layertreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "layertreestore.h"
-#include "iconcontroller.h"
-#include <gtkmm/button.h>
-#include <synfig/paramdesc.h>
-#include <synfigapp/action.h>
-#include <synfigapp/instance.h>
-#include "app.h"
-#include "instance.h"
-#include <synfig/layer_pastecanvas.h>
-#include <synfigapp/action_system.h>
-
-#include <gtk/gtkversion.h>
-#include <ETL/clock>
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static LayerTreeStore::Model& ModelHack()
-{
-       static LayerTreeStore::Model* model(0);
-       if(!model)model=new LayerTreeStore::Model;
-       return *model;
-}
-
-LayerTreeStore::LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
-       Gtk::TreeStore                  (ModelHack()),
-       queued                                  (false),
-       canvas_interface_               (canvas_interface_)
-{
-       layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
-
-       // Connect Signals to Terminals
-       canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_status_changed));
-       canvas_interface()->signal_layer_lowered().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_lowered));
-       canvas_interface()->signal_layer_raised().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_raised));
-       canvas_interface()->signal_layer_removed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_removed));
-       canvas_interface()->signal_layer_inserted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_inserted));
-       canvas_interface()->signal_layer_moved().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_moved));
-       //canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_param_changed));
-       canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_new_description));
-
-       canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::refresh));
-
-       //canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_changed));
-       //canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_added));
-       //canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_deleted));
-       //canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_replaced));
-
-       set_default_sort_func(sigc::ptr_fun(index_sorter));
-
-//     rebuild();
-}
-
-LayerTreeStore::~LayerTreeStore()
-{
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("LayerTreeStore::~LayerTreeStore(): Deleted");
-}
-
-int
-LayerTreeStore::z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
-       const Model model;
-
-       float diff((float)(*rhs)[model.z_depth]-(float)(*lhs)[model.z_depth]);
-
-       if(diff<0)
-               return -1;
-       if(diff>0)
-               return 1;
-       return 0;
-}
-
-int
-LayerTreeStore::index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
-{
-       const Model model;
-
-       return ((int)(*rhs)[model.index]-(int)(*lhs)[model.index]);
-}
-
-bool
-LayerTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
-{
-       const Model model;
-
-       Glib::ustring substr(x.uppercase());
-       Glib::ustring label((*iter)[model.label]);
-       label=label.uppercase();
-
-       return label.find(substr)==Glib::ustring::npos;
-}
-
-
-Glib::RefPtr<LayerTreeStore>
-LayerTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
-       return Glib::RefPtr<LayerTreeStore>(new LayerTreeStore(canvas_interface_));
-}
-
-void
-LayerTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
-       if(column==model.index.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<int> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(layer->get_depth());
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else if(column==model.z_depth.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<float> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(layer->get_z_depth(canvas_interface()->get_time())*1.0001+layer->get_depth());
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else if(column==model.children_lock.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-               x.set(false);
-
-               ValueBase v(layer->get_param("children_lock"));
-               if(v.same_type_as(bool()))
-                       x.set(v.get(bool()));
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else if(column==model.label.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(layer->get_non_empty_description());
-
-               g_value_init(value.gobj(),x.value_type());
-               //g_value_copy(x.gobj(),value.gobj());
-               value=x;
-       }
-       else if(column==model.tooltip.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),x.value_type());
-
-
-               x.set(layer->get_local_name());
-
-               g_value_init(value.gobj(),x.value_type());
-               //g_value_copy(x.gobj(),value.gobj());
-               value=x;
-       }
-       else if(column==model.canvas.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<Canvas::Handle> x;
-               g_value_init(x.gobj(),x.value_type());
-
-
-               x.set(layer->get_canvas());
-
-               g_value_init(value.gobj(),x.value_type());
-               //g_value_copy(x.gobj(),value.gobj());
-               value=x;
-       }
-       else if(column==model.active.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-
-               if(!layer)return;
-
-               Glib::Value<bool> x;
-               g_value_init(x.gobj(),x.value_type());
-
-               x.set(layer->active());
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else if(column==model.icon.index())
-       {
-               synfig::Layer::Handle layer((*iter)[model.layer]);
-               if(!layer)return;
-
-               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
-               g_value_init(x.gobj(),x.value_type());
-
-               //x.set(layer_icon);
-               x.set(get_tree_pixbuf_layer(layer->get_name()));
-
-               g_value_init(value.gobj(),x.value_type());
-               g_value_copy(x.gobj(),value.gobj());
-       }
-       else
-               Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-void
-LayerTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
-       //if(!iterator_sane(row))
-       //      return;
-
-       if(column>=get_n_columns_vfunc())
-       {
-               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
-               return;
-       }
-
-       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
-       {
-               g_warning("LayerTreeStore::set_value_impl: Bad value type");
-               return;
-       }
-
-       try
-       {
-               if(column==model.label.index())
-               {
-                       Glib::Value<Glib::ustring> x;
-                       g_value_init(x.gobj(),model.label.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       synfig::Layer::Handle layer((*iter)[model.layer]);
-                       if(!layer)
-                               return;
-                       synfig::String new_desc(x.get());
-
-                       if(new_desc==layer->get_local_name())
-                               new_desc=synfig::String();
-
-                       if(new_desc==layer->get_description())
-                               return;
-
-                       synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
-
-                       if(!action)
-                               return;
-
-                       action->set_param("canvas",canvas_interface()->get_canvas());
-                       action->set_param("canvas_interface",canvas_interface());
-                       action->set_param("layer",layer);
-                       action->set_param("new_description",synfig::String(x.get()));
-
-                       canvas_interface()->get_instance()->perform_action(action);
-                       return;
-               }
-               else if(column==model.active.index())
-               {
-                       synfig::Layer::Handle layer((*iter)[model.layer]);
-
-                       if(!layer)return;
-
-                       Glib::Value<bool> x;
-                       g_value_init(x.gobj(),model.active.type());
-                       g_value_copy(value.gobj(),x.gobj());
-
-                       synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
-
-                       if(!action)
-                               return;
-
-                       action->set_param("canvas",canvas_interface()->get_canvas());
-                       action->set_param("canvas_interface",canvas_interface());
-                       action->set_param("layer",layer);
-                       action->set_param("new_status",bool(x.get()));
-
-                       canvas_interface()->get_instance()->perform_action(action);
-                       return;
-               }
-               else
-                       Gtk::TreeStore::set_value_impl(iter,column, value);
-
-       }
-       catch(std::exception x)
-       {
-               g_warning("%s", x.what());
-       }
-}
-
-
-
-
-bool
-LayerTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
-{
-       //if(!get_iter(path)) return false;
-//     Gtk::TreeModel::Row row(*get_iter(path));
-
-       return true;
-//     return (bool)true;
-}
-
-bool
-LayerTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
-{
-       if(!const_cast<LayerTreeStore*>(this)->get_iter(path)) return false;
-       //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
-       //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
-       //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
-       Gtk::TreeModel::Row row(*const_cast<LayerTreeStore*>(this)->get_iter(path));
-
-       if((bool)true)
-       {
-               Layer* layer(((Layer::Handle)row[model.layer]).get());
-               assert(layer);
-               bool included(false);
-
-               //gtk_selection_data_set (selection_data, gdk_atom_intern("LAYER",false), 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
-
-               std::vector<Layer*> layers;
-               // The following is a hack for multiple row DND
-               {
-                       synfigapp::SelectionManager::LayerList bleh(get_canvas_interface()->get_selection_manager()->get_selected_layers());
-                       if(bleh.empty())
-                       {
-                               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
-                               return true;
-                       }
-                       while(!bleh.empty())
-                       {
-                               if(bleh.back().get()==layer)
-                                       included=true;
-                               layers.push_back(bleh.back().get());
-                               bleh.pop_back();
-                       }
-               }
-               if(!included)
-                       layers.push_back(layer);
-               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
-
-               return true;
-       }
-       return false;
-}
-
-bool
-LayerTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
-{
-       return true;
-}
-
-bool
-LayerTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
-{
-       //if(!const_cast<LayerTreeStore*>(this)->get_iter(dest)) return false;
-
-       //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
-       //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
-       //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
-
-       //Gtk::TreeModel::Row row(*get_iter(dest));
-
-       if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
-       {
-               //Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
-               //assert(src);
-
-               //return true;
-               TreeModel::Path dest_parent(dest);
-               if(!dest_parent.up() || dest.get_depth()==1)
-               {
-                       //row=(*get_iter(dest));
-                       //dest_canvas=(Canvas::Handle)(row[model.canvas]);
-                       return true;
-               }
-               else if((bool)const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))
-                       return (bool)(Canvas::Handle)(*const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))[model.contained_canvas];
-       }
-       return false;
-}
-
-bool
-LayerTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
-{
-
-       //if(!dest_parent.up() || !get_iter(dest)) return false;
-
-       bool ret=false;
-       int i(0);
-
-
-       //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
-       //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
-       //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
-       synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Move Layers"));
-
-       // Save the selection data
-       synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
-
-       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
-       {
-               Gtk::TreeModel::Row row;
-               Canvas::Handle dest_canvas;
-
-               int dest_layer_depth=dest.back();
-
-               TreeModel::Path dest_parent(dest);
-               if(!dest_parent.up() || !get_iter(dest_parent))
-               {
-                       TreeModel::Path dest_(dest);
-                       if(!get_iter(dest_))
-                               dest_.prev();
-
-                       if(!get_iter(dest_))
-                               return false;
-
-                       {
-                               row=(*get_iter(dest_));
-                               dest_canvas=(Canvas::Handle)(row[model.canvas]);
-                       }
-               }
-               else
-               {
-                       row=(*get_iter(dest_parent));
-                       dest_canvas=row[model.contained_canvas];
-               }
-
-               assert(dest_canvas);
-
-               Layer::Handle dest_layer(row[model.layer]);
-
-               if(synfig::String(selection_data.get_data_type())=="LAYER")for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
-               {
-                       //synfig::info("dest_layer_depth=%d",dest_layer_depth);
-
-                       Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
-                       assert(src);
-                       if(dest_layer==src)
-                               continue;
-
-                       if(dest_canvas==src->get_canvas() && src->get_depth()<dest_layer_depth)
-                               dest_layer_depth--;
-
-                       // In this case, we are just moving.
-//                     if(dest_canvas==src->get_canvas())
-                       {
-                               //if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
-                               //      dest_layer_depth--;
-                               if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
-                                       continue;
-
-                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
-                               action->set_param("canvas",dest_canvas);
-                               action->set_param("canvas_interface",canvas_interface());
-                               action->set_param("layer",src);
-                               action->set_param("new_index",dest_layer_depth);
-                               action->set_param("dest_canvas",dest_canvas);
-                               if(canvas_interface()->get_instance()->perform_action(action))
-                                       ret=true;
-                               else
-                               {
-                                       passive_grouper.cancel();
-                                       return false;
-                               }
-                               continue;
-                       }
-                       /*else // In this case we need to remove and then add
-                       {
-
-                               synfigapp::Action::Handle action;
-                               action=synfigapp::Action::create("LayerRemove");
-                               action->set_param("canvas",Canvas::Handle(src->get_canvas()));
-                               if(!action->set_param("canvas_interface",App::get_instance(src->get_canvas())->find_canvas_interface(src->get_canvas())))
-                                       action->set_param("canvas_interface",canvas_interface());
-                               action->set_param("layer",src);
-                               if(!canvas_interface()->get_instance()->perform_action(action))
-                               {
-                                       passive_grouper.cancel();
-                                       ret=false;
-                                       return false;
-                               }
-
-                               action=synfigapp::Action::create("LayerAdd");
-                               action->set_param("canvas",dest_canvas);
-                               action->set_param("canvas_interface",canvas_interface());
-                               action->set_param("new",src);
-                               if(!canvas_interface()->get_instance()->perform_action(action))
-                               {
-                                       passive_grouper.cancel();
-                                       ret=false;
-                                       return false;
-                               }
-
-                               if(dest_layer_depth!=0)
-                               {
-                                       action=synfigapp::Action::create("LayerMove");
-                                       action->set_param("canvas",dest_canvas);
-                                       action->set_param("canvas_interface",canvas_interface());
-                                       action->set_param("layer",src);
-                                       action->set_param("new_index",dest_layer_depth);
-                                       if(!canvas_interface()->get_instance()->perform_action(action))
-                                       {
-                                               passive_grouper.cancel();
-                                               ret=false;
-                                               return false;
-                                       }
-                               }
-                               ret=true;
-                       }
-                       */
-               }
-       }
-       synfig::info("I supposedly moved %d layers",i);
-
-       // Reselect the previously selected layers
-       canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
-
-       return ret;
-}
-
-void
-LayerTreeStore::queue_rebuild()
-{
-       if (queued) return;
-       queued = false;
-       queue_connection.disconnect();
-       queue_connection=Glib::signal_timeout().connect(
-               sigc::bind_return(
-                       sigc::mem_fun(*this,&LayerTreeStore::rebuild),
-                       false
-               )
-       ,150);
-}
-
-void
-LayerTreeStore::rebuild()
-{
-       if (queued) queued = false;
-
-       // disconnect any subcanvas_changed connections
-       std::map<synfig::Layer::Handle, sigc::connection>::iterator iter;
-       for (iter = subcanvas_changed_connections.begin(); iter != subcanvas_changed_connections.end(); iter++)
-               iter->second.disconnect();
-       subcanvas_changed_connections.clear();
-
-       //etl::clock timer;timer.reset();
-
-       //synfig::warning("---------rebuilding layer table---------");
-       // Save the selection data
-       synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
-
-       // Clear out the current list
-       clear();
-
-       // Go ahead and add all the layers
-       std::for_each(
-               canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
-               sigc::mem_fun(*this, &studio::LayerTreeStore::on_layer_added)
-       );
-
-       // Reselect the previously selected layers
-       if(!layer_list.empty())
-               canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
-
-       //synfig::info("LayerTreeStore::rebuild() took %f seconds",float(timer()));
-}
-
-void
-LayerTreeStore::refresh()
-{
-       etl::clock timer;timer.reset();
-
-       Gtk::TreeModel::Children children_(children());
-
-       Gtk::TreeModel::Children::iterator iter;
-
-       if(!children_.empty())
-               for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
-               {
-                       Gtk::TreeRow row=*iter;
-                       refresh_row(row);
-               }
-       //synfig::info("LayerTreeStore::refresh() took %f seconds",float(timer()));
-}
-
-void
-LayerTreeStore::refresh_row(Gtk::TreeModel::Row &row)
-{
-       Layer::Handle layer=row[model.layer];
-       /*
-       {
-               row[model.name] = layer->get_local_name();
-               if(layer->get_description().empty())
-               {
-                       row[model.label] = layer->get_local_name();
-                       row[model.tooltip] = Glib::ustring("Layer");
-               }
-               else
-               {
-                       row[model.label] = layer->get_description();
-                       row[model.tooltip] = layer->get_local_name();
-               }
-       }
-       */
-
-       if(layer->dynamic_param_list().count("z_depth"))
-               row[model.z_depth]=Time::begin();
-       //      row_changed(get_path(row),row);
-
-       Gtk::TreeModel::Children children = row.children();
-       Gtk::TreeModel::Children::iterator iter;
-
-       if(!children.empty())
-               for(iter = children.begin(); iter && iter != children.end(); ++iter)
-               {
-                       Gtk::TreeRow row=*iter;
-                       refresh_row(row);
-               }
-}
-
-
-void
-LayerTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
-{
-       //row[model.id] = handle->get_name();
-       //row[model.name] = handle->get_local_name();
-       /*if(handle->get_description().empty())
-       {
-               //row[model.label] = handle->get_local_name();
-               row[model.tooltip] = Glib::ustring("Layer");
-       }
-       else
-       {
-               //row[model.label] = handle->get_description();
-               row[model.tooltip] = handle->get_local_name();
-       }*/
-
-       //row[model.active] = handle->active();
-       row[model.layer] = handle;
-       //row[model.canvas] = handle->get_canvas();
-       //row[model.icon] = layer_icon;
-
-       synfig::Layer::ParamList paramlist=handle->get_param_list();
-
-       synfig::Layer::Vocab vocab=handle->get_param_vocab();
-       synfig::Layer::Vocab::iterator iter;
-
-       for(iter=vocab.begin();iter!=vocab.end();++iter)
-       {
-               if(iter->get_hidden())
-                       continue;
-               if(handle->get_param(iter->get_name()).get_type()!=ValueBase::TYPE_CANVAS)
-                       continue;
-
-               {
-                       Canvas::Handle canvas;
-                       canvas=handle->get_param(iter->get_name()).get(canvas);
-                       if(!canvas)
-                               continue;
-
-                       Canvas::reverse_iterator iter;
-                       row[model.contained_canvas]=canvas;
-
-                       for(iter=canvas->rbegin();iter!=canvas->rend();++iter)
-                       {
-                               Gtk::TreeRow row_(*(prepend(row.children())));
-                               set_row_layer(row_,*iter);
-                       }
-                       continue;
-               }
-
-               /*
-               etl::handle<ValueNode> value_node;
-               if(handle.constant()->dynamic_param_list().count(iter->get_name()))
-                       value_node=handle->dynamic_param_list()[iter->get_name()];
-
-               Gtk::TreeRow child_row = *(append(row.children()));
-               set_row_param(
-                       child_row,
-                       handle,
-                       iter->get_name(),
-                       iter->get_local_name(),
-                       paramlist[iter->get_name()],
-                       value_node,
-                       &*iter
-               );
-               */
-       }
-}
-
-void
-LayerTreeStore::on_layer_added(synfig::Layer::Handle layer)
-{
-       if (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))
-               subcanvas_changed_connections[layer] =
-                       (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))->signal_subcanvas_changed().connect(
-                               sigc::mem_fun(*this,&studio::LayerTreeStore::queue_rebuild)
-                       );
-
-       assert(layer);
-       Gtk::TreeRow row;
-       if(canvas_interface()->get_canvas()==layer->get_canvas())
-       {
-               row=*(prepend());
-       }
-       else
-       {
-               Gtk::TreeModel::Children::iterator iter;
-               if(!find_canvas_row(layer->get_canvas(),iter))
-               {
-                       rebuild();
-                       return;
-               }
-               row=*(prepend(iter->children()));
-       }
-       set_row_layer(row,layer);
-}
-
-void
-LayerTreeStore::on_layer_removed(synfig::Layer::Handle handle)
-{
-       if (etl::handle<Layer_PasteCanvas>::cast_dynamic(handle))
-       {
-               subcanvas_changed_connections[handle].disconnect();
-               subcanvas_changed_connections.erase(handle);
-       }
-       Gtk::TreeModel::Children::iterator iter;
-       if(find_layer_row(handle,iter))
-               erase(iter);
-       else
-       {
-               synfig::error("LayerTreeStore::on_layer_removed():Unable to find layer to be removed, forced to rebuild...");
-               rebuild();
-       }
-}
-
-void
-LayerTreeStore::on_layer_inserted(synfig::Layer::Handle handle,int depth)
-{
-       if(depth==0)
-       {
-               on_layer_added(handle);
-               return;
-       }
-
-       Gtk::TreeModel::Children children_(children());
-       if(canvas_interface()->get_canvas()!=handle->get_canvas())
-       {
-               Gtk::TreeModel::Children::iterator iter;
-               if(!find_canvas_row(handle->get_canvas(),iter))
-               {
-                       synfig::error("LayerTreeStore::on_layer_inserted():Unable to find canvas row, forced to rebuild...");
-                       rebuild();
-                       return;
-               }
-               children_=iter->children();
-       }
-
-       Gtk::TreeModel::Children::iterator iter(children_.begin());
-       while(depth-- && iter)
-       {
-               ++iter;
-               if(!iter || iter==children_.end())
-               {
-                       synfig::error("LayerTreeStore::on_layer_inserted():Unable to achieve desired depth, forced to rebuild...");
-                       rebuild();
-                       return;
-               }
-       }
-
-       Gtk::TreeModel::Row row(*insert(iter));
-       set_row_layer(row,handle);
-}
-
-void
-LayerTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(find_layer_row(handle,iter))
-               (*iter)[model.layer]=handle;
-       else
-       {
-               synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
-               rebuild();
-       }
-}
-
-void
-LayerTreeStore::on_layer_lowered(synfig::Layer::Handle layer)
-{
-       Gtk::TreeModel::Children::iterator iter, iter2;
-       if(find_layer_row(layer,iter))
-       {
-               // Save the selection data
-               //synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
-               iter2=iter;
-               iter2++;
-               if(!iter2)
-               {
-                       rebuild();
-                       return;
-               }
-
-               //Gtk::TreeModel::Row row(*iter);
-               Gtk::TreeModel::Row row2 = *iter2;
-               synfig::Layer::Handle layer2=row2[model.layer];
-
-               erase(iter2);
-               row2=*insert(iter);
-               set_row_layer(row2,layer2);
-
-       }
-       else
-               rebuild();
-}
-
-void
-LayerTreeStore::on_layer_raised(synfig::Layer::Handle layer)
-{
-       Gtk::TreeModel::Children::iterator iter, iter2;
-
-       Gtk::TreeModel::Children children_(children());
-
-       if(find_layer_row_(layer, canvas_interface()->get_canvas(), children_, iter,iter2))
-       {
-               if(iter!=iter2)
-               {
-                       //Gtk::TreeModel::Row row = *iter;
-                       Gtk::TreeModel::Row row2 = *iter2;
-                       synfig::Layer::Handle layer2=row2[model.layer];
-
-                       erase(iter2);
-                       iter++;
-                       row2=*insert(iter);
-                       set_row_layer(row2,layer2);
-
-                       return;
-               }
-       }
-
-       rebuild();
-}
-
-void
-LayerTreeStore::on_layer_moved(synfig::Layer::Handle layer,int depth, synfig::Canvas::Handle /*canvas*/)
-{
-       on_layer_removed(layer);
-       on_layer_inserted(layer,depth);
-}
-
-void
-LayerTreeStore::on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)
-{
-       if(param_name=="z_depth")
-       {
-               Gtk::TreeModel::Children::iterator iter;
-               if(find_layer_row(handle,iter))
-               {
-                       (*iter)[model.z_depth]=Time::begin();
-               }
-       }
-
-       /*
-       Gtk::TreeModel::Children::iterator iter;
-       if(find_layer_row(handle,iter))
-       {
-               Gtk::TreeModel::Children children(iter->children());
-
-               for(iter = children.begin(); iter && iter != children.end(); ++iter)
-               {
-                       if((Glib::ustring)(*iter)[model.param_name]==param_name)
-                       {
-                               Gtk::TreeRow row=*iter;
-                               refresh_row(row);
-                               return;
-                       }
-               }
-       }
-       rebuild();
-       */
-}
-
-void
-LayerTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(find_layer_row(handle,iter))
-       {
-               Gtk::TreeRow row(*iter);
-
-               Layer::Handle layer(row[model.layer]);
-
-               if(desc.empty())
-               {
-                       //row[model.label]=layer->get_local_name();
-                       row[model.tooltip]=Glib::ustring(_("Layer"));
-               }
-               else
-                       //row[model.label]=layer->get_description();
-                       row[model.tooltip]=layer->get_local_name();
-       }
-       else
-       {
-               rebuild();
-       }
-}
-
-bool
-LayerTreeStore::find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter)
-{
-       if(canvas==parent)
-               return false;
-
-       {
-               for(iter=layers.begin(); iter && iter != layers.end(); ++iter)
-               {
-                       Gtk::TreeModel::Row row = *iter;
-                       if(canvas==(synfig::Canvas::Handle)row[model.contained_canvas])
-                               return true;
-               }
-
-               iter=children().end();
-               //return false;
-       }
-
-       Gtk::TreeModel::Children::iterator iter2;
-       //Gtk::TreeModel::Children::iterator iter3;
-
-       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
-       {
-               Gtk::TreeModel::Row row = *iter2;
-               assert((bool)true);
-
-               if(row.children().empty())
-                       continue;
-
-               Canvas::Handle sub_canvas((*row.children().begin())[model.canvas]);
-               if(!sub_canvas)
-                       continue;
-
-               if(find_canvas_row_(canvas,sub_canvas,iter2->children(),iter))
-                       return true;
-       }
-
-       iter=children().end();
-       return false;
-}
-
-bool
-LayerTreeStore::find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter)
-{
-       return find_canvas_row_(canvas,canvas_interface()->get_canvas(),children(),iter);
-}
-
-
-bool
-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)
-{
-       assert(layer);
-
-       //if(layer->get_canvas()==canvas)
-       {
-               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
-               {
-                       Gtk::TreeModel::Row row = *iter;
-                       if(layer==(synfig::Layer::Handle)row[model.layer])
-                               return true;
-               }
-
-               iter=children().end();
-               //return false;
-       }
-
-       Gtk::TreeModel::Children::iterator iter2;
-
-       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
-       {
-               Gtk::TreeModel::Row row = *iter2;
-               assert((bool)true);
-
-               if(row.children().empty())
-                       continue;
-
-               Canvas::Handle canvas((*row.children().begin())[model.canvas]);
-               if(!canvas)
-                       continue;
-
-               if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
-                       return true;
-       }
-
-       iter=children().end();
-       return false;
-}
-
-bool
-LayerTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
-{
-       Gtk::TreeModel::Children::iterator prev;
-       return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
-}
-
-bool
-LayerTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
-{
-       Gtk::TreeModel::Children::iterator iter;
-       if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
-               return false;
-       if(iter==children().begin())
-               return false;
-       return true;
-}
diff --git a/synfig-studio/src/gui/layertreestore.h b/synfig-studio/src/gui/layertreestore.h
deleted file mode 100644 (file)
index 5b33309..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file layertreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_LAYERTREESTORE_H
-#define __SYNFIG_STUDIO_LAYERTREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <synfig/value.h>
-#include <synfig/valuenode.h>
-#include <gtkmm/treeview.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace studio {
-
-class LayerTreeStore : virtual public Gtk::TreeStore
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       class Model : public Gtk::TreeModel::ColumnRecord
-       {
-       public:
-               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
-               Gtk::TreeModelColumn<Glib::ustring> label;
-               Gtk::TreeModelColumn<Glib::ustring> name;
-               Gtk::TreeModelColumn<Glib::ustring> id;
-
-               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
-
-               Gtk::TreeModelColumn<Glib::ustring> tooltip;
-
-
-               Gtk::TreeModelColumn<bool>                                              active;
-               Gtk::TreeModelColumn<synfig::Layer::Handle>             layer;
-               Gtk::TreeModelColumn<synfig::Canvas::Handle>                    contained_canvas;
-
-               Gtk::TreeModelColumn<bool>                                              children_lock;
-
-               Gtk::TreeModelColumn<float> z_depth;
-               Gtk::TreeModelColumn<int> index;
-
-               Model()
-               {
-                       add(icon);
-                       add(label);
-                       add(name);
-                       add(id);
-                       add(canvas);
-                       add(tooltip);
-                       add(active);
-                       add(layer);
-                       add(contained_canvas);
-                       add(z_depth);
-                       add(index);
-                       add(children_lock);
-               }
-       };
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       //! TreeModel for the layers
-       const Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       bool queued;
-
-       sigc::connection queue_connection;
-
-       std::map<synfig::Layer::Handle, sigc::connection> subcanvas_changed_connections;
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
-       Glib::RefPtr<Gdk::Pixbuf> layer_icon;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
-       */
-
-private:
-       virtual void  set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
-       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-
-       virtual bool  row_draggable_vfunc (const TreeModel::Path& path)const;
-       virtual bool  drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
-       virtual bool  drag_data_delete_vfunc (const TreeModel::Path& path);
-       virtual bool  drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
-       virtual bool  row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       bool on_layer_tree_event(GdkEvent *event);
-
-       void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
-
-       void on_layer_added(synfig::Layer::Handle handle);
-
-       void on_layer_removed(synfig::Layer::Handle handle);
-
-       void on_layer_inserted(synfig::Layer::Handle handle,int depth);
-
-       void on_layer_moved(synfig::Layer::Handle handle,int depth, synfig::Canvas::Handle canvas);
-
-       void on_layer_status_changed(synfig::Layer::Handle handle,bool);
-
-       void on_layer_lowered(synfig::Layer::Handle handle);
-
-       void on_layer_raised(synfig::Layer::Handle handle);
-
-       void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
-
-       //void on_value_node_added(synfig::ValueNode::Handle value_node);
-
-       //void on_value_node_deleted(synfig::ValueNode::Handle value_node);
-
-       //void on_value_node_changed(synfig::ValueNode::Handle value_node);
-
-       //void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
-
-       bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
-
-       bool find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter);
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-       ~LayerTreeStore();
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
-       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
-       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
-
-       bool find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter);
-
-       bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
-       bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
-
-       void queue_rebuild();
-
-       void rebuild();
-
-       void refresh();
-
-       void refresh_row(Gtk::TreeModel::Row &row);
-
-       void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
-
-       static int z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
-       static int index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
-
-       //void set_row_param(Gtk::TreeRow &row,synfig::Layer::Handle &handle,const std::string& name, const std::string& local_name, const synfig::ValueBase &value, etl::handle<synfig::ValueNode> value_node,synfig::ParamDesc *param_desc);
-
-       //virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
-       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
-
-       /*
- -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
-       */
-
-public:
-
-       static Glib::RefPtr<LayerTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
-
-
-}; // END of class LayerTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/metadatatreestore.cpp b/synfig-studio/src/gui/metadatatreestore.cpp
deleted file mode 100644 (file)
index 98bb7c6..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file metadatatreestore.cpp
-**     \brief Template File
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2008 Chris Moore
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-#      include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-#      include <config.h>
-#endif
-
-#include "metadatatreestore.h"
-#include <synfigapp/canvasinterface.h>
-
-#include "general.h"
-
-#endif
-
-/* === U S I N G =========================================================== */
-
-using namespace std;
-using namespace etl;
-using namespace synfig;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-static MetaDataTreeStore::Model& ModelHack()
-{
-       static MetaDataTreeStore::Model* model(0);
-       if(!model)model=new MetaDataTreeStore::Model;
-       return *model;
-}
-
-MetaDataTreeStore::MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
-       Gtk::TreeStore  (ModelHack()),
-       canvas_interface_               (canvas_interface_)
-{
-       // Connect the signal
-       get_canvas()->signal_meta_data_changed().connect(sigc::mem_fun(*this,&MetaDataTreeStore::meta_data_changed));
-
-       rebuild();
-}
-
-MetaDataTreeStore::~MetaDataTreeStore()
-{
-       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
-               synfig::info("MetaDataTreeStore::~MetaDataTreeStore(): Deleted");
-}
-
-Glib::RefPtr<MetaDataTreeStore>
-MetaDataTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
-{
-       return Glib::RefPtr<MetaDataTreeStore>(new MetaDataTreeStore(canvas_interface_));
-}
-
-void
-MetaDataTreeStore::meta_data_changed(synfig::String /*key*/)
-{
-       rebuild();
-}
-
-void
-MetaDataTreeStore::rebuild()
-{
-       clear();
-
-       std::list<String> keys(get_canvas()->get_meta_data_keys());
-
-       for(;!keys.empty();keys.pop_front())
-       {
-               Gtk::TreeRow row(*append());
-               row[model.key]=keys.front();
-       }
-}
-
-void
-MetaDataTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
-{
-       if(column>=get_n_columns_vfunc())
-       {
-               g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
-               return;
-       }
-
-       if(column==model.data.index())
-       {
-               synfig::String key((Glib::ustring)(*iter)[model.key]);
-               g_value_init(value.gobj(),G_TYPE_STRING);
-               g_value_set_string(value.gobj(),get_canvas()->get_meta_data(key).c_str());
-               return;
-       }
-       else
-               Gtk::TreeStore::get_value_vfunc(iter,column,value);
-}
-
-void
-MetaDataTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
-{
-       if(column>=get_n_columns_vfunc())
-       {
-               g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
-               return;
-       }
-
-       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
-       {
-               g_warning("MetaDataTreeStore::set_value_impl: Bad value type");
-               return;
-       }
-
-       if(column==model.data.index())
-       {
-               Glib::Value<Glib::ustring> x;
-               g_value_init(x.gobj(),model.data.type());
-               g_value_copy(value.gobj(),x.gobj());
-
-               synfig::String key((Glib::ustring)(*iter)[model.key]);
-               synfig::String new_data(x.get());
-
-               get_canvas_interface()->set_meta_data(key,new_data);
-       }
-       else
-               Gtk::TreeStore::set_value_impl(iter,column, value);
-}
diff --git a/synfig-studio/src/gui/metadatatreestore.h b/synfig-studio/src/gui/metadatatreestore.h
deleted file mode 100644 (file)
index 6ad41d4..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* === S Y N F I G ========================================================= */
-/*!    \file metadatatreestore.h
-**     \brief Template Header
-**
-**     $Id$
-**
-**     \legal
-**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**
-**     This package is free software; you can redistribute it and/or
-**     modify it under the terms of the GNU General Public License as
-**     published by the Free Software Foundation; either version 2 of
-**     the License, or (at your option) any later version.
-**
-**     This package is distributed in the hope that it will be useful,
-**     but WITHOUT ANY WARRANTY; without even the implied warranty of
-**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-**     General Public License for more details.
-**     \endlegal
-*/
-/* ========================================================================= */
-
-/* === S T A R T =========================================================== */
-
-#ifndef __SYNFIG_STUDIO_METADATATREESTORE_H
-#define __SYNFIG_STUDIO_METADATATREESTORE_H
-
-/* === H E A D E R S ======================================================= */
-
-#include <gtkmm/treestore.h>
-#include <synfigapp/canvasinterface.h>
-#include <gdkmm/pixbuf.h>
-#include <synfigapp/action.h>
-
-/* === M A C R O S ========================================================= */
-
-/* === T Y P E D E F S ===================================================== */
-
-/* === C L A S S E S & S T R U C T S ======================================= */
-
-namespace synfigapp { class CanvasInterface; }
-
-namespace studio {
-
-class MetaDataTreeStore : virtual public Gtk::TreeStore
-{
-       /*
- -- ** -- P U B L I C   T Y P E S ---------------------------------------------
-       */
-
-public:
-
-       class Model : public Gtk::TreeModel::ColumnRecord
-       {
-       public:
-       public:
-               Gtk::TreeModelColumn<Glib::ustring> key;
-               Gtk::TreeModelColumn<Glib::ustring> data;
-
-               Model()
-               {
-                       add(key);
-                       add(data);
-               }
-       };
-
-       /*
- -- ** -- P U B L I C  D A T A ------------------------------------------------
-       */
-
-public:
-
-       const Model model;
-
-       /*
- -- ** -- P R I V A T E   D A T A ---------------------------------------------
-       */
-
-private:
-
-       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
-
-       /*
- -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
-       */
-
-private:
-
-       /*
- -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
-       */
-
-private:
-
-       void meta_data_changed(synfig::String key);
-
-       /*
- -- ** -- P U B L I C   M E T H O D S -----------------------------------------
-       */
-
-public:
-
-       ~MetaDataTreeStore();
-
-       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface() { return canvas_interface_; }
-       etl::loose_handle<const synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
-       synfig::Canvas::Handle get_canvas()const { return canvas_interface_->get_canvas(); }
-       synfig::Canvas::Handle get_canvas() { return canvas_interface_->get_canvas(); }
-
-       void rebuild();
-
-       void refresh() { rebuild(); }
-
-       /*
- -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
-       */
-
-protected:
-       MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface>);
-       void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
-       void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
-
-public:
-
-       static Glib::RefPtr<MetaDataTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface>);
-
-}; // END of class MetaDataTreeStore
-
-}; // END of namespace studio
-
-/* === E N D =============================================================== */
-
-#endif
diff --git a/synfig-studio/src/gui/trees/canvastreestore.cpp b/synfig-studio/src/gui/trees/canvastreestore.cpp
new file mode 100644 (file)
index 0000000..8673c35
--- /dev/null
@@ -0,0 +1,622 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file canvastreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "trees/canvastreestore.h"
+#include <synfig/valuenode.h>
+#include "iconcontroller.h"
+#include <synfig/valuenode_timedswap.h>
+#include <synfig/valuenode_animated.h>
+#include <gtkmm/button.h>
+#include <synfigapp/instance.h>
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <ETL/clock>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static CanvasTreeStore::Model& ModelHack()
+{
+       static CanvasTreeStore::Model* model(0);
+       if(!model)model=new CanvasTreeStore::Model;
+       return *model;
+}
+
+CanvasTreeStore::CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore(ModelHack()),
+       canvas_interface_               (canvas_interface_)
+{
+}
+
+CanvasTreeStore::~CanvasTreeStore()
+{
+}
+
+void
+CanvasTreeStore::get_value_vfunc(const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column==model.value.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<synfig::ValueBase> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if(!value_desc)
+               {
+                       x.set(ValueBase());
+               }
+               else
+               if(value_desc.is_const())
+                       x.set(value_desc.get_value());
+               else
+               if(value_desc.is_value_node())
+                       x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
+               else
+               {
+                       synfig::error(__FILE__":%d: Unable to figure out value",__LINE__);
+                       return;
+               }
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_value_node.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(value_desc && value_desc.is_value_node());
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_shared.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_exported.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_canvas.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.id.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if(value_desc && value_desc.is_value_node())
+                       x.set(value_desc.get_value_node()->get_id());
+               else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
+                       x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
+               else
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_editable.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(!value_desc.is_value_node() || synfigapp::is_editable(value_desc.get_value_node()));
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.type.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               // Set the type
+               if(!value_desc)
+               {
+                       if((*iter)[model.is_canvas])
+                               x.set(_("Canvas"));
+               }
+               else
+               {
+                       if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
+                       {
+                               x.set(ValueBase::type_local_name(value_desc.get_value_type()));
+                       }
+                       else
+                       {
+                               x.set(value_desc.get_value_node()->get_local_name());
+                       }
+               }
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.label.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               // Set the type
+               if(!value_desc)
+               {
+                       Canvas::Handle canvas((*iter)[model.canvas]);
+                       if(canvas)
+                       {
+                               if(!canvas->get_id().empty())
+                                       x.set(canvas->get_id());
+                               else
+                               if(!canvas->get_name().empty())
+                                       x.set(canvas->get_name());
+                               else
+                                       x.set(_("[Unnamed]"));
+                               x.set(_("Canvas"));
+                       }
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+               }
+               else
+               {
+                       ValueNode::Handle value_node=value_desc.get_value_node();
+
+                       // Setup the row's label
+                       if(value_node->get_id().empty())
+                               x.set(Glib::ustring((*iter)[model.name]));
+                       else if(Glib::ustring((*iter)[model.name]).empty())
+                               x.set(value_node->get_id());
+                       else
+                               x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');
+               }
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.icon.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+               if(!value_desc)
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+
+               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(get_tree_pixbuf(value_desc.get_value_type()));
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+bool
+CanvasTreeStore::find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
+{
+       iter=children().begin();
+       while(iter && value_desc!=(*iter)[model.value_desc])
+       {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       //! \todo confirm that the && should be done before the ||
+                       if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+                       iter==iter->parent();
+               else
+                       iter=iter2;
+       }
+       return (bool)iter && value_desc==(*iter)[model.value_desc];
+}
+
+bool
+CanvasTreeStore::find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
+{
+       if(!iter) return find_first_value_desc(value_desc,iter);
+
+       if(iter) do {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       //! \todo confirm that the && should be done before the ||
+                       if((iter2 && value_desc==(*iter2)[model.value_desc]) || find_next_value_desc(value_desc, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+               {
+                       iter==iter->parent();
+                       if(iter)++iter;
+               }
+               else
+                       iter=iter2;
+       } while(iter && value_desc!=(*iter)[model.value_desc]);
+       return (bool)iter && value_desc==(*iter)[model.value_desc];
+}
+
+bool
+CanvasTreeStore::find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
+{
+       iter=children().begin();
+       while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
+       {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       //! \todo confirm that the && should be done before the ||
+                       if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+                       iter==iter->parent();
+               else
+                       iter=iter2;
+       }
+       return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
+}
+
+bool
+CanvasTreeStore::find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter)
+{
+       if(!iter) return find_first_value_node(value_node,iter);
+
+       if(iter) do {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       //! \todo confirm that the && should be done before the ||
+                       if((iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node]) || find_next_value_node(value_node, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+               {
+                       iter==iter->parent();
+                       if(iter)++iter;
+               }
+               else
+                       iter=iter2;
+       } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
+       return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
+}
+
+void
+CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
+{
+       Gtk::TreeModel::Children children = row.children();
+       while(!children.empty() && erase(children.begin()))
+               ;
+
+       row[model.value_desc]=value_desc;
+       try
+       {
+               //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
+
+               if(value_desc.is_value_node())
+               {
+                       ValueNode::Handle value_node=value_desc.get_value_node();
+
+                       assert(value_node);
+
+                       row[model.value_node] = value_node;
+                       //row[model.is_canvas] = false;
+                       //row[model.is_value_node] = true;
+                       //row[model.is_editable] = synfigapp::is_editable(value_node);
+                       //row[model.id]=value_node->get_id();
+
+                       // Set the canvas
+                       if(value_desc.parent_is_canvas())
+                               row[model.canvas]=value_desc.get_canvas();
+                       else
+                               row[model.canvas]=canvas_interface()->get_canvas();
+
+                       LinkableValueNode::Handle linkable;
+                       linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+
+                       if(linkable && do_children)
+                       {
+                               row[model.link_count] = linkable->link_count();
+                               for(int i=0;i<linkable->link_count();i++)
+                               {
+                                       Gtk::TreeRow child_row=*(append(row.children()));
+                                       child_row[model.link_id] = i;
+                                       child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
+                                       child_row[model.name] = linkable->link_local_name(i);
+                                       set_row(child_row,synfigapp::ValueDesc(linkable,i));
+                               }
+                       }
+                       return;
+               }
+               else
+               {
+                       //row[model.is_value_node] = false;
+                       //row[model.is_editable] = true;
+                       //row[model.label] = Glib::ustring(row[model.name]);
+                       return;
+               }
+       }
+       catch(synfig::Exception::IDNotFound x)
+       {
+               synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
+               erase(row);
+               return;
+       }
+
+       // We should never get to this point
+       assert(0);
+}
+
+void
+CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
+{
+       synfigapp::ValueDesc value_desc=row[model.value_desc];
+
+       if(value_desc)
+       {
+               if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
+                       (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
+               {
+                       set_row(row,value_desc,do_children);
+                       return;
+               }
+
+               if(row[model.is_value_node])
+               {
+                       ValueNode::Handle value_node(value_desc.get_value_node());
+
+                       if(ValueNode::Handle(row[model.value_node])!=value_node)
+                       {
+                               rebuild_row(row,do_children);
+                               return;
+                       }
+
+                       //row[model.id]=value_node->get_id();
+
+                       // Setup the row's label
+                       /*
+                       if(value_node->get_id().empty())
+                               row[model.label] = Glib::ustring(row[model.name]);
+                       else if(Glib::ustring(row[model.name]).empty())
+                               row[model.label] = value_node->get_id();
+                       else
+                               row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
+                       */
+
+                       LinkableValueNode::Handle linkable;
+                       linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+                       if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
+                       {
+       //                      Gtk::TreeModel::Children children = row.children();
+       //                      while(!children.empty() && erase(children.begin()));
+
+                               set_row(row,value_desc);
+                               return;
+                       }
+               }
+               else
+               {
+                       //row[model.label] = Glib::ustring(row[model.name]);
+                       //row[model.is_value_node] = false;
+                       //row[model.is_editable] = true;
+               }
+       }
+       if(!do_children)
+               return;
+
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+       for(iter = children.begin(); iter != children.end(); ++iter)
+       {
+               Gtk::TreeRow row=*iter;
+               refresh_row(row);
+       }
+}
+
+void
+CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
+{
+       synfigapp::ValueDesc value_desc=(synfigapp::ValueDesc)row[model.value_desc];
+
+       if(value_desc && value_desc.get_value_node())
+       {
+               ValueNode::Handle value_node;
+               value_node=value_desc.get_value_node();
+
+               assert(value_node);if(!value_node)return;
+
+               if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
+               {
+//                     Gtk::TreeModel::Children children = row.children();
+//                     while(!children.empty() && erase(children.begin()));
+
+                       set_row(row,value_desc,do_children);
+                       return;
+               }
+
+               LinkableValueNode::Handle linkable;
+               linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+
+               if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
+               {
+//                     Gtk::TreeModel::Children children = row.children();
+//                     while(!children.empty() && erase(children.begin()));
+
+                       set_row(row,value_desc);
+                       return;
+               }
+
+               //if(!value_node)
+               //      value_node=row[model.value_node];
+
+               row[model.id]=value_node->get_id();
+
+               // Setup the row's label
+               if(value_node->get_id().empty())
+                       row[model.label] = Glib::ustring(row[model.name]);
+               else if(Glib::ustring(row[model.name]).empty())
+                       row[model.label] = value_node->get_id();
+               else
+                       row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';
+       }
+       else
+       {
+               row[model.label] = Glib::ustring(row[model.name]);
+               row[model.is_value_node] = false;
+               row[model.is_editable] = true;
+               Gtk::TreeModel::Children children = row.children();
+               while(!children.empty() && erase(children.begin()))
+                       ;
+       }
+       if(!do_children)
+               return;
+
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+       if(!children.empty())
+       for(iter = children.begin(); iter != children.end(); ++iter)
+       {
+               Gtk::TreeRow row=*iter;
+               rebuild_row(row);
+       }
+}
+
+CellRenderer_ValueBase*
+CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
+{
+       const CanvasTreeStore::Model model;
+
+       CellRenderer_ValueBase* ret;
+
+       ret=Gtk::manage( new CellRenderer_ValueBase() );
+
+       column->pack_start(*ret,true);
+       column->add_attribute(ret->property_value(), model.value);
+       column->add_attribute(ret->property_editable(), model.is_editable);
+       column->add_attribute(ret->property_canvas(), model.canvas);
+
+       return ret;
+}
+
+CellRenderer_TimeTrack*
+CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
+{
+       const CanvasTreeStore::Model model;
+
+       CellRenderer_TimeTrack* ret;
+
+       ret = Gtk::manage( new CellRenderer_TimeTrack() );
+
+       column->pack_start(*ret,true);
+       //column->add_attribute(ret->property_visible(), model.is_value_node);
+       column->add_attribute(ret->property_value_desc(), model.value_desc);
+       column->add_attribute(ret->property_canvas(), model.canvas);
+
+
+       return ret;
+}
diff --git a/synfig-studio/src/gui/trees/canvastreestore.h b/synfig-studio/src/gui/trees/canvastreestore.h
new file mode 100644 (file)
index 0000000..d7e119a
--- /dev/null
@@ -0,0 +1,195 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/canvastreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_CANVASTREESTORE_H
+#define __SYNFIG_STUDIO_CANVASTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfigapp/value_desc.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+       enum ColumnID
+       {
+               COLUMNID_ID,
+               COLUMNID_VALUE,
+               COLUMNID_TIME_TRACK,
+               COLUMNID_TYPE,
+
+               COLUMNID_END                    //!< \internal
+       };
+#define        COLUMNID_NAME COLUMNID_ID
+
+class CanvasTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<Glib::ustring> label;
+               Gtk::TreeModelColumn<Glib::ustring> name;
+               Gtk::TreeModelColumn<Glib::ustring> id;
+
+               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+               Gtk::TreeModelColumn<bool> is_canvas;
+
+               Gtk::TreeModelColumn<synfig::ValueNode::Handle> value_node;
+               Gtk::TreeModelColumn<bool> is_value_node;
+               Gtk::TreeModelColumn<synfig::ValueBase> value;
+               Gtk::TreeModelColumn<Glib::ustring> type;
+               Gtk::TreeModelColumn<int> link_id;
+               Gtk::TreeModelColumn<int> link_count;
+
+               Gtk::TreeModelColumn<bool> is_editable;
+
+               Gtk::TreeModelColumn<bool> is_shared;
+               Gtk::TreeModelColumn<bool> is_exported;
+
+               Gtk::TreeModelColumn<synfigapp::ValueDesc> value_desc;
+
+               Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+               Model()
+               {
+                       add(value);
+                       add(name);
+                       add(label);
+                       add(icon);
+                       add(type);
+                       add(id);
+                       add(canvas);
+                       add(value_node);
+                       add(is_canvas);
+                       add(is_value_node);
+
+                       add(is_shared);
+                       add(is_exported);
+                       add(is_editable);
+                       add(value_desc);
+                       add(link_count);
+                       add(link_id);
+
+                       add(tooltip);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       const Model model;
+
+       //std::multimap<etl::handle<ValueNode>, sigc::connection> connection_map;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+protected:
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       CanvasTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+       ~CanvasTreeStore();
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+
+       virtual void rebuild_row(Gtk::TreeModel::Row &row, bool do_children=true);
+
+       virtual void refresh_row(Gtk::TreeModel::Row &row, bool do_children=true);
+
+       virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children=true);
+
+       bool find_first_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
+       bool find_next_value_desc(const synfigapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
+
+       bool find_first_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
+       bool find_next_value_node(const synfig::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
+
+
+       static CellRenderer_ValueBase* add_cell_renderer_value(Gtk::TreeView::Column* column);
+
+       static CellRenderer_TimeTrack* add_cell_renderer_value_node(Gtk::TreeView::Column* column);
+
+       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       virtual void on_value_node_changed(synfig::ValueNode::Handle value_node)=0;
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+public:
+
+}; // END of class CanvasTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/childrentree.cpp b/synfig-studio/src/gui/trees/childrentree.cpp
new file mode 100644 (file)
index 0000000..d2311e0
--- /dev/null
@@ -0,0 +1,439 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file childrentree.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "trees/childrentree.h"
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include <gtkmm/scrolledwindow.h>
+#include <synfig/timepointcollect.h>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef SMALL_BUTTON
+#define SMALL_BUTTON(button,stockid,tooltip)   \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       button->set_relief(Gtk::RELIEF_NONE); \
+       button->show()
+#endif
+
+#ifndef NORMAL_BUTTON
+#define NORMAL_BUTTON(button,stockid,tooltip)  \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       /*button->set_relief(Gtk::RELIEF_NONE);*/ \
+       button->show()
+#endif
+
+#define NEW_SMALL_BUTTON(x,y,z)        Gtk::Button *SMALL_BUTTON(x,y,z)
+
+#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ChildrenTree::ChildrenTree()
+{
+       const ChildrenTreeStore::Model model;
+
+       {       // --- N A M E --------------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ID")) );
+
+               // Set up the icon cell-renderer
+               Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               column->pack_start(*icon_cellrenderer,false);
+               column->add_attribute(icon_cellrenderer->property_pixbuf(), model.icon);
+
+               // Pack the label into the column
+               column->pack_start(model.label,true);
+
+               // Finish setting up the column
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               column->set_min_width(150);
+               column->set_sort_column(model.label);
+               tree_view.append_column(*column);
+
+       }
+       {       // --- T Y P E --------------------------------------------------------
+               int cols_count = tree_view.append_column(_("Type"),model.type);
+               Gtk::TreeViewColumn* column = tree_view.get_column(cols_count-1);
+               if(column)
+               {
+                       column->set_reorderable();
+                       column->set_resizable();
+                       column->set_clickable();
+                       column->set_sort_column(model.type);
+               }
+       }
+       {       // --- V A L U E  -----------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
+
+               // Set up the value cell-renderer
+               cellrenderer_value=ChildrenTreeStore::add_cell_renderer_value(column);
+               cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_edited_value));
+               cellrenderer_value->property_value()=synfig::ValueBase();
+
+               // Finish setting up the column
+               tree_view.append_column(*column);
+               column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+               column->set_min_width(150);
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable(false);
+       }
+       {       // --- T I M E   T R A C K --------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
+               column_time_track=column;
+
+               // Set up the value-node cell-renderer
+               cellrenderer_time_track=ChildrenTreeStore::add_cell_renderer_value_node(column);
+               cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+               cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_waypoint_clicked_childrentree) );
+               column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
+               column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
+
+               //column->pack_start(*cellrenderer_time_track);
+
+               // Finish setting up the column
+               column->set_reorderable();
+               column->set_resizable();
+               tree_view.append_column(*column);
+       }
+
+       // This makes things easier to read.
+       tree_view.set_rules_hint();
+
+       // Make us more sensitive to several events
+       tree_view.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+       tree_view.signal_event().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_event));
+
+       // Create a scrolled window for that tree
+       Gtk::ScrolledWindow *scroll_children_tree = manage(new class Gtk::ScrolledWindow());
+       scroll_children_tree->set_flags(Gtk::CAN_FOCUS);
+       scroll_children_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scroll_children_tree->add(tree_view);
+       scroll_children_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scroll_children_tree->show();
+
+       attach(*scroll_children_tree, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       hbox=manage(new Gtk::HBox());
+
+       attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+       tree_view.set_enable_search(true);
+       tree_view.set_search_column(model.label);
+
+/*  // Buttons to raise/lower/duplicate/delete children valuenodes
+       //   Commented out because these functions are not implemented
+    //   and children sort themselves alphabetically
+
+       Gtk::Image *icon;
+       //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
+       Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       SMALL_BUTTON(button_raise,"gtk-go-up",_("Raise"));
+       SMALL_BUTTON(button_lower,"gtk-go-down",_("Lower"));
+       SMALL_BUTTON(button_duplicate,"synfig-duplicate",_("Duplicate"));
+       SMALL_BUTTON(button_delete,"gtk-delete",_("Delete"));
+
+       hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
+
+       button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_raise_pressed));
+       button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_lower_pressed));
+       button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_duplicate_pressed));
+       button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_delete_pressed));
+
+       button_raise->set_sensitive(false);
+       button_lower->set_sensitive(false);
+       button_duplicate->set_sensitive(false);
+       button_delete->set_sensitive(false);
+*/
+
+       get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_selection_changed));
+
+       tree_view.set_reorderable(true);
+
+       hbox->show();
+       tree_view.show();
+
+       tooltips_.enable();
+
+       //get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+}
+
+ChildrenTree::~ChildrenTree()
+{
+}
+
+void
+ChildrenTree::set_show_timetrack(bool x)
+{
+       column_time_track->set_visible(x);
+}
+
+void
+ChildrenTree::set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store)
+{
+       children_tree_store_=children_tree_store;
+       tree_view.set_model(children_tree_store_);
+       cellrenderer_time_track->set_canvas_interface(children_tree_store_->canvas_interface()); // am I smart people?  (cellrenderer_timetrack.h:176)
+       children_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::ChildrenTree::on_dirty_preview));
+}
+
+void
+ChildrenTree::set_time_adjustment(Gtk::Adjustment &adjustment)
+{
+       cellrenderer_time_track->set_adjustment(adjustment);
+}
+
+void
+ChildrenTree::on_dirty_preview()
+{
+}
+
+void
+ChildrenTree::on_selection_changed()
+{
+       if(0)
+               {
+               button_raise->set_sensitive(false);
+               button_lower->set_sensitive(false);
+               button_duplicate->set_sensitive(false);
+               button_delete->set_sensitive(false);
+               return;
+       }
+}
+
+void
+ChildrenTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+       row[model.value]=value;
+//     signal_edited_value()(row[model.value_desc],value);
+}
+
+void
+ChildrenTree::on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
+                                                                                          const synfig::Time& time __attribute__ ((unused)),
+                                                                                          const synfig::Time& time_offset __attribute__ ((unused)),
+                                                                                          int button __attribute__ ((unused)))
+{
+       std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
+       synfig::waypoint_collect(waypoint_set,time,node);
+
+       synfigapp::ValueDesc value_desc;
+
+       if (waypoint_set.size() == 1)
+       {
+               ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
+               assert(value_node);
+
+               Gtk::TreeRow row;
+               if (children_tree_store_->find_first_value_node(value_node, row) && row)
+                       value_desc = static_cast<synfigapp::ValueDesc>(row[model.value_desc]);
+       }
+
+       if (!waypoint_set.empty())
+               signal_waypoint_clicked_childrentree()(value_desc,waypoint_set,button);
+}
+
+bool
+ChildrenTree::on_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!tree_view.get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+                       if(column->get_first_cell_renderer()==cellrenderer_time_track)
+                       {
+                               Gdk::Rectangle rect;
+                               tree_view.get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+                       }
+                       else if(column->get_first_cell_renderer()==cellrenderer_value)
+                               return signal_user_click()(event->button.button,row,COLUMNID_VALUE);
+                       else
+                               return signal_user_click()(event->button.button,row,COLUMNID_ID);
+
+               }
+               break;
+
+       case GDK_MOTION_NOTIFY:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!tree_view.get_path_at_pos(
+                               (int)event->button.x,(int)event->button.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+
+                       if(!tree_view.get_model()->get_iter(path))
+                               break;
+
+                       Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+                       if(cellrenderer_time_track==column->get_first_cell_renderer())
+                       {
+                               // Movement on TimeLine
+                               Gdk::Rectangle rect;
+                               tree_view.get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               queue_draw();
+                               //queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+                       }
+                       else
+                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+                       {
+                               tooltips_.unset_tip(*this);
+                               Glib::ustring tooltips_string(row[model.tooltip]);
+                               last_tooltip_path=path;
+                               if(!tooltips_string.empty())
+                               {
+                                       tooltips_.set_tip(*this,tooltips_string);
+                                       tooltips_.force_window();
+                               }
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!tree_view.get_path_at_pos(
+                                  (int)event->button.x,(int)event->button.y,   // x, y
+                                  path, // TreeModel::Path&
+                                  column, //TreeViewColumn*&
+                                  cell_x,cell_y //int&cell_x,int&cell_y
+                                  )
+                               ) break;
+
+                       if(!tree_view.get_model()->get_iter(path))
+                               break;
+
+                       Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+                       if(column && cellrenderer_time_track == column->get_first_cell_renderer())
+                       {
+                               Gdk::Rectangle rect;
+                               tree_view.get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               queue_draw();
+                               queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+void
+ChildrenTree::on_raise_pressed()
+{
+}
+
+void
+ChildrenTree::on_lower_pressed()
+{
+}
+
+void
+ChildrenTree::on_duplicate_pressed()
+{
+}
+
+void
+ChildrenTree::on_delete_pressed()
+{
+}
diff --git a/synfig-studio/src/gui/trees/childrentree.h b/synfig-studio/src/gui/trees/childrentree.h
new file mode 100644 (file)
index 0000000..f2afc5c
--- /dev/null
@@ -0,0 +1,179 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/childrentree.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_CHILDRENTREE_H
+#define __SYNFIG_STUDIO_CHILDRENTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/box.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/button.h>
+
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "trees/childrentreestore.h"
+#include <synfig/valuenode_animated.h>
+
+#include "widgets/widget_value.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+class ChildrenTree : public Gtk::Table
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       typedef studio::ColumnID ColumnID;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       ChildrenTreeStore::Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Gtk::Tooltips tooltips_;
+
+       Gtk::TreePath last_tooltip_path;
+
+       Gtk::TreeView tree_view;
+
+       Gtk::HBox *hbox;
+
+       Glib::RefPtr<ChildrenTreeStore> children_tree_store_;
+
+       CellRenderer_TimeTrack *cellrenderer_time_track;
+
+       Gtk::TreeView::Column* column_time_track;
+
+       CellRenderer_ValueBase *cellrenderer_value;
+
+       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
+
+       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_user_click_;
+
+       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_childrentree_;
+
+       Gtk::Button *button_raise;
+       Gtk::Button *button_lower;
+       Gtk::Button *button_duplicate;
+       Gtk::Button *button_delete;
+
+       Widget_ValueBase blend_method_widget;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
+
+       void on_waypoint_clicked_childrentree(const etl::handle<synfig::Node>& node,const synfig::Time&,const synfig::Time&,int button);
+
+       bool on_tree_event(GdkEvent *event);
+
+       void on_selection_changed();
+
+       void on_dirty_preview();
+
+       //! \todo Implement raise/lower/duplicate/delete functions
+       void on_raise_pressed();
+
+       void on_lower_pressed();
+
+       void on_duplicate_pressed();
+
+       void on_delete_pressed();
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       Gtk::HBox& get_hbox() { return *hbox; }
+
+       Gtk::TreeView& get_tree_view() { return tree_view; }
+
+       Glib::RefPtr<Gtk::TreeSelection> get_selection() { return tree_view.get_selection(); }
+       Glib::SignalProxy1< bool,GdkEvent* >  signal_event () { return tree_view.signal_event(); }
+
+       ChildrenTree();
+       ~ChildrenTree();
+
+       void set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store_);
+
+       void set_time_adjustment(Gtk::Adjustment &adjustment);
+
+       void set_show_timetrack(bool x=true);
+
+       //! Signal called with a value has been edited.
+       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
+
+       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
+
+       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_childrentree() { return signal_waypoint_clicked_childrentree_; }
+
+       etl::handle<synfigapp::SelectionManager> get_selection_manager() { return children_tree_store_->canvas_interface()->get_selection_manager(); }
+
+}; // END of ChildrenTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/childrentreestore.cpp b/synfig-studio/src/gui/trees/childrentreestore.cpp
new file mode 100644 (file)
index 0000000..1ab3bfe
--- /dev/null
@@ -0,0 +1,389 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file childrentreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "trees/childrentreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include <ETL/clock>
+
+#include "general.h"
+
+class Profiler : private etl::clock
+{
+       const std::string name;
+public:
+       Profiler(const std::string& name):name(name) { reset(); }
+       ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
+};
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static ChildrenTreeStore::Model& ModelHack()
+{
+       static ChildrenTreeStore::Model* model(0);
+       if(!model)model=new ChildrenTreeStore::Model;
+       return *model;
+}
+
+ChildrenTreeStore::ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore                  (ModelHack()),
+       CanvasTreeStore                 (canvas_interface_)
+{
+       canvas_row=*append();
+       canvas_row[model.label]=_("Canvases");
+       canvas_row[model.is_canvas] = false;
+       canvas_row[model.is_value_node] = false;
+
+       value_node_row=*append();
+       value_node_row[model.label]=_("ValueBase Nodes");
+       value_node_row[model.is_canvas] = false;
+       value_node_row[model.is_value_node] = false;
+
+       // Connect all the signals
+       canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_changed));
+       canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_renamed));
+       canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_added));
+       canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_deleted));
+       canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_replaced));
+       canvas_interface()->signal_canvas_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_added));
+       canvas_interface()->signal_canvas_removed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_removed));
+
+       rebuild();
+}
+
+ChildrenTreeStore::~ChildrenTreeStore()
+{
+}
+
+Glib::RefPtr<ChildrenTreeStore>
+ChildrenTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<ChildrenTreeStore>(new ChildrenTreeStore(canvas_interface_));
+}
+
+void
+ChildrenTreeStore::rebuild()
+{
+       // Profiler profiler("ChildrenTreeStore::rebuild()");
+       rebuild_value_nodes();
+       rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::refresh()
+{
+       // Profiler profiler("ChildrenTreeStore::refresh()");
+       refresh_value_nodes();
+       refresh_canvases();
+}
+
+void
+ChildrenTreeStore::rebuild_value_nodes()
+{
+       Gtk::TreeModel::Children children(value_node_row.children());
+
+       while(!children.empty())erase(children.begin());
+
+       clear_changed_queue();
+
+       std::for_each(
+               canvas_interface()->get_canvas()->value_node_list().rbegin(), canvas_interface()->get_canvas()->value_node_list().rend(),
+               sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_value_node_added)
+       );
+}
+
+void
+ChildrenTreeStore::refresh_value_nodes()
+{
+       Gtk::TreeModel::Children children(value_node_row.children());
+
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+               for(iter = children.begin(); iter != children.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+}
+
+void
+ChildrenTreeStore::rebuild_canvases()
+{
+       Gtk::TreeModel::Children children(canvas_row.children());
+
+       while(!children.empty())erase(children.begin());
+
+       std::for_each(
+               canvas_interface()->get_canvas()->children().rbegin(), canvas_interface()->get_canvas()->children().rend(),
+               sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_canvas_added)
+       );
+}
+
+void
+ChildrenTreeStore::refresh_canvases()
+{
+       rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool /*do_children*/)
+{
+       CanvasTreeStore::refresh_row(row,false);
+
+       if((bool)row[model.is_value_node])
+       {
+               changed_set_.erase(row[model.value_node]);
+       }
+
+}
+
+void
+ChildrenTreeStore::on_canvas_added(synfig::Canvas::Handle canvas)
+{
+       Gtk::TreeRow row = *(prepend(canvas_row.children()));
+
+       row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+       row[model.id] = canvas->get_id();
+       row[model.name] = canvas->get_name();
+
+       if(!canvas->get_id().empty())
+               row[model.label] = canvas->get_id();
+       else
+       if(!canvas->get_name().empty())
+               row[model.label] = canvas->get_name();
+       else
+               row[model.label] = _("[Unnamed]");
+
+       row[model.canvas] = canvas;
+       row[model.type] = _("Canvas");
+       //row[model.is_canvas] = true;
+       //row[model.is_value_node] = false;
+}
+
+void
+ChildrenTreeStore::on_canvas_removed(synfig::Canvas::Handle /*canvas*/)
+{
+       rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::on_value_node_added(synfig::ValueNode::Handle value_node)
+{
+//     if(value_node->get_id().find("Unnamed")!=String::npos)
+//             return;
+
+       Gtk::TreeRow row = *prepend(value_node_row.children());
+
+       set_row(row,synfigapp::ValueDesc(canvas_interface()->get_canvas(),value_node->get_id()),false);
+}
+
+void
+ChildrenTreeStore::on_value_node_deleted(synfig::ValueNode::Handle value_node)
+{
+       Gtk::TreeIter iter;
+       //int i(0);
+
+       if(find_first_value_node(value_node,iter))
+       {
+               erase(iter);
+       }
+       //rebuild_value_nodes();
+}
+
+bool
+ChildrenTreeStore::execute_changed_value_nodes()
+{
+       // Profiler profiler("ChildrenTreeStore::execute_changed_value_nodes()");
+       if(!replaced_set_.empty())
+               rebuild_value_nodes();
+
+       etl::clock timer;
+       timer.reset();
+
+       while(!changed_set_.empty())
+       {
+               ValueNode::Handle value_node(*changed_set_.begin());
+               changed_set_.erase(value_node);
+
+               Gtk::TreeIter iter;
+
+               try
+               {
+                       Gtk::TreeIter iter;
+                       int i(0);
+
+                       if(!value_node->is_exported() && find_first_value_node(value_node,iter))
+                       {
+                               rebuild_value_nodes();
+                               continue;
+                       }
+
+                       if(value_node->is_exported() && find_first_value_node(value_node,iter)) do
+                       {
+                               Gtk::TreeRow row(*iter);
+                               i++;
+                               refresh_row(row);
+                       }while(find_next_value_node(value_node,iter));
+
+                       if(!i)
+                       {
+                               refresh_value_nodes();
+                               return false;
+                       }
+
+               }
+               catch(...)
+               {
+                       rebuild_value_nodes();
+                       return false;
+               }
+
+               // If we are taking too long...
+               if(timer()>4)
+               {
+                       refresh_value_nodes();
+                       return false;
+               }
+       }
+
+       return false;
+}
+
+void
+ChildrenTreeStore::on_value_node_changed(synfig::ValueNode::Handle value_node)
+{
+
+       if(!value_node->is_exported())
+               return;
+       changed_connection.disconnect();
+//     if(!execute_changed_queued())
+//             changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
+       changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
+
+       changed_set_.insert(value_node);
+       /*
+       try
+       {
+               Gtk::TreeIter iter;
+               int i(0);
+               while(find_next_value_node(value_node,iter))
+               {
+                       Gtk::TreeRow row(*iter);
+                       i++;
+                       refresh_row(row);
+               }
+               if(!i)
+               {
+                       refresh_value_nodes();
+               }
+       }
+       catch(...)
+       {
+               rebuild_value_nodes();
+       }
+       */
+}
+
+void
+ChildrenTreeStore::on_value_node_renamed(synfig::ValueNode::Handle value_node __attribute__ ((unused)))
+{
+       rebuild_value_nodes();
+}
+
+void
+ChildrenTreeStore::on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle /*new_value_node*/)
+{
+       changed_connection.disconnect();
+       //if(!execute_changed_queued())
+//             changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
+               changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
+
+       replaced_set_.insert(replaced_value_node);
+}
+
+void
+ChildrenTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.value.index())
+               {
+                       Glib::Value<synfig::ValueBase> x;
+                       g_value_init(x.gobj(),model.value.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+                       if(value_desc)
+                       {
+                               canvas_interface()->change_value(value_desc,x.get());
+                               row_changed(get_path(*iter),*iter);
+                       }
+
+                       return;
+               }
+               else
+                       CanvasTreeStore::set_value_impl(iter,column, value);
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
diff --git a/synfig-studio/src/gui/trees/childrentreestore.h b/synfig-studio/src/gui/trees/childrentreestore.h
new file mode 100644 (file)
index 0000000..ed81205
--- /dev/null
@@ -0,0 +1,143 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/childrentreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_CHILDRENTREESTORE_H
+#define __SYNFIG_STUDIO_CHILDRENTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include "trees/canvastreestore.h"
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class ChildrenTreeStore : public CanvasTreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       //! TreeModel for the layers
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Gtk::TreeModel::Row value_node_row;
+       Gtk::TreeModel::Row canvas_row;
+
+       std::set<synfig::ValueNode::Handle> changed_set_;
+
+       std::set<synfig::ValueNode::Handle> replaced_set_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       sigc::connection changed_connection;
+       bool execute_changed_queued()const { return !changed_set_.empty() || !replaced_set_.empty(); }
+       bool execute_changed_value_nodes();
+       void clear_changed_queue() { changed_set_.clear(); replaced_set_.clear(); }
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_value_node_added(synfig::ValueNode::Handle value_node);
+       void on_value_node_deleted(synfig::ValueNode::Handle value_node);
+       void on_value_node_changed(synfig::ValueNode::Handle value_node);
+       void on_value_node_renamed(synfig::ValueNode::Handle value_node);
+       void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
+       void on_canvas_added(synfig::Canvas::Handle canvas);
+       void on_canvas_removed(synfig::Canvas::Handle canvas);
+
+       void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       ChildrenTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+       ~ChildrenTreeStore();
+
+       void rebuild();
+
+       void refresh();
+
+       void rebuild_value_nodes();
+
+       void refresh_value_nodes();
+
+       void rebuild_canvases();
+
+       void refresh_canvases();
+
+       void refresh_row(Gtk::TreeModel::Row &row, bool do_children=false);
+
+       Gtk::TreeModel::Row get_canvas_row()const { return canvas_row; }
+
+       Gtk::TreeModel::Row get_value_node_row()const { return value_node_row; }
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<ChildrenTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+}; // END of class ChildrenTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/historytreestore.cpp b/synfig-studio/src/gui/trees/historytreestore.cpp
new file mode 100644 (file)
index 0000000..8375053
--- /dev/null
@@ -0,0 +1,235 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file historytreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "trees/historytreestore.h"
+#include <synfig/valuenode.h>
+#include "iconcontroller.h"
+#include <synfig/valuenode_timedswap.h>
+#include <gtkmm/button.h>
+#include <synfigapp/action.h>
+#include "instance.h"
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static HistoryTreeStore::Model& ModelHack()
+{
+       static HistoryTreeStore::Model* model(0);
+       if(!model)model=new HistoryTreeStore::Model;
+       return *model;
+}
+
+HistoryTreeStore::HistoryTreeStore(etl::loose_handle<studio::Instance> instance_):
+       Gtk::TreeStore  (ModelHack()),
+       instance_               (instance_)
+{
+       instance_->signal_undo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo));
+       instance_->signal_redo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo));
+       instance_->signal_undo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo_stack_cleared));
+       instance_->signal_redo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo_stack_cleared));
+       instance_->signal_new_action().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_new_action));
+       instance_->signal_action_status_changed().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_action_status_changed));
+}
+
+HistoryTreeStore::~HistoryTreeStore()
+{
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("HistoryTreeStore::~HistoryTreeStore(): Deleted");
+}
+
+Glib::RefPtr<HistoryTreeStore>
+HistoryTreeStore::create(etl::loose_handle<studio::Instance> instance_)
+{
+       return Glib::RefPtr<HistoryTreeStore>(new HistoryTreeStore(instance_));
+}
+
+void
+HistoryTreeStore::rebuild()
+{
+       synfigapp::Action::Stack::const_iterator iter;
+
+       clear();
+
+       for(iter=instance()->undo_action_stack().begin();iter!=instance()->undo_action_stack().end();++iter)
+       {
+               insert_action(*(prepend()),*iter,true,true,false);
+       }
+       curr_row=*children().end();
+       for(iter=instance()->redo_action_stack().begin();iter!=instance()->redo_action_stack().end();++iter)
+       {
+               insert_action(*(append()),*iter,true,false,true);
+       }
+
+       signal_undo_tree_changed()();
+}
+
+void
+HistoryTreeStore::insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool /*is_active*/, bool is_undo, bool is_redo)
+{
+       assert(action);
+
+       row[model.action] = action;
+       row[model.name] = static_cast<Glib::ustring>(action->get_local_name());
+       row[model.is_active] = action->is_active();
+       row[model.is_undo] = is_undo;
+       row[model.is_redo] = is_redo;
+
+       synfigapp::Action::CanvasSpecific *specific_action;
+       specific_action=dynamic_cast<synfigapp::Action::CanvasSpecific*>(action.get());
+       if(specific_action)
+       {
+               row[model.canvas] = specific_action->get_canvas();
+               row[model.canvas_id] = specific_action->get_canvas()->get_id();
+       }
+
+       etl::handle<synfigapp::Action::Group> group;
+       group=etl::handle<synfigapp::Action::Group>::cast_dynamic(action);
+       if(group)
+       {
+               synfigapp::Action::ActionList::const_iterator iter;
+               for(iter=group->action_list().begin();iter!=group->action_list().end();++iter)
+               {
+                       Gtk::TreeRow child_row = *(append(row.children()));
+                       insert_action(child_row,*iter,true,is_undo,is_redo);
+               }
+       }
+
+       //row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("synfig-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+}
+
+
+void
+HistoryTreeStore::on_undo()
+{
+       refresh();
+}
+
+void
+HistoryTreeStore::on_redo()
+{
+       refresh();
+}
+
+void
+HistoryTreeStore::on_undo_stack_cleared()
+{
+       Gtk::TreeModel::Children::iterator iter,next;
+       Gtk::TreeModel::Children children_(children());
+
+       for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(row[model.is_undo])
+                       erase(iter);
+       }
+}
+
+void
+HistoryTreeStore::on_redo_stack_cleared()
+{
+       Gtk::TreeModel::Children::iterator iter,next;
+       Gtk::TreeModel::Children children_(children());
+
+       for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(row[model.is_redo])
+                       erase(iter);
+       }
+}
+
+void
+HistoryTreeStore::on_new_action(etl::handle<synfigapp::Action::Undoable> action)
+{
+//     Gtk::TreeRow row = *(append());
+       Gtk::TreeRow row;
+       Gtk::TreeModel::Children::iterator iter;
+       for(iter=children().begin(); iter != children().end(); ++iter)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(row[model.is_redo])
+               {
+                       break;
+               }
+       }
+
+       row=*insert(iter);
+
+       insert_action(row,action);
+
+       signal_undo_tree_changed()();
+}
+
+void
+HistoryTreeStore::on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       Gtk::TreeModel::Children children_(children());
+
+       for(iter=children_.begin(); iter != children_.end(); ++iter)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(action == (etl::handle<synfigapp::Action::Undoable>)row[model.action])
+               {
+                       row[model.is_active]=action->is_active();
+                       return;
+               }
+       }
+}
+
+bool
+HistoryTreeStore::search_func(const Glib::RefPtr<Gtk::TreeModel>&,int,const Glib::ustring& x,const Gtk::TreeModel::iterator& iter)
+{
+       const Model model;
+
+       Glib::ustring substr(x.uppercase());
+       Glib::ustring name((*iter)[model.name]);
+       name=name.uppercase();
+
+       return name.find(substr)==Glib::ustring::npos;
+}
diff --git a/synfig-studio/src/gui/trees/historytreestore.h b/synfig-studio/src/gui/trees/historytreestore.h
new file mode 100644 (file)
index 0000000..a0fec66
--- /dev/null
@@ -0,0 +1,172 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/historytreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_HISTORYTREESTORE_H
+#define __SYNFIG_STUDIO_HISTORYTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfigapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Instance;
+
+class HistoryTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+       public:
+               Gtk::TreeModelColumn<etl::handle<synfigapp::Action::Undoable> > action;
+               Gtk::TreeModelColumn<Glib::ustring> name;
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<bool> is_active;
+               Gtk::TreeModelColumn<bool> is_undo;
+               Gtk::TreeModelColumn<bool> is_redo;
+
+               Gtk::TreeModelColumn<Glib::ustring> canvas_id;
+               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+
+               Model()
+               {
+                       add(action);
+                       add(name);
+                       add(icon);
+                       add(is_active);
+                       add(is_undo);
+                       add(is_redo);
+                       add(canvas_id);
+                       add(canvas);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<studio::Instance> instance_;
+       Gtk::TreeIter curr_row;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       sigc::signal<void> signal_undo_tree_changed_;
+
+       /*
+ -- ** -- S I G N A L   I N T E R F A C E S -----------------------------------
+       */
+
+public:
+
+       sigc::signal<void>& signal_undo_tree_changed() { return signal_undo_tree_changed_; }
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_undo();
+
+       void on_redo();
+
+       void on_undo_stack_cleared();
+
+       void on_redo_stack_cleared();
+
+       void on_new_action(etl::handle<synfigapp::Action::Undoable> action);
+
+       void on_action_status_changed(etl::handle<synfigapp::Action::Undoable> action);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       HistoryTreeStore(etl::loose_handle<studio::Instance> instance_);
+       ~HistoryTreeStore();
+
+       etl::loose_handle<studio::Instance> instance() { return instance_; }
+       etl::loose_handle<const studio::Instance> instance()const { return instance_; }
+
+       void rebuild();
+
+       void refresh() { rebuild(); }
+
+       void insert_action(Gtk::TreeRow row,etl::handle<synfigapp::Action::Undoable> action, bool is_active=true, bool is_undo=true, bool is_redo=false);
+
+       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<HistoryTreeStore> create(etl::loose_handle<studio::Instance> instance);
+
+}; // END of class HistoryTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/keyframetree.cpp b/synfig-studio/src/gui/trees/keyframetree.cpp
new file mode 100644 (file)
index 0000000..776ae65
--- /dev/null
@@ -0,0 +1,291 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file keyframetree.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "trees/keyframetree.h"
+#include "cellrenderer_time.h"
+#include <gtkmm/treemodelsort.h>
+#include <ETL/misc>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+KeyframeTree::KeyframeTree()
+{
+       const KeyframeTreeStore::Model model;
+
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time")) );
+
+               cell_renderer_time = Gtk::manage( new CellRenderer_Time() );
+               column->pack_start(*cell_renderer_time,true);
+               column->add_attribute(cell_renderer_time->property_time(), model.time);
+               cell_renderer_time->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time));
+
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               column->set_sort_column(model.time);
+
+               append_column(*column);
+       }
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Length")) );
+
+               cell_renderer_time_delta = Gtk::manage( new CellRenderer_Time() );
+               column->pack_start(*cell_renderer_time_delta,true);
+               column->add_attribute(cell_renderer_time_delta->property_time(), model.time_delta);
+               cell_renderer_time_delta->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time_delta));
+
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable(false);
+               // column->set_sort_column(model.time_delta);
+
+               append_column(*column);
+       }
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Jump")) );
+
+               Gtk::CellRendererText* cell_renderer_jump=Gtk::manage(new Gtk::CellRendererText());
+               column->pack_start(*cell_renderer_jump,true);
+               cell_renderer_jump->property_text()=_("(JMP)");
+               cell_renderer_jump->property_foreground()="#003a7f";
+
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable(false);
+               column->set_sort_column(COLUMNID_JUMP); // without this, (JMP) needs a double click?!
+
+               append_column(*column);
+       }
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Description")) );
+
+               cell_renderer_description=Gtk::manage(new Gtk::CellRendererText());
+               column->pack_start(*cell_renderer_description,true);
+               column->add_attribute(cell_renderer_description->property_text(), model.description);
+               cell_renderer_description->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_description));
+
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               column->set_sort_column(model.description);
+
+               append_column(*column);
+       }
+
+       set_enable_search(true);
+       set_search_column(model.description);
+
+       // This makes things easier to read.
+       set_rules_hint();
+
+       // Make us more sensitive to several events
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+}
+
+KeyframeTree::~KeyframeTree()
+{
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("KeyframeTree::~KeyframeTree(): Deleted");
+}
+
+void
+KeyframeTree::on_rend_desc_changed()
+{
+       cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+       queue_draw();
+}
+
+void
+KeyframeTree::set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store)
+{
+       keyframe_tree_store_=keyframe_tree_store;
+       KeyframeTreeStore::Model model;
+
+       if(true)
+       {
+               Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(keyframe_tree_store_));
+               sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
+               sorted_store->set_sort_func(model.time,                 sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
+               sorted_store->set_sort_func(model.description,  sigc::ptr_fun(&studio::KeyframeTreeStore::description_sorter));
+               Gtk::TreeView::set_model(sorted_store);
+       }
+       else
+               Gtk::TreeView::set_model(keyframe_tree_store);
+
+       keyframe_tree_store_->canvas_interface()->signal_rend_desc_changed().connect(
+               sigc::mem_fun(
+                       *this,
+                       &studio::KeyframeTree::on_rend_desc_changed
+               )
+       );
+       cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+       cell_renderer_time_delta->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+}
+
+void
+KeyframeTree::set_editable(bool x)
+{
+       editable_=x;
+
+       if(editable_)
+       {
+               cell_renderer_time->property_editable()=true;
+               cell_renderer_time_delta->property_editable()=true;
+               cell_renderer_description->property_editable()=true;
+       }
+       else
+       {
+               cell_renderer_time->property_editable()=false;
+               cell_renderer_time_delta->property_editable()=false;
+               cell_renderer_description->property_editable()=false;
+       }
+}
+
+void
+KeyframeTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+       synfig::Keyframe keyframe(row[model.keyframe]);
+       if(time!=keyframe.get_time())
+       {
+               row[model.time]=time;
+               //keyframe.set_time(time);
+               //signal_edited_time()(keyframe,time);
+               //signal_edited()(keyframe);
+       }
+}
+
+void
+KeyframeTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+       if(row)row[model.time_delta]=time;
+}
+
+void
+KeyframeTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+       const synfig::String description(desc);
+       synfig::Keyframe keyframe(row[model.keyframe]);
+       if(description!=keyframe.get_description())
+       {
+               row[model.description]=desc;
+               keyframe.set_description(description);
+               signal_edited_description()(keyframe,description);
+               signal_edited()(keyframe);
+       }
+}
+
+bool
+KeyframeTree::on_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
+                       //tree_to_widget_coords (,, wx, wy);
+                       if(!get_path_at_pos(
+                               wx,wy,  // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+                       signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+                       {
+                               keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
+                       }
+               }
+               break;
+       case GDK_2BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+                       {
+                               keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
+                               return true;
+                       }
+               }
+               break;
+
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
diff --git a/synfig-studio/src/gui/trees/keyframetree.h b/synfig-studio/src/gui/trees/keyframetree.h
new file mode 100644 (file)
index 0000000..cb5d5ca
--- /dev/null
@@ -0,0 +1,149 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/keyframetree.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_KEYFRAMETREE_H
+#define __SYNFIG_STUDIO_KEYFRAMETREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "trees/keyframetreestore.h"
+#include <synfig/keyframe.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_Time;
+
+class KeyframeTree : public Gtk::TreeView
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       enum ColumnID
+       {
+               COLUMNID_TIME,
+               COLUMNID_DESCRIPTION,
+               COLUMNID_JUMP,
+
+               COLUMNID_END                    //!< \internal
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       KeyframeTreeStore::Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_;
+
+       CellRenderer_Time *cell_renderer_time;
+
+       CellRenderer_Time *cell_renderer_time_delta;
+
+       Gtk::CellRendererText *cell_renderer_description;
+
+       sigc::signal<void,synfig::Keyframe> signal_edited_;
+
+       sigc::signal<void,synfig::Keyframe,synfig::Time> signal_edited_time_;
+
+       sigc::signal<void,synfig::Keyframe,synfig::String> signal_edited_description_;
+
+       sigc::signal<void, int, Gtk::TreeRow, ColumnID> signal_user_click_;
+
+       bool editable_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_edited_time(const Glib::ustring&path_string,synfig::Time time);
+
+       void on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time);
+
+       void on_edited_description(const Glib::ustring&path_string,const Glib::ustring &description);
+
+       bool on_event(GdkEvent *event);
+
+       void on_rend_desc_changed();
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       KeyframeTree();
+       ~KeyframeTree();
+
+       void set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_);
+
+       void set_editable(bool x=true);
+
+       bool get_editable()const { return editable_; }
+
+       //! Signal called when a keyframe has been edited in any way
+       sigc::signal<void,synfig::Keyframe>& signal_edited() { return signal_edited_; }
+
+       //! Signal called when a time has been edited.
+       sigc::signal<void,synfig::Keyframe,synfig::Time>& signal_edited_time() { return signal_edited_time_; }
+
+       //! Signal called when a description has been edited.
+       sigc::signal<void,synfig::Keyframe,synfig::String>& signal_edited_description() { return signal_edited_description_; }
+
+       sigc::signal<void,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
+}; // END of KeyframeTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/keyframetreestore.cpp b/synfig-studio/src/gui/trees/keyframetreestore.cpp
new file mode 100644 (file)
index 0000000..d1925b4
--- /dev/null
@@ -0,0 +1,901 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file keyframetreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007, 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "trees/keyframetreestore.h"
+#include <synfig/valuenode.h>
+#include "iconcontroller.h"
+#include <synfig/valuenode_timedswap.h>
+#include <gtkmm/button.h>
+#include <gtkmm/treerowreference.h>
+#include <synfig/canvas.h>
+#include <synfig/keyframe.h>
+#include <time.h>
+#include <cstdlib>
+#include <ETL/smart_ptr>
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include "onemoment.h"
+#include <synfig/exception.h>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+// KeyframeTreeStore_Class KeyframeTreeStore::keyframe_tree_store_class_;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+struct _keyframe_iterator
+{
+       synfig::KeyframeList::iterator iter;
+       int ref_count;
+       int index;
+};
+
+/*
+Gtk::TreeModel::iterator keyframe_iter_2_model_iter(synfig::KeyframeList::iterator iter,int index)
+{
+       Gtk::TreeModel::iterator ret;
+
+       _keyframe_iterator*& data(static_cast<_keyframe_iterator*&>(ret->gobj()->user_data));
+       data=new _keyframe_iterator();
+       data->ref_count=1;
+       data->iter=iter;
+       data->index=index;
+
+       return ret;
+}
+*/
+
+synfig::KeyframeList::iterator model_iter_2_keyframe_iter(Gtk::TreeModel::iterator iter)
+{
+       _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
+       if(!data)
+               throw std::runtime_error("bad data");
+       return data->iter;
+}
+
+int get_index_from_model_iter(Gtk::TreeModel::iterator iter)
+{
+       _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
+       if(!data)
+               throw std::runtime_error("bad data");
+       return data->index;
+}
+
+
+/*
+#ifndef TreeRowReferenceHack
+class TreeRowReferenceHack
+{
+       GtkTreeRowReference *gobject_;
+public:
+       TreeRowReferenceHack():
+               gobject_(0)
+       {
+       }
+
+       TreeRowReferenceHack(const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path):
+               gobject_ ( gtk_tree_row_reference_new(model->gobj(), const_cast<GtkTreePath*>(path.gobj())) )
+       {
+       }
+
+       TreeRowReferenceHack(const TreeRowReferenceHack &x):
+               gobject_ ( x.gobject_?gtk_tree_row_reference_copy(x.gobject_):0 )
+       {
+
+       }
+
+       void swap(TreeRowReferenceHack & other)
+       {
+               GtkTreeRowReference *const temp = gobject_;
+               gobject_ = other.gobject_;
+               other.gobject_ = temp;
+       }
+
+       const TreeRowReferenceHack &
+       operator=(const TreeRowReferenceHack &rhs)
+       {
+               TreeRowReferenceHack temp (rhs);
+               swap(temp);
+               return *this;
+       }
+
+       ~TreeRowReferenceHack()
+       {
+               if(gobject_)
+                       gtk_tree_row_reference_free(gobject_);
+       }
+
+       Gtk::TreeModel::Path get_path() { return Gtk::TreeModel::Path(gtk_tree_row_reference_get_path(gobject_),false); }
+       GtkTreeRowReference *gobj() { return gobject_; }
+};
+#endif
+*/
+
+/* === P R O C E D U R E S ================================================= */
+
+void clear_iterator(GtkTreeIter* iter)
+{
+       iter->stamp=0;
+       iter->user_data=iter->user_data2=iter->user_data3=0;
+}
+
+/* === M E T H O D S ======================================================= */
+
+const Glib::Class&
+KeyframeTreeStore_Class::init()
+{
+       if(!gtype_)
+       {
+               class_init_func_ = &KeyframeTreeStore_Class::class_init_function;
+
+               const GTypeInfo derived_info =
+               {
+                       sizeof(GObjectClass),
+                       NULL,
+                       NULL,
+                       class_init_func_,
+                       NULL,
+                       NULL,
+                       sizeof(GObject),
+                       0,
+                       0,
+                       NULL
+               };
+
+               gtype_ = g_type_register_static(G_TYPE_OBJECT, "KeyframeTreeStore", &derived_info, GTypeFlags(0));
+               Gtk::TreeModel::add_interface(get_type());
+       }
+       return *this;
+}
+
+void
+KeyframeTreeStore_Class::class_init_function(gpointer /*g_class*/, gpointer /*class_data*/)
+{
+       // ???
+}
+
+KeyframeTreeStore::KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+       Glib::ObjectBase        ("KeyframeTreeStore"),
+       //! \todo what is going on here?  why the need for this KeyframeTreeStore_Class at all?
+       // Glib::Object         (Glib::ConstructParams(keyframe_tree_store_class_.init(), (char*) 0, (char*) 0)),
+       canvas_interface_       (canvas_interface_)
+{
+       reset_stamp();
+       //reset_path_table();
+
+       canvas_interface()->signal_keyframe_added().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::add_keyframe));
+       canvas_interface()->signal_keyframe_removed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::remove_keyframe));
+       canvas_interface()->signal_keyframe_changed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::change_keyframe));
+}
+
+KeyframeTreeStore::~KeyframeTreeStore()
+{
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("KeyframeTreeStore::~KeyframeTreeStore(): Deleted");
+}
+
+Glib::RefPtr<KeyframeTreeStore>
+KeyframeTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+       KeyframeTreeStore *store(new KeyframeTreeStore(canvas_interface_));
+       Glib::RefPtr<KeyframeTreeStore> ret(store);
+       assert(ret);
+       return ret;
+}
+
+void
+KeyframeTreeStore::reset_stamp()
+{
+       stamp_=time(0)+reinterpret_cast<long>(this);
+}
+
+/*
+void
+KeyframeTreeStore::reset_path_table()
+{
+       Gtk::TreeModel::Children::iterator iter;
+       const Gtk::TreeModel::Children children(children());
+       path_table_.clear();
+       for(iter = children.begin(); iter != children.end(); ++iter)
+       {
+               Gtk::TreeModel::Row row(*iter);
+               path_table_[(Keyframe)row[model.keyframe]]=TreeRowReferenceHack(Glib::RefPtr<KeyframeTreeStore>(this),Gtk::TreePath(row));
+       }
+}
+*/
+
+
+inline bool
+KeyframeTreeStore::iterator_sane(const GtkTreeIter* iter)const
+{
+       if(iter && iter->stamp==stamp_)
+               return true;
+       g_warning("KeyframeTreeStore::iterator_sane(): Bad iterator stamp");
+       return false;
+}
+
+inline bool
+KeyframeTreeStore::iterator_sane(const Gtk::TreeModel::iterator& iter)const
+{
+       return iterator_sane(iter->gobj());
+}
+
+inline void
+KeyframeTreeStore::dump_iterator(const GtkTreeIter* /*gtk_iter*/, const Glib::ustring &/*name*/)const
+{
+#if 0
+       if(!gtk_iter)
+       {
+               g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is NULL (Root?)",name.c_str());
+               return;
+       }
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+       if(gtk_iter->stamp!=stamp_ || !iter)
+       {
+               g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is INVALID",name.c_str());
+               return;
+       }
+
+       if((unsigned)iter->index>=canvas_interface()->get_canvas()->keyframe_list().size())
+               g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) has bad index(index:%d)",name.c_str(),gtk_iter,iter->index);
+
+       g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) ref:%d, index:%d, time:%s",name.c_str(),gtk_iter,iter->ref_count,iter->index,iter->iter->get_time().get_string().c_str());
+#endif
+}
+
+inline void
+KeyframeTreeStore::dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const
+{
+       dump_iterator(iter->gobj(),name);
+}
+
+int
+KeyframeTreeStore::time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+       const Model model;
+
+       _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
+       _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
+
+       Time diff(rhs_iter->iter->get_time()-lhs_iter->iter->get_time());
+       if(diff<0)
+               return -1;
+       if(diff>0)
+               return 1;
+       return 0;
+}
+
+int
+KeyframeTreeStore::description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+       const Model model;
+
+       _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
+       _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
+
+       int comp = rhs_iter->iter->get_description().compare(lhs_iter->iter->get_description());
+       if (comp > 0) return 1;
+       if (comp < 0) return -1;
+       return 0;
+}
+
+void
+KeyframeTreeStore::set_value_impl(const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value)
+{
+       if(!iterator_sane(row))
+               return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("KeyframeTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("KeyframeTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(row.gobj()->user_data));
+
+       try
+       {
+               if(column==model.time_delta.index())
+               {
+                       Glib::Value<synfig::Time> x;
+                       g_value_init(x.gobj(),model.time.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       Time new_delta(x.get());
+                       if(new_delta<=Time::zero()+Time::epsilon())
+                       {
+                               // Bad value
+                               return;
+                       }
+
+                       Time old_delta((*row)[model.time_delta]);
+                       if(old_delta<=Time::zero()+Time::epsilon())
+                       {
+                               // Bad old delta
+                               return;
+                       }
+                       // row(row) on the next line is bad - don't use it, because it leaves 'row' uninitialized
+                       //Gtk::TreeModel::iterator row(row);
+                       //row++;
+                       //if(!row)return;
+
+                       Time change_delta(new_delta-old_delta);
+
+                       if(change_delta<=Time::zero()+Time::epsilon() &&change_delta>=Time::zero()-Time::epsilon())
+                       {
+                               // Not an error, just no change
+                               return;
+                       }
+
+                       {
+                               Keyframe keyframe((*row)[model.keyframe]);
+                               synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSetDelta"));
+
+                               if(!action)return;
+
+                               action->set_param("canvas",canvas_interface()->get_canvas());
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("keyframe",keyframe);
+                               action->set_param("delta",change_delta);
+
+                               canvas_interface()->get_instance()->perform_action(action);
+                       }
+
+                       return;
+               }
+               else
+               if(column==model.time.index())
+               {
+                       OneMoment one_moment;
+
+                       Glib::Value<synfig::Time> x;
+                       g_value_init(x.gobj(),model.time.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       synfig::Keyframe keyframe(*iter->iter);
+
+                       synfig::info("KeyframeTreeStore::set_value_impl():old_time=%s",keyframe.get_time().get_string().c_str());
+                       keyframe.set_time(x.get());
+                       synfig::info("KeyframeTreeStore::set_value_impl():new_time=%s",keyframe.get_time().get_string().c_str());
+
+                       synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
+
+                       if(!action)
+                               return;
+
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("keyframe",keyframe);
+
+                       canvas_interface()->get_instance()->perform_action(action);
+               }
+               else if(column==model.description.index())
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),model.description.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       synfig::Keyframe keyframe(*iter->iter);
+                       keyframe.set_description(x.get());
+
+                       synfigapp::Action::Handle action(synfigapp::Action::create("KeyframeSet"));
+
+                       if(!action)
+                               return;
+
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("keyframe",keyframe);
+
+                       canvas_interface()->get_instance()->perform_action(action);
+               }
+               else if(column==model.keyframe.index())
+               {
+                       g_warning("KeyframeTreeStore::set_value_impl: This column is read-only");
+               }
+               else
+               {
+                       assert(0);
+               }
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
+
+Gtk::TreeModelFlags
+KeyframeTreeStore::get_flags_vfunc ()
+{
+       return Gtk::TREE_MODEL_LIST_ONLY;
+}
+
+int
+KeyframeTreeStore::get_n_columns_vfunc ()
+{
+       return model.size();
+}
+
+GType
+KeyframeTreeStore::get_column_type_vfunc (int index)
+{
+       return model.types()[index];
+}
+
+bool
+KeyframeTreeStore::iter_next_vfunc (const iterator& xiter, iterator& iter_next) const
+{
+       if(!iterator_sane(xiter)) return false;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(xiter.gobj()->user_data));
+
+       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               return false;
+
+       _keyframe_iterator *next(new _keyframe_iterator());
+       iter_next.gobj()->user_data=static_cast<gpointer>(next);
+       next->ref_count=1;
+       next->index=iter->index+1;
+       next->iter=iter->iter;
+       ++next->iter;
+
+       if(next->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               return false;
+
+       iter_next.gobj()->stamp=stamp_;
+
+       return true;
+}
+
+/*
+bool
+KeyframeTreeStore::iter_next_vfunc (GtkTreeIter* gtk_iter)
+{
+       if(!iterator_sane(gtk_iter)) return false;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+       // If we are already at the end, then we are very invalid
+       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               return false;
+
+       ++(iter->iter);
+
+       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+       {
+               --(iter->iter);
+               return false;
+       }
+       (iter->index)++;
+       return true;
+}
+
+bool
+KeyframeTreeStore::iter_children_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent)
+{
+       dump_iterator(gtk_iter,"gtk_iter");
+       dump_iterator(parent,"parent");
+
+       if(!parent || !iterator_sane(parent))
+       {
+               clear_iterator(gtk_iter);
+               return false;
+       }
+
+       _keyframe_iterator *iter(new _keyframe_iterator());
+       iter->ref_count=1;
+       iter->index=0;
+       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+
+       gtk_iter->user_data=static_cast<gpointer>(iter);
+       gtk_iter->stamp=stamp_;
+
+       return true;
+}
+
+bool
+KeyframeTreeStore::iter_has_child_vfunc (const GtkTreeIter*parent)
+{
+       dump_iterator(parent,"parent");
+
+       if(parent)
+               return false;
+
+       return true;
+}
+
+int
+KeyframeTreeStore::iter_n_children_vfunc (const GtkTreeIter* parent)
+{
+       dump_iterator(parent,"parent");
+
+       if(parent)
+               return 0;
+
+       return canvas_interface()->get_canvas()->keyframe_list().size();
+}
+*/
+
+int
+KeyframeTreeStore::iter_n_root_children_vfunc () const
+{
+       return canvas_interface()->get_canvas()->keyframe_list().size();
+}
+
+bool
+KeyframeTreeStore::iter_nth_root_child_vfunc (int n, iterator& xiter)const
+{
+       if(canvas_interface()->get_canvas()->keyframe_list().size()==0)
+       {
+               return false;
+       }
+
+       if(n<0)
+       {
+               g_warning("KeyframeTreeStore::iter_nth_root_child_vfunc: Out of range (negative index)");
+               return false;
+       }
+       if(n && (unsigned)n>=canvas_interface()->get_canvas()->keyframe_list().size())
+       {
+               g_warning("KeyframeTreeStore::iter_nth_child_vfunc: Out of range (large index)");
+               return false;
+       }
+
+       _keyframe_iterator *iter(new _keyframe_iterator());
+       iter->ref_count=1;
+       iter->index=n;
+       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+       while(n--)
+       {
+               if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               {
+                       g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
+                       delete iter;
+                       return false;
+               }
+               ++iter->iter;
+       }
+       xiter.gobj()->user_data=static_cast<gpointer>(iter);
+       xiter.gobj()->stamp=stamp_;
+       return true;
+}
+
+/*
+bool
+KeyframeTreeStore::iter_nth_child_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent, int n)
+{
+       dump_iterator(parent,"parent");
+
+       if(parent)
+       {
+               g_warning("KeyframeTreeStore::iter_nth_child_vfunc: I am a list");
+               clear_iterator(gtk_iter);
+               return false;
+       }
+
+
+
+       _keyframe_iterator *iter(new _keyframe_iterator());
+       iter->ref_count=1;
+       iter->index=n;
+       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+       while(n--)
+       {
+               if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               {
+                       g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
+                       delete iter;
+                       clear_iterator(gtk_iter);
+                       return false;
+               }
+               ++iter->iter;
+       }
+
+       gtk_iter->user_data=static_cast<gpointer>(iter);
+       gtk_iter->stamp=stamp_;
+       return true;
+}
+
+bool
+KeyframeTreeStore::iter_parent_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* child)
+{
+       dump_iterator(child,"child");
+       iterator_sane(child);
+       clear_iterator(gtk_iter);
+       return false;
+}
+*/
+
+void
+KeyframeTreeStore::ref_node_vfunc (iterator& xiter)const
+{
+       GtkTreeIter* gtk_iter(xiter.gobj());
+       if(!gtk_iter || !iterator_sane(gtk_iter)) return;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+       iter->ref_count++;
+}
+
+void
+KeyframeTreeStore::unref_node_vfunc (iterator& xiter)const
+{
+       GtkTreeIter* gtk_iter(xiter.gobj());
+       if(!gtk_iter || !iterator_sane(gtk_iter)) return;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+       iter->ref_count--;
+       if(!iter->ref_count)
+       {
+               delete iter;
+
+               // Make this iterator invalid
+               gtk_iter->stamp=0;
+       }
+}
+
+Gtk::TreeModel::Path
+KeyframeTreeStore::get_path_vfunc (const iterator& gtk_iter)const
+{
+       Gtk::TreeModel::Path path;
+
+       // If this is the root node, then return
+       // a root path
+       if(!iterator_sane(gtk_iter))
+               return path;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
+
+       path.append_index(iter->index);
+
+       return path;
+}
+
+bool
+KeyframeTreeStore::get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter)const
+{
+       if(path.get_depth()>=1)
+               return iter_nth_root_child_vfunc(path.front(),iter);
+
+       // Error case
+       g_warning("KeyframeTreeStore::get_iter_vfunc(): Bad path \"%s\"",path.to_string().c_str());
+       //clear_iterator(iter);
+       return false;
+}
+
+bool
+KeyframeTreeStore::iter_is_valid (const iterator& iter) const
+{
+       return iterator_sane(iter);
+}
+
+void
+KeyframeTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& gtk_iter, int column, Glib::ValueBase& value)const
+{
+       dump_iterator(gtk_iter,"gtk_iter");
+       if(!iterator_sane(gtk_iter))
+               return;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
+
+       switch(column)
+       {
+       case 0:         // Time
+       {
+               Glib::Value<synfig::Time> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(iter->iter->get_time());
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+               return;
+       }
+       case 3:         // Time Delta
+       {
+               Glib::Value<synfig::Time> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               synfig::Keyframe prev_keyframe(*iter->iter);
+               synfig::Keyframe keyframe;
+               {
+                       KeyframeList::iterator tmp(iter->iter);
+                       tmp++;
+                       if(tmp==get_canvas()->keyframe_list().end())
+                       {
+                               x.set(Time(0));
+                               g_value_init(value.gobj(),x.value_type());
+                               g_value_copy(x.gobj(),value.gobj());
+                               return;
+                       }
+                       keyframe=*tmp;
+               }
+
+               Time delta(0);
+               try {
+                       delta=keyframe.get_time()-prev_keyframe.get_time();
+               }catch(...) { }
+               x.set(delta);
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+               return;
+       }
+       case 1:         // Description
+       {
+               g_value_init(value.gobj(),G_TYPE_STRING);
+               g_value_set_string(value.gobj(),iter->iter->get_description().c_str());
+               return;
+       }
+       case 2:         // Keyframe
+       {
+               Glib::Value<synfig::Keyframe> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(*iter->iter);
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+               return;
+       }
+       default:
+               break;
+       }
+}
+
+Gtk::TreeModel::Row
+KeyframeTreeStore::find_row(const synfig::Keyframe &keyframe)
+{
+       Gtk::TreeModel::Row row(*(children().begin()));
+       dump_iterator(row,"find_row,begin");
+       const GtkTreeIter *gtk_iter(row.gobj());
+       if(!iterator_sane(gtk_iter))
+               throw std::runtime_error(_("Unable to find Keyframe in table"));
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+       synfig::KeyframeList &keyframe_list(canvas_interface()->get_canvas()->keyframe_list());
+       if(keyframe_list.empty())
+               throw std::runtime_error(_("There are no keyframes n this canvas"));
+
+       iter->index=0;
+
+       for(iter->iter=keyframe_list.begin();iter->iter!=keyframe_list.end() && *iter->iter!=keyframe;++iter->iter)
+       {
+               iter->index++;
+       }
+       if(iter->iter==keyframe_list.end())
+               throw std::runtime_error(_("Unable to find Keyframe in table"));
+       return row;
+}
+
+void
+KeyframeTreeStore::add_keyframe(synfig::Keyframe keyframe)
+{
+       try
+       {
+               Gtk::TreeRow row(find_row(keyframe));
+               dump_iterator(row.gobj(),"add_keyframe,row");
+               Gtk::TreePath path(get_path(row));
+
+               row_inserted(path,row);
+
+               old_keyframe_list=get_canvas()->keyframe_list();
+               //old_keyframe_list.add(keyframe);
+               //old_keyframe_list.sort();
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
+
+void
+KeyframeTreeStore::remove_keyframe(synfig::Keyframe keyframe)
+{
+       try
+       {
+               if(1)
+               {
+                       Gtk::TreeRow row(find_row(keyframe));
+                       dump_iterator(row,"remove_keyframe,row");
+                       Gtk::TreePath path(get_path(row));
+                       row_deleted(path);
+
+                       old_keyframe_list.erase(keyframe);
+               }
+               else
+               {
+                       g_warning("KeyframeTreeStore::remove_keyframe: Keyframe not in table");
+               }
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
+
+void
+KeyframeTreeStore::change_keyframe(synfig::Keyframe keyframe)
+{
+       try
+       {
+               Gtk::TreeRow row(find_row(keyframe));
+
+               unsigned int new_index(get_index_from_model_iter(row));
+               unsigned int old_index(0);
+               synfig::KeyframeList::iterator iter;
+               for(old_index=0,iter=old_keyframe_list.begin();iter!=old_keyframe_list.end() && (UniqueID)*iter!=(UniqueID)keyframe;++iter,old_index++)
+                       ;
+
+               if(iter!=old_keyframe_list.end() && new_index!=old_index)
+               {
+                       std::vector<int> new_order;
+                       for(unsigned int i=0;i<old_keyframe_list.size();i++)
+                       {
+                               new_order.push_back(i);
+                       }
+                       if(new_order.size()>new_index)
+                       {
+                               new_order.erase(new_order.begin()+new_index);
+                               new_order.insert(new_order.begin()+old_index,new_index);
+
+                               //new_order[old_index]=
+
+                               rows_reordered (Path(), iterator(), &new_order[0]);
+                       }
+                       old_keyframe_list=get_canvas()->keyframe_list();
+
+                       row=find_row(keyframe);
+               }
+
+               dump_iterator(row,"change_keyframe,row");
+               row_changed(get_path(row),row);
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
diff --git a/synfig-studio/src/gui/trees/keyframetreestore.h b/synfig-studio/src/gui/trees/keyframetreestore.h
new file mode 100644 (file)
index 0000000..bfbd00d
--- /dev/null
@@ -0,0 +1,224 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/keyframetreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
+#define __SYNFIG_STUDIO_KEYFRAMETREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/liststore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfig/keyframe.h>
+#include <map>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+//class TreeRowReferenceHack;
+//#define TreeRowReferenceHack Gtk::TreeRowReference
+
+namespace studio {
+
+class KeyframeTreeStore_Class;
+
+class KeyframeTreeStore :
+       public Glib::Object,
+       public Gtk::TreeModel,
+       public Gtk::TreeDragSource,
+       public Gtk::TreeDragDest
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<synfig::Time> time;
+               Gtk::TreeModelColumn<Glib::ustring> description;
+               Gtk::TreeModelColumn<synfig::Keyframe> keyframe;
+               Gtk::TreeModelColumn<synfig::Time> time_delta;
+
+               Model()
+               {
+                       add(time);
+                       add(description);
+                       add(keyframe);
+                       add(time_delta);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+       //! Unique stamp for this TreeModel.
+       int stamp_;
+
+       static KeyframeTreeStore_Class keyframe_tree_store_class_;
+
+       //std::map<synfig::Keyframe,TreeRowReferenceHack> path_table_;
+
+       synfig::KeyframeList old_keyframe_list;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       void add_keyframe(synfig::Keyframe);
+
+       void remove_keyframe(synfig::Keyframe);
+
+       void change_keyframe(synfig::Keyframe);
+
+       static int sorter(const Gtk::TreeModel::iterator &,const Gtk::TreeModel::iterator &);
+
+       bool iterator_sane(const GtkTreeIter* iter)const;
+
+       bool iterator_sane(const Gtk::TreeModel::iterator& iter)const;
+
+       void dump_iterator(const GtkTreeIter* iter, const Glib::ustring &name)const;
+
+       void dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const;
+
+       //! Resets the iterator stamp for this model.
+       /*!     This should be called whenever the class is
+       **      constructed     or when large numbers of
+       **      iterators become invalid. */
+       void reset_stamp();
+
+       //void reset_path_table();
+
+       /*
+ -- ** -- V I R T U A L   F U N C T I O N S -----------------------------------
+       */
+
+protected:
+
+       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual Gtk::TreeModelFlags  get_flags_vfunc ();
+       virtual int  get_n_columns_vfunc ();
+       virtual GType  get_column_type_vfunc (int index);
+       virtual bool iter_next_vfunc (const iterator& iter, iterator& iter_next) const;
+       virtual bool  get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter_next)const;
+       virtual bool  iter_nth_root_child_vfunc (int n, iterator& iter)const;
+       virtual Gtk::TreeModel::Path  get_path_vfunc (const iterator& iter)const;
+       virtual void  ref_node_vfunc (iterator& iter)const;
+       virtual void  unref_node_vfunc (iterator& iter)const;
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+       virtual bool    iter_is_valid (const iterator& iter) const;
+       virtual int     iter_n_root_children_vfunc () const;
+
+       //virtual bool  iter_nth_child_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent, int n);
+       //virtual bool  iter_children_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent);
+       //virtual bool  iter_has_child_vfunc (const GtkTreeIter* iter);
+       //virtual int  iter_n_children_vfunc (const GtkTreeIter* iter);
+       //virtual bool  iter_parent_vfunc (GtkTreeIter* iter, const GtkTreeIter* child);
+
+       /*
+       virtual bool  get_sort_column_id_vfunc (int* sort_column_id, Gtk::SortType* order);
+       virtual void  set_sort_column_id_vfunc (int sort_column_id, Gtk::SortType order);
+       virtual void  set_sort_func_vfunc (int sort_column_id, GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
+       virtual void  set_default_sort_func_vfunc (GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
+       virtual bool  has_default_sort_func_vfunc ();
+       */
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       KeyframeTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+       ~KeyframeTreeStore();
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+
+       synfig::Canvas::Handle get_canvas() { return canvas_interface()->get_canvas(); }
+       synfig::Canvas::Handle get_canvas()const { return canvas_interface()->get_canvas(); }
+
+       Gtk::TreeModel::Row find_row(const synfig::Keyframe &keyframe);
+
+       /*
+ -- ** -- S T A T I C  M E T H O D S ------------------------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<KeyframeTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+
+       static int time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+       static int description_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+
+}; // END of class KeyframeTreeStore
+
+//! \internal
+class KeyframeTreeStore_Class : public Glib::Class
+{
+public:
+       struct KeyframeTreeStoreClass
+       {
+               GObjectClass parent_class;
+       };
+
+       friend class KeyframeTreeStore;
+
+       const Glib::Class& init();
+
+       static void class_init_function(gpointer g_blass, gpointer class_data);
+}; // END of CustomTreeStore_Class
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/layergrouptree.cpp b/synfig-studio/src/gui/trees/layergrouptree.cpp
new file mode 100644 (file)
index 0000000..0be0596
--- /dev/null
@@ -0,0 +1,334 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layergrouptree.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <synfig/layer.h>
+#include "trees/layergrouptree.h"
+#include <gtkmm/treemodelsort.h>
+#include <ETL/misc>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LayerGroupTree::LayerGroupTree()
+{
+       const LayerGroupTreeStore::Model model;
+
+
+       {       // --- O N / O F F ----------------------------------------------------
+               int index;
+               index=append_column_editable(_(" "),model.active);
+               //Gtk::TreeView::Column* column = get_column(index-1);
+       }
+       {       // --- I C O N --------------------------------------------------------
+               int index;
+               index=append_column(_(" "),model.icon);
+               Gtk::TreeView::Column* column = get_column(index-1);
+               set_expander_column(*column);
+       }
+       {       // --- N A M E --------------------------------------------------------
+               int index;
+               index=append_column_editable(_("Name"),model.label);
+               label_column = get_column(index-1);
+
+               //column->set_sort_column(layer_model.index);
+
+               //set_expander_column(*column);
+               //column->set_reorderable();
+               //column->set_resizable();
+               //column->set_clickable(false);
+
+               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               //column->pack_start(*icon_cellrenderer,false);
+               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+       }
+
+       set_enable_search(true);
+       set_search_column(model.label);
+       set_search_equal_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::search_func));
+
+       // This makes things easier to read.
+       set_rules_hint();
+
+       // Make us more sensitive to several events
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+       set_reorderable(true);
+
+       get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+
+       //set_flags(get_flags()|Gtk::RECEIVES_DEFAULT|Gtk::HAS_GRAB);
+
+       //std::list<Gtk::TargetEntry> listTargets;
+       //listTargets.push_back( Gtk::TargetEntry("LAYER") );
+       //listTargets.push_back( Gtk::TargetEntry("GROUP") );
+       //drag_dest_set(listTargets);
+}
+
+LayerGroupTree::~LayerGroupTree()
+{
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("LayerGroupTree::~LayerGroupTree(): Deleted");
+}
+
+void
+LayerGroupTree::set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store)
+{
+       layer_group_tree_store_=layer_group_tree_store;
+       LayerGroupTreeStore::Model model;
+
+#if 0
+       {
+               Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(layer_group_tree_store_));
+               sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
+               sorted_store->set_sort_func(model.time.index(),sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
+               sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
+               Gtk::TreeView::set_model(sorted_store);
+       }
+#else
+               Gtk::TreeView::set_model(layer_group_tree_store);
+#endif
+}
+
+void
+LayerGroupTree::set_editable(bool x)
+{
+       editable_=x;
+/*
+       if(editable_)
+       {
+               cell_renderer_time->property_editable()=true;
+               cell_renderer_time_delta->property_editable()=true;
+               cell_renderer_description->property_editable()=true;
+       }
+       else
+       {
+               cell_renderer_time->property_editable()=false;
+               cell_renderer_time_delta->property_editable()=false;
+               cell_renderer_description->property_editable()=false;
+       }
+*/
+}
+/*
+void
+LayerGroupTree::on_edited_time(const Glib::ustring&path_string,synfig::Time time)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+       synfig::Keyframe keyframe(row[model.keyframe]);
+       if(time!=keyframe.get_time())
+       {
+               row[model.time]=time;
+               //keyframe.set_time(time);
+               //signal_edited_time()(keyframe,time);
+               //signal_edited()(keyframe);
+       }
+}
+
+void
+LayerGroupTree::on_edited_time_delta(const Glib::ustring&path_string,synfig::Time time)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+
+       if(row)row[model.time_delta]=time;
+}
+
+void
+LayerGroupTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+       const synfig::String description(desc);
+       synfig::Keyframe keyframe(row[model.keyframe]);
+       if(description!=keyframe.get_description())
+       {
+               row[model.description]=desc;
+               keyframe.set_description(description);
+               signal_edited_description()(keyframe,description);
+               signal_edited()(keyframe);
+       }
+}
+*/
+
+bool
+LayerGroupTree::on_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
+                       //tree_to_widget_coords (,, wx, wy);
+                       if(!get_path_at_pos(
+                               wx,wy,  // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+                       if(row[model.is_layer] && event->button.button==3)
+                       {
+                               signal_popup_layer_menu()((Layer::Handle)row[model.layer]);
+                               return true;
+                       }
+
+                       /*signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+                       {
+                               layer_group_tree_store_->canvas_interface()->set_time(row[model.time]);
+                       }*/
+               }
+               break;
+       case GDK_2BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+                       LayerList layer_list(row[model.all_layers]);
+                       if(!layer_list.empty())
+                       {
+                               if(!(event->button.state&GDK_CONTROL_MASK))
+                               {
+                                       layer_group_tree_store_->canvas_interface()->get_selection_manager()->clear_selected_layers();
+                               }
+                               layer_group_tree_store_->canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
+                               return true;
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return Gtk::TreeView::on_event(event);
+       //return false;
+}
+
+static inline void __group_grabber(const Gtk::TreeModel::iterator& iter, std::list<synfig::String>* ret)
+{
+       const LayerGroupTreeStore::Model model;
+       if((bool)(*iter)[model.is_group])
+               ret->push_back((Glib::ustring)(*iter)[model.group_name]);
+}
+
+std::list<synfig::String>
+LayerGroupTree::get_selected_groups()const
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
+
+       if(!selection)
+               return std::list<synfig::String>();
+
+       std::list<synfig::String> ret;
+
+       selection->selected_foreach_iter(
+               sigc::bind(
+                       sigc::ptr_fun(
+                               &__group_grabber
+                       ),
+                       &ret
+               )
+       );
+
+       return ret;
+}
+
+static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerGroupTree::LayerList* ret)
+{
+       const LayerGroupTreeStore::Model model;
+       if((bool)(*iter)[model.is_layer])
+               ret->push_back((Layer::Handle)(*iter)[model.layer]);
+}
+
+LayerGroupTree::LayerList
+LayerGroupTree::get_selected_layers()const
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
+
+       if(!selection)
+               return LayerList();
+
+       LayerList ret;
+
+       selection->selected_foreach_iter(
+               sigc::bind(
+                       sigc::ptr_fun(
+                               &__layer_grabber
+                       ),
+                       &ret
+               )
+       );
+
+       return ret;
+}
+
+void
+LayerGroupTree::set_cursor(const Gtk::TreeModel::Path& path, bool start_editing)
+{
+       Gtk::TreeView::set_cursor(path, *label_column, start_editing);
+}
diff --git a/synfig-studio/src/gui/trees/layergrouptree.h b/synfig-studio/src/gui/trees/layergrouptree.h
new file mode 100644 (file)
index 0000000..8f11024
--- /dev/null
@@ -0,0 +1,127 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/layergrouptree.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERGROUPTREE_H
+#define __SYNFIG_STUDIO_LAYERGROUPTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "trees/layergrouptreestore.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfig { class Layer; }
+
+namespace studio {
+
+class LayerGroupTree : public Gtk::TreeView
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       typedef std::list<synfig::Layer::Handle> LayerList;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       LayerGroupTreeStore::Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_;
+
+       Gtk::CellRendererText *cell_renderer_description;
+
+       bool editable_;
+
+
+       sigc::signal<void,etl::handle<synfig::Layer> > signal_popup_layer_menu_;
+
+//     sigc::signal<void,LayerList> signal_select_layers_;
+       Gtk::TreeView::Column* label_column;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       bool on_event(GdkEvent *event);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       LayerGroupTree();
+       ~LayerGroupTree();
+       void set_cursor(const Gtk::TreeModel::Path& path, bool start_editing=false);
+
+       Glib::RefPtr<LayerGroupTreeStore> get_model() { return layer_group_tree_store_; }
+
+       sigc::signal<void,etl::handle<synfig::Layer> >& signal_popup_layer_menu() { return signal_popup_layer_menu_; }
+
+//     sigc::signal<void,LayerList>& signal_select_layers() { return signal_select_layers_; }
+
+       void set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_);
+
+       void set_editable(bool x=true);
+
+       bool get_editable()const { return editable_; }
+
+       std::list<synfig::String> get_selected_groups()const;
+
+       LayerList get_selected_layers()const;
+}; // END of LayerGroupTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/layergrouptreestore.cpp b/synfig-studio/src/gui/trees/layergrouptreestore.cpp
new file mode 100644 (file)
index 0000000..02aa8eb
--- /dev/null
@@ -0,0 +1,1031 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layergrouptreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "trees/layergrouptreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include "app.h"
+#include "instance.h"
+#include <synfigapp/action_system.h>
+#include "docks/dockmanager.h"
+#include "docks/dockable.h"
+
+#include <gtk/gtkversion.h>
+#include <ETL/clock>
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define GROUP_NEST_CHAR        '.'
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerGroupTreeStore::Model& ModelHack()
+{
+       static LayerGroupTreeStore::Model* model(0);
+       if(!model)model=new LayerGroupTreeStore::Model;
+       return *model;
+}
+
+LayerGroupTreeStore::LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore                  (ModelHack()),
+       canvas_interface_               (canvas_interface_)
+{
+       layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+       group_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-group"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       // Connect Signals to Terminals
+       canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_status_changed));
+       canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_new_description));
+
+       canvas_interface()->get_canvas()->signal_group_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_added)));
+       canvas_interface()->get_canvas()->signal_group_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_removed)));
+       canvas_interface()->get_canvas()->signal_group_changed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_changed)));
+
+       canvas_interface()->get_canvas()->signal_group_pair_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_added)));
+       canvas_interface()->get_canvas()->signal_group_pair_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_removed)));
+
+       rebuild();
+}
+
+LayerGroupTreeStore::~LayerGroupTreeStore()
+{
+       //clear();
+
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("LayerGroupTreeStore::~LayerGroupTreeStore(): Deleted");
+}
+
+bool
+LayerGroupTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
+{
+       const Model model;
+
+       Glib::ustring substr(x.uppercase());
+       Glib::ustring label((*iter)[model.label]);
+       label=label.uppercase();
+
+       return label.find(substr)==Glib::ustring::npos;
+}
+
+
+Glib::RefPtr<LayerGroupTreeStore>
+LayerGroupTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<LayerGroupTreeStore>(new LayerGroupTreeStore(canvas_interface_));
+}
+
+void
+LayerGroupTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column==model.child_layers.index())
+       {
+               Glib::Value<LayerList> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if((bool)(*iter)[model.is_group])
+               {
+                       set<Layer::Handle> layer_set(canvas_interface()->get_canvas()->get_layers_in_group((Glib::ustring)(*iter)[model.group_name]));
+
+                       x.set(LayerList(layer_set.begin(),layer_set.end()));
+               }
+               else if((bool)(*iter)[model.is_layer])
+               {
+                       LayerList layer_list;
+                       layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
+                       x.set(layer_list);
+               }
+
+               g_value_init(value.gobj(),x.value_type());
+               value=x;
+       }
+       else if(column==model.all_layers.index())
+       {
+               Glib::Value<LayerList> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if((bool)(*iter)[model.is_group])
+               {
+                       LayerList layer_list;
+                       Gtk::TreeModel::iterator child_iter(iter->children().begin());
+                       for(;child_iter;++child_iter)
+                       {
+                               LayerList layer_list2((LayerList)(*child_iter)[model.all_layers]);
+                               for(;layer_list2.size();layer_list2.pop_front())
+                                       layer_list.push_back(layer_list2.front());
+                       }
+                       x.set(layer_list);
+               }
+               else if((bool)(*iter)[model.is_layer])
+               {
+                       LayerList layer_list;
+                       layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
+                       x.set(layer_list);
+               }
+
+               g_value_init(value.gobj(),x.value_type());
+               value=x;
+       }
+       else if(column==model.group_name.index())
+       {
+               if((bool)(*iter)[model.is_group])
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+               return get_value_vfunc(iter->parent(),column,value);
+       }
+       else if(column==model.parent_group_name.index())
+       {
+               if(iter->parent())
+                       return get_value_vfunc(iter->parent(),model.group_name.index(),value);
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(Glib::ustring());
+               g_value_init(value.gobj(),x.value_type());
+               value=x;
+       }
+       else if(column==model.label.index())
+       {
+               if((bool)(*iter)[model.is_group])
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),x.value_type());
+
+                       Glib::ustring group_name((*iter)[model.group_name]);
+
+                       // Get rid of any parent group crap
+                       while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+                               group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+
+                       x.set(group_name);
+
+                       g_value_init(value.gobj(),x.value_type());
+
+                       value=x;
+               }
+               else if((bool)(*iter)[model.is_layer])
+               {
+                       synfig::Layer::Handle layer((*iter)[model.layer]);
+
+                       if(!layer)return;
+
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),x.value_type());
+
+                       x.set(layer->get_non_empty_description());
+
+                       g_value_init(value.gobj(),x.value_type());
+                       //g_value_copy(x.gobj(),value.gobj());
+                       value=x;
+               }
+       }
+       else
+       if(column==model.tooltip.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_local_name());
+
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else
+       if(column==model.canvas.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Canvas::Handle> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_canvas());
+
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else
+       if(column==model.active.index())
+       {
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if((bool)(*iter)[model.is_layer])
+               {
+                       synfig::Layer::Handle layer((*iter)[model.layer]);
+                       x.set(layer->active());
+               }
+               else if((bool)(*iter)[model.is_group])
+               {
+                       int activecount(0),total(0);
+                       Gtk::TreeModel::iterator child_iter(iter->children().begin());
+                       for(;child_iter;++child_iter)
+                       {
+                               total++;
+                               if((*child_iter)[model.active])
+                                       activecount++;
+                       }
+                       x.set(activecount>total/2);
+               }
+               else
+                       x.set(false);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.icon.index())
+       {
+               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if((bool)(*iter)[model.is_layer])
+               {
+                       synfig::Layer::Handle layer((*iter)[model.layer]);
+                       if(!layer)return;
+                       //x.set(layer_icon);
+                       x.set(get_tree_pixbuf_layer(layer->get_name()));
+               }
+               if((bool)(*iter)[model.is_group])
+                       x.set(group_icon);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+LayerGroupTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       //if(!iterator_sane(row))
+       //      return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerGroupTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerGroupTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.label.index())
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),model.label.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       if((bool)(*iter)[model.is_layer])
+                       {
+                               synfig::Layer::Handle layer((*iter)[model.layer]);
+                               if(!layer)
+                                       return;
+                               synfig::String new_desc(x.get());
+
+                               if(new_desc==layer->get_local_name())
+                                       new_desc=synfig::String();
+
+                               if(new_desc==layer->get_description())
+                                       return;
+
+                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
+
+                               if(!action)
+                                       return;
+
+                               action->set_param("canvas",canvas_interface()->get_canvas());
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",layer);
+                               action->set_param("new_description",synfig::String(x.get()));
+
+                               canvas_interface()->get_instance()->perform_action(action);
+                               return;
+                       }
+                       else if((bool)(*iter)[model.is_group])
+                       {
+                               synfig::String group((Glib::ustring)(*iter)[model.label]);
+                               synfig::String new_group(x.get());
+
+                               if(x.get()==group)
+                                       return;
+
+                               Glib::ustring group_name((*iter)[model.group_name]);
+                               group=group_name;
+                               new_group.clear();
+
+                               // Get rid of any parent group crap
+                               while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+                               {
+                                       new_group+=Glib::ustring(group_name,0,group_name.find(GROUP_NEST_CHAR)+1);
+                                       group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+                               }
+                               new_group+=x.get();
+
+                               synfig::info("Renaming group \"%s\" to \"%s\"...",group.c_str(),new_group.c_str());
+
+                               // Check to see if this group is real or not.
+                               // If it isn't real, then renaming it is a cinch.
+                               // We know it isn't real if it doesn't have any
+                               // children yet.
+                               if(iter->children().empty())
+                               {
+                                       (*iter)[model.group_name]=new_group;
+                               }
+                               else
+                               {
+                                       synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
+
+                                       if(!action)
+                                               return;
+
+                                       action->set_param("canvas",canvas_interface()->get_canvas());
+                                       action->set_param("canvas_interface",canvas_interface());
+                                       action->set_param("group",group);
+                                       action->set_param("new_group",new_group);
+
+                                       canvas_interface()->get_instance()->perform_action(action);
+                               }
+                               return;
+                       }
+                       return;
+               }
+               else
+               if(column==model.active.index())
+               {
+                       Glib::Value<bool> x;
+                       g_value_init(x.gobj(),model.active.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       if((bool)(*iter)[model.is_layer])
+                       {
+                               synfig::Layer::Handle layer((*iter)[model.layer]);
+                               if(!layer)return;
+
+                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
+
+                               if(!action)
+                                       return;
+
+                               action->set_param("canvas",canvas_interface()->get_canvas());
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",layer);
+                               action->set_param("new_status",bool(x.get()));
+
+
+                               canvas_interface()->get_instance()->perform_action(action);
+                               return;
+                       }
+                       else if(!iter->children().empty())
+                       {
+                               synfigapp::Action::PassiveGrouper group(
+                                       get_canvas_interface()->get_instance().get(),
+                                       String(
+                                               x.get()?_("Activate "):_("Deactivate ")
+                                       )+(Glib::ustring)(*iter)[model.label]
+                               );
+
+                               Gtk::TreeModel::iterator child_iter(iter->children().begin());
+
+                               for(;child_iter;++child_iter)
+                                       (*child_iter)[model.active]=x.get();
+
+                               Gtk::TreeStore::set_value_impl(iter,column, value);
+                       }
+               }
+               else
+                       Gtk::TreeStore::set_value_impl(iter,column, value);
+
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
+
+
+
+
+bool
+LayerGroupTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
+{
+       //if(!get_iter(path)) return false;
+//     Gtk::TreeModel::Row row(*get_iter(path));
+
+       return true;
+}
+
+bool
+LayerGroupTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
+{
+       if(!const_cast<LayerGroupTreeStore*>(this)->get_iter(path)) return false;
+       //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+       //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       Gtk::TreeModel::Row row(*const_cast<LayerGroupTreeStore*>(this)->get_iter(path));
+
+       if((bool)row[model.is_layer])
+       {
+               Layer* layer(((Layer::Handle)row[model.layer]).get());
+               assert(layer);
+
+               std::vector<Layer*> layers;
+
+               layers.push_back(layer);
+
+               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
+
+               return true;
+       }
+       else if((bool)row[model.is_group])
+       {
+               synfig::String group((Glib::ustring)row[model.group_name]);
+               if(group.empty())
+                       return false;
+
+               selection_data.set("GROUP", 8, reinterpret_cast<const guchar*>(&*group.begin()), sizeof(void*)*group.size());
+
+               return true;
+       }
+
+       return false;
+}
+
+bool
+LayerGroupTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
+{
+       return true;
+}
+
+bool
+LayerGroupTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
+{
+       Gtk::TreeIter iter(const_cast<LayerGroupTreeStore*>(this)->get_iter(dest));
+       if(!iter) return false;
+
+       if(synfig::String(selection_data.get_data_type())=="LAYER")
+               return true;
+
+       if(synfig::String(selection_data.get_data_type())=="GROUP")
+       {
+               synfig::String dest_group((Glib::ustring)(*iter)[model.group_name]);
+               synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
+               //synfig::String src_group(const_cast<gchar*>(selection_data.get_data()));
+
+               // Avoid putting a group inside of itself
+               if(dest_group.size()>src_group.size() && src_group==String(dest_group,0,src_group.size()))
+                       return false;
+               return true;
+       }
+
+       return false;
+       //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
+       //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       //Gtk::TreeModel::Row row(*get_iter(dest));
+
+/*     if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
+               return true;
+*/
+       return false;
+}
+
+bool
+LayerGroupTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
+{
+       if(!get_iter(dest)) return false;
+//     bool ret=false;
+       //int i(0);
+
+       Gtk::TreeModel::Row row(*get_iter(dest));
+
+       //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+       //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Regroup"));
+
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               synfig::String dest_group;
+
+               dest_group=(Glib::ustring)row[model.group_name];
+
+               if(dest_group.empty())
+                       return false;
+
+               if(synfig::String(selection_data.get_data_type())=="LAYER")
+               {
+                       synfigapp::Action::Handle action(synfigapp::Action::create("GroupAddLayers"));
+
+                       if(!action)
+                               return false;
+
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("group",dest_group);
+
+                       for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
+                       {
+                               Layer::Handle layer(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+                               assert(layer);
+
+                               action->set_param("layer",layer);
+                       }
+                       if(!canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               passive_grouper.cancel();
+                               return false;
+                       }
+                       return true;
+               }
+               if(synfig::String(selection_data.get_data_type())=="GROUP")
+               {
+                       synfig::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
+                       synfig::String group(src_group);
+
+                       // Get rid of any parent group crap
+                       while(group.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+                               group=Glib::ustring(group,group.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+
+                       group=dest_group+GROUP_NEST_CHAR+group;
+
+                       synfigapp::Action::Handle action(synfigapp::Action::create("GroupRename"));
+
+                       if(!action)
+                               return false;
+
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("group",src_group);
+                       action->set_param("new_group",group);
+
+                       if(!canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               passive_grouper.cancel();
+                               return false;
+                       }
+                       return true;
+               }
+       }
+/*     // Save the selection data
+       synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Canvas::Handle dest_canvas;
+               Layer::Handle dest_layer;
+
+               dest_canvas=(Canvas::Handle)(row[model.canvas]);
+               dest_layer=(Layer::Handle)(row[model.layer]);
+               assert(dest_canvas);
+
+               if(!dest_layer)
+                       return false;
+
+               int dest_layer_depth=dest_layer->get_depth();
+
+               if(synfig::String(selection_data.get_data_type())=="LAYER")for(i=0;i<selection_data.get_length()/sizeof(void*);i++)
+               {
+                       //synfig::info("dest_layer_depth=%d",dest_layer_depth);
+
+                       Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+                       assert(src);
+                       if(dest_layer==src)
+                               continue;
+
+                       // In this case, we are just moving.
+//                     if(dest_canvas==src->get_canvas())
+                       {
+                               if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
+                                       dest_layer_depth--;
+                               if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
+                                       continue;
+
+                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",src);
+                               action->set_param("new_index",dest_layer_depth);
+                               action->set_param("dest_canvas",dest_canvas);
+                               if(canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       ret=true;
+                               }
+                               else
+                               {
+                                       passive_grouper.cancel();
+                                       return false;
+                               }
+                               continue;
+                       }
+               }
+       }
+       synfig::info("I supposedly moved %d layers",i);
+
+       // Reselect the previously selected layers
+       canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
+
+       return ret;
+       */
+       return false;
+}
+
+
+
+
+
+
+
+void
+LayerGroupTreeStore::rebuild()
+{
+       rebuilding=true;
+       // etl::clock timer;timer.reset();
+       try {
+
+               // Clear out the current list
+               clear();
+               Canvas::Handle canvas(canvas_interface()->get_canvas());
+               std::set<String> groups(canvas->get_groups());
+               for(;groups.size();groups.erase(groups.begin()))
+               {
+                       String group(*groups.begin());
+                       Gtk::TreeRow row(on_group_added(group));
+                       std::set<Layer::Handle> layers(canvas->get_layers_in_group(group));
+
+                       for(;layers.size();layers.erase(layers.begin()))
+                       {
+                               Gtk::TreeRow layer_row(*(prepend(row.children())));
+                               Layer::Handle layer(*layers.begin());
+                               set_row_layer(layer_row,layer);
+                       }
+               }
+
+               // Go ahead and add all the layers
+               /*std::for_each(
+                       canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
+                       sigc::mem_fun(*this, &studio::LayerGroupTreeStore::on_layer_added)
+               );*/
+       }
+       catch(...)
+       {
+               rebuilding=false;
+               throw;
+       }
+       rebuilding=false;
+       // synfig::info("LayerGroupTreeStore::rebuild() took %f seconds",float(timer()));
+}
+
+void
+LayerGroupTreeStore::refresh()
+{
+       rebuild();
+}
+
+void
+LayerGroupTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+       if((bool)row[model.is_layer])
+       {
+               Layer::Handle layer=row[model.layer];
+
+
+               //if(layer->dynamic_param_list().count("z_depth"))
+               //      row[model.z_depth]=Time::begin();
+       }
+
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+               for(iter = children.begin(); iter && iter != children.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+}
+
+
+void
+LayerGroupTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
+{
+       row[model.is_layer] = true;
+       row[model.is_group] = false;
+       row[model.layer] = handle;
+}
+
+Gtk::TreeRow
+LayerGroupTreeStore::on_group_added(synfig::String group)
+{
+       // Check to see if this group perhaps already
+       // exists
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(find_group_row(group,  iter))
+                       return *iter;
+       }
+
+       if(group.find(GROUP_NEST_CHAR)!=String::npos)
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               String parent_name;
+               do
+               {
+                       if(parent_name.size())
+                               parent_name+=GROUP_NEST_CHAR;
+                       parent_name+=string(group,0,group.find(GROUP_NEST_CHAR));
+
+                       if(!find_group_row(parent_name, iter))
+                               iter=on_group_added(parent_name);
+
+                       group=String(group,group.find(GROUP_NEST_CHAR)+1,String::npos);
+               }while(group.find(GROUP_NEST_CHAR)!=String::npos);
+
+               if(parent_name.size())
+                       parent_name+=GROUP_NEST_CHAR;
+               parent_name+=group;
+
+               if(iter)
+               {
+                       Gtk::TreeRow row(*(prepend(iter->children())));
+                       row[model.group_name]=parent_name;
+                       row[model.is_layer]=false;
+                       row[model.is_group]=true;
+                       on_activity();
+                       return row;
+               }
+       }
+
+       Gtk::TreeRow row(*(append()));
+       row[model.group_name]=group;
+       row[model.is_layer]=false;
+       row[model.is_group]=true;
+       on_activity();
+       return row;
+}
+
+bool
+LayerGroupTreeStore::on_group_removed(synfig::String group)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_group_row(group,iter) && iter->children().size()==0)
+               erase(iter);
+       else
+               return false;
+
+       return true;
+}
+
+bool
+LayerGroupTreeStore::on_group_changed(synfig::String /*group*/)
+{
+       return true;
+}
+
+void
+LayerGroupTreeStore::on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer)
+{
+       if(!layer->get_canvas())
+               return;
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_group_row(group, iter))
+               iter=on_group_added(group);
+
+       Gtk::TreeRow layer_row(*(append(iter->children())));
+       set_row_layer(layer_row,layer);
+       on_activity();
+}
+
+void
+LayerGroupTreeStore::on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer)
+{
+       if(!layer->get_canvas())
+               return;
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_group_row(group, iter))
+               return;
+
+       Gtk::TreeModel::Children::iterator prev,layer_iter;
+
+       if(!find_layer_row_(layer, layer->get_canvas(), iter->children(), layer_iter, prev))
+               return;
+
+       erase(layer_iter);
+
+       on_activity();
+}
+
+void
+LayerGroupTreeStore::on_activity()
+{
+       // If we aren't rebuilding and the last action
+       // had something to do with groups, then go
+       // a head and present the groups dialog.
+       if(!rebuilding && canvas_interface()->get_instance()->get_most_recent_action() && canvas_interface()->get_instance()->get_most_recent_action()->get_name().find("Group")!=String::npos)
+       try
+       {
+               App::dock_manager->find_dockable("groups").present();
+       }
+       catch(...) { }
+}
+
+void
+LayerGroupTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+               (*iter)[model.layer]=handle;
+       else
+       {
+               // Not need to send a warning when a layer changes its status and
+               // it is not found in any group.
+               //synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
+               rebuild();
+       }
+}
+
+
+void
+LayerGroupTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+       {
+               Gtk::TreeRow row(*iter);
+
+               Layer::Handle layer(row[model.layer]);
+
+               if(desc.empty())
+               {
+                       //row[model.label]=layer->get_local_name();
+                       row[model.tooltip]=Glib::ustring(_("Layer"));
+               }
+               else
+                       //row[model.label]=layer->get_description();
+                       row[model.tooltip]=layer->get_local_name();
+       }
+       else
+       {
+               rebuild();
+       }
+}
+
+bool
+LayerGroupTreeStore::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)
+{
+       assert(layer);
+
+       //if(layer->get_canvas()==canvas)
+       {
+               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if((bool)row[model.is_layer] && layer==(synfig::Layer::Handle)row[model.layer])
+                               return true;
+               }
+
+               iter=children().end();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+
+               if(row.children().empty())
+                       continue;
+
+               /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
+               if(!canvas)
+                       continue;
+               */
+
+               if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
+                       return true;
+       }
+
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerGroupTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
+{
+       Gtk::TreeModel::Children::iterator prev;
+       return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
+}
+
+bool
+LayerGroupTreeStore::find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter)
+{
+       Gtk::TreeModel::Children::iterator prev;
+       return find_group_row_(group,children(),iter,prev);
+}
+
+bool
+LayerGroupTreeStore::find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
+{
+       //if(layer->get_canvas()==canvas)
+       {
+               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
+                               return true;
+               }
+
+               iter=children().end();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+
+               if(row.children().empty())
+                       continue;
+
+               if(find_group_row_(group,iter2->children(),iter,prev))
+                       return true;
+       }
+
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerGroupTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
+               return false;
+       if(iter==children().begin())
+               return false;
+       return true;
+}
diff --git a/synfig-studio/src/gui/trees/layergrouptreestore.h b/synfig-studio/src/gui/trees/layergrouptreestore.h
new file mode 100644 (file)
index 0000000..874bec9
--- /dev/null
@@ -0,0 +1,202 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file trees/layergrouptreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
+#define __SYNFIG_STUDIO_LAYERGROUPTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerGroupTreeStore :  public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+       typedef std::list<synfig::Layer::Handle> LayerList;
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<Glib::ustring> label;
+               Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+               Gtk::TreeModelColumn<Glib::ustring> group_name;
+               Gtk::TreeModelColumn<Glib::ustring> parent_group_name;
+
+               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+
+               Gtk::TreeModelColumn<bool>                                              active;
+               Gtk::TreeModelColumn<bool>                                              is_layer;
+               Gtk::TreeModelColumn<bool>                                              is_group;
+               Gtk::TreeModelColumn<synfig::Layer::Handle>             layer;
+
+               Gtk::TreeModelColumn<LayerList>         all_layers;
+               Gtk::TreeModelColumn<LayerList>         child_layers;
+
+               Model()
+               {
+                       add(icon);
+                       add(label);
+                       add(group_name);
+                       add(parent_group_name);
+                       add(canvas);
+                       add(tooltip);
+                       add(active);
+                       add(layer);
+                       add(is_layer);
+                       add(is_group);
+                       add(all_layers);
+                       add(child_layers);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       //! TreeModel for the layers
+       const Model model;
+
+       bool rebuilding;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+       Glib::RefPtr<Gdk::Pixbuf> layer_icon;
+       Glib::RefPtr<Gdk::Pixbuf> group_icon;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+private:
+
+       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+       virtual bool  row_draggable_vfunc (const TreeModel::Path& path)const;
+       virtual bool  drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
+       virtual bool  drag_data_delete_vfunc (const TreeModel::Path& path);
+       virtual bool  drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
+       virtual bool  row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
+
+
+       void on_group_pair_added(synfig::String group, etl::handle<synfig::Layer> layer);
+       void on_group_pair_removed(synfig::String group, etl::handle<synfig::Layer> layer);
+
+       void on_activity();
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       bool on_layer_tree_event(GdkEvent *event);
+
+       void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
+
+       void on_layer_status_changed(synfig::Layer::Handle handle,bool);
+
+       bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+       bool find_group_row_(const synfig::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+       bool on_group_removed(synfig::String group);
+       bool on_group_changed(synfig::String group);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       LayerGroupTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+       ~LayerGroupTreeStore();
+
+       Gtk::TreeRow on_group_added(synfig::String group);
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_group_row(const synfig::String &group, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       void rebuild();
+
+       void refresh();
+
+       void refresh_row(Gtk::TreeModel::Row &row);
+
+       void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
+
+       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<LayerGroupTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+
+}; // END of class LayerGroupTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/layerparamtreestore.cpp b/synfig-studio/src/gui/trees/layerparamtreestore.cpp
new file mode 100644 (file)
index 0000000..8fe850a
--- /dev/null
@@ -0,0 +1,577 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layerparamtreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007, 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamtreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include "layertree.h"
+#include <synfigapp/action_system.h>
+#include <synfigapp/instance.h>
+#include "app.h"
+#include <ETL/clock>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+class Profiler : private etl::clock
+{
+       const std::string name;
+public:
+       Profiler(const std::string& name):name(name) { reset(); }
+       ~Profiler() { float time(operator()()); synfig::info("%s: took %f msec",name.c_str(),time*1000); }
+};
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerParamTreeStore::Model& ModelHack()
+{
+       static LayerParamTreeStore::Model* model(0);
+       if(!model)model=new LayerParamTreeStore::Model;
+       return *model;
+}
+
+LayerParamTreeStore::LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,LayerTree* layer_tree):
+       Gtk::TreeStore                  (ModelHack()),
+       CanvasTreeStore                 (canvas_interface_),
+       layer_tree                              (layer_tree)
+{
+       queued=0;
+       // Connect all the signals
+       canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_changed));
+       canvas_interface()->signal_value_node_renamed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_renamed));
+       canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_added));
+       canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_deleted));
+       canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_replaced));
+       canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_layer_param_changed));
+
+       canvas_interface()->signal_value_node_child_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_added));
+       canvas_interface()->signal_value_node_child_removed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_removed));
+
+
+       layer_tree->get_selection()->signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_rebuild));
+
+       signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_refresh));
+       rebuild();
+}
+
+LayerParamTreeStore::~LayerParamTreeStore()
+{
+       while(!changed_connection_list.empty())
+       {
+               changed_connection_list.back().disconnect();
+               changed_connection_list.pop_back();
+       }
+
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("LayerParamTreeStore::~LayerParamTreeStore(): Deleted");
+}
+
+Glib::RefPtr<LayerParamTreeStore>
+LayerParamTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree)
+{
+       return Glib::RefPtr<LayerParamTreeStore>(new LayerParamTreeStore(canvas_interface_,layer_tree));
+}
+
+
+
+void
+LayerParamTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column<0)
+       {
+               synfig::error("LayerParamTreeStore::get_value_vfunc(): Bad column!");
+               return;
+       }
+
+/*     if(column==model.label.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(layer->get_non_empty_description());
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+*/
+       if(column==model.label.index())
+       {
+               synfigapp::ValueDesc value_desc((*iter)[model.value_desc]);
+               Glib::ustring label;
+
+               if(!(*iter)[model.is_toplevel])
+                       return CanvasTreeStore::get_value_vfunc(iter,column,value);
+               synfig::ParamDesc param_desc((*iter)[model.param_desc]);
+               label=param_desc.get_local_name();
+
+               if(!(*iter)[model.is_inconsistent])
+               if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
+               {
+                       label+=strprintf(" (%s)",value_desc.get_value_node()->get_id().c_str());
+               }
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(label);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_toplevel.index())
+       {
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               TreeModel::Path path(get_path(iter));
+
+               x.set(path.get_depth()<=1);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_inconsistent.index())
+       {
+               if((*iter)[model.is_toplevel])
+               {
+                       CanvasTreeStore::get_value_vfunc(iter,column,value);
+                       return;
+               }
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(false);
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       CanvasTreeStore::get_value_vfunc(iter,column,value);
+}
+
+
+
+void
+LayerParamTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       //if(!iterator_sane(row))
+       //      return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.value.index())
+               {
+                       Glib::Value<synfig::ValueBase> x;
+                       g_value_init(x.gobj(),model.value.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       if((bool)(*iter)[model.is_toplevel])
+                       {
+                               synfigapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Set Layer Params"));
+
+                               synfig::ParamDesc param_desc((*iter)[model.param_desc]);
+
+                               LayerList::iterator iter2(layer_list.begin());
+
+                               for(;iter2!=layer_list.end();++iter2)
+                               {
+                                       if(!canvas_interface()->change_value(synfigapp::ValueDesc(*iter2,param_desc.get_name()),x.get()))
+                                       {
+                                               // ERROR!
+                                               group.cancel();
+                                               App::dialog_error_blocking(_("Error"),_("Unable to set all layer parameters."));
+
+                                               return;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               canvas_interface()->change_value((*iter)[model.value_desc],x.get());
+                       }
+                       return;
+               }
+               else
+/*
+               if(column==model.active.index())
+               {
+                       synfig::Layer::Handle layer((*iter)[model.layer]);
+
+                       if(!layer)return;
+
+                       Glib::Value<bool> x;
+                       g_value_init(x.gobj(),model.active.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
+
+                       if(!action)
+                               return;
+
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("layer",layer);
+                       action->set_param("new_status",bool(x.get()));
+
+                       canvas_interface()->get_instance()->perform_action(action);
+                       return;
+               }
+               else
+*/
+               CanvasTreeStore::set_value_impl(iter,column, value);
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
+
+
+
+
+
+
+
+
+
+
+void
+LayerParamTreeStore::rebuild()
+{
+       // Profiler profiler("LayerParamTreeStore::rebuild()");
+       if(queued)queued=0;
+       clear();
+       layer_list=layer_tree->get_selected_layers();
+
+       if(layer_list.size()<=0)
+               return;
+
+       // Get rid of all the connections,
+       // and clear the connection map.
+       //while(!connection_map.empty())connection_map.begin()->second.disconnect(),connection_map.erase(connection_map.begin());
+       while(!changed_connection_list.empty())
+       {
+               changed_connection_list.back().disconnect();
+               changed_connection_list.pop_back();
+       }
+
+       struct REBUILD_HELPER
+       {
+               ParamVocab vocab;
+               Layer::Handle layer_0;
+
+               static ParamVocab::iterator find_param_desc(ParamVocab& vocab, const synfig::String& x)
+               {
+                       ParamVocab::iterator iter;
+
+                       for(iter=vocab.begin();iter!=vocab.end();++iter)
+                               if(iter->get_name()==x)
+                                       break;
+                       return iter;
+               }
+
+               void process_vocab(synfig::Layer::Handle layer_n)
+               {
+                       ParamVocab x = layer_n->get_param_vocab();
+                       ParamVocab::iterator iter;
+
+                       for(iter=vocab.begin();iter!=vocab.end();++iter)
+                       {
+                               String name(iter->get_name());
+                               ParamVocab::iterator iter2(find_param_desc(x,name));
+                               if(iter2==x.end() ||
+                                  layer_0->get_param(name).get_type() != layer_n->get_param(name).get_type())
+                               {
+                                       // remove it and start over
+                                       vocab.erase(iter);
+                                       iter=vocab.begin();
+                                       iter--;
+                                       continue;
+                               }
+                       }
+               }
+
+       } rebuild_helper;
+
+
+       {
+               LayerList::iterator iter(layer_list.begin());
+               rebuild_helper.vocab=(*iter)->get_param_vocab();
+               rebuild_helper.layer_0=*iter;
+
+               for(++iter;iter!=layer_list.end();++iter)
+               {
+                       rebuild_helper.process_vocab(*iter);
+                       changed_connection_list.push_back(
+                               (*iter)->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &LayerParamTreeStore::changed
+                                       )
+                               )
+                       );
+               }
+       }
+
+       ParamVocab::iterator iter;
+       for(iter=rebuild_helper.vocab.begin();iter!=rebuild_helper.vocab.end();++iter)
+       {
+               if(iter->get_hidden())
+                       continue;
+
+               /*
+               if(iter->get_animation_only())
+               {
+                       int length(layer_list.front()->get_canvas()->rend_desc().get_frame_end()-layer_list.front()->get_canvas()->rend_desc().get_frame_start());
+                       if(!length)
+                               continue;
+               }
+               */
+               Gtk::TreeRow row(*(append()));
+               synfigapp::ValueDesc value_desc(layer_list.front(),iter->get_name());
+               CanvasTreeStore::set_row(row,value_desc);
+               if(value_desc.is_value_node())
+               {
+                       changed_connection_list.push_back(
+                               value_desc.get_value_node()->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               this,
+                                               &LayerParamTreeStore::changed
+                                       )
+                               )
+                       );
+               }
+               if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
+               {
+                       Canvas::Handle canvas_handle = value_desc.get_value().get(Canvas::Handle());
+                       if(canvas_handle) changed_connection_list.push_back(
+                               canvas_handle->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               this,
+                                               &LayerParamTreeStore::changed
+                                       )
+                               )
+                       );
+               }
+               //row[model.label] = iter->get_local_name();
+               row[model.param_desc] = *iter;
+               row[model.canvas] = layer_list.front()->get_canvas();
+               row[model.is_inconsistent] = false;
+               //row[model.is_toplevel] = true;
+
+
+               LayerList::iterator iter2(layer_list.begin());
+               ValueBase value((*iter2)->get_param(iter->get_name()));
+               for(++iter2;iter2!=layer_list.end();++iter2)
+               {
+                       if(value!=((*iter2)->get_param(iter->get_name())))
+                       {
+                               row[model.is_inconsistent] = true;
+                               while(!row.children().empty() && erase(row.children().begin()))
+                                       ;
+                               break;
+                       }
+               }
+       }
+}
+
+void
+LayerParamTreeStore::queue_refresh()
+{
+       if(queued)
+               return;
+       queued=1;
+       queue_connection.disconnect();
+       queue_connection=Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&LayerParamTreeStore::refresh),
+                       false
+               )
+       ,150);
+
+}
+
+void
+LayerParamTreeStore::queue_rebuild()
+{
+       if(queued==2)
+               return;
+       queued=2;
+       queue_connection.disconnect();
+       queue_connection=Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&LayerParamTreeStore::rebuild),
+                       false
+               )
+       ,150);
+
+}
+
+void
+LayerParamTreeStore::refresh()
+{
+       if(queued)queued=0;
+
+       Gtk::TreeModel::Children children_(children());
+
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children_.empty())
+               for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+}
+
+void
+LayerParamTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+       if(row[model.is_toplevel])
+       {
+               row[model.is_inconsistent] = false;
+               ParamDesc param_desc(row[model.param_desc]);
+
+               LayerList::iterator iter2(layer_list.begin());
+               ValueBase value((*iter2)->get_param(param_desc.get_name()));
+               for(++iter2;iter2!=layer_list.end();++iter2)
+               {
+                       if(value!=((*iter2)->get_param(param_desc.get_name())))
+                       {
+                               row[model.is_inconsistent] = true;
+                               while(!row.children().empty() && erase(row.children().begin()))
+                                       ;
+                               return;
+                       }
+               }
+       }
+
+       //handle<ValueNode> value_node=row[model.value_node];
+       //if(value_node)
+       {
+               CanvasTreeStore::refresh_row(row);
+               return;
+       }
+}
+
+void
+LayerParamTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc)
+{
+       Gtk::TreeModel::Children children = row.children();
+       while(!children.empty() && erase(children.begin()))
+               ;
+
+       CanvasTreeStore::set_row(row,value_desc);
+}
+
+void
+LayerParamTreeStore::on_value_node_added(synfig::ValueNode::Handle /*value_node*/)
+{
+//     queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_deleted(synfig::ValueNode::Handle /*value_node*/)
+{
+//     queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_child_added(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
+{
+       queue_rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_child_removed(synfig::ValueNode::Handle /*value_node*/,synfig::ValueNode::Handle /*child*/)
+{
+       rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_changed(synfig::ValueNode::Handle /*value_node*/)
+{
+       queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_renamed(synfig::ValueNode::Handle /*value_node*/)
+{
+       rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_replaced(synfig::ValueNode::Handle /*replaced_value_node*/,synfig::ValueNode::Handle /*new_value_node*/)
+{
+       queue_rebuild();
+}
+
+void
+LayerParamTreeStore::on_layer_param_changed(synfig::Layer::Handle /*handle*/,synfig::String /*param_name*/)
+{
+       queue_refresh();
+}
diff --git a/synfig-studio/src/gui/trees/layerparamtreestore.h b/synfig-studio/src/gui/trees/layerparamtreestore.h
new file mode 100644 (file)
index 0000000..7d3eb99
--- /dev/null
@@ -0,0 +1,166 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layerparamtreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
+#define __SYNFIG_STUDIO_LAYERPARAMTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include "trees/canvastreestore.h"
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <synfig/paramdesc.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerTree;
+
+class LayerParamTreeStore : public CanvasTreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+       typedef std::list<synfig::Layer::Handle> LayerList;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       //! TreeModel for the layer parameters
+       class Model : public CanvasTreeStore::Model
+       {
+       public:
+
+               Gtk::TreeModelColumn<synfig::ParamDesc> param_desc;
+
+               Gtk::TreeModelColumn<bool>      is_inconsistent;
+               Gtk::TreeModelColumn<bool>      is_toplevel;
+
+               Model()
+               {
+                       add(param_desc);
+                       add(is_inconsistent);
+                       add(is_toplevel);
+               }
+       };
+
+       Model model;
+
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       int queued;
+
+       LayerTree* layer_tree;
+
+       LayerList layer_list;
+
+       sigc::connection queue_connection;
+
+       std::list<sigc::connection> changed_connection_list;
+
+       sigc::signal<void> signal_changed_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+protected:
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_value_node_child_added(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
+       void on_value_node_child_removed(synfig::ValueNode::Handle value_node,synfig::ValueNode::Handle child);
+
+       void on_value_node_added(synfig::ValueNode::Handle value_node);
+       void on_value_node_deleted(synfig::ValueNode::Handle value_node);
+       virtual void on_value_node_changed(synfig::ValueNode::Handle value_node);
+       virtual void on_value_node_renamed(synfig::ValueNode::Handle value_node);
+       void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
+       void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       LayerParamTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_,
+               LayerTree* layer_tree);
+       ~LayerParamTreeStore();
+
+       void rebuild();
+
+       void refresh();
+
+       void queue_refresh();
+
+       void queue_rebuild();
+
+       void refresh_row(Gtk::TreeModel::Row &row);
+
+       sigc::signal<void>& signal_changed() { return signal_changed_; }
+
+       void changed() { signal_changed_(); }
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<LayerParamTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree);
+}; // END of class LayerParamTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/layertree.cpp b/synfig-studio/src/gui/trees/layertree.cpp
new file mode 100644 (file)
index 0000000..a69f234
--- /dev/null
@@ -0,0 +1,1232 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layertree.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007, 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layertree.h"
+#include "layerparamtreestore.h"
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/paned.h>
+#include "app.h"
+#include "instance.h"
+#include <gtkmm/treemodelsort.h>
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+#  include <synfig/timepointcollect.h>
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef SMALL_BUTTON
+#define SMALL_BUTTON(button,stockid,tooltip)   \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       button->set_relief(Gtk::RELIEF_NONE); \
+       button->show()
+#endif
+
+#ifndef NORMAL_BUTTON
+#define NORMAL_BUTTON(button,stockid,tooltip)  \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       /*button->set_relief(Gtk::RELIEF_NONE);*/ \
+       button->show()
+#endif
+
+#define NEW_SMALL_BUTTON(x,y,z)        Gtk::Button *SMALL_BUTTON(x,y,z)
+
+#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LayerTree::LayerTree():
+       layer_amount_adjustment_(1,0,1,0.01,0.01,0)
+{
+       param_tree_view_=new Gtk::TreeView;
+       layer_tree_view_=new Gtk::TreeView;
+
+       //Gtk::HPaned* hpaned(manage(new Gtk::HPaned()));
+       //hpaned->show();
+       //attach(*hpaned, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+       //attach(*create_layer_tree(), 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       create_layer_tree();
+       create_param_tree();
+
+       //hpaned->pack1(*create_layer_tree(),false,false);
+       //hpaned->pack2(*create_param_tree(),true,false);
+       //hpaned->set_position(200);
+       hbox=manage(new Gtk::HBox());
+
+       attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       attach(blend_method_widget, 2, 3, 1, 2,Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+       layer_amount_hscale=manage(new Gtk::HScale(layer_amount_adjustment_));
+       layer_amount_hscale->set_digits(2);
+       layer_amount_hscale->set_value_pos(Gtk::POS_LEFT);
+       layer_amount_hscale->set_sensitive(false);
+       layer_amount_hscale->set_update_policy( Gtk::UPDATE_DISCONTINUOUS);
+       attach(*layer_amount_hscale, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 1, 1);
+       layer_amount_adjustment_.signal_value_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_amount_value_changed));
+
+       Gtk::Image *icon;
+       //Gtk::IconSize iconsize(Gtk::IconSize::from_name("synfig-small_icon"));
+       Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       SMALL_BUTTON(button_raise,"gtk-go-up","Raise");
+       SMALL_BUTTON(button_lower,"gtk-go-down","Lower");
+       SMALL_BUTTON(button_duplicate,"synfig-duplicate","Duplicate");
+       SMALL_BUTTON(button_encapsulate,"synfig-encapsulate","Encapsulate");
+       SMALL_BUTTON(button_delete,"gtk-delete","Delete");
+
+       hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_encapsulate,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
+
+       // button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_raise_pressed));
+       // button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_lower_pressed));
+       // button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_duplicate_pressed));
+       // button_encapsulate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_encapsulate_pressed));
+       // button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_delete_pressed));
+
+       button_raise->set_sensitive(false);
+       button_lower->set_sensitive(false);
+       button_duplicate->set_sensitive(false);
+       button_encapsulate->set_sensitive(false);
+       button_delete->set_sensitive(false);
+
+       get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_selection_changed));
+
+       get_layer_tree_view().set_reorderable(true);
+       get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+       //get_param_tree_view().get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+       get_layer_tree_view().show();
+       get_param_tree_view().show();
+
+       hbox->show();
+       layer_amount_hscale->show();
+       blend_method_widget.show();
+
+       tooltips_.enable();
+       disable_amount_changed_signal=false;
+
+       blend_method_widget.set_param_desc(ParamDesc(Color::BlendMethod(),"blend_method"));
+
+       blend_method_widget.set_value((int)Color::BLEND_COMPOSITE);
+       blend_method_widget.set_size_request(150,-1);
+       blend_method_widget.set_sensitive(false);
+       blend_method_widget.signal_activate().connect(sigc::mem_fun(*this, &studio::LayerTree::on_blend_method_changed));
+}
+
+LayerTree::~LayerTree()
+{
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("LayerTree::~LayerTree(): Deleted");
+}
+
+Gtk::Widget*
+LayerTree::create_layer_tree()
+{
+       const LayerTreeStore::Model model;
+
+       {       // --- O N / O F F ----------------------------------------------------
+               //int index;
+               //index=get_layer_tree_view().append_column_editable(_(" "),layer_model.active);
+               //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_(" ")) );
+
+               // Set up the icon cell-renderer
+               Gtk::CellRendererToggle* cellrenderer = Gtk::manage( new Gtk::CellRendererToggle() );
+               cellrenderer->signal_toggled().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_toggle));
+
+               column->pack_start(*cellrenderer,false);
+               column->add_attribute(cellrenderer->property_active(), layer_model.active);
+               get_layer_tree_view().append_column(*column);
+       }
+
+       {       // --- I C O N --------------------------------------------------------
+               int index;
+               index=get_layer_tree_view().append_column(_("Z"),layer_model.icon);
+               Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+               get_layer_tree_view().set_expander_column(*column);
+
+               column->set_sort_column(layer_model.z_depth);
+               //column->set_reorderable();
+               //column->set_resizable();
+               //column->set_clickable();
+
+               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               //column->pack_start(*icon_cellrenderer,false);
+               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+       }
+       //get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
+       {       // --- N A M E --------------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
+
+               // Set up the icon cell-renderer
+               Gtk::CellRendererText* cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+               column->pack_start(*cellrenderer,false);
+               column->add_attribute(cellrenderer->property_text(), layer_model.label);
+               cellrenderer->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_renamed));
+               cellrenderer->property_editable()=true;
+
+               column->set_reorderable();
+               // column->set_resizable();
+               column->set_clickable(true);
+               column->set_sort_column(layer_model.label);
+
+               get_layer_tree_view().append_column(*column);
+
+               //              int index;
+//             index=get_layer_tree_view().append_column_editable(_("Layer"),layer_model.label);
+               //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+
+               //get_layer_tree_view().set_expander_column(*column);
+
+               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               //column->pack_start(*icon_cellrenderer,false);
+               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+       }
+       {       // --- Z D E P T H ----------------------------------------------------
+               int index;
+               index=get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
+               column_z_depth=get_layer_tree_view().get_column(index-1);
+
+               column_z_depth->set_reorderable();
+               column_z_depth->set_resizable();
+               column_z_depth->set_clickable();
+
+               column_z_depth->set_sort_column(layer_model.z_depth);
+       }
+
+       get_layer_tree_view().set_enable_search(true);
+       get_layer_tree_view().set_search_column(layer_model.label);
+       get_layer_tree_view().set_search_equal_func(sigc::ptr_fun(&studio::LayerTreeStore::search_func));
+
+       std::list<Gtk::TargetEntry> listTargets;
+       listTargets.push_back( Gtk::TargetEntry("LAYER") );
+       get_layer_tree_view().drag_dest_set(listTargets);
+
+       // This makes things easier to read.
+       get_layer_tree_view().set_rules_hint();
+
+       // Make us more sensitive to several events
+       //get_layer_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+       get_layer_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_tree_event));
+       get_layer_tree_view().show();
+
+       Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
+       scroll->set_flags(Gtk::CAN_FOCUS);
+       scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       //scroll->add(get_layer_tree_view());
+       scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scroll->show();
+
+       return scroll;
+}
+
+Gtk::Widget*
+LayerTree::create_param_tree()
+{
+       Pango::AttrList attr_list;
+       {
+               Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8));
+               pango_size.set_start_index(0);
+               pango_size.set_end_index(64);
+               attr_list.change(pango_size);
+       }
+
+       Gtk::IconSize icon_size(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       {       // --- N A M E --------------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Name")) );
+
+               // Set up the icon cell-renderer
+               Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               column->pack_start(*icon_cellrenderer,false);
+               column->add_attribute(icon_cellrenderer->property_pixbuf(), param_model.icon);
+
+               // Pack the label into the column
+               //column->pack_start(layer_model.label,true);
+               Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+               column->pack_start(*text_cellrenderer,false);
+               column->add_attribute(text_cellrenderer->property_text(), param_model.label);
+               text_cellrenderer->property_attributes()=attr_list;
+
+               text_cellrenderer->property_foreground()=Glib::ustring("#7f7f7f");
+               column->add_attribute(text_cellrenderer->property_foreground_set(),param_model.is_inconsistent);
+
+               // Pack the label into the column
+               //column->pack_start(param_model.label,true);
+
+               // Set up the value-node icon cell-renderer to be on the far right
+               Gtk::CellRendererPixbuf* valuenode_icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               column->pack_end(*valuenode_icon_cellrenderer,false);
+               valuenode_icon_cellrenderer->property_pixbuf()=Gtk::Button().render_icon(Gtk::StockID("synfig-value_node"),icon_size);
+               column->add_attribute(valuenode_icon_cellrenderer->property_visible(), param_model.is_shared);
+
+               // Finish setting up the column
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+
+               get_param_tree_view().append_column(*column);
+       }
+       {       // --- V A L U E  -----------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Value")) );
+
+               // Set up the value cell-renderer
+               cellrenderer_value=LayerParamTreeStore::add_cell_renderer_value(column);
+               cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_edited_value));
+               cellrenderer_value->property_value()=synfig::ValueBase();
+               column->add_attribute(cellrenderer_value->property_param_desc(), param_model.param_desc);
+               column->add_attribute(cellrenderer_value->property_inconsistent(),param_model.is_inconsistent);
+               //cellrenderer_value->property_canvas()=canvas_interface->get_canvas(); // Is this line necessary?
+               cellrenderer_value->property_attributes()=attr_list;
+
+               // Finish setting up the column
+               get_param_tree_view().append_column(*column);
+               column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+               column->set_clickable();
+               column->set_min_width(120);
+               column->set_reorderable();
+               column->set_resizable();
+       }
+       {       // --- T Y P E --------------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Type")) );
+               Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+               column->pack_start(*text_cellrenderer,false);
+               column->add_attribute(text_cellrenderer->property_text(), param_model.type);
+               text_cellrenderer->property_attributes()=attr_list;
+               get_param_tree_view().append_column(*column);
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               column->set_sort_column(param_model.type);
+       }
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+       {       // --- T I M E   T R A C K --------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
+               column_time_track=column;
+
+               // Set up the value-node cell-renderer
+               cellrenderer_time_track=LayerParamTreeStore::add_cell_renderer_value_node(column);
+               cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+               cellrenderer_time_track->signal_waypoint_clicked_cellrenderer().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_clicked_layertree) );
+               cellrenderer_time_track->signal_waypoint_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_changed) );
+               column->add_attribute(cellrenderer_time_track->property_value_desc(), param_model.value_desc);
+               column->add_attribute(cellrenderer_time_track->property_canvas(), param_model.canvas);
+               column->add_attribute(cellrenderer_time_track->property_visible(), param_model.is_value_node);
+
+               // Finish setting up the column
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_min_width(200);
+
+               if (!getenv("SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK"))
+                       get_param_tree_view().append_column(*column);
+       }
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+       // This makes things easier to read.
+       get_param_tree_view().set_rules_hint();
+
+       // Make us more sensitive to several events
+       get_param_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+       get_param_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_param_tree_event));
+       get_param_tree_view().show();
+
+       Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
+       scroll->set_flags(Gtk::CAN_FOCUS);
+       scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       //scroll->add(get_param_tree_view());
+       scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scroll->show();
+
+       //column_time_track->set_visible(false);
+
+       return scroll;
+}
+
+void
+LayerTree::on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node)
+{
+       synfigapp::Action::ParamList param_list;
+       param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+       param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+       param_list.add("value_node",value_node);
+       param_list.add("waypoint",waypoint);
+//     param_list.add("time",canvas_interface()->get_time());
+
+       etl::handle<studio::Instance>::cast_static(layer_tree_store_->canvas_interface()->get_instance())->process_action("WaypointSetSmart", param_list);
+}
+
+void
+LayerTree::select_layer(synfig::Layer::Handle layer)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(layer_tree_store_->find_layer_row(layer,iter))
+       {
+               if(sorted_layer_tree_store_)
+                       iter=sorted_layer_tree_store_->convert_child_iter_to_iter(iter);
+
+               Gtk::TreePath path(iter);
+               for(int i=path.get_depth();i;i--)
+               {
+                       int j;
+                       path=Gtk::TreePath(iter);
+                       for(j=i;j;j--)
+                               path.up();
+                       get_layer_tree_view().expand_row(path,false);
+               }
+               get_layer_tree_view().scroll_to_row(Gtk::TreePath(iter));
+               get_layer_tree_view().get_selection()->select(iter);
+       }
+}
+
+void
+LayerTree::select_all_children(Gtk::TreeModel::Children::iterator iter)
+{
+       get_layer_tree_view().get_selection()->select(iter);
+       if((bool)(*iter)[layer_model.children_lock])
+               return;
+       get_layer_tree_view().expand_row(layer_tree_store_->get_path(iter),false);
+       Gtk::TreeModel::Children children(iter->children());
+       for(iter=children.begin();iter!=children.end();++iter)
+               select_all_children(iter);
+}
+
+void
+LayerTree::select_all_children_layers(synfig::Layer::Handle layer)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(layer_tree_store_->find_layer_row(layer,iter))
+               select_all_children(iter);
+}
+
+void
+LayerTree::select_layers(const LayerList &layer_list)
+{
+       LayerList::const_iterator iter;
+       for(iter = layer_list.begin(); iter != layer_list.end(); ++iter)
+               select_layer(*iter);
+}
+
+static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerTree::LayerList* ret)
+{
+       const LayerTreeStore::Model layer_tree_model;
+       ret->push_back((Layer::Handle)(*iter)[layer_tree_model.layer]);
+}
+
+LayerTree::LayerList
+LayerTree::get_selected_layers()const
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<Gtk::TreeView&>(get_layer_tree_view()).get_selection();
+
+       if(!selection)
+               return LayerList();
+
+       LayerList ret;
+
+       selection->selected_foreach_iter(
+               sigc::bind(
+                       sigc::ptr_fun(
+                               &__layer_grabber
+                       ),
+                       &ret
+               )
+       );
+
+       return ret;
+}
+
+synfig::Layer::Handle
+LayerTree::get_selected_layer()const
+{
+       LayerList layers(get_selected_layers());
+
+       if(layers.empty())
+               return 0;
+
+       return *layers.begin();
+}
+
+void
+LayerTree::clear_selected_layers()
+{
+       get_layer_tree_view().get_selection()->unselect_all();
+}
+
+void
+LayerTree::set_show_timetrack(bool x)
+{
+       //column_time_track->set_visible(x);
+//     column_time_track->set_visible(false);
+       column_z_depth->set_visible(x);
+}
+
+void
+LayerTree::set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store)
+{
+       layer_tree_store_=layer_tree_store;
+
+       if(false)
+       {
+               sorted_layer_tree_store_=Gtk::TreeModelSort::create(layer_tree_store);
+
+               sorted_layer_tree_store_->set_default_sort_func(sigc::ptr_fun(&studio::LayerTreeStore::z_sorter));
+
+               //sorted_store->set_sort_func(model.time.index(),sigc::mem_fun(&studio::KeyframeTreeStore::time_sorter));
+               //sorted_store->set_sort_column(model.time.index(), Gtk::SORT_ASCENDING);
+
+               get_layer_tree_view().set_model(sorted_layer_tree_store_);
+       }
+       else
+               get_layer_tree_view().set_model(layer_tree_store_);
+
+       layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
+
+       //layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
+
+       layer_tree_store_->canvas_interface()->signal_time_changed().connect(
+               sigc::mem_fun(
+                       &get_param_tree_view(),
+                       &Gtk::Widget::queue_draw
+               )
+       );
+       if(!param_tree_store_)
+       {
+               param_tree_store_=LayerParamTreeStore::create(layer_tree_store_->canvas_interface(), this);
+               get_param_tree_view().set_model(param_tree_store_);
+       }
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+       if(cellrenderer_time_track && layer_tree_store_ && layer_tree_store_->canvas_interface())
+               cellrenderer_time_track->set_canvas_interface(layer_tree_store_->canvas_interface());
+#endif // TIMETRACK_IN_PARAMS_PANEL
+}
+
+void
+LayerTree::set_time_adjustment(Gtk::Adjustment &adjustment)
+{
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+       cellrenderer_time_track->set_adjustment(adjustment);
+#endif // TIMETRACK_IN_PARAMS_PANEL
+       adjustment.signal_value_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
+       adjustment.signal_changed().connect(sigc::mem_fun(get_param_tree_view(),&Gtk::TreeView::queue_draw));
+}
+
+void
+LayerTree::on_dirty_preview()
+{
+/*
+       if(quick_layer && !disable_amount_changed_signal)
+       {
+               layer_amount_hscale->set_sensitive(true);
+               disable_amount_changed_signal=true;
+               layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
+               disable_amount_changed_signal=false;
+               if(quick_layer->get_param("blend_method").is_valid())
+               {
+                       blend_method_widget.set_sensitive(true);
+                       disable_amount_changed_signal=true;
+                       blend_method_widget.set_value(quick_layer->get_param("blend_method"));
+                       disable_amount_changed_signal=false;
+               }
+       }
+*/
+}
+
+void
+LayerTree::on_selection_changed()
+{
+       synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+
+       Gtk::TreeIter iter;
+       if(last_top_selected_layer && !layer_tree_store_->find_layer_row(last_top_selected_layer,iter))
+       {
+               if(layer_list.empty())
+               {
+                       last_top_selected_layer=0;
+                       layer_tree_view_->get_selection()->select(last_top_selected_path);
+                       return;
+               }
+       }
+
+       {
+               if(!layer_list.empty())
+               {
+                       last_top_selected_layer=layer_list.front();
+                       last_top_selected_path=*layer_tree_view_->get_selection()->get_selected_rows().begin();
+               }
+               else
+               {
+                       last_top_selected_layer=0;
+               }
+       }
+
+       if(layer_list.empty())
+       {
+               button_raise->set_sensitive(false);
+               button_lower->set_sensitive(false);
+               button_duplicate->set_sensitive(false);
+               button_encapsulate->set_sensitive(false);
+               button_delete->set_sensitive(false);
+               layer_amount_hscale->set_sensitive(false);
+               blend_method_widget.set_sensitive(false);
+               return;
+       }
+
+       button_raise->set_sensitive(true);
+       button_lower->set_sensitive(true);
+       button_duplicate->set_sensitive(true);
+       button_encapsulate->set_sensitive(true);
+       button_delete->set_sensitive(true);
+
+       if(layer_list.size()==1 && (*layer_list.begin())->get_param("amount").is_valid()&& (*layer_list.begin())->get_param("amount").same_type_as(Real()))
+       {
+               quick_layer=*layer_list.begin();
+       }
+       else
+               quick_layer=0;
+
+       if(quick_layer)
+       {
+               layer_amount_hscale->set_sensitive(true);
+               disable_amount_changed_signal=true;
+               layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
+               disable_amount_changed_signal=false;
+               if(quick_layer->get_param("blend_method").is_valid())
+               {
+                       blend_method_widget.set_sensitive(true);
+                       disable_amount_changed_signal=true;
+                       blend_method_widget.set_value(quick_layer->get_param("blend_method"));
+                       disable_amount_changed_signal=false;
+               }
+               else
+                       blend_method_widget.set_sensitive(false);
+       }
+       else
+       {
+               layer_amount_hscale->set_sensitive(false);
+               blend_method_widget.set_sensitive(false);
+       }
+}
+
+void
+LayerTree::on_blend_method_changed()
+{
+       if(disable_amount_changed_signal)
+               return;
+       if(!quick_layer)
+               return;
+
+       if(quick_layer->get_param("blend_method").is_valid())
+       {
+               disable_amount_changed_signal=true;
+               signal_edited_value()(synfigapp::ValueDesc(quick_layer,"blend_method"),blend_method_widget.get_value());
+               disable_amount_changed_signal=false;
+       }
+}
+
+void
+LayerTree::on_amount_value_changed()
+{
+       if(disable_amount_changed_signal)
+               return;
+       if(!quick_layer)
+               return;
+
+       disable_amount_changed_signal=true;
+       signal_edited_value()(synfigapp::ValueDesc(quick_layer,"amount"),synfig::ValueBase(layer_amount_adjustment_.get_value()));
+       disable_amount_changed_signal=false;
+}
+
+void
+LayerTree::on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+       if(!row)
+               return;
+       row[param_model.value]=value;
+       //signal_edited_value()(row[param_model.value_desc],value);
+}
+
+void
+LayerTree::on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+       if(!row)
+               return;
+       row[layer_model.label]=value;
+       get_layer_tree_view().columns_autosize();
+}
+
+void
+LayerTree::on_layer_toggle(const Glib::ustring& path_string)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+       bool active=static_cast<bool>(row[layer_model.active]);
+       row[layer_model.active]=!active;
+}
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+void
+LayerTree::on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node __attribute__ ((unused)),
+                                                                                const synfig::Time& time __attribute__ ((unused)),
+                                                                                const synfig::Time& time_offset __attribute__ ((unused)),
+                                                                                int button __attribute__ ((unused)))
+{
+       std::set<synfig::Waypoint, std::less<UniqueID> > waypoint_set;
+       synfig::waypoint_collect(waypoint_set,time,node);
+
+       synfigapp::ValueDesc value_desc;
+
+       if (waypoint_set.size() == 1)
+       {
+               ValueNode::Handle value_node(waypoint_set.begin()->get_parent_value_node());
+               assert(value_node);
+
+               Gtk::TreeRow row;
+               if (param_tree_store_->find_first_value_node(value_node, row) && row)
+                       value_desc = static_cast<synfigapp::ValueDesc>(row[param_tree_store_->model.value_desc]);
+       }
+
+       if (!waypoint_set.empty())
+               signal_waypoint_clicked_layertree()(value_desc,waypoint_set,button);
+}
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+bool
+LayerTree::on_layer_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_layer_tree_view().get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+                       if(column->get_first_cell_renderer()==cellrenderer_time_track)
+                               return signal_layer_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+                       else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+                       if(column->get_first_cell_renderer()==cellrenderer_value)
+                               return signal_layer_user_click()(event->button.button,row,COLUMNID_VALUE);
+                       else
+                               return signal_layer_user_click()(event->button.button,row,COLUMNID_NAME);
+
+               }
+               break;
+
+       case GDK_MOTION_NOTIFY:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_layer_tree_view().get_path_at_pos(
+                               (int)event->button.x,(int)event->button.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+
+                       if(!get_layer_tree_view().get_model()->get_iter(path))
+                               break;
+
+                       Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+                       if(cellrenderer_time_track==column->get_first_cell_renderer())
+                               // Movement on TimeLine
+                               return true;
+                       else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+                       {
+                               tooltips_.unset_tip(*this);
+                               Glib::ustring tooltips_string(row[layer_model.tooltip]);
+                               last_tooltip_path=path;
+                               if(!tooltips_string.empty())
+                               {
+                                       tooltips_.set_tip(*this,tooltips_string);
+                                       tooltips_.force_window();
+                               }
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+bool
+LayerTree::on_param_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_param_tree_view().get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+                       if(column && column->get_first_cell_renderer()==cellrenderer_time_track)
+                       {
+                               Gdk::Rectangle rect;
+                               get_param_tree_view().get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+                               //return signal_param_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+                       }
+                       else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+                       {
+                               if(event->button.button==3)
+                               {
+                                       LayerList layer_list(get_selected_layers());
+                                       if(layer_list.size()<=1)
+                                       {
+                                               synfigapp::ValueDesc value_desc(row[param_model.value_desc]);
+                                               Gtk::Menu* menu(manage(new Gtk::Menu()));
+                                               menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
+                                               App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc,0.5f);
+                                               menu->popup(event->button.button,gtk_get_current_event_time());
+                                               return true;
+                                       }
+                                       Gtk::Menu* menu(manage(new Gtk::Menu()));
+                                       menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
+                                       std::list<synfigapp::ValueDesc> value_desc_list;
+                                       ParamDesc param_desc(row[param_model.param_desc]);
+                                       for(;!layer_list.empty();layer_list.pop_back())
+                                               value_desc_list.push_back(synfigapp::ValueDesc(layer_list.back(),param_desc.get_name()));
+                                       App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc_list);
+                                       menu->popup(event->button.button,gtk_get_current_event_time());
+                                       return true;
+                               }
+                               else
+                               {
+                                       if(column->get_first_cell_renderer()==cellrenderer_value)
+                                               return signal_param_user_click()(event->button.button,row,COLUMNID_VALUE);
+                                       else
+                                               return signal_param_user_click()(event->button.button,row,COLUMNID_NAME);
+                               }
+                       }
+               }
+               break;
+
+       case GDK_MOTION_NOTIFY:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_param_tree_view().get_path_at_pos(
+                               (int)event->motion.x,(int)event->motion.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+
+                       if(!get_param_tree_view().get_model()->get_iter(path))
+                               break;
+
+                       Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+                       if((event->motion.state&GDK_BUTTON1_MASK ||event->motion.state&GDK_BUTTON3_MASK) && column && cellrenderer_time_track==column->get_first_cell_renderer())
+                       {
+                               Gdk::Rectangle rect;
+                               get_param_tree_view().get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               get_param_tree_view().queue_draw();
+                               //get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+                       }
+                       else
+#endif // TIMETRACK_IN_PARAMS_PANEL
+                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+                       {
+                               tooltips_.unset_tip(*this);
+                               Glib::ustring tooltips_string(row[layer_model.tooltip]);
+                               last_tooltip_path=path;
+                               if(!tooltips_string.empty())
+                               {
+                                       tooltips_.set_tip(*this,tooltips_string);
+                                       tooltips_.force_window();
+                               }
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_param_tree_view().get_path_at_pos(
+                               (int)event->button.x,(int)event->button.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+
+                       if(!get_param_tree_view().get_model()->get_iter(path))
+                               break;
+
+                       Gtk::TreeRow row = *(get_param_tree_view().get_model()->get_iter(path));
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+                       if(column && cellrenderer_time_track==column->get_first_cell_renderer())
+                       {
+                               Gdk::Rectangle rect;
+                               get_param_tree_view().get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               get_param_tree_view().queue_draw();
+                               get_param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+
+                       }
+#endif // TIMETRACK_IN_PARAMS_PANEL
+               }
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+// void
+// LayerTree::on_raise_pressed()
+// {
+//     synfigapp::Action::ParamList param_list;
+//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+//     {
+//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+//             synfigapp::SelectionManager::LayerList::iterator iter;
+//
+//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+//                     param_list.add("layer",Layer::Handle(*iter));
+//     }
+//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerRaise"));
+//     action->set_param_list(param_list);
+//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_lower_pressed()
+// {
+//     synfigapp::Action::ParamList param_list;
+//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+//     {
+//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+//             synfigapp::SelectionManager::LayerList::iterator iter;
+//
+//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+//                     param_list.add("layer",Layer::Handle(*iter));
+//     }
+//
+//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerLower"));
+//     action->set_param_list(param_list);
+//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_duplicate_pressed()
+// {
+//     synfigapp::Action::ParamList param_list;
+//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+//     {
+//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+//             synfigapp::SelectionManager::LayerList::iterator iter;
+//
+//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+//                     param_list.add("layer",Layer::Handle(*iter));
+//     }
+//
+//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerDuplicate"));
+//     action->set_param_list(param_list);
+//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_encapsulate_pressed()
+// {
+//     synfigapp::Action::ParamList param_list;
+//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+//     {
+//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+//             synfigapp::SelectionManager::LayerList::iterator iter;
+//
+//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+//                     param_list.add("layer",Layer::Handle(*iter));
+//     }
+//
+//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerEncapsulate"));
+//     action->set_param_list(param_list);
+//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+// void
+// LayerTree::on_delete_pressed()
+// {
+//     synfigapp::Action::ParamList param_list;
+//     param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+//     param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+//     param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+//
+//     {
+//             synfigapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+//             synfigapp::SelectionManager::LayerList::iterator iter;
+//
+//             for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+//                     param_list.add("layer",Layer::Handle(*iter));
+//     }
+//
+//     synfigapp::Action::Handle action(synfigapp::Action::create("LayerRemove"));
+//     action->set_param_list(param_list);
+//     layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+// }
+
+/*
+void
+LayerTree::on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&context, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+       synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+       synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+       synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       Gtk::TreeModel::Path path;
+       Gtk::TreeViewColumn *column;
+       int cell_x, cell_y;
+       if(get_selection()
+       Gtk::TreeRow row = *(get_selection()->get_selected());
+
+       if(synfig::String(gdk_atom_name(selection_data->target))=="LAYER" && (bool)row[model.is_layer])
+       {
+               Layer* layer(((Layer::Handle)row[model.layer]).get());
+               assert(layer);
+               selection_data.set(8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+               return;
+       }
+}
+
+void
+LayerTree::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+       synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+       synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+       synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       synfig::info("Dropped x=%d, y=%d",x,y);
+       bool success=false;
+       bool dropped_on_specific_row=false;
+
+       Gtk::TreeModel::Path path;
+       Gtk::TreeViewColumn *column;
+       int cell_x, cell_y;
+       if(!get_path_at_pos(
+               x,y,    // x, y
+               path, // TreeModel::Path&
+               column, //TreeViewColumn*&
+               cell_x,cell_y //int&cell_x,int&cell_y
+               )
+       )
+       {
+               dropped_on_specific_row=false;
+       }
+       else
+               dropped_on_specific_row=true;
+
+       Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               if(synfig::String(selection_data.get_data_type())=="LAYER")do
+               {
+                       Layer::Handle src(*reinterpret_cast<Layer**>(selection_data.get_data()));
+                       assert(src);
+
+                       Canvas::Handle dest_canvas;
+                       Layer::Handle dest_layer;
+
+                       if(dropped_on_specific_row)
+                       {
+                               dest_canvas=(Canvas::Handle)(row[model.canvas]);
+                               dest_layer=(Layer::Handle)(row[model.layer]);
+                               assert(dest_canvas);
+                       }
+                       else
+                               dest_canvas=layer_tree_store_->canvas_interface()->get_canvas();
+
+                       // In this case, we are just moving.
+                       if(dest_canvas==src->get_canvas())
+                       {
+                               if(!dest_layer || dest_layer==src)
+                                       break;
+
+                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",layer_tree_store_->canvas_interface());
+                               action->set_param("layer",src);
+                               action->set_param("new_index",dest_canvas->get_depth(dest_layer));
+                               if(layer_tree_store_->canvas_interface()->get_instance()->perform_action(action))
+                                       success=true;
+                               else
+                                       success=false;
+                               break;
+                       }
+               }while(0);
+       }
+
+       // Finish the drag
+       context->drag_finish(success, false, time);
+}
+*/
+
+/*bool
+LayerTree::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,int x, int    y, guint    time)
+{
+       return get_layer_tree_view().on_drag_motion(context,x,y,time);
+}
+
+void
+LayerTree::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+       get_layer_tree_view().on_drag_data_received(context,x,y,selection_data,info,time);
+*/
+/*
+       if(context->gobj()->source_window==context->gobj()->dest_window)
+       {
+               Gtk::TreeView::on_drag_data_received(context,x,y,selection_data,info,time);
+               return;
+       }
+
+       Gtk::TreeModel::Path path;
+       Gtk::TreeViewColumn *column;
+       int cell_x, cell_y;
+       if(!get_path_at_pos(
+               x,y,    // x, y
+               path, // TreeModel::Path&
+               column, //TreeViewColumn*&
+               cell_x,cell_y //int&cell_x,int&cell_y
+               )
+       )
+       {
+               context->drag_finish(false, false, time);
+       }
+
+       if(layer_tree_store_->row_drop_possible(path,selection_data))
+       {
+               if(layer_tree_store_->drag_data_received(path,selection_data))
+                       context->drag_finish(true, false, time);
+       }
+       context->drag_finish(false, false, time);
+}
+*/
diff --git a/synfig-studio/src/gui/trees/layertree.h b/synfig-studio/src/gui/trees/layertree.h
new file mode 100644 (file)
index 0000000..cf06899
--- /dev/null
@@ -0,0 +1,261 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layertree.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERTREE_H
+#define __SYNFIG_STUDIO_LAYERTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/box.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/button.h>
+
+#include <synfigapp/canvasinterface.h>
+#include <synfigapp/value_desc.h>
+#include "layertreestore.h"
+#include "layerparamtreestore.h"
+#include <synfig/valuenode_animated.h>
+
+#include "widgets/widget_value.h"
+
+/* === M A C R O S ========================================================= */
+
+// comment this out if you don't want the params dialog to have a 'timetrack' column
+// (alternatively, export SYNFIG_DISABLE_PARAMS_PANEL_TIMETRACK=1 in environment at runtime)
+#define TIMETRACK_IN_PARAMS_PANEL
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class TreeModelSort; };
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+class LayerTree : public Gtk::Table
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       typedef studio::ColumnID ColumnID;
+/*     enum ColumnID
+       {
+               COLUMNID_NAME,
+               COLUMNID_VALUE,
+               COLUMNID_TIME_TRACK,
+
+               COLUMNID_END                    //!< \internal
+       };
+*/
+       typedef std::list<synfig::Layer::Handle> LayerList;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       //LayerTreeStore::Model model;
+
+       LayerTreeStore::Model layer_model;
+       LayerParamTreeStore::Model param_model;
+
+       synfig::Layer::Handle last_top_selected_layer;
+       Gtk::TreePath last_top_selected_path;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Gtk::Tooltips tooltips_;
+       Gtk::TreePath last_tooltip_path;
+
+       Gtk::TreeView* layer_tree_view_;
+
+       Gtk::TreeView* param_tree_view_;
+
+       Gtk::HBox *hbox;
+
+       Gtk::Adjustment layer_amount_adjustment_;
+
+       Gtk::HScale *layer_amount_hscale;
+
+       synfig::Layer::Handle quick_layer;
+
+       Glib::RefPtr<LayerTreeStore> layer_tree_store_;
+
+       Glib::RefPtr<LayerParamTreeStore> param_tree_store_;
+
+       Glib::RefPtr<Gtk::TreeModelSort> sorted_layer_tree_store_;
+
+#ifdef TIMETRACK_IN_PARAMS_PANEL
+       CellRenderer_TimeTrack *cellrenderer_time_track;
+#endif // TIMETRACK_IN_PARAMS_PANEL
+
+       Gtk::TreeView::Column* column_time_track;
+
+       Gtk::TreeView::Column* column_z_depth;
+
+       CellRenderer_ValueBase *cellrenderer_value;
+
+       sigc::signal<void,synfig::Layer::Handle> signal_layer_toggle_;
+
+       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase> signal_edited_value_;
+
+       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_layer_user_click_;
+
+       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_param_user_click_;
+
+       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int> signal_waypoint_clicked_layertree_;
+
+       bool disable_amount_changed_signal;
+
+       Gtk::Button *button_raise;
+       Gtk::Button *button_lower;
+       Gtk::Button *button_duplicate;
+       Gtk::Button *button_encapsulate;
+       Gtk::Button *button_delete;
+
+       Widget_ValueBase blend_method_widget;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       Gtk::Widget* create_layer_tree();
+       Gtk::Widget* create_param_tree();
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_edited_value(const Glib::ustring&path_string,synfig::ValueBase value);
+
+       void on_layer_renamed(const Glib::ustring&path_string,const Glib::ustring& value);
+
+       void on_layer_toggle(const Glib::ustring& path_string);
+
+       void on_waypoint_clicked_layertree(const etl::handle<synfig::Node>& node, const synfig::Time&, const synfig::Time&, int button);
+
+       void on_waypoint_changed( synfig::Waypoint waypoint , synfig::ValueNode::Handle value_node);
+
+       bool on_layer_tree_event(GdkEvent *event);
+
+       bool on_param_tree_event(GdkEvent *event);
+
+       void on_selection_changed();
+
+       void on_dirty_preview();
+
+       void on_amount_value_changed();
+
+       void on_blend_method_changed();
+
+public:
+
+       // void on_raise_pressed();
+
+       // void on_lower_pressed();
+
+       // void on_duplicate_pressed();
+
+       // void on_encapsulate_pressed();
+
+       // void on_delete_pressed();
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       //Gtk::TreeView* get_param_tree_view() { return param_tree_view_; }
+       //Gtk::TreeView& param_tree_view() { return *param_tree_view_; }
+       Gtk::HBox& get_hbox() { return *hbox; }
+
+       Gtk::TreeView& get_layer_tree_view() { return *layer_tree_view_; }
+       Gtk::TreeView& get_param_tree_view() { return *param_tree_view_; }
+
+       const Gtk::TreeView& get_layer_tree_view()const { return *layer_tree_view_; }
+       const Gtk::TreeView& get_param_tree_view()const { return *param_tree_view_; }
+
+       Glib::RefPtr<Gtk::TreeSelection> get_selection() { return get_layer_tree_view().get_selection(); }
+       Glib::SignalProxy1< bool,GdkEvent* >  signal_event () { return get_layer_tree_view().signal_event(); }
+
+       LayerTree();
+       ~LayerTree();
+
+       void set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store_);
+
+       void set_time_adjustment(Gtk::Adjustment &adjustment);
+
+       void set_show_timetrack(bool x=true);
+
+       //! Signal called when layer is toggled.
+       sigc::signal<void,synfig::Layer::Handle>& signal_layer_toggle() { return signal_layer_toggle_; }
+
+       //! Signal called with a value has been edited.
+       sigc::signal<void,synfigapp::ValueDesc,synfig::ValueBase>& signal_edited_value() { return signal_edited_value_; }
+
+       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_layer_user_click() { return signal_layer_user_click_; }
+
+       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_param_user_click() { return signal_param_user_click_; }
+
+       sigc::signal<void,synfigapp::ValueDesc,std::set<synfig::Waypoint,std::less<synfig::UniqueID> >,int>& signal_waypoint_clicked_layertree() { return signal_waypoint_clicked_layertree_; }
+
+       etl::handle<synfigapp::SelectionManager> get_selection_manager() { return layer_tree_store_->canvas_interface()->get_selection_manager(); }
+
+       void select_layer(synfig::Layer::Handle layer);
+       void select_layers(const LayerList& layer_list);
+       void select_all_children_layers(synfig::Layer::Handle layer);
+       void select_all_children(Gtk::TreeModel::Children::iterator iter);
+       LayerList get_selected_layers()const;
+       synfig::Layer::Handle get_selected_layer()const;
+       void clear_selected_layers();
+
+}; // END of LayerTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/layertreestore.cpp b/synfig-studio/src/gui/trees/layertreestore.cpp
new file mode 100644 (file)
index 0000000..16b7fc8
--- /dev/null
@@ -0,0 +1,1081 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layertreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layertreestore.h"
+#include "iconcontroller.h"
+#include <gtkmm/button.h>
+#include <synfig/paramdesc.h>
+#include <synfigapp/action.h>
+#include <synfigapp/instance.h>
+#include "app.h"
+#include "instance.h"
+#include <synfig/layer_pastecanvas.h>
+#include <synfigapp/action_system.h>
+
+#include <gtk/gtkversion.h>
+#include <ETL/clock>
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerTreeStore::Model& ModelHack()
+{
+       static LayerTreeStore::Model* model(0);
+       if(!model)model=new LayerTreeStore::Model;
+       return *model;
+}
+
+LayerTreeStore::LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore                  (ModelHack()),
+       queued                                  (false),
+       canvas_interface_               (canvas_interface_)
+{
+       layer_icon=Gtk::Button().render_icon(Gtk::StockID("synfig-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       // Connect Signals to Terminals
+       canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_status_changed));
+       canvas_interface()->signal_layer_lowered().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_lowered));
+       canvas_interface()->signal_layer_raised().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_raised));
+       canvas_interface()->signal_layer_removed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_removed));
+       canvas_interface()->signal_layer_inserted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_inserted));
+       canvas_interface()->signal_layer_moved().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_moved));
+       //canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_param_changed));
+       canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_new_description));
+
+       canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::refresh));
+
+       //canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_changed));
+       //canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_added));
+       //canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_deleted));
+       //canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_replaced));
+
+       set_default_sort_func(sigc::ptr_fun(index_sorter));
+
+//     rebuild();
+}
+
+LayerTreeStore::~LayerTreeStore()
+{
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("LayerTreeStore::~LayerTreeStore(): Deleted");
+}
+
+int
+LayerTreeStore::z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+       const Model model;
+
+       float diff((float)(*rhs)[model.z_depth]-(float)(*lhs)[model.z_depth]);
+
+       if(diff<0)
+               return -1;
+       if(diff>0)
+               return 1;
+       return 0;
+}
+
+int
+LayerTreeStore::index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+       const Model model;
+
+       return ((int)(*rhs)[model.index]-(int)(*lhs)[model.index]);
+}
+
+bool
+LayerTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
+{
+       const Model model;
+
+       Glib::ustring substr(x.uppercase());
+       Glib::ustring label((*iter)[model.label]);
+       label=label.uppercase();
+
+       return label.find(substr)==Glib::ustring::npos;
+}
+
+
+Glib::RefPtr<LayerTreeStore>
+LayerTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<LayerTreeStore>(new LayerTreeStore(canvas_interface_));
+}
+
+void
+LayerTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column==model.index.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<int> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(layer->get_depth());
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else if(column==model.z_depth.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<float> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(layer->get_z_depth(canvas_interface()->get_time())*1.0001+layer->get_depth());
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else if(column==model.children_lock.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(false);
+
+               ValueBase v(layer->get_param("children_lock"));
+               if(v.same_type_as(bool()))
+                       x.set(v.get(bool()));
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else if(column==model.label.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(layer->get_non_empty_description());
+
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else if(column==model.tooltip.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_local_name());
+
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else if(column==model.canvas.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Canvas::Handle> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_canvas());
+
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else if(column==model.active.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(layer->active());
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else if(column==model.icon.index())
+       {
+               synfig::Layer::Handle layer((*iter)[model.layer]);
+               if(!layer)return;
+
+               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+               g_value_init(x.gobj(),x.value_type());
+
+               //x.set(layer_icon);
+               x.set(get_tree_pixbuf_layer(layer->get_name()));
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+LayerTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       //if(!iterator_sane(row))
+       //      return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.label.index())
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),model.label.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       synfig::Layer::Handle layer((*iter)[model.layer]);
+                       if(!layer)
+                               return;
+                       synfig::String new_desc(x.get());
+
+                       if(new_desc==layer->get_local_name())
+                               new_desc=synfig::String();
+
+                       if(new_desc==layer->get_description())
+                               return;
+
+                       synfigapp::Action::Handle action(synfigapp::Action::create("LayerSetDesc"));
+
+                       if(!action)
+                               return;
+
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("layer",layer);
+                       action->set_param("new_description",synfig::String(x.get()));
+
+                       canvas_interface()->get_instance()->perform_action(action);
+                       return;
+               }
+               else if(column==model.active.index())
+               {
+                       synfig::Layer::Handle layer((*iter)[model.layer]);
+
+                       if(!layer)return;
+
+                       Glib::Value<bool> x;
+                       g_value_init(x.gobj(),model.active.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       synfigapp::Action::Handle action(synfigapp::Action::create("LayerActivate"));
+
+                       if(!action)
+                               return;
+
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("layer",layer);
+                       action->set_param("new_status",bool(x.get()));
+
+                       canvas_interface()->get_instance()->perform_action(action);
+                       return;
+               }
+               else
+                       Gtk::TreeStore::set_value_impl(iter,column, value);
+
+       }
+       catch(std::exception x)
+       {
+               g_warning("%s", x.what());
+       }
+}
+
+
+
+
+bool
+LayerTreeStore::row_draggable_vfunc (const TreeModel::Path& /*path*/)const
+{
+       //if(!get_iter(path)) return false;
+//     Gtk::TreeModel::Row row(*get_iter(path));
+
+       return true;
+//     return (bool)true;
+}
+
+bool
+LayerTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
+{
+       if(!const_cast<LayerTreeStore*>(this)->get_iter(path)) return false;
+       //synfig::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+       //synfig::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //synfig::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       Gtk::TreeModel::Row row(*const_cast<LayerTreeStore*>(this)->get_iter(path));
+
+       if((bool)true)
+       {
+               Layer* layer(((Layer::Handle)row[model.layer]).get());
+               assert(layer);
+               bool included(false);
+
+               //gtk_selection_data_set (selection_data, gdk_atom_intern("LAYER",false), 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+
+               std::vector<Layer*> layers;
+               // The following is a hack for multiple row DND
+               {
+                       synfigapp::SelectionManager::LayerList bleh(get_canvas_interface()->get_selection_manager()->get_selected_layers());
+                       if(bleh.empty())
+                       {
+                               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+                               return true;
+                       }
+                       while(!bleh.empty())
+                       {
+                               if(bleh.back().get()==layer)
+                                       included=true;
+                               layers.push_back(bleh.back().get());
+                               bleh.pop_back();
+                       }
+               }
+               if(!included)
+                       layers.push_back(layer);
+               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
+
+               return true;
+       }
+       return false;
+}
+
+bool
+LayerTreeStore::drag_data_delete_vfunc (const TreeModel::Path& /*path*/)
+{
+       return true;
+}
+
+bool
+LayerTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
+{
+       //if(!const_cast<LayerTreeStore*>(this)->get_iter(dest)) return false;
+
+       //synfig::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
+       //synfig::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //synfig::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       //Gtk::TreeModel::Row row(*get_iter(dest));
+
+       if(synfig::String(selection_data.get_data_type())=="LAYER" && (bool)true)
+       {
+               //Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+               //assert(src);
+
+               //return true;
+               TreeModel::Path dest_parent(dest);
+               if(!dest_parent.up() || dest.get_depth()==1)
+               {
+                       //row=(*get_iter(dest));
+                       //dest_canvas=(Canvas::Handle)(row[model.canvas]);
+                       return true;
+               }
+               else if((bool)const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))
+                       return (bool)(Canvas::Handle)(*const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))[model.contained_canvas];
+       }
+       return false;
+}
+
+bool
+LayerTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
+{
+
+       //if(!dest_parent.up() || !get_iter(dest)) return false;
+
+       bool ret=false;
+       int i(0);
+
+
+       //synfig::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+       //synfig::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //synfig::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       synfigapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Move Layers"));
+
+       // Save the selection data
+       synfigapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Gtk::TreeModel::Row row;
+               Canvas::Handle dest_canvas;
+
+               int dest_layer_depth=dest.back();
+
+               TreeModel::Path dest_parent(dest);
+               if(!dest_parent.up() || !get_iter(dest_parent))
+               {
+                       TreeModel::Path dest_(dest);
+                       if(!get_iter(dest_))
+                               dest_.prev();
+
+                       if(!get_iter(dest_))
+                               return false;
+
+                       {
+                               row=(*get_iter(dest_));
+                               dest_canvas=(Canvas::Handle)(row[model.canvas]);
+                       }
+               }
+               else
+               {
+                       row=(*get_iter(dest_parent));
+                       dest_canvas=row[model.contained_canvas];
+               }
+
+               assert(dest_canvas);
+
+               Layer::Handle dest_layer(row[model.layer]);
+
+               if(synfig::String(selection_data.get_data_type())=="LAYER")for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
+               {
+                       //synfig::info("dest_layer_depth=%d",dest_layer_depth);
+
+                       Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+                       assert(src);
+                       if(dest_layer==src)
+                               continue;
+
+                       if(dest_canvas==src->get_canvas() && src->get_depth()<dest_layer_depth)
+                               dest_layer_depth--;
+
+                       // In this case, we are just moving.
+//                     if(dest_canvas==src->get_canvas())
+                       {
+                               //if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
+                               //      dest_layer_depth--;
+                               if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
+                                       continue;
+
+                               synfigapp::Action::Handle action(synfigapp::Action::create("LayerMove"));
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",src);
+                               action->set_param("new_index",dest_layer_depth);
+                               action->set_param("dest_canvas",dest_canvas);
+                               if(canvas_interface()->get_instance()->perform_action(action))
+                                       ret=true;
+                               else
+                               {
+                                       passive_grouper.cancel();
+                                       return false;
+                               }
+                               continue;
+                       }
+                       /*else // In this case we need to remove and then add
+                       {
+
+                               synfigapp::Action::Handle action;
+                               action=synfigapp::Action::create("LayerRemove");
+                               action->set_param("canvas",Canvas::Handle(src->get_canvas()));
+                               if(!action->set_param("canvas_interface",App::get_instance(src->get_canvas())->find_canvas_interface(src->get_canvas())))
+                                       action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",src);
+                               if(!canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       passive_grouper.cancel();
+                                       ret=false;
+                                       return false;
+                               }
+
+                               action=synfigapp::Action::create("LayerAdd");
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("new",src);
+                               if(!canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       passive_grouper.cancel();
+                                       ret=false;
+                                       return false;
+                               }
+
+                               if(dest_layer_depth!=0)
+                               {
+                                       action=synfigapp::Action::create("LayerMove");
+                                       action->set_param("canvas",dest_canvas);
+                                       action->set_param("canvas_interface",canvas_interface());
+                                       action->set_param("layer",src);
+                                       action->set_param("new_index",dest_layer_depth);
+                                       if(!canvas_interface()->get_instance()->perform_action(action))
+                                       {
+                                               passive_grouper.cancel();
+                                               ret=false;
+                                               return false;
+                                       }
+                               }
+                               ret=true;
+                       }
+                       */
+               }
+       }
+       synfig::info("I supposedly moved %d layers",i);
+
+       // Reselect the previously selected layers
+       canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
+
+       return ret;
+}
+
+void
+LayerTreeStore::queue_rebuild()
+{
+       if (queued) return;
+       queued = false;
+       queue_connection.disconnect();
+       queue_connection=Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&LayerTreeStore::rebuild),
+                       false
+               )
+       ,150);
+}
+
+void
+LayerTreeStore::rebuild()
+{
+       if (queued) queued = false;
+
+       // disconnect any subcanvas_changed connections
+       std::map<synfig::Layer::Handle, sigc::connection>::iterator iter;
+       for (iter = subcanvas_changed_connections.begin(); iter != subcanvas_changed_connections.end(); iter++)
+               iter->second.disconnect();
+       subcanvas_changed_connections.clear();
+
+       //etl::clock timer;timer.reset();
+
+       //synfig::warning("---------rebuilding layer table---------");
+       // Save the selection data
+       synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+       // Clear out the current list
+       clear();
+
+       // Go ahead and add all the layers
+       std::for_each(
+               canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
+               sigc::mem_fun(*this, &studio::LayerTreeStore::on_layer_added)
+       );
+
+       // Reselect the previously selected layers
+       if(!layer_list.empty())
+               canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
+
+       //synfig::info("LayerTreeStore::rebuild() took %f seconds",float(timer()));
+}
+
+void
+LayerTreeStore::refresh()
+{
+       etl::clock timer;timer.reset();
+
+       Gtk::TreeModel::Children children_(children());
+
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children_.empty())
+               for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+       //synfig::info("LayerTreeStore::refresh() took %f seconds",float(timer()));
+}
+
+void
+LayerTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+       Layer::Handle layer=row[model.layer];
+       /*
+       {
+               row[model.name] = layer->get_local_name();
+               if(layer->get_description().empty())
+               {
+                       row[model.label] = layer->get_local_name();
+                       row[model.tooltip] = Glib::ustring("Layer");
+               }
+               else
+               {
+                       row[model.label] = layer->get_description();
+                       row[model.tooltip] = layer->get_local_name();
+               }
+       }
+       */
+
+       if(layer->dynamic_param_list().count("z_depth"))
+               row[model.z_depth]=Time::begin();
+       //      row_changed(get_path(row),row);
+
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+               for(iter = children.begin(); iter && iter != children.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+}
+
+
+void
+LayerTreeStore::set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle)
+{
+       //row[model.id] = handle->get_name();
+       //row[model.name] = handle->get_local_name();
+       /*if(handle->get_description().empty())
+       {
+               //row[model.label] = handle->get_local_name();
+               row[model.tooltip] = Glib::ustring("Layer");
+       }
+       else
+       {
+               //row[model.label] = handle->get_description();
+               row[model.tooltip] = handle->get_local_name();
+       }*/
+
+       //row[model.active] = handle->active();
+       row[model.layer] = handle;
+       //row[model.canvas] = handle->get_canvas();
+       //row[model.icon] = layer_icon;
+
+       synfig::Layer::ParamList paramlist=handle->get_param_list();
+
+       synfig::Layer::Vocab vocab=handle->get_param_vocab();
+       synfig::Layer::Vocab::iterator iter;
+
+       for(iter=vocab.begin();iter!=vocab.end();++iter)
+       {
+               if(iter->get_hidden())
+                       continue;
+               if(handle->get_param(iter->get_name()).get_type()!=ValueBase::TYPE_CANVAS)
+                       continue;
+
+               {
+                       Canvas::Handle canvas;
+                       canvas=handle->get_param(iter->get_name()).get(canvas);
+                       if(!canvas)
+                               continue;
+
+                       Canvas::reverse_iterator iter;
+                       row[model.contained_canvas]=canvas;
+
+                       for(iter=canvas->rbegin();iter!=canvas->rend();++iter)
+                       {
+                               Gtk::TreeRow row_(*(prepend(row.children())));
+                               set_row_layer(row_,*iter);
+                       }
+                       continue;
+               }
+
+               /*
+               etl::handle<ValueNode> value_node;
+               if(handle.constant()->dynamic_param_list().count(iter->get_name()))
+                       value_node=handle->dynamic_param_list()[iter->get_name()];
+
+               Gtk::TreeRow child_row = *(append(row.children()));
+               set_row_param(
+                       child_row,
+                       handle,
+                       iter->get_name(),
+                       iter->get_local_name(),
+                       paramlist[iter->get_name()],
+                       value_node,
+                       &*iter
+               );
+               */
+       }
+}
+
+void
+LayerTreeStore::on_layer_added(synfig::Layer::Handle layer)
+{
+       if (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))
+               subcanvas_changed_connections[layer] =
+                       (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))->signal_subcanvas_changed().connect(
+                               sigc::mem_fun(*this,&studio::LayerTreeStore::queue_rebuild)
+                       );
+
+       assert(layer);
+       Gtk::TreeRow row;
+       if(canvas_interface()->get_canvas()==layer->get_canvas())
+       {
+               row=*(prepend());
+       }
+       else
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(!find_canvas_row(layer->get_canvas(),iter))
+               {
+                       rebuild();
+                       return;
+               }
+               row=*(prepend(iter->children()));
+       }
+       set_row_layer(row,layer);
+}
+
+void
+LayerTreeStore::on_layer_removed(synfig::Layer::Handle handle)
+{
+       if (etl::handle<Layer_PasteCanvas>::cast_dynamic(handle))
+       {
+               subcanvas_changed_connections[handle].disconnect();
+               subcanvas_changed_connections.erase(handle);
+       }
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+               erase(iter);
+       else
+       {
+               synfig::error("LayerTreeStore::on_layer_removed():Unable to find layer to be removed, forced to rebuild...");
+               rebuild();
+       }
+}
+
+void
+LayerTreeStore::on_layer_inserted(synfig::Layer::Handle handle,int depth)
+{
+       if(depth==0)
+       {
+               on_layer_added(handle);
+               return;
+       }
+
+       Gtk::TreeModel::Children children_(children());
+       if(canvas_interface()->get_canvas()!=handle->get_canvas())
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(!find_canvas_row(handle->get_canvas(),iter))
+               {
+                       synfig::error("LayerTreeStore::on_layer_inserted():Unable to find canvas row, forced to rebuild...");
+                       rebuild();
+                       return;
+               }
+               children_=iter->children();
+       }
+
+       Gtk::TreeModel::Children::iterator iter(children_.begin());
+       while(depth-- && iter)
+       {
+               ++iter;
+               if(!iter || iter==children_.end())
+               {
+                       synfig::error("LayerTreeStore::on_layer_inserted():Unable to achieve desired depth, forced to rebuild...");
+                       rebuild();
+                       return;
+               }
+       }
+
+       Gtk::TreeModel::Row row(*insert(iter));
+       set_row_layer(row,handle);
+}
+
+void
+LayerTreeStore::on_layer_status_changed(synfig::Layer::Handle handle,bool /*x*/)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+               (*iter)[model.layer]=handle;
+       else
+       {
+               synfig::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
+               rebuild();
+       }
+}
+
+void
+LayerTreeStore::on_layer_lowered(synfig::Layer::Handle layer)
+{
+       Gtk::TreeModel::Children::iterator iter, iter2;
+       if(find_layer_row(layer,iter))
+       {
+               // Save the selection data
+               //synfigapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+               iter2=iter;
+               iter2++;
+               if(!iter2)
+               {
+                       rebuild();
+                       return;
+               }
+
+               //Gtk::TreeModel::Row row(*iter);
+               Gtk::TreeModel::Row row2 = *iter2;
+               synfig::Layer::Handle layer2=row2[model.layer];
+
+               erase(iter2);
+               row2=*insert(iter);
+               set_row_layer(row2,layer2);
+
+       }
+       else
+               rebuild();
+}
+
+void
+LayerTreeStore::on_layer_raised(synfig::Layer::Handle layer)
+{
+       Gtk::TreeModel::Children::iterator iter, iter2;
+
+       Gtk::TreeModel::Children children_(children());
+
+       if(find_layer_row_(layer, canvas_interface()->get_canvas(), children_, iter,iter2))
+       {
+               if(iter!=iter2)
+               {
+                       //Gtk::TreeModel::Row row = *iter;
+                       Gtk::TreeModel::Row row2 = *iter2;
+                       synfig::Layer::Handle layer2=row2[model.layer];
+
+                       erase(iter2);
+                       iter++;
+                       row2=*insert(iter);
+                       set_row_layer(row2,layer2);
+
+                       return;
+               }
+       }
+
+       rebuild();
+}
+
+void
+LayerTreeStore::on_layer_moved(synfig::Layer::Handle layer,int depth, synfig::Canvas::Handle /*canvas*/)
+{
+       on_layer_removed(layer);
+       on_layer_inserted(layer,depth);
+}
+
+void
+LayerTreeStore::on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name)
+{
+       if(param_name=="z_depth")
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(find_layer_row(handle,iter))
+               {
+                       (*iter)[model.z_depth]=Time::begin();
+               }
+       }
+
+       /*
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+       {
+               Gtk::TreeModel::Children children(iter->children());
+
+               for(iter = children.begin(); iter && iter != children.end(); ++iter)
+               {
+                       if((Glib::ustring)(*iter)[model.param_name]==param_name)
+                       {
+                               Gtk::TreeRow row=*iter;
+                               refresh_row(row);
+                               return;
+                       }
+               }
+       }
+       rebuild();
+       */
+}
+
+void
+LayerTreeStore::on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+       {
+               Gtk::TreeRow row(*iter);
+
+               Layer::Handle layer(row[model.layer]);
+
+               if(desc.empty())
+               {
+                       //row[model.label]=layer->get_local_name();
+                       row[model.tooltip]=Glib::ustring(_("Layer"));
+               }
+               else
+                       //row[model.label]=layer->get_description();
+                       row[model.tooltip]=layer->get_local_name();
+       }
+       else
+       {
+               rebuild();
+       }
+}
+
+bool
+LayerTreeStore::find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter)
+{
+       if(canvas==parent)
+               return false;
+
+       {
+               for(iter=layers.begin(); iter && iter != layers.end(); ++iter)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if(canvas==(synfig::Canvas::Handle)row[model.contained_canvas])
+                               return true;
+               }
+
+               iter=children().end();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+       //Gtk::TreeModel::Children::iterator iter3;
+
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+
+               if(row.children().empty())
+                       continue;
+
+               Canvas::Handle sub_canvas((*row.children().begin())[model.canvas]);
+               if(!sub_canvas)
+                       continue;
+
+               if(find_canvas_row_(canvas,sub_canvas,iter2->children(),iter))
+                       return true;
+       }
+
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerTreeStore::find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter)
+{
+       return find_canvas_row_(canvas,canvas_interface()->get_canvas(),children(),iter);
+}
+
+
+bool
+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)
+{
+       assert(layer);
+
+       //if(layer->get_canvas()==canvas)
+       {
+               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if(layer==(synfig::Layer::Handle)row[model.layer])
+                               return true;
+               }
+
+               iter=children().end();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+
+               if(row.children().empty())
+                       continue;
+
+               Canvas::Handle canvas((*row.children().begin())[model.canvas]);
+               if(!canvas)
+                       continue;
+
+               if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
+                       return true;
+       }
+
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerTreeStore::find_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
+{
+       Gtk::TreeModel::Children::iterator prev;
+       return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
+}
+
+bool
+LayerTreeStore::find_prev_layer_row(const synfig::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
+               return false;
+       if(iter==children().begin())
+               return false;
+       return true;
+}
diff --git a/synfig-studio/src/gui/trees/layertreestore.h b/synfig-studio/src/gui/trees/layertreestore.h
new file mode 100644 (file)
index 0000000..5b33309
--- /dev/null
@@ -0,0 +1,226 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file layertreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_LAYERTREESTORE_H
+#define __SYNFIG_STUDIO_LAYERTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <synfig/value.h>
+#include <synfig/valuenode.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<Glib::ustring> label;
+               Gtk::TreeModelColumn<Glib::ustring> name;
+               Gtk::TreeModelColumn<Glib::ustring> id;
+
+               Gtk::TreeModelColumn<synfig::Canvas::Handle> canvas;
+
+               Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+
+               Gtk::TreeModelColumn<bool>                                              active;
+               Gtk::TreeModelColumn<synfig::Layer::Handle>             layer;
+               Gtk::TreeModelColumn<synfig::Canvas::Handle>                    contained_canvas;
+
+               Gtk::TreeModelColumn<bool>                                              children_lock;
+
+               Gtk::TreeModelColumn<float> z_depth;
+               Gtk::TreeModelColumn<int> index;
+
+               Model()
+               {
+                       add(icon);
+                       add(label);
+                       add(name);
+                       add(id);
+                       add(canvas);
+                       add(tooltip);
+                       add(active);
+                       add(layer);
+                       add(contained_canvas);
+                       add(z_depth);
+                       add(index);
+                       add(children_lock);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       //! TreeModel for the layers
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       bool queued;
+
+       sigc::connection queue_connection;
+
+       std::map<synfig::Layer::Handle, sigc::connection> subcanvas_changed_connections;
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+       Glib::RefPtr<Gdk::Pixbuf> layer_icon;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+private:
+       virtual void  set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+       virtual bool  row_draggable_vfunc (const TreeModel::Path& path)const;
+       virtual bool  drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
+       virtual bool  drag_data_delete_vfunc (const TreeModel::Path& path);
+       virtual bool  drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
+       virtual bool  row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       bool on_layer_tree_event(GdkEvent *event);
+
+       void on_layer_new_description(synfig::Layer::Handle handle,synfig::String desc);
+
+       void on_layer_added(synfig::Layer::Handle handle);
+
+       void on_layer_removed(synfig::Layer::Handle handle);
+
+       void on_layer_inserted(synfig::Layer::Handle handle,int depth);
+
+       void on_layer_moved(synfig::Layer::Handle handle,int depth, synfig::Canvas::Handle canvas);
+
+       void on_layer_status_changed(synfig::Layer::Handle handle,bool);
+
+       void on_layer_lowered(synfig::Layer::Handle handle);
+
+       void on_layer_raised(synfig::Layer::Handle handle);
+
+       void on_layer_param_changed(synfig::Layer::Handle handle,synfig::String param_name);
+
+       //void on_value_node_added(synfig::ValueNode::Handle value_node);
+
+       //void on_value_node_deleted(synfig::ValueNode::Handle value_node);
+
+       //void on_value_node_changed(synfig::ValueNode::Handle value_node);
+
+       //void on_value_node_replaced(synfig::ValueNode::Handle replaced_value_node,synfig::ValueNode::Handle new_value_node);
+
+       bool find_layer_row_(const synfig::Layer::Handle &handle, synfig::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+       bool find_canvas_row_(synfig::Canvas::Handle canvas, synfig::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       LayerTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+       ~LayerTreeStore();
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const synfigapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       bool find_canvas_row(synfig::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_prev_layer_row(const synfig::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       void queue_rebuild();
+
+       void rebuild();
+
+       void refresh();
+
+       void refresh_row(Gtk::TreeModel::Row &row);
+
+       void set_row_layer(Gtk::TreeRow &row,synfig::Layer::Handle &handle);
+
+       static int z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+       static int index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+
+       //void set_row_param(Gtk::TreeRow &row,synfig::Layer::Handle &handle,const std::string& name, const std::string& local_name, const synfig::ValueBase &value, etl::handle<synfig::ValueNode> value_node,synfig::ParamDesc *param_desc);
+
+       //virtual void set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc);
+       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<LayerTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_);
+
+
+}; // END of class LayerTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/src/gui/trees/metadatatreestore.cpp b/synfig-studio/src/gui/trees/metadatatreestore.cpp
new file mode 100644 (file)
index 0000000..98bb7c6
--- /dev/null
@@ -0,0 +1,152 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file metadatatreestore.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2008 Chris Moore
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "metadatatreestore.h"
+#include <synfigapp/canvasinterface.h>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static MetaDataTreeStore::Model& ModelHack()
+{
+       static MetaDataTreeStore::Model* model(0);
+       if(!model)model=new MetaDataTreeStore::Model;
+       return *model;
+}
+
+MetaDataTreeStore::MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore  (ModelHack()),
+       canvas_interface_               (canvas_interface_)
+{
+       // Connect the signal
+       get_canvas()->signal_meta_data_changed().connect(sigc::mem_fun(*this,&MetaDataTreeStore::meta_data_changed));
+
+       rebuild();
+}
+
+MetaDataTreeStore::~MetaDataTreeStore()
+{
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("MetaDataTreeStore::~MetaDataTreeStore(): Deleted");
+}
+
+Glib::RefPtr<MetaDataTreeStore>
+MetaDataTreeStore::create(etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<MetaDataTreeStore>(new MetaDataTreeStore(canvas_interface_));
+}
+
+void
+MetaDataTreeStore::meta_data_changed(synfig::String /*key*/)
+{
+       rebuild();
+}
+
+void
+MetaDataTreeStore::rebuild()
+{
+       clear();
+
+       std::list<String> keys(get_canvas()->get_meta_data_keys());
+
+       for(;!keys.empty();keys.pop_front())
+       {
+               Gtk::TreeRow row(*append());
+               row[model.key]=keys.front();
+       }
+}
+
+void
+MetaDataTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(column==model.data.index())
+       {
+               synfig::String key((Glib::ustring)(*iter)[model.key]);
+               g_value_init(value.gobj(),G_TYPE_STRING);
+               g_value_set_string(value.gobj(),get_canvas()->get_meta_data(key).c_str());
+               return;
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+MetaDataTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("MetaDataTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("MetaDataTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       if(column==model.data.index())
+       {
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),model.data.type());
+               g_value_copy(value.gobj(),x.gobj());
+
+               synfig::String key((Glib::ustring)(*iter)[model.key]);
+               synfig::String new_data(x.get());
+
+               get_canvas_interface()->set_meta_data(key,new_data);
+       }
+       else
+               Gtk::TreeStore::set_value_impl(iter,column, value);
+}
diff --git a/synfig-studio/src/gui/trees/metadatatreestore.h b/synfig-studio/src/gui/trees/metadatatreestore.h
new file mode 100644 (file)
index 0000000..6ad41d4
--- /dev/null
@@ -0,0 +1,133 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file metadatatreestore.h
+**     \brief Template Header
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
+**
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SYNFIG_STUDIO_METADATATREESTORE_H
+#define __SYNFIG_STUDIO_METADATATREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <synfigapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <synfigapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace synfigapp { class CanvasInterface; }
+
+namespace studio {
+
+class MetaDataTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+       public:
+               Gtk::TreeModelColumn<Glib::ustring> key;
+               Gtk::TreeModelColumn<Glib::ustring> data;
+
+               Model()
+               {
+                       add(key);
+                       add(data);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<synfigapp::CanvasInterface> canvas_interface_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void meta_data_changed(synfig::String key);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       ~MetaDataTreeStore();
+
+       etl::loose_handle<synfigapp::CanvasInterface> get_canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const synfigapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+       synfig::Canvas::Handle get_canvas()const { return canvas_interface_->get_canvas(); }
+       synfig::Canvas::Handle get_canvas() { return canvas_interface_->get_canvas(); }
+
+       void rebuild();
+
+       void refresh() { rebuild(); }
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+protected:
+       MetaDataTreeStore(etl::loose_handle<synfigapp::CanvasInterface>);
+       void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+       void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
+
+public:
+
+       static Glib::RefPtr<MetaDataTreeStore> create(etl::loose_handle<synfigapp::CanvasInterface>);
+
+}; // END of class MetaDataTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif