/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * HUMBOLDT EU Integrated Project #030962 * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.ui.io.source; import java.io.InputStream; import java.util.List; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import eu.esdihumboldt.hale.common.core.io.HaleIO; import eu.esdihumboldt.hale.common.core.io.IOProvider; import eu.esdihumboldt.hale.common.core.io.ImportProvider; import eu.esdihumboldt.hale.common.core.io.extension.IOProviderDescriptor; import eu.esdihumboldt.hale.common.core.io.supplier.LocatableInputSupplier; import eu.esdihumboldt.hale.ui.io.ImportSource; /** * Abstract {@link ImportSource} implementation offering provider selection. * * @param <P> the supported {@link IOProvider} type * * @author Simon Templer * @since 2.5 */ public abstract class AbstractProviderSource<P extends ImportProvider> extends AbstractSource<P> { private ComboViewer providers; /** * Create the provider selector combo viewer. Once created it can be * retrieved using {@link #getProviders()}. This should be called in * {@link #createControls(Composite)}. * * @param parent the parent composite * @return the created combo viewer */ protected ComboViewer createProviders(Composite parent) { // create provider combo providers = new ComboViewer(parent, SWT.DROP_DOWN | SWT.READ_ONLY); providers.setContentProvider(ArrayContentProvider.getInstance()); providers.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { if (element instanceof IOProviderDescriptor) { return ((IOProviderDescriptor) element).getDisplayName(); } return super.getText(element); } }); // process selection changes providers.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { onProviderSelectionChanged(event); } }); return providers; } /** * Called when the provider selection changes. * * @param event the selection changed event */ protected void onProviderSelectionChanged(SelectionChangedEvent event) { updateState(false); } /** * Get the provider selector combo viewer. * * @return the combo viewer with the I/O providers */ protected ComboViewer getProviders() { return providers; } /** * Update the provider selector when the content type has changed. This is * based on the content type stored in the source configuration. */ protected void updateProvider() { IContentType contentType = getConfiguration().getContentType(); if (contentType != null) { IOProviderDescriptor lastSelected = null; ISelection provSel = providers.getSelection(); if (!provSel.isEmpty() && provSel instanceof IStructuredSelection) { lastSelected = (IOProviderDescriptor) ((IStructuredSelection) provSel) .getFirstElement(); } List<IOProviderDescriptor> supported = HaleIO.filterFactories(getConfiguration() .getFactories(), contentType); providers.setInput(supported); if (lastSelected != null && supported.contains(lastSelected)) { // reuse old selection providers.setSelection(new StructuredSelection(lastSelected), true); } else if (!supported.isEmpty()) { // select first provider providers.setSelection(new StructuredSelection(supported.get(0)), true); } providers.getControl().setEnabled(supported.size() > 1); } else { providers.setInput(null); providers.getControl().setEnabled(false); } } /** * Update the page state. This includes setting a provider factory on the * wizard if applicable and setting the complete state of the page.<br> * <br> * This should be called in {@link #createControls(Composite)} to initialize * the page state. * * @param updateContentType if <code>true</code> the content type and the * supported providers will be updated before updating the page * state */ protected void updateState(boolean updateContentType) { if (updateContentType) { updateContentType(); } // update provider factory ISelection provSel = providers.getSelection(); if (!provSel.isEmpty() && provSel instanceof IStructuredSelection) { getConfiguration().setProviderFactory( (IOProviderDescriptor) ((IStructuredSelection) provSel).getFirstElement()); } else { getConfiguration().setProviderFactory(null); } getPage().setPageComplete( isValidSource() && getConfiguration().getContentType() != null && getConfiguration().getProviderFactory() != null); } /** * Update the content type.<br> * <br> * The default implementation only calls {@link #updateProvider()}. * Subclasses may add logic to change the content type in the source * configuration. */ protected void updateContentType() { // update provider selector updateProvider(); } /** * Configures the provider with the input supplier obtained using * {@link #getSource()} as source. * * @see AbstractSource#updateConfiguration(ImportProvider) * @see #getSource() */ @Override public boolean updateConfiguration(P provider) { boolean ok = super.updateConfiguration(provider); if (!ok) { return ok; } LocatableInputSupplier<? extends InputStream> source = getSource(); if (source != null) { provider.setSource(source); return true; } return false; } /** * Get the source to configure the import provider with. * * @return the input supplier as source for the import provider or * <code>null</code> if no valid source can be created * * @see #isValidSource() */ protected abstract LocatableInputSupplier<? extends InputStream> getSource(); /** * Determines if the current page state will result in a valid source for * the import provider. Used among others to determine the complete state of * the wizard page. * * @return if the source is valid * * @see #getSource() */ protected abstract boolean isValidSource(); }