/*****************************************************************************
* Limpet - the Lightweight InforMation ProcEssing Toolkit
* http://limpet.info
*
* (C) 2015-2016, Deep Blue C Technologies Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html)
*
* This library 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.
*****************************************************************************/
package info.limpet.ui.data_provider.data;
import info.limpet.ICollection;
import info.limpet.IQuantityCollection;
import info.limpet.QuantityRange;
import info.limpet.data.impl.samples.StockTypes.NonTemporal;
import info.limpet.data.impl.samples.StockTypes.NonTemporal.Location;
import info.limpet.data.operations.spatial.GeoSupport;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import javax.measure.Measurable;
import javax.measure.Measure;
import javax.measure.quantity.Quantity;
import javax.measure.unit.Unit;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
/**
* This class provides property sheet properties for ButtonElement.
*/
public class CollectionPropertySource implements IPropertySource
{
private static final String PROPERTY_NAME = "limpet.collection.name";
private static final String PROPERTY_SIZE = "limpet.collection.size";
private static final String PROPERTY_DESCRIPTION =
"limpet.collection.description";
private static final String PROPERTY_VALUE = "limpet.collection.value";
private static final String PROPERTY_VALUE_SLIDER =
"limpet.collection.value.slider";
private static final String PROPERTY_UNITS = "limpet.collection.units";
private static final String PROPERTY_RANGE = "limpet.collection.range";
private static final String PROPERTY_LOC_LAT = "limpet.collection.loc.lat";
private static final String PROPERTY_LOC_LONG = "limpet.collection.loc.long";
private IPropertyDescriptor[] propertyDescriptors;
private final CollectionWrapper _collection;
/**
* Creates a new ButtonElementPropertySource.
*
* @param element
* the element whose properties this instance represents
*/
public CollectionPropertySource(final CollectionWrapper element)
{
_collection = element;
}
@Override
public Object getEditableValue()
{
return _collection;
}
/**
* @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
*/
@Override
public IPropertyDescriptor[] getPropertyDescriptors()
{
if (propertyDescriptors == null)
{
List<PropertyDescriptor> dList = new ArrayList<PropertyDescriptor>();
final PropertyDescriptor textDescriptor =
new TextPropertyDescriptor(PROPERTY_NAME, "Name");
textDescriptor.setCategory("Label");
final PropertyDescriptor sizeDescriptor =
new PropertyDescriptor(PROPERTY_SIZE, "Size");
sizeDescriptor.setCategory("Metadata");
final PropertyDescriptor descriptionDescriptor =
new TextPropertyDescriptor(PROPERTY_DESCRIPTION, "Description");
descriptionDescriptor.setCategory("Label");
// see if we want to add a value editor
final ICollection coll = (ICollection) _collection.getCollection();
if (coll.getValuesCount() == 1)
{
// ok, just use a text editor
if (coll.isQuantity())
{
final PropertyDescriptor valueDescriptor =
new TextPropertyDescriptor(PROPERTY_VALUE, "Value");
valueDescriptor.setCategory("Value");
dList.add(valueDescriptor);
}
// see if the type has any units
if (coll instanceof IQuantityCollection)
{
IQuantityCollection<?> qc =
(IQuantityCollection<?>) _collection.getCollection();
if (qc.getUnits() != null)
{
final PropertyDescriptor unitsDescriptor =
new PropertyDescriptor(PROPERTY_UNITS, "Units");
unitsDescriptor.setCategory("Value");
dList.add(unitsDescriptor);
}
// also provide a range descriptor
final PropertyDescriptor rangeDescriptor =
new TextPropertyDescriptor(PROPERTY_RANGE, "Range");
rangeDescriptor.setCategory("Metadata");
dList.add(rangeDescriptor);
}
else if (coll instanceof NonTemporal.Location
&& coll.getValuesCount() == 1)
{
final PropertyDescriptor latDescriptor =
new TextPropertyDescriptor(PROPERTY_LOC_LAT, "Latitude");
latDescriptor.setCategory("Value");
dList.add(latDescriptor);
final PropertyDescriptor longDescriptor =
new TextPropertyDescriptor(PROPERTY_LOC_LONG, "Longitude");
longDescriptor.setCategory("Value");
dList.add(longDescriptor);
}
}
dList.add(textDescriptor);
dList.add(sizeDescriptor);
dList.add(descriptionDescriptor);
propertyDescriptors = dList.toArray(new IPropertyDescriptor[]
{});
}
return propertyDescriptors;
}
@SuppressWarnings("unchecked")
@Override
public Object getPropertyValue(final Object id)
{
final String prop = (String) id;
final ICollection coll = (ICollection) _collection.getCollection();
if (prop.equals(PROPERTY_NAME))
{
return coll.getName();
}
else if (prop.equals(PROPERTY_SIZE))
{
return coll.getValuesCount();
}
else if (prop.equals(PROPERTY_DESCRIPTION))
{
return coll.getDescription();
}
else if (prop.equals(PROPERTY_VALUE))
{
if (coll instanceof IQuantityCollection<?>)
{
IQuantityCollection<Quantity> qc = (IQuantityCollection<Quantity>) coll;
Measurable<Quantity> first = getSingleton();
if (first != null)
{
return "" + first.doubleValue(qc.getUnits());
}
}
}
else if (prop.equals(PROPERTY_RANGE))
{
if (coll instanceof IQuantityCollection<?>)
{
final String str;
IQuantityCollection<Quantity> qc = (IQuantityCollection<Quantity>) coll;
QuantityRange<Quantity> range = qc.getRange();
if (range != null)
{
str =
"" + range.getMinimum().longValue(qc.getUnits()) + " : "
+ range.getMaximum().longValue(qc.getUnits());
}
else
{
str = " : ";
}
return str;
}
}
else if (prop.equals(PROPERTY_VALUE_SLIDER))
{
if (coll instanceof IQuantityCollection<?>)
{
// ok - we have to create a composite object that includes both the
// range and the current value - so it can be passed to the slider
IQuantityCollection<Quantity> qc = (IQuantityCollection<Quantity>) coll;
Measurable<Quantity> first = getSingleton();
if (first != null)
{
return "" + first.doubleValue(qc.getUnits());
}
}
}
else if (prop.equals(PROPERTY_UNITS))
{
if (coll instanceof IQuantityCollection<?>)
{
// ok - we have to create a composite object that includes both the
// range and the current value - so it can be passed to the slider
IQuantityCollection<?> qc = (IQuantityCollection<?>) coll;
return "" + qc.getUnits();
}
}
else if (prop.equals(PROPERTY_LOC_LAT))
{
if (coll.getValuesCount() > 0 && coll instanceof NonTemporal.Location)
{
NonTemporal.Location locColl = (Location) coll;
Point2D point = locColl.getValues().iterator().next();
return "" + point.getY();
}
}
else if (prop.equals(PROPERTY_LOC_LONG))
{
if (coll.getValuesCount() > 0 && coll instanceof NonTemporal.Location)
{
NonTemporal.Location locColl = (Location) coll;
Point2D point = locColl.getValues().iterator().next();
return "" + point.getX();
}
}
return null;
}
private Measurable<Quantity> getSingleton()
{
Measurable<Quantity> res = null;
@SuppressWarnings("unchecked")
final IQuantityCollection<Quantity> tt =
(IQuantityCollection<Quantity>) _collection.getCollection();
res = tt.getValues().iterator().next();
return res;
}
@Override
public boolean isPropertySet(final Object id)
{
// TODO Auto-generated method stub
return false;
}
@Override
public void resetPropertyValue(final Object id)
{
// TODO Auto-generated method stub
}
@SuppressWarnings(
{"unchecked", "rawtypes"})
@Override
public void setPropertyValue(final Object id, final Object value)
{
final String prop = (String) id;
final ICollection coll = (ICollection) _collection.getCollection();
if (prop.equals(PROPERTY_NAME))
{
coll.setName((String) value);
}
else if (prop.equals(PROPERTY_SIZE))
{
throw new RuntimeException("Can't set size, silly");
}
else if (prop.equals(PROPERTY_DESCRIPTION))
{
coll.setDescription((String) value);
}
else if (prop.equals(PROPERTY_VALUE))
{
if (coll instanceof IQuantityCollection<?>)
{
IQuantityCollection<?> tt = (IQuantityCollection<?>) coll;
tt.replaceSingleton(Double.parseDouble((String) value));
// ok, fire changed!
tt.fireDataChanged();
}
}
else if (prop.equals(PROPERTY_VALUE_SLIDER))
{
if (coll instanceof IQuantityCollection<?>)
{
IQuantityCollection<?> tt = (IQuantityCollection<?>) coll;
// ok, extract the new value from the input object. It's probably
// going to be a composite object that combines both range and value
tt.replaceSingleton(Double.parseDouble((String) value));
// ok, fire changed!
tt.fireDataChanged();
}
}
else if (prop.equals(PROPERTY_LOC_LAT))
{
if (coll instanceof NonTemporal.Location)
{
NonTemporal.Location locColl = (Location) coll;
// get the current location
if (locColl.getValuesCount() > 0)
{
Point2D loc = (Point2D) locColl.getValues().iterator().next();
// ok, create replacement
double newLat = Double.parseDouble((String) value);
Point2D newLoc =
GeoSupport.getCalculator().createPoint(loc.getX(), newLat);
locColl.clear();
locColl.add(newLoc);
// ok, fire changed!
locColl.fireDataChanged();
}
}
}
else if (prop.equals(PROPERTY_LOC_LONG))
{
if (coll instanceof NonTemporal.Location)
{
NonTemporal.Location locColl = (Location) coll;
if (locColl.getValuesCount() > 0)
{
// get the current location
Point2D loc = locColl.getValues().iterator().next();
// ok, create replacement
double newLong = Double.parseDouble((String) value);
Point2D newLoc =
GeoSupport.getCalculator().createPoint(newLong, loc.getY());
locColl.clear();
locColl.add(newLoc);
// ok, fire changed!
locColl.fireDataChanged();
}
}
}
else if (prop.equals(PROPERTY_RANGE))
{
if (coll instanceof IQuantityCollection<?>)
{
IQuantityCollection<?> tt = (IQuantityCollection<?>) coll;
// try to get a range from the string
String str = (String) value;
if (str.length() > 0)
{
// ok, split it up
String[] bits = str.split(":");
if (bits.length == 2)
{
String min = bits[0].trim();
String max = bits[1].trim();
try
{
double minV = Double.parseDouble(min);
double maxV = Double.parseDouble(max);
if (maxV > minV)
{
Unit<?> collUnits = tt.getUnits();
QuantityRange newR =
new QuantityRange(Measure.valueOf(minV, collUnits), Measure
.valueOf(maxV, collUnits));
tt.setRange(newR);
}
}
catch (NumberFormatException fe)
{
System.err.println("Failed to extract number range: fe");
}
}
else
{
System.err.println("Number format string not properly constructed:"
+ str + " (should be 1:10)");
}
}
// ok, fire changed!
tt.fireMetadataChanged();
}
}
}
}