bool
Action::TimepointsMove::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="addlayer" && param.get_type()==Param::TYPE_LAYER)
	{
		//add a layer to the list
		sel_layers.push_back(param.get_layer());
		//synfig::info("action got layer");

		return true;
	}

	if(name=="addcanvas" && param.get_type()==Param::TYPE_CANVAS)
	{
		//add a layer to the list
		sel_canvases.push_back(param.get_canvas());
		//synfig::info("action got canvas");

		return true;
	}

	if(name=="addvaluedesc" && param.get_type()==Param::TYPE_VALUEDESC)
	{
		//add a layer to the list
		sel_values.push_back(param.get_value_desc());
		//synfig::info("action got valuedesc");

		return true;
	}

	if(name=="addtime" && param.get_type()==Param::TYPE_TIME)
	{
		//add a layer to the list
		sel_times.insert(param.get_time());
		//synfig::info("action got time");

		return true;
	}

	if(name=="deltatime" && param.get_type()==Param::TYPE_TIME)
	{
		timemove = param.get_time();
		//synfig::info("action got time to move");

		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 2
0
bool
Action::ValueDescSet::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
	{
		value_desc=param.get_value_desc();
		return true;
	}
	if(name=="new_value" && param.get_type()==Param::TYPE_VALUE)
	{
		value=param.get_value();
		return true;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}
	if(name=="recursive" && param.get_type()==Param::TYPE_BOOL)
	{
		recursive=param.get_bool();
		return true;
	}
	if(name=="animate" && param.get_type()==Param::TYPE_BOOL)
	{
		animate=param.get_bool();
		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 3
0
bool
Action::ValueDescBLineLink::set_param(const synfig::String& name, const Action::Param &param)
{
    if (name == "time" && param.get_type() == Param::TYPE_TIME)
    {
        time = param.get_time();
        return true;
    }

    if (name == "value_desc" && param.get_type() == Param::TYPE_VALUEDESC)
    {
        value_desc = param.get_value_desc();
        index = value_desc.get_index();
        return true;
    }

    if (name == "selected_value_desc" && param.get_type() == Param::TYPE_VALUEDESC)
    {
        ValueDesc value_desc(param.get_value_desc());
        value_desc_list.push_back(value_desc);
        return true;
    }

    if (name == "origin" && param.get_type() == Param::TYPE_REAL)
    {
        origin = param.get_real();
        return true;
    }

    return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 4
0
bool
Action::ColorSet::set_param(const synfig::String& name, const Action::Param &param)
{
	if (name == "value_desc" && param.get_type() == Param::TYPE_VALUEDESC)
	{
		// Grab the value_desc
		ValueDesc value_desc = param.get_value_desc();
		if (value_desc.get_value_type() != type_color)
			return false;

		value_desc_list.push_back(value_desc);

		// Grab the current outline or fill color
		if (use_outline_color)
			color = synfigapp::Main::get_outline_color();
		else
			color = synfigapp::Main::get_fill_color();

		return true;
	}

	if (name == "time" && param.get_type() == Param::TYPE_TIME)
	{
		time = param.get_time();

		return true;
	}

	return Action::CanvasSpecific::set_param(name, param);
}
Exemplo n.º 5
0
bool
Action::WaypointAdd::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
	{
		value_node=ValueNode_Animated::Handle::cast_dynamic(param.get_value_node());
		if(time_set)
			calc_waypoint();

		return static_cast<bool>(value_node);
	}
	if(name=="waypoint" && param.get_type()==Param::TYPE_WAYPOINT && !time_set)
	{
		waypoint=param.get_waypoint();

		return true;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME && waypoint.get_time()==Time::begin()-1)
	{
		waypoint.set_time(param.get_time());
		time_set=true;

		if(value_node)
			calc_waypoint();

		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 6
0
bool
Action::KeyframeDuplicate::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
	{
		keyframe=param.get_keyframe();
		new_keyframe.set_description(keyframe.get_description()+_(" (Duplicate)"));

		//! TODO add and use keyframe::operator=

		//! Copy the kf's Waypoint::model is exist
		if(keyframe.has_model())
		    new_keyframe.apply_model(keyframe.get_waypoint_model());
		//! Copy the active status
		new_keyframe.set_active(keyframe.active());

		return true;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		new_keyframe.set_time(param.get_time());

		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
bool
Action::ValueNodeLinkDisconnect::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="parent_value_node" && param.get_type()==Param::TYPE_VALUENODE)
	{
		parent_value_node=LinkableValueNode::Handle::cast_dynamic(param.get_value_node());

		return static_cast<bool>(parent_value_node);
	}

	if(name=="index" && param.get_type()==Param::TYPE_INTEGER)
	{
		index=param.get_integer();

		return true;
	}

	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();

		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 8
0
bool
Action::ValueDescSkeletonLink::set_param(const synfig::String& name, const Action::Param &param)
{
	if (name == "value_desc" && param.get_type() == Param::TYPE_VALUEDESC
	 && param.get_value_desc().parent_is_value_node()
	 && ValueNode_Bone::Handle::cast_dynamic(param.get_value_desc().get_parent_value_node())
	 && param.get_value_desc().get_parent_desc().parent_is_value_node()
	 && ValueNode_StaticList::Handle::cast_dynamic(param.get_value_desc().get_parent_desc().get_parent_value_node()) )
	{
		value_desc = param.get_value_desc();
		return true;
	}

	if (name == "selected_value_desc" && param.get_type() == Param::TYPE_VALUEDESC)
	{
		value_desc_list.push_back(param.get_value_desc());
		return true;
	}

	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
bool
Action::ValueNodeDynamicListRemoveSmart::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
	{
		ValueDesc value_desc(param.get_value_desc());
		if(!value_desc.parent_is_value_node())
			return false;
		value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
		if(!value_node)
		{
			ValueNode::Handle compo(ValueNode_Composite::Handle::cast_dynamic(value_desc.get_parent_value_node()));
			if(compo)
			{
				ValueNode_DynamicList::Handle parent_list=NULL;
				std::set<Node*>::iterator iter;
				// now check if the composite's parent is a dynamic list type
				for(iter=compo->parent_set.begin();iter!=compo->parent_set.end();++iter)
					{
						parent_list=ValueNode_DynamicList::Handle::cast_dynamic(*iter);
						if(parent_list)
						{
							value_node=parent_list;
							// Now we need to find the index of this composite item
							// on the dynamic list
							int i;
							for(i=0;i<value_node->link_count();i++)
								if(compo->get_guid()==value_node->get_link(i)->get_guid())
									break;
							if(i<value_node->link_count())
								value_desc=synfigapp::ValueDesc(value_node, i);
							else
								return false;
							break;
						}
					}
				if(!value_node)
					return false;
			}
			else
				return false;
			if(!value_node)
				return false;
		}
		index=value_desc.get_index();
		return true;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}
	if(name=="origin" && param.get_type()==Param::TYPE_REAL)
	{
		origin=param.get_real();
		return true;
	}
	return Action::CanvasSpecific::set_param(name,param);
}
bool
Action::KeyframeSetDelta::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
	{
		keyframe=param.get_keyframe();
		return true;
	}
	if(name=="delta" && param.get_type()==Param::TYPE_TIME)
	{
		delta=param.get_time();
		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
// called from two places - both set 'canvas' and 'canvasinterface', and then:
//
//		ValueNodeStaticListRotateOrder::prepare() sets "value_desc", "item"
//			action->set_param("item",child);									<- sets item=list_entry=child
//			action->set_param("value_desc",ValueDesc(value_node,0));			<- sets value_node=value_node, index=0, list_entry=item
//
//		ValueNodeStaticListInsertSmart::prepare() sets "time", "origin", "value_desc"
//			action->set_param("time",time);
//			action->set_param("origin",origin);
//			action->set_param("value_desc",ValueDesc(value_node,index));		<- sets value_node=value_node, index=index, list_entry=create_list_entry(...)
//
// all the perform() does is 	value_node->add(list_entry,index);
//
bool
Action::ValueNodeStaticListInsert::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
	{
		ValueDesc value_desc(param.get_value_desc());

		if(!value_desc.parent_is_value_node())
			return false;

		value_node=ValueNode_StaticList::Handle::cast_dynamic(value_desc.get_parent_value_node());

		if(!value_node)
			return false;

		index=value_desc.get_index();

		if(item)
			list_entry=item;
		else
			list_entry=value_node->create_list_entry(index,time,origin);

		return true;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();

		return true;
	}
	if(name=="item" && param.get_type()==Param::TYPE_VALUENODE)
	{
		item=param.get_value_node();
		if(item)
			list_entry=item;

		return true;
	}
	if(name=="origin" && param.get_type()==Param::TYPE_REAL)
	{
		origin=param.get_real();

		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
bool
Action::ActivepointSetSmart::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
	{
		value_desc=param.get_value_desc();

		if(!value_desc.parent_is_value_node())
			return false;

		value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());

		if(!value_node)
			return false;

		index=value_desc.get_index();

		if(time_set)
			calc_activepoint();

		return true;
	}
	if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT && !time_set)
	{
		activepoint=param.get_activepoint();

		return true;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME && activepoint.get_time()==Time::begin()-1)
	{
		activepoint.set_time(param.get_time());
		time_set=true;

		if(value_node)
			calc_activepoint();

		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 13
0
bool
Action::ValueDescDisconnect::set_param(const synfig::String& name, const Action::Param &param)
{
    if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
    {
        value_desc=param.get_value_desc();

        return true;
    }

    if(name=="time" && param.get_type()==Param::TYPE_TIME)
    {
        time=param.get_time();

        return true;
    }

    return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 14
0
bool
Action::ValueDescCreateChildBone::set_param(const synfig::String& name, const Action::Param &param)
{
	if (name == "value_desc" && param.get_type() == Param::TYPE_VALUEDESC
	 && param.get_value_desc().parent_is_value_node()
	 && ValueNode_Bone::Handle::cast_dynamic(param.get_value_desc().get_parent_value_node()) )
	{
		value_desc = param.get_value_desc();
		return true;
	}

	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 15
0
bool
Action::LayerResetPose::set_param(const synfig::String& name, const Action::Param &param)
{
	if (name=="layer"
	 && param.get_type()==Param::TYPE_LAYER
	 && param.get_layer()->get_name() == "skeleton_deformation" )
	{
		layers.push_back(param.get_layer());
		return true;
	}

	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 16
0
bool
Action::LayerAddFrame::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
	{
		layer_switch = etl::handle<Layer_Switch>::cast_dynamic(param.get_layer());
		if (layer_switch)
		{
			layer_base = layer_switch->get_current_layer();
			if (!layer_base) layer_switch = NULL;
		}
		return layer_switch;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 17
0
bool
Action::BLinePointTangentSplitAngle::set_param(const synfig::String& name, const Action::Param &param)
{
    if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
    {
        value_node=value_node.cast_dynamic(param.get_value_node());
        if(value_node && value_node->get_type()==ValueBase::TYPE_BLINEPOINT)
            return true;
        ValueNode_RadialComposite::Handle radial_value_node;
        radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(param.get_value_node());
        if(radial_value_node && radial_value_node->get_type()==ValueBase::TYPE_VECTOR)
            // value_node is radial composite and vector (user rigth click on a tangent)
        {
            ValueNode_Composite::Handle blinepoint;
            std::set<Node*>::iterator iter;
            // now check if the parent of value_node is a blinepoint type
            for(iter=radial_value_node->parent_set.begin(); iter!=radial_value_node->parent_set.end(); ++iter)
            {
                blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
                if(blinepoint && blinepoint->get_type()==ValueBase::TYPE_BLINEPOINT)
                {
                    value_node=blinepoint;
                    return true;
                }
            }
            return false;
        }
        return false;
    }
    if(name=="time" && param.get_type()==Param::TYPE_TIME)
    {
        time=param.get_time();
        return true;
    }
    return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 18
0
bool
Action::ValueDescRemoveSmart::set_param(const synfig::String& name, const Action::Param &param)
{
	ValueNode_DynamicList::Handle value_node;
	if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
	{
		ValueDesc value_desc(param.get_value_desc());
		if(!value_desc.parent_is_value_node())
			return false;
		value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
		if(!value_node)
		{
			ValueNode::Handle compo(ValueNode_Composite::Handle::cast_dynamic(value_desc.get_parent_value_node()));
			if(compo)
			{
				ValueNode_DynamicList::Handle parent_list=NULL;
				std::set<Node*>::iterator iter;
				// now check if the composite's parent is a dynamic list type
				for(iter=compo->parent_set.begin();iter!=compo->parent_set.end();++iter)
					{
						parent_list=ValueNode_DynamicList::Handle::cast_dynamic(*iter);
						if(parent_list)
						{
							value_node=parent_list;
							// Now we need to find the index of this composite item
							// on the dynamic list
							int i;
							for(i=0;i<value_node->link_count();i++)
								if(compo->get_guid()==value_node->get_link(i)->get_guid())
									break;
							if(i<value_node->link_count())
								value_desc=synfigapp::ValueDesc(value_node, i);
							else
								return false;
							break;
						}
					}
				if(!value_node)
					return false;
			}
			else
				return false;
			if(!value_node)
				return false;
		}
		ValueNodes::iterator it;
		// Try to find the current parent value node in our map
		it=value_nodes.find(value_node);
		if(it==value_nodes.end())
		{
			// Not found, then create a new one
			value_nodes[value_node].push_back(value_desc.get_index());
		}
		else
		{
			// found, then insert the index of the value desc.
			// Maybe the index is already inserted.
			// Later is ignored if that happen
			it->second.push_back(value_desc.get_index());
		}
		return true;
	}
	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}
	if(name=="origin" && param.get_type()==Param::TYPE_REAL)
	{
		origin=param.get_real();
		return true;
	}
	return Action::CanvasSpecific::set_param(name,param);
}
Exemplo n.º 19
0
bool
Action::ValueDescLink::set_param(const synfig::String& name, const Action::Param &param)
{
	if(name=="time" && param.get_type()==Param::TYPE_TIME)
	{
		time=param.get_time();
		return true;
	}

	// don't bother looking for the best value to use if there's already been an error
	if (poison==true) return false;

	if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
	{
		ValueDesc value_desc(param.get_value_desc());
		// If we are handling a Composite WidthPoint then use its position as param
		if(value_desc.is_value_node() && value_desc.parent_is_linkable_value_node())
		{
			synfig::ValueNode_Composite::Handle compo(synfig::ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()));
			if(compo)
			{
				String param_name;
				if (value_desc.parent_is_value_desc() && !value_desc.get_sub_name().empty())
				{
					LinkableValueNode::Vocab vocab = compo->get_children_vocab();
					for(LinkableValueNode::Vocab::const_iterator i = vocab.begin(); i != vocab.end(); ++i)
						if (i->get_name() == value_desc.get_sub_name())
							param_name = value_desc.get_sub_name();
				}
				
				//! Test used for with point handle
				if (param_name.empty() && compo->get_type() == type_width_point)
					param_name = "position";

				if (param_name.empty() && compo->get_type() == type_bline_point)
					param_name = "point";
				
				if ( compo->get_type() == type_bline_point
				  && param_name == "t2"
				  && (*compo)(time).get(BLinePoint()).get_merge_tangent_both())
				{
					param_name = "t1";
				}
				
				if (!param_name.empty())
				{
					synfigapp::Action::Param param(synfigapp::ValueDesc(compo, compo->get_link_index_from_name(param_name)));
					return set_param("value_desc", param);
				}
			}
		}

		if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
		{
			if(link_value_node==value_desc.get_value_node())
				return true;

			if(link_value_node && link_value_node->is_exported())
			{
				poison=true;
				status_message = (_("Cannot link two different exported values ('") +
								  value_desc.get_value_node()->get_id() + _("' and '") +
								  link_value_node->get_id()) + _("')");
				return false;
			}

			link_value_node=value_desc.get_value_node();
			link_scalar=value_desc.parent_is_linkable_value_node()?value_desc.get_scalar():1.0;
			status_message = _("Used exported ValueNode ('") + link_value_node->get_id() + _("').");
		}
		else if(value_desc.is_value_node())
		{
			if(!link_value_node)
			{
				status_level = 1;
				status_message = _("Using the only available ValueNode.");
				link_value_node=value_desc.get_value_node();
				link_scalar=value_desc.parent_is_linkable_value_node()?value_desc.get_scalar():1.0;
			}
			else if(link_value_node->is_exported())
			{
				// we've already seen an exported value, so use that rather than the current value
			}
			// Use the one that is referenced more
			else if(link_value_node->rcount()!=value_desc.get_value_node()->rcount())
			{
				if(link_value_node->rcount()<value_desc.get_value_node()->rcount())
				{
					status_level = 2;
					status_message = _("Using the most referenced ValueNode.");
					link_value_node=value_desc.get_value_node();
					link_scalar=value_desc.parent_is_linkable_value_node()?value_desc.get_scalar():1.0;
				}
				else if (status_level <= 2)
				{
					status_level = 2;
					status_message = _("Using the most referenced ValueNode.");
				}
			}
			// If the current link value node is a constant and
			// this one isn't, then give preference to the exotic
			else if(ValueNode_Const::Handle::cast_dynamic(link_value_node) && !ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
			{
				status_level = 3;
				status_message = _("There's a tie for most referenced; using the animated ValueNode.");
				link_value_node=value_desc.get_value_node();
				link_scalar=value_desc.parent_is_linkable_value_node()?value_desc.get_scalar():1.0;
			}
			else if(ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()) && !ValueNode_Const::Handle::cast_dynamic(link_value_node))
			{
				if (status_level <= 3)
				{
					status_level = 3;
					status_message = _("There's a tie for most referenced; using the animated ValueNode.");
				}
			}
			// If both are animated, and this one has more waypoints, then use the one with more waypoints
			else if(ValueNode_Animated::Handle::cast_dynamic(link_value_node) &&
					ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node()) &&
					ValueNode_Animated::Handle::cast_dynamic(link_value_node)->waypoint_list().size() !=
					ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())->waypoint_list().size())
			{
				if (ValueNode_Animated::Handle::cast_dynamic(link_value_node)->waypoint_list().size() <
					ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())->waypoint_list().size())
				{
					status_level = 4;
					status_message = _("There's a tie for most referenced, and both are animated; using the one with the most waypoints.");
					link_value_node=value_desc.get_value_node();
					link_scalar=value_desc.parent_is_linkable_value_node()?value_desc.get_scalar():1.0;
				}
				else if (status_level <= 4)
				{
					status_level = 4;
					status_message = _("There's a tie for most referenced, and both are animated; using the one with the most waypoints.");
				}
			}
			// If both are Linkable Value Nodes and has waypoint in its children, use the one with more waypoints
			else if(LinkableValueNode::Handle::cast_dynamic(link_value_node) &&
					LinkableValueNode::Handle::cast_dynamic(value_desc.get_value_node()) &&
					LinkableValueNode::Handle::cast_dynamic(link_value_node)->get_times().size() !=
					LinkableValueNode::Handle::cast_dynamic(value_desc.get_value_node())->get_times().size())
			{
				if(LinkableValueNode::Handle::cast_dynamic(link_value_node)->get_times().size() <
				LinkableValueNode::Handle::cast_dynamic(value_desc.get_value_node())->get_times().size())
				{
					status_level = 4;
					status_message = _("There's a tie for most referenced, and both are linkable value node animated; using the one with the most waypoints.");
					link_value_node=value_desc.get_value_node();
					link_scalar=value_desc.parent_is_linkable_value_node()?value_desc.get_scalar():1.0;
				}
				else if (status_level <= 4)
				{
					status_level = 4;
					status_message = _("There's a tie for most referenced, and both are linkable value node animated; using the one with the most waypoints.");
				}
			}
			// Use the one that was least recently changed
			else if(link_value_node->get_time_last_changed()!=value_desc.get_value_node()->get_time_last_changed())
			{
				if(link_value_node->get_time_last_changed()>value_desc.get_value_node()->get_time_last_changed())
				{
					status_level = 5;
					status_message = _("Everything is tied; using the least recently modified value.");
					link_value_node=value_desc.get_value_node();
					link_scalar=value_desc.parent_is_linkable_value_node()?value_desc.get_scalar():1.0;
				}
				else if (status_level <= 5)
				{
					status_level = 5;
					status_message = _("Everything is tied; using the least recently modified value.");
				}
			}
			else
			{
				status_level = 6;
				status_message = _("Absolutely everything is tied.");
			}
		}

		if(value_desc_list.size() && value_desc.get_value_type()!=value_desc_list.front().get_value_type())
		{
			// Everything must be of the same type
			poison=true;
			status_message = (strprintf(_("Cannot link two values of different types ('%s' and '%s')"),
										value_desc.get_value_type().description.local_name.c_str(),
										value_desc_list.front().get_value_type().description.local_name.c_str()));
			return false;
		}

		value_desc_list.push_back(value_desc);

		return true;
	}

	return Action::CanvasSpecific::set_param(name,param);
}