/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.workflow.editor.properties; import org.eclipse.gef.commands.CommandStack; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.views.properties.IPropertyDescriptor; import org.eclipse.ui.views.properties.TextPropertyDescriptor; import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory; import de.rcenvironment.core.component.workflow.model.api.WorkflowNode; import de.rcenvironment.core.gui.utils.common.configuration.ConfigurationViewer; import de.rcenvironment.core.gui.utils.common.configuration.ConfigurationViewerContentProvider; import de.rcenvironment.core.gui.utils.common.configuration.ConfigurationViewerLabelProvider; import de.rcenvironment.core.gui.utils.common.configuration.IConfigurationSource; /** * {@link WorkflowNodePropertySection} for displaying and editing the properties of a workflow node. * * @author Christian Weiss */ public class WorkflowNodePropertiesSection extends WorkflowNodePropertySection { private static final String NULL_CONTROL_PROPERTY_KEY = ""; private static final int MINIMUM_HEIGHT = 60; /** The content provider for the {@link #configurationViewer}. */ private final ConfigurationViewerContentProvider configurationViewerContentProvider = new ConfigurationViewerContentProvider(); /** The label provider for the {@link #configurationViewer}. */ private final ConfigurationViewerLabelProvider configurationViewerLabelProvider = new ConfigurationViewerLabelProvider(); private final ISelectionChangedListener propertyValueTextSynchronizer = new ConfigurationViewerSelectionChangedListener(); private ConfigurationViewer configurationViewer; private Text propertyValueText; @Override protected void createCompositeContent(final Composite parent, final TabbedPropertySheetPage aTabbedPropertySheetPage) { final TabbedPropertySheetWidgetFactory toolkit = aTabbedPropertySheetPage.getWidgetFactory(); final Composite content = parent; content.setLayout(new GridLayout(1, true)); GridData layoutData; layoutData = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL); parent.setLayoutData(layoutData); final SashForm sashForm = createSash(content, SWT.VERTICAL); toolkit.adapt(sashForm); } private SashForm createSash(final Composite content, final int style) { GridData layoutData; // sash final SashForm sashForm = new SashForm(content, style); // configuration viewer configurationViewer = new ConfigurationViewer(sashForm, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE); layoutData = new GridData(GridData.FILL_BOTH); layoutData.minimumHeight = MINIMUM_HEIGHT; layoutData.grabExcessHorizontalSpace = true; layoutData.grabExcessVerticalSpace = true; configurationViewer.getTree().getParent().setLayoutData(layoutData); configurationViewer.setContentProvider(configurationViewerContentProvider); configurationViewer.setLabelProvider(configurationViewerLabelProvider); // property value text propertyValueText = new Text(sashForm, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); propertyValueText.setText(""); layoutData = new GridData(GridData.FILL_BOTH); layoutData.minimumHeight = MINIMUM_HEIGHT; propertyValueText.setLayoutData(layoutData); propertyValueText.setData(CONTROL_PROPERTY_KEY, NULL_CONTROL_PROPERTY_KEY); sashForm.setWeights(new int[] { 3, 1 }); layoutData = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL); layoutData.minimumHeight = MINIMUM_HEIGHT; layoutData.grabExcessHorizontalSpace = true; layoutData.grabExcessVerticalSpace = true; sashForm.setLayoutData(layoutData); return sashForm; } @Override protected void afterInitializingModelBinding() { configurationViewer.addSelectionChangedListener(propertyValueTextSynchronizer); } @Override protected void beforeTearingDownModelBinding() { configurationViewer.removeSelectionChangedListener(propertyValueTextSynchronizer); } @Override protected Synchronizer createSynchronizer() { return new PropertiesSynchronizer(); } @Override public void refreshSection() { super.refreshSection(); configurationViewer.setInput(new PropertiesConfigurationSource(getCommandStack(), (WorkflowNode) getConfiguration())); configurationViewer.getTree().update(); } /** * {@link Synchronizer} implementation to update the {@link #configurationViewer} upon property * changes. * * @author Christian Weiss */ protected class PropertiesSynchronizer extends DefaultSynchronizer { @Override public void handlePropertyChange(final String propertyName, final String newValue, final String oldValue) { super.handlePropertyChange(propertyName, newValue, oldValue); super.handlePropertyChange(propertyName, newValue, oldValue); configurationViewer.refresh(); } } /** * {@link IConfigurationSource} implementation to wrap the properties of a * {@link de.rcenvironment.rce.component.workflow.ReadableComponentInstanceConfiguration} to * display them in a {@link ConfigurationViewer}. * * @author Christian Weiss */ protected class PropertiesConfigurationSource extends ComponentPropertySource implements IConfigurationSource { public PropertiesConfigurationSource(final CommandStack stack, final WorkflowNode node) { super(stack, node); } @Override public Object getPropertyValue(final Object key) { return getProperty((String) key); } @Override public void setPropertyValue(final Object key, final Object value) { final String propertyName = (String) key; String propertyValue = (String) value; WorkflowNodePropertiesSection.this.setProperty(propertyName, propertyValue); } @Override public IPropertyDescriptor[] getConfigurationPropertyDescriptors() { final IPropertyDescriptor[] propertyDescriptors = getPropertyDescriptors(); final int propertyCount = propertyDescriptors.length; final IPropertyDescriptor[] result = new IPropertyDescriptor[propertyCount]; for (int index = 0; index < propertyCount; ++index) { result[index] = propertyDescriptors[index]; } return result; } } /** * {@link ISelectionChangedListener} to listen to selection changes in the * {@link #configurationViewer} and update the {@link #propertyValueText} with the property * content. * * @author Christian Weiss */ private class ConfigurationViewerSelectionChangedListener implements ISelectionChangedListener { @Override public void selectionChanged(final SelectionChangedEvent event) { String propertyKey = NULL_CONTROL_PROPERTY_KEY; final IStructuredSelection selection = (IStructuredSelection) event.getSelection(); if (selection.size() == 1) { final Object firstElement = selection.getFirstElement(); if (firstElement instanceof TextPropertyDescriptor) { final IPropertyDescriptor propertyDescriptor = (IPropertyDescriptor) firstElement; propertyKey = (String) propertyDescriptor.getId(); } } final boolean validProperty = propertyKey != null && !propertyKey.equals(NULL_CONTROL_PROPERTY_KEY); propertyValueText.setEnabled(validProperty); propertyValueText.setData(CONTROL_PROPERTY_KEY, propertyKey); final String value = getProperty(propertyKey); getUpdater().initializeControl(propertyValueText, propertyKey, value); } } }