Convert static lists entirely consisting of blinepoints into 'bline' valuenodes,...
[synfig.git] / synfig-studio / trunk / src / synfigapp / canvasinterface.cpp
index 31f36ee..c062522 100644 (file)
@@ -6,7 +6,7 @@
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-**     Copyright (c) 2007 Chris Moore
+**     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
@@ -91,7 +91,8 @@ CanvasInterface::CanvasInterface(etl::loose_handle<Instance> instance,etl::handl
 
 CanvasInterface::~CanvasInterface()
 {
-       synfig::info("synfigapp::CanvasInterface::~CanvasInterface(): Deleted");
+       if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
+               synfig::info("CanvasInterface::~CanvasInterface(): Deleted");
 }
 
 void
@@ -227,15 +228,39 @@ CanvasInterface::add_layer_to(synfig::String name, synfig::Canvas::Handle canvas
                // Grab the layer's list of parameters
                Layer::ParamList paramlist=layer->get_param_list();
                Layer::ParamList::iterator iter;
+
+               // loop through the static parameters
                for(iter=paramlist.begin();iter!=paramlist.end();++iter)
                {
                        ValueNode::Handle value_node;
 
+                       // if we find any which are list values then make them
+                       // into dynamic list valuenodes, unless every element of
+                       // the list is a blinepoint, in which case convert it to a
+                       // bline
                        if(iter->second.get_type()==ValueBase::TYPE_LIST)
-                               value_node=LinkableValueNode::create("dynamic_list",iter->second);
+                       {
+                               // check whether it's a list of blinepoints only
+                               vector<ValueBase> list(iter->second.get_list());
+                               if (list.size())
+                               {
+                                       vector<ValueBase>::iterator iter2;
+                                       for (iter2 = list.begin(); iter2 != list.end(); iter2++)
+                                               if (iter2->get_type() != ValueBase::TYPE_BLINEPOINT)
+                                                       break;
+                                       if (iter2 == list.end())
+                                               value_node=LinkableValueNode::create("bline",iter->second);
+                               }
+
+                               if (!value_node)
+                                       value_node=LinkableValueNode::create("dynamic_list",iter->second);
+                       }
+                       // otherwise, if it's a type that can be converted to
+                       // 'composite' (other than the types that can be radial
+                       // composite) then do so
                        else if(LinkableValueNode::check_type("composite",iter->second.get_type()) &&
-                               (iter->second.get_type()!=ValueBase::TYPE_COLOR && iter->second.get_type()!=ValueBase::TYPE_VECTOR)
-                       )
+                                        (iter->second.get_type()!=ValueBase::TYPE_COLOR &&
+                                         iter->second.get_type()!=ValueBase::TYPE_VECTOR))
                                value_node=LinkableValueNode::create("composite",iter->second);
 
                        if(value_node)
@@ -266,7 +291,8 @@ CanvasInterface::add_layer_to(synfig::String name, synfig::Canvas::Handle canvas
                return 0;
        }
 
-       synfig::info("DEPTH=%d",depth);
+       // synfig::info("DEPTH=%d",depth);
+
        // Action to move the layer (if necessary)
        if(depth>0)
        {
@@ -377,7 +403,18 @@ CanvasInterface::generate_param_list(const ValueDesc &value_desc)
                param_list.add("value_node",value_desc.get_value_node());
 
        if(value_desc.is_const())
-               param_list.add("value",value_desc.get_value());
+       {
+               // Fix 1868911: if we put a ValueBase holding a Canvas handle
+               // into the param_list and then export the canvas, the handle
+               // will miss out of having its reference count reduced,
+               // because by the time the handle is destructed the canvas
+               // will no longer be inline.  So let's not propogate that
+               // ValueBase any further than here.
+               if (value_desc.get_value_type() == ValueBase::TYPE_CANVAS)
+                       param_list.add("value",Canvas::LooseHandle(value_desc.get_value().get(Canvas::LooseHandle())));
+               else
+                       param_list.add("value",value_desc.get_value());
+       }
 
        if(value_desc.parent_is_layer_param())
        {
@@ -599,6 +636,13 @@ CanvasInterface::import(const synfig::String &filename, bool /*copy*/)
 void
 CanvasInterface::waypoint_duplicate(synfigapp::ValueDesc value_desc,synfig::Waypoint waypoint)
 {
+       ValueNode::Handle value_node();
+       waypoint_duplicate(value_desc.get_value_node(), waypoint);
+}
+
+void
+CanvasInterface::waypoint_duplicate(ValueNode::Handle value_node,synfig::Waypoint waypoint)
+{
        Action::Handle  action(Action::create("waypoint_set_smart"));
 
        assert(action);
@@ -608,8 +652,6 @@ CanvasInterface::waypoint_duplicate(synfigapp::ValueDesc value_desc,synfig::Wayp
        waypoint.make_unique();
        waypoint.set_time(get_time());
 
-       ValueNode::Handle value_node(value_desc.get_value_node());
-
        action->set_param("canvas",get_canvas());
        action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
        action->set_param("waypoint",waypoint);
@@ -623,14 +665,19 @@ CanvasInterface::waypoint_duplicate(synfigapp::ValueDesc value_desc,synfig::Wayp
 void
 CanvasInterface::waypoint_remove(synfigapp::ValueDesc value_desc,synfig::Waypoint waypoint)
 {
+       ValueNode::Handle value_node();
+       waypoint_remove(value_desc.get_value_node(), waypoint);
+}
+
+void
+CanvasInterface::waypoint_remove(ValueNode::Handle value_node,synfig::Waypoint waypoint)
+{
        Action::Handle  action(Action::create("waypoint_remove"));
 
        assert(action);
        if(!action)
                return;
 
-       ValueNode::Handle value_node(value_desc.get_value_node());
-
        action->set_param("canvas",get_canvas());
        action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
        action->set_param("waypoint",waypoint);