/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.utils.common.configuration; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ComboBoxCellEditor; import org.eclipse.jface.viewers.ICellEditorValidator; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.views.properties.PropertyDescriptor; /** * A {@link PropertyDescriptor} representing a property to which only a set of values can be * applied, which shall be represented through a selection. * * @author Christian Weiss */ public class SelectionPropertyDescriptor extends PropertyDescriptor { /** Index Value pointing to 'no such element'. */ private static final int NO_SUCH_VALUE_INDEX = -1; /** * The interface to be implemented by value providers of the selection values. * * @author Christian Weiss */ public interface ValueProvider { /** * Returns the values. * * @return the values */ Object[] getValues(); } /** The value provider. */ private final ValueProvider valueProvider; /** The labels. */ private List<String> labels; /** The values. */ private List<Object> values; /** * Instantiates a new {@link SelectionPropertyDescriptor}. * * @param id the id * @param displayName the display name * @param selectionProvider the selection provider */ public SelectionPropertyDescriptor(final Object id, final String displayName, final ValueProvider valueProvider) { super(id, displayName); this.valueProvider = valueProvider; } /** * Creates the property editor. * * @param parent the parent * @return the cell editor */ @Override public CellEditor createPropertyEditor(Composite parent) { refresh(); CellEditor editor = new ComboBoxCellEditor(parent, labels.toArray(new String[0]), SWT.READ_ONLY) { @Override protected void doSetValue(final Object value) { if (!(value instanceof Integer)) { super.doSetValue(getIndex(value)); } else { super.doSetValue(value); } } }; editor.setValidator(new ICellEditorValidator() { @Override public String isValid(final Object value) { final List<Object> valuesRef = getValues(); if (valuesRef.contains(value)) { return null; } if (value instanceof Integer) { final int index = (Integer) value; if (index >= NO_SUCH_VALUE_INDEX && index < valuesRef.size()) { return null; } } return "invalid value"; } }); if (getValidator() != null) { editor.setValidator(getValidator()); } return editor; } /** * Returns the labels. * * @return the labels */ private List<String> getLabels() { if (labels == null) { refresh(); } return labels; } /** * Returns the label of the given value. * * @param value the value * @return the label */ public String getLabel(final Object value) { final int index = getIndex(value); if (index < 0) { return null; } return getLabels().get(index); } /** * Returns the index of the given value. * * @param value the value * @return the index */ public Integer getIndex(final Object value) { final int index = getValues().indexOf(value); if (index < 0) { return null; } return index; } /** * Returns the values. * * @return the values */ private List<Object> getValues() { if (values == null) { refresh(); } return values; } /** * Returns the value at the given index. * * @param index the index * @return the value */ public Object getValue(final Integer index) { if (index == NO_SUCH_VALUE_INDEX) { return null; } return values.get(index); } /** * Refresh. */ private void refresh() { if (labels == null || values == null) { labels = new ArrayList<String>(); values = new ArrayList<Object>(); } labels.clear(); values.clear(); for (final Object value : valueProvider.getValues()) { labels.add(getLabelProvider().getText(value)); values.add(value); } } /** * Returns the {@link ILabelProvider}. * * @return the {@link ILabelProvider} */ @Override public ILabelProvider getLabelProvider() { final ILabelProvider labelProvider = super.getLabelProvider(); return new LabelProvider() { @Override public Image getImage(final Object element) { return labelProvider.getImage(lookup(element)); } @Override public String getText(final Object element) { return labelProvider.getText(lookup(element)); } }; } private Object lookup(final Object element) { // if the element is UNknown and an instance of integer it might be the index to // the values list, in that case check the index range and return the element at // that index final List<Object> valuesRef = getValues(); if (!valuesRef.contains(element) && element instanceof Integer) { final int index = (Integer) element; if (index >= 0 && index < valuesRef.size()) { return valuesRef.get(index); } } return element; } }