/*******************************************************************************
 * Copyright (c) 2015-2016 Oak Ridge National Laboratory.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.csstudio.display.builder.model.properties;

import javax.xml.stream.XMLStreamWriter;

import org.csstudio.display.builder.model.MacroizedWidgetProperty;
import org.csstudio.display.builder.model.Widget;
import org.csstudio.display.builder.model.WidgetPropertyDescriptor;
import org.csstudio.display.builder.model.persist.ModelReader;
import org.csstudio.display.builder.model.persist.ModelWriter;
import org.csstudio.display.builder.model.persist.XMLUtil;
import org.w3c.dom.Element;

/** Widget property with Double value.
 *
 *  @author Kay Kasemir
 */
@SuppressWarnings("nls")
public class DoubleWidgetProperty extends MacroizedWidgetProperty<Double>
{
    final private Double min, max;

    /** Constructor
     *  @param descriptor Property descriptor
     *  @param widget Widget that holds the property and handles listeners
     *  @param default_value Default and initial value
     */
    public DoubleWidgetProperty(
            final WidgetPropertyDescriptor<Double> descriptor,
            final Widget widget,
            final Double default_value)
    {
        this(descriptor, widget, default_value,
             Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
    }

    /** Constructor
     *  @param descriptor Property descriptor
     *  @param widget Widget that holds the property and handles listeners
     *  @param default_value Default and initial value
     *  @param min Minimum value
     *  @param max Maximum value
     */
    public DoubleWidgetProperty(
            final WidgetPropertyDescriptor<Double> descriptor,
            final Widget widget,
            final Double default_value,
            final Double min, final Double max)
    {
        super(descriptor, widget, default_value);
        this.min = min;
        this.max = max;
        if (! restrictValue(default_value).equals(default_value))
            throw new IllegalArgumentException("Default value outside range");
    }

    @Override
    protected Double parseExpandedSpecification(final String text) throws Exception
    {
        try
        {
            return Double.valueOf(text);
        }
        catch (final NumberFormatException ex2)
        {
            throw new Exception("Double property '" + getName() +
                                "' has invalid value " + text);
        }
    }

    @Override
    protected Double restrictValue(final Double requested_value)
    {
        if (requested_value.compareTo(min) < 0)
            return min;
        if (requested_value.compareTo(max) > 0)
            return max;
        return requested_value;
    }

    @Override
    public void setValueFromObject(final Object value) throws Exception
    {
        if (value instanceof Number)
            setValue( ((Number)value).doubleValue());
        else if (value instanceof String)
            setValue(parseExpandedSpecification((String)value));
        else
            throw new IllegalArgumentException("Property '" + getName() +
                "' requires double, but received " + value.getClass().getName());
    }

    @Override
    public void writeToXML(final ModelWriter model_writer, final XMLStreamWriter writer) throws Exception
    {
        writer.writeCharacters(specification);
    }

    @Override
    public void readFromXML(final ModelReader model_reader, final Element property_xml) throws Exception
    {
        setSpecification(XMLUtil.getString(property_xml));
    }
}

@@ -2702,12 +2702,11 @@
 n ex
-2
 )%0D%0A
+
     
@@ -2836,24 +2836,28 @@
 lue %22 + text
+, ex
 );%0D%0A        
@@ -2948,32 +2948,158 @@
 _value)%0D%0A    %7B%0D%0A
+        if (Double.isFinite(requested_value))%0D%0A        %7B   // Only check limits for finite value. NaN is passed through.%0D%0A    
         if (requ
@@ -3135,32 +3135,36 @@
 0)%0D%0A            
+    
 return min;%0D%0A   
@@ -3160,32 +3160,36 @@
 n min;%0D%0A        
+ 
+   
 if (requested_va
@@ -3217,32 +3217,36 @@
 0)%0D%0A            
+    
 return max;%0D%0A   
@@ -3238,24 +3238,35 @@
 eturn max;%0D%0A
+        %7D%0D%0A
         retu

Allow NaN as default/initial value