/*
* 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);
}
}
}