Java tutorial
/*=============================================================================# # Copyright (c) 2007-2015 Stephan Wahlbrink (WalWare.de) 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: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.statet.r.internal.sweave.processing; import java.util.List; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.Diffs; import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.databinding.observable.value.AbstractObservableValue; import org.eclipse.core.databinding.observable.value.WritableValue; import org.eclipse.core.databinding.validation.IValidator; import org.eclipse.core.databinding.validation.ValidationStatus; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationListener; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.ui.EnvironmentTab; import org.eclipse.debug.ui.ILaunchConfigurationTab; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.statushandlers.StatusManager; import de.walware.ecommons.ICommonStatusConstants; import de.walware.ecommons.debug.ui.LaunchConfigTabWithDbc; import de.walware.ecommons.ui.util.LayoutUtil; import de.walware.ecommons.ui.util.UIAccess; import net.sourceforge.texlipse.Texlipse; import net.sourceforge.texlipse.viewer.TexLaunchConfigurationDelegate; import net.sourceforge.texlipse.viewer.TexLaunchConfigurationTab; import net.sourceforge.texlipse.viewer.ViewerConfiguration; import de.walware.statet.r.internal.sweave.Messages; import de.walware.statet.r.internal.sweave.SweavePlugin; public class PreviewTab extends LaunchConfigTabWithDbc { public static final String NS = "de.walware.statet.r.debug/DocPreview/"; //$NON-NLS-1$ public static final String ATTR_VIEWER_CODE = NS + "Viewer.code"; //$NON-NLS-1$ private class SelectionObservable extends AbstractObservableValue implements SelectionListener, ISelectionChangedListener, IDocumentListener, IValidator { private String fEncodedValue; private IStatus fCurrentStatus; public SelectionObservable() { fCurrentStatus = ValidationStatus.ok(); } @Override public Object getValueType() { return String.class; } @Override protected void doSetValue(final Object value) { if (value instanceof String) { final String s = (String) value; fEncodedValue = s; if (s.startsWith(RweaveTexLaunchDelegate.PREVIEW_IDE)) { updateEnablement(RweaveTexLaunchDelegate.PREVIEW_IDE); fCurrentStatus = ValidationStatus.ok(); return; } else if (s.startsWith(RweaveTexLaunchDelegate.PREVIEW_SPECIAL)) { updateEnablement(RweaveTexLaunchDelegate.PREVIEW_SPECIAL); final String[] split = s.split(":", 2); //$NON-NLS-1$ if (split.length == 2 && split[1].length() > 0) { final List<ViewerConfiguration> configs = fAvailablePreviewConfigs; for (final ViewerConfiguration config : configs) { if (config.getName().equals(split[1])) { fLaunchConfigTable.setSelection(new StructuredSelection(config)); fCurrentStatus = ValidationStatus.ok(); return; } } } fLaunchConfigTable.setSelection(new StructuredSelection()); fCurrentStatus = ValidationStatus .warning(Messages.PreviewTab_LaunchConfig_error_NoConfigSelected_message); return; } } fCurrentStatus = ValidationStatus.ok(); updateEnablement(null); } @Override protected Object doGetValue() { return fEncodedValue; } @Override public void widgetDefaultSelected(final SelectionEvent e) { } @Override public void widgetSelected(final SelectionEvent e) { if (!isInitializing()) { updateValue(); } } @Override public void selectionChanged(final SelectionChangedEvent event) { if (!isInitializing()) { updateValue(); } } @Override public void documentAboutToBeChanged(final DocumentEvent event) { } @Override public void documentChanged(final DocumentEvent event) { if (!isInitializing()) { updateValue(); } } private void updateValue() { String value; if (fSystemSelectControl.getSelection()) { value = RweaveTexLaunchDelegate.PREVIEW_IDE; fCurrentStatus = ValidationStatus.ok(); updateEnablement(RweaveTexLaunchDelegate.PREVIEW_IDE); } else if (fLaunchConfigSelectControl.getSelection()) { final Object selectedLaunch = ((StructuredSelection) fLaunchConfigTable.getSelection()) .getFirstElement(); value = RweaveTexLaunchDelegate.PREVIEW_SPECIAL; if (selectedLaunch instanceof ViewerConfiguration) { value += ':' + ((ViewerConfiguration) selectedLaunch).getName(); fCurrentStatus = ValidationStatus.ok(); } else { fCurrentStatus = ValidationStatus .warning(Messages.PreviewTab_LaunchConfig_error_NoConfigSelected_message); } updateEnablement(RweaveTexLaunchDelegate.PREVIEW_SPECIAL); } else { value = ""; //$NON-NLS-1$ fCurrentStatus = ValidationStatus.ok(); updateEnablement(null); } if (!value.equals(fEncodedValue)) { final String oldValue = fEncodedValue; fEncodedValue = value; fireValueChange(Diffs.createValueDiff(oldValue, value)); } } @Override public IStatus validate(final Object value) { return fCurrentStatus; } public void updateEnablement(final String selection) { fDisableSelectControl.setSelection(selection == null); fSystemSelectControl.setSelection(selection == RweaveTexLaunchDelegate.PREVIEW_IDE); fLaunchConfigSelectControl.setSelection(selection == RweaveTexLaunchDelegate.PREVIEW_SPECIAL); fLaunchConfigTable.getControl().setEnabled(selection == RweaveTexLaunchDelegate.PREVIEW_SPECIAL); fLaunchConfigNewButton.setEnabled(selection == RweaveTexLaunchDelegate.PREVIEW_SPECIAL); } } private List<ViewerConfiguration> fAvailablePreviewConfigs; private WritableValue fSelectionValue; private ILaunchConfigurationListener fLaunchConfigurationListener; private Button fDisableSelectControl; private Button fSystemSelectControl; private Button fLaunchConfigSelectControl; private TableViewer fLaunchConfigTable; private Button fLaunchConfigNewButton; private String fOutputFormat; private TexTab fTexTab; private SelectionObservable fSelectionObservable; @Override public String getName() { return Messages.Processing_PreviewTab_label; } @Override public Image getImage() { return SweavePlugin.getDefault().getImageRegistry().get(SweavePlugin.IMG_TOOL_PREVIEW); } @Override public void createControl(final Composite parent) { final Composite mainComposite = new Composite(parent, SWT.NONE); setControl(mainComposite); mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); mainComposite.setLayout(new GridLayout()); final Label label = new Label(mainComposite, SWT.NONE); label.setText(Messages.PreviewTab_label); label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); LayoutUtil.addSmallFiller(mainComposite, false); Composite composite; composite = new Composite(mainComposite, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); createOptions(composite); fLaunchConfigurationListener = new ILaunchConfigurationListener() { @Override public void launchConfigurationAdded(final ILaunchConfiguration configuration) { updateAvailableConfigs(); } @Override public void launchConfigurationChanged(final ILaunchConfiguration configuration) { updateAvailableConfigs(); } @Override public void launchConfigurationRemoved(final ILaunchConfiguration configuration) { updateAvailableConfigs(); } }; DebugPlugin.getDefault().getLaunchManager().addLaunchConfigurationListener(fLaunchConfigurationListener); initBindings(); } private void createOptions(final Composite group) { GridData gd; group.setLayout(LayoutUtil.applyCompositeDefaults(new GridLayout(), 2)); fDisableSelectControl = new Button(group, SWT.RADIO); fDisableSelectControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); fDisableSelectControl.setText(Messages.PreviewTab_Disable_label); LayoutUtil.addSmallFiller(group, false); fSystemSelectControl = new Button(group, SWT.RADIO); fSystemSelectControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); fSystemSelectControl.setText(Messages.PreviewTab_SystemEditor_label); LayoutUtil.addSmallFiller(group, false); fLaunchConfigSelectControl = new Button(group, SWT.RADIO); fLaunchConfigSelectControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); fLaunchConfigSelectControl.setText(Messages.PreviewTab_LaunchConfig_label); fLaunchConfigTable = new TableViewer(group, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION); gd = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1); gd.horizontalIndent = LayoutUtil.defaultIndent(); gd.heightHint = LayoutUtil.hintHeight(fLaunchConfigTable.getTable(), 5); fLaunchConfigTable.getControl().setLayoutData(gd); fLaunchConfigTable.setLabelProvider(new LabelProvider() { @Override public String getText(final Object element) { if (element instanceof ViewerConfiguration) { return ((ViewerConfiguration) element).getName(); } return super.getText(element); } }); fLaunchConfigTable.setContentProvider(new ArrayContentProvider()); fLaunchConfigTable.setInput(new Object()); fLaunchConfigNewButton = new Button(group, SWT.PUSH); fLaunchConfigNewButton.setText(Messages.PreviewTab_LaunchConfig_NewConfig_label); gd = new GridData(SWT.FILL, SWT.TOP, false, false); gd.widthHint = LayoutUtil.hintWidth(fLaunchConfigNewButton); fLaunchConfigNewButton.setLayoutData(gd); fLaunchConfigNewButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { createNewPreviewLaunchConfig(); } }); } private final Runnable fUpdateConfigsRunnable = new Runnable() { @Override public void run() { fUpdateConfigsScheduled = false; if (fTexTab == null) { final ILaunchConfigurationTab[] tabs = getLaunchConfigurationDialog().getTabs(); for (int i = 0; i < tabs.length; i++) { if (tabs[i] instanceof TexTab) { fTexTab = (TexTab) tabs[i]; } } if (fTexTab == null) { return; } if (!fTexTab.addOutputFormatListener(new IChangeListener() { @Override public void handleChange(final ChangeEvent event) { updateAvailableConfigs(); } })) { fTexTab = null; return; } } fOutputFormat = fTexTab.getOutputFormat(); fAvailablePreviewConfigs = Texlipse.getViewerManager().getAvailableConfigurations(fOutputFormat); if (UIAccess.isOkToUse(fLaunchConfigTable)) { fLaunchConfigTable.setInput(fAvailablePreviewConfigs); if (fSelectionObservable != null) { fSelectionObservable.updateValue(); } } } }; private volatile boolean fUpdateConfigsScheduled; private void updateAvailableConfigs() { final Display display = UIAccess.getDisplay(); if (display.getThread() == Thread.currentThread()) { fUpdateConfigsRunnable.run(); } else if (!fUpdateConfigsScheduled) { fUpdateConfigsScheduled = true; display.asyncExec(fUpdateConfigsRunnable); } } private void createNewPreviewLaunchConfig() { try { final ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); final ILaunchConfigurationType type = launchManager .getLaunchConfigurationType(TexLaunchConfigurationDelegate.CONFIGURATION_ID); final String name = getLaunchConfigurationDialog().generateName( NLS.bind(Messages.PreviewTab_LaunchConfig_NewConfig_seed, fOutputFormat.toUpperCase())); final ILaunchConfigurationWorkingCopy config = type.newInstance(null, name); new EnvironmentTab().setDefaults(config); new TexLaunchConfigurationTab().setDefaults(config); fSelectionValue.setValue(RweaveTexLaunchDelegate.PREVIEW_SPECIAL + ':' + name); setDirty(true); config.doSave(); } catch (final CoreException e) { StatusManager.getManager().handle( new Status(IStatus.ERROR, SweavePlugin.PLUGIN_ID, ICommonStatusConstants.LAUNCHCONFIG_ERROR, Messages.PreviewTab_LaunchConfig_NewConfig_error_Creating_message, e), StatusManager.LOG | StatusManager.SHOW); } } @Override protected void addBindings(final DataBindingContext dbc, final Realm realm) { fSelectionValue = new WritableValue(realm, String.class); fSelectionObservable = new SelectionObservable(); fDisableSelectControl.addSelectionListener(fSelectionObservable); fSystemSelectControl.addSelectionListener(fSelectionObservable); fLaunchConfigSelectControl.addSelectionListener(fSelectionObservable); fLaunchConfigTable.addSelectionChangedListener(fSelectionObservable); fSelectionValue.setValue("init"); //$NON-NLS-1$ dbc.bindValue(fSelectionObservable, fSelectionValue, new UpdateValueStrategy().setAfterGetValidator(fSelectionObservable), null); } @Override public void setDefaults(final ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(ATTR_VIEWER_CODE, RweaveTexLaunchDelegate.PREVIEW_IDE); } @Override protected void doInitialize(final ILaunchConfiguration configuration) { updateAvailableConfigs(); String value = null; try { value = configuration.getAttribute(ATTR_VIEWER_CODE, ""); //$NON-NLS-1$ } catch (final CoreException e) { logReadingError(e); } final Object firstConfig = fLaunchConfigTable.getElementAt(0); fLaunchConfigTable.setSelection( (firstConfig != null) ? new StructuredSelection(firstConfig) : new StructuredSelection()); fSelectionValue.setValue(value); } @Override protected void doSave(final ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(ATTR_VIEWER_CODE, (String) fSelectionValue.getValue()); } @Override public void dispose() { if (fLaunchConfigurationListener != null) { DebugPlugin.getDefault().getLaunchManager() .removeLaunchConfigurationListener(fLaunchConfigurationListener); fLaunchConfigurationListener = null; } super.dispose(); } }