package org.marketcetera.photon.strategy.engine.ui; import java.text.MessageFormat; import java.util.List; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.databinding.observable.set.IObservableSet; import org.eclipse.core.databinding.property.value.IValueProperty; import org.eclipse.emf.databinding.EMFProperties; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; import org.eclipse.swt.graphics.Image; import org.marketcetera.photon.commons.ui.SWTUtils; import org.marketcetera.photon.commons.ui.databinding.PropertyWatcher; import org.marketcetera.photon.commons.ui.databinding.PropertyWatcher.IPropertiesChangedListener; import org.marketcetera.photon.strategy.engine.model.core.Strategy; import org.marketcetera.photon.strategy.engine.model.core.StrategyEngine; import org.marketcetera.photon.strategy.engine.model.core.StrategyEngineCorePackage; import org.marketcetera.photon.strategy.engine.model.core.util.StrategyEngineCoreSwitch; import org.marketcetera.util.misc.ClassVersion; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; /* $License$ */ /** * Provides a basic label and image for strategy engine core model objects. It * implements {@link IStyledLabelProvider} so it may be used in viewers with * styled labels. * <p> * Instances of this class are thread confined. They can only be instantiated * and accessed on a single UI thread. * * @author <a href="mailto:will@marketcetera.com">Will Horn</a> * @version $Id: StrategyEnginesLabelProvider.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ @ClassVersion("$Id: StrategyEnginesLabelProvider.java 16154 2012-07-14 16:34:05Z colin $") public class StrategyEnginesLabelProvider extends LabelProvider implements IStyledLabelProvider { /** * Creates a StrategyEnginesLabelProvider that tracks the given set of * elements, updating their labels when related properties change. Tracking * will not stop until this StrategyEnginesLabelProvider is * {@link #dispose() disposed}. * * @param elements * the observable set of elements to track, must be on the realm * of the current display * @throws IllegalStateException * if called from a non UI thread, i.e. a thread where * Display.getCurrent() is null * @throws IllegalArgumentException * if the provided elements set is not on the realm of the * current display */ public static StrategyEnginesLabelProvider createAndTrack( IObservableSet elements) { SWTUtils.checkThread(); StrategyEnginesLabelProvider provider = new StrategyEnginesLabelProvider(); provider.track(elements); return provider; } private final static List<IValueProperty> PROPERTIES = ImmutableList .<IValueProperty> of( EMFProperties .value(StrategyEngineCorePackage.Literals.STRATEGY_ENGINE__NAME), EMFProperties .value(StrategyEngineCorePackage.Literals.STRATEGY__INSTANCE_NAME)); private final PropertyWatcher mPropertyWatcher = new PropertyWatcher( PROPERTIES, new IPropertiesChangedListener() { @Override public void propertiesChanged(ImmutableSet<?> affectedElements) { LabelProviderChangedEvent newEvent = new LabelProviderChangedEvent( StrategyEnginesLabelProvider.this, affectedElements .toArray()); fireLabelProviderChanged(newEvent); } }); private final LocalResourceManager mResourceManager; /** * Constructor. Must be called from the UI thread. * * @throws IllegalStateException * if called from a non UI thread, i.e. a thread where * Display.getCurrent() is null */ public StrategyEnginesLabelProvider() { SWTUtils.checkThread(); mResourceManager = new LocalResourceManager(JFaceResources .getResources()); } /** * Causes this label provider to track the given set of elements, updating * their labels when related properties change. Tracking will not stop until * this StrategyEnginesLabelProvider is {@link #dispose() disposed}. * * @param elements * the observable set of elements to track, must be on the realm * of the current display * @throws IllegalStateException * if called from a non UI thread, i.e. a thread where * Display.getCurrent() is null * @throws IllegalArgumentException * if the provided elements set is not on the realm of the * current display */ public void track(IObservableSet elements) { SWTUtils.checkThread(); final Realm realm = elements.getRealm(); if (!realm.isCurrent()) { throw new IllegalArgumentException( MessageFormat .format( "the realm of elements [{0}] is not the realm of the current display", //$NON-NLS-1$ realm)); } mPropertyWatcher.watch(elements); } @Override public String getText(Object element) { SWTUtils.checkThread(); if (element instanceof EObject) { String text = new StrategyEngineCoreSwitch<String>() { @Override public String caseStrategyEngine(StrategyEngine object) { return object.getName(); } @Override public String caseStrategy(Strategy object) { return object.getInstanceName(); }; }.doSwitch((EObject) element); if (text != null) { return text; } } return super.getText(element); } @Override public StyledString getStyledText(Object element) { SWTUtils.checkThread(); return new StyledString(getText(element)); } @Override public Image getImage(Object element) { SWTUtils.checkThread(); if (element instanceof EObject) { Image image = new StrategyEngineCoreSwitch<Image>() { @Override public Image caseStrategyEngine(StrategyEngine object) { return getResourceManager() .createImageWithDefault( StrategyEngineImage.ENGINE_OBJ .getImageDescriptor()); } @Override public Image caseStrategy(Strategy object) { return getResourceManager().createImageWithDefault( StrategyEngineImage.STRATEGY_OBJ .getImageDescriptor()); } }.doSwitch((EObject) element); if (image != null) { return image; } } return super.getImage(element); } /** * Provides the resource manager that will be disposed with this object. * Subclasses can use this to safely allocate images. * * @return the resource manager. */ protected LocalResourceManager getResourceManager() { return mResourceManager; } @Override public void dispose() { mPropertyWatcher.dispose(); getResourceManager().dispose(); super.dispose(); } }