package org.openlca.app.viewers; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.swt.widgets.Composite; import org.openlca.app.util.viewers.Viewers; public abstract class AbstractViewer<T, V extends StructuredViewer> implements org.eclipse.jface.viewers.ISelectionChangedListener { private List<ISelectionChangedListener<T>> listener = new ArrayList<>(); private V viewer; private boolean nullable; private String nullText; protected Object[] viewerParameters; protected AbstractViewer(Composite parent, Object... viewerParameters) { this.viewerParameters = viewerParameters; viewer = createViewer(parent); } protected abstract V createViewer(Composite parent); protected IBaseLabelProvider getLabelProvider() { return new BaseLabelProvider(); } public V getViewer() { return viewer; } public void refresh() { viewer.refresh(); } public void addSelectionChangedListener( ISelectionChangedListener<T> listener) { if (this.listener.size() == 0) { startListening(); } this.listener.add(listener); } public void removeSelectionChangedListener( ISelectionChangedListener<T> listener) { this.listener.remove(listener); if (this.listener.size() == 0) { stopListening(); } } @SuppressWarnings("unchecked") public ISelectionChangedListener<T>[] getSelectionChangedListeners() { return listener.toArray(new ISelectionChangedListener[listener.size()]); } /** * Adds an empty/null value as first element in the viewer, you can specify * the text of this null element via #setNullText */ public void setNullable(boolean nullable) { boolean changed = this.nullable != nullable; this.nullable = nullable; if (changed && viewer.getInput() != null) setInternalInput((Object[]) viewer.getInput()); } public boolean isNullable() { return nullable; } protected void setNullText(String nullText) { this.nullText = nullText; } private Object[] getInternalInput() { return (Object[]) viewer.getInput(); } public void setInput(Collection<T> collection) { if (collection == null) setInternalInput(new Object[0]); else setInternalInput(collection.toArray()); } public void setInput(T[] input) { if (input == null) setInternalInput(new Object[0]); else setInternalInput(input); } private void setInternalInput(Object[] input) { Object[] internalInput = new Object[nullable ? input.length + 1 : input.length]; if (nullable) internalInput[0] = new Null(); for (int i = 0; i < input.length; i++) internalInput[nullable ? i + 1 : i] = input[i]; viewer.setInput(internalInput); } public T getSelected() { if (Viewers.getFirst(viewer.getSelection()) instanceof AbstractViewer.Null) return null; return Viewers.getFirst(viewer.getSelection()); } public void select(T value) { internalSelect(value); } private void internalSelect(Object value) { if (value != null) viewer.setSelection(new StructuredSelection(value)); else if (nullable) viewer.setSelection(new StructuredSelection(new Null())); else viewer.setSelection(new StructuredSelection()); } public void selectFirst() { Object[] input = getInternalInput(); if (input == null) return; if (input.length == 0) return; internalSelect(input[0]); } @Override @SuppressWarnings("unchecked") public void selectionChanged(SelectionChangedEvent event) { Object obj = Viewers.getFirst(event.getSelection()); T selection = null; if (!Null.class.isInstance(obj)) selection = (T) obj; for (ISelectionChangedListener<T> listener : this.listener) { listener.selectionChanged(selection); } } public void setEnabled(boolean value) { getViewer().getControl().setEnabled(value); } private void startListening() { viewer.addSelectionChangedListener(this); } private void stopListening() { viewer.removeSelectionChangedListener(this); } protected class Null { @Override public boolean equals(Object arg0) { return true; } @Override public String toString() { return nullText == null ? "" : nullText; } } }