/******************************************************************************* * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) and others. * 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 * * Contributors: * Soyatec - initial API and implementation *******************************************************************************/ package org.eclipse.papyrus.xwt.core; import java.util.HashMap; import org.eclipse.core.databinding.conversion.IConverter; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.papyrus.xwt.XWT; import org.eclipse.papyrus.xwt.internal.utils.UserData; import org.eclipse.swt.widgets.Widget; /** * * @author yyang (yves.yang@soyatec.com) */ public class DataTrigger extends TriggerBase { private Object value; private Operator operator = Operator.EQ; private IBinding binding; private SetterBase[] setters; private ValueChangeListener changeListener; public Operator getOperator() { return operator; } public void setOperator(Operator operator) { this.operator = operator; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public IBinding getBinding() { return binding; } public void setBinding(IBinding binding) { this.binding = binding; } public SetterBase[] getSetters() { if(setters == null) { return Setter.EMPTY_SETTERS; } return setters; } public void setSetters(SetterBase[] setters) { this.setters = setters; } class ValueChangeListener extends AbstractChangeListener { public ValueChangeListener(Object element) { super(element); } public void handleChange(ChangeEvent event) { doHandleChange(true); } public void doHandleChange(boolean update) { Widget widget = UserData.getWidget(element); if(widget == null) { return; } Object currentValue = binding.getValue(null); if(currentValue == null) { return; } while(currentValue instanceof IObservableValue) { currentValue = ((IObservableValue)currentValue).getValue(); } Class<?> currentValueType = currentValue.getClass(); Class<?> valueType = value.getClass(); Object normalizedValue = value; if(!currentValueType.isAssignableFrom(valueType) && !valueType.isAssignableFrom(currentValueType)) { IConverter converter = XWT.findConvertor(valueType, currentValueType); if(converter != null) { normalizedValue = converter.convert(normalizedValue); } else if(value != null && value.toString().trim().length() > 0) { boolean found = false; // in case where the value is a boolean converter = XWT.findConvertor(valueType, Boolean.class); if(converter != null) { try { Object booleanValue = converter.convert(value); if(booleanValue != null) { converter = XWT.findConvertor(currentValueType, Boolean.class); if(converter != null) { currentValue = converter.convert(currentValue); normalizedValue = booleanValue; found = true; } } } catch (RuntimeException e) { } } if(!found) { converter = XWT.findConvertor(valueType, Integer.class); if(converter != null) { try { Object booleanValue = converter.convert(value); if(booleanValue != null) { converter = XWT.findConvertor(currentValueType, Integer.class); if(converter != null) { currentValue = converter.convert(currentValue); normalizedValue = booleanValue; found = true; } } } catch (Exception e) { } } } if(!found) { converter = XWT.findConvertor(valueType, Double.class); if(converter != null) { try { Object booleanValue = converter.convert(value); if(booleanValue != null) { converter = XWT.findConvertor(currentValueType, Double.class); if(converter != null) { currentValue = converter.convert(currentValue); normalizedValue = booleanValue; found = true; } } } catch (Exception e) { } } } if(!found) { converter = XWT.findConvertor(valueType, String.class); if(converter != null) { try { Object booleanValue = converter.convert(value); if(booleanValue != null) { converter = XWT.findConvertor(currentValueType, String.class); if(converter != null) { currentValue = converter.convert(currentValue); normalizedValue = booleanValue; found = true; } } } catch (Exception e) { } } } } } if(!Operator.compare(currentValue, operator, normalizedValue) && update) { restoreValues(); return; } for(SetterBase setter : getSetters()) { try { Object oldValue = setter.applyTo(element, update); if(!update) { if(oldvalues == null) { oldvalues = new HashMap<SetterBase, Object>(); } oldvalues.put(setter, oldValue); } } catch (RuntimeException e) { continue; } } } } public void prepare(Object target) { if(value == null) { return; } Widget widget = UserData.getWidget(target); if(widget == null) { return; } Object bindingTarget = null; if(binding != null) { if(binding instanceof IDynamicBinding) { IDynamicBinding dynamicBinding = (IDynamicBinding)binding; bindingTarget = dynamicBinding.createBoundSource(); } else { bindingTarget = binding.getValue(null); } } else { bindingTarget = XWT.getDataContext(widget); } if(!(bindingTarget instanceof IObservableValue)) { return; } IObservableValue observableValue = (IObservableValue)bindingTarget; changeListener = new ValueChangeListener(target); observableValue.addChangeListener(changeListener); changeListener.doHandleChange(false); // get default value } @Override public void on(Object target) { changeListener.doHandleChange(true); } }