/*******************************************************************************
* Copyright (c) 2012 Pivotal Software, Inc.
* 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:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springsource.ide.eclipse.commons.frameworks.ui.internal.wizard;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.CompositeCommandParameter;
import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.ICommandParameter;
import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.ICommandParameterDescriptor;
import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.IFrameworkCommand;
import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.JavaParameterDescriptor;
import org.springsource.ide.eclipse.commons.frameworks.core.internal.commands.ParameterKind;
import org.springsource.ide.eclipse.commons.frameworks.ui.internal.contentassist.JavaContentAssistUIAdapter;
import org.springsource.ide.eclipse.commons.frameworks.ui.internal.parameters.editors.BooleanParameterEditor;
import org.springsource.ide.eclipse.commons.frameworks.ui.internal.parameters.editors.IParameterEditor;
import org.springsource.ide.eclipse.commons.frameworks.ui.internal.parameters.editors.IProjectSelectionChangeListener;
import org.springsource.ide.eclipse.commons.frameworks.ui.internal.parameters.editors.IUIChangeListener;
import org.springsource.ide.eclipse.commons.frameworks.ui.internal.parameters.editors.ParameterEditorFactory;
import org.springsource.ide.eclipse.commons.frameworks.ui.internal.parameters.editors.UIEvent;
/**
* Displays editors for each parameter in a command.
* <p>
* Editors are aligned and spaced using equal units. The amount of space between
* the edge of the main composite and all the editors can be controlled by this
* wizard page.
* </p>
* <p>
* Usually most editors each are displayed in 2 column composites, where the
* first column contains a label with the parameter name, and is left-aligned,
* and the second column contains all the remaining controls for the editor. The
* wizard defines the composite that is passed to each editor, that way it can
* control the spacing and alignment of the editor layout, and maintain
* exactness for all of them.
* </p>
* @author Nieraj Singh
*/
public class GenericWizardCommandParametersPage extends
AbstractGenericWizardPage implements IUIChangeListener {
private IFrameworkCommand command;
private Point longestLabelWidth;
private List<IProjectSelectionChangeListener> projectSelectionListeners;
/**
* Keeps track of which characters have mneumonics for Alt+? keyboard
* shortcut navigation NOTE that there are RESERVED letters that are already
* used by the wizard for the Next, Back and Finish buttons
*/
public static final String RESERVED_KEYBOARD_SHORTCUTS = "BbNnFf";
private StringBuffer mneumonicsKeyBoardShortcuts = new StringBuffer()
.append(RESERVED_KEYBOARD_SHORTCUTS);
// This can't be a mneumonic, therefore use it to determine that no valid
// letters were encountered in a label when deciding to find a suitable
// shortcut
private static final char NON_MNEUMONIC = '\0';
public GenericWizardCommandParametersPage(IFrameworkCommand command) {
super("Configure command parameters");
setDescription("Configure the command parameters. Finishing the wizard will execute the command. Required fields must have values before the wizard can complete.");
this.command = command;
if (command != null) {
setTitle(command.getCommandDescriptor().getName());
}
projectSelectionListeners = new ArrayList<IProjectSelectionChangeListener>();
}
/**
* Returns the command instance that was edited by this page. Cannot be
* null.
*
* @return non-null command instance that was edited by this page.
*/
public IFrameworkCommand getCommand() {
return command;
}
protected Composite createPageArea(Composite parent) {
if (command == null) {
setErrorMessage("No command specified. Please select a command first");
return parent;
}
List<ICommandParameter> parameters = command.getParameters();
if (parameters == null) {
return parent;
}
Composite parameterArea = new Composite(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parameterArea);
GridDataFactory.fillDefaults().grab(true, true).applyTo(parameterArea);
if (groupRequiredParameters()) {
// Group required parameters first
List<ICommandParameter> requiredParameters = new ArrayList<ICommandParameter>();
List<ICommandParameter> optionalParameters = new ArrayList<ICommandParameter>();
for (ICommandParameter parameter : parameters) {
boolean isMandatory = parameter.getParameterDescriptor()
.isMandatory();
if (isMandatory) {
requiredParameters.add(parameter);
} else {
optionalParameters.add(parameter);
}
}
if (!requiredParameters.isEmpty()) {
createParameterEditors(parameterArea, "Required Parameters",
requiredParameters);
}
if (!optionalParameters.isEmpty()) {
createParameterEditors(parameterArea, "Optional Parameters",
optionalParameters);
}
} else {
createParameterEditors(parameterArea, "Parameters", parameters);
}
checkPageComplete(false);
return parameterArea;
}
protected Composite createParameterEditors(Composite parent,
String groupLabel, List<ICommandParameter> parameters) {
Group parameterGroup = new Group(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parameterGroup);
GridDataFactory.fillDefaults().grab(true, true).applyTo(parameterGroup);
parameterGroup.setText(groupLabel);
ScrolledComposite scrolledParameterArea = new ScrolledComposite(
parameterGroup, SWT.V_SCROLL);
GridDataFactory.fillDefaults().grab(true, true)
.applyTo(scrolledParameterArea);
scrolledParameterArea.setFont(parent.getFont());
scrolledParameterArea.setExpandHorizontal(true);
scrolledParameterArea.setExpandVertical(true);
// Contains the actual editors that need to be placed under the
// scrollable composite
Composite editorContent = new Composite(scrolledParameterArea, SWT.NONE);
GridLayoutFactory
.fillDefaults()
.numColumns(1)
.margins(getEditorAreaWidthMargin(),
getEditorAreaHeightMargin())
.spacing(SWT.DEFAULT, getVerticalEditorControlSpacing())
.applyTo(editorContent);
GridDataFactory.fillDefaults().grab(true, true).applyTo(editorContent);
createEditors(editorContent, parameters);
// Content has to be set AFTER the editors are created
scrolledParameterArea.setContent(editorContent);
scrolledParameterArea.setMinSize(editorContent.computeSize(SWT.DEFAULT,
SWT.DEFAULT));
return scrolledParameterArea;
}
/**
* If true group mandatory/required parameters first. If false create the
* parameter controls in the order that they appear in the command
* descriptor. This does NOT rearrange the order of the parameters in the
* command. It only affects the order of the controls in the UI, but the
* order of the parameters in the command itself is unchanged.
*
* @return true if group mandatory parameters. False if parameter order is
* to be preserved.
*/
protected boolean groupRequiredParameters() {
return getGenericCommandWizard().groupRequiredParameters();
}
/**
* Converts a label into a shortcut-enabled label, IF one of the characters
* in the label hasn't already been used by another label. If all the
* characters in the label have already been used, the same label is
* returned and no shortcuts are enabled for that control
*
* @param label
* to convert into shortcut-enabled version
* @return shortcut-enabled version if a letter is found that can be used as
* a shortcut, or the same label if no shortcut letters are found
*/
protected String getControlLabelWithKeyboardShortcut(String label) {
if (label == null || label.length() == 0) {
return label;
}
// This can't be a mneumonic so use it to decide if a mneumonic was
// found or not
char possibleMneumonic = NON_MNEUMONIC;
int mneumonicLocation = 0;
for (; mneumonicLocation < label.length(); mneumonicLocation++) {
if (!isMneumonicShortcutAssigned(label.charAt(mneumonicLocation))) {
possibleMneumonic = label.charAt(mneumonicLocation);
mneumonicsKeyBoardShortcuts.append(possibleMneumonic);
break;
}
}
if (possibleMneumonic != NON_MNEUMONIC) {
// Add support for the Alt+? navigation which means adding an '&'
// before the
// shortcut letter
String keyBoardShortCutLabel = new StringBuffer(label).insert(
mneumonicLocation, '&').toString();
return keyBoardShortCutLabel;
}
return label;
}
/**
* Determine if a character has already been used as a shortcut for another
* label control. If so return true. Else return false.
*
* @param ch
* @return true if character is already used as a shortcut. False otherwise.
*/
protected boolean isMneumonicShortcutAssigned(char ch) {
for (int i = 0; i < mneumonicsKeyBoardShortcuts.length(); i++) {
if (mneumonicsKeyBoardShortcuts.charAt(i) == ch) {
return true;
}
}
return false;
}
/**
* Create editors for each parameter in the parameter list. All editors are
* added to the specified Composite parent.
*
* @param parent
* parent composite containing the editor controls
* @param parameters
* list of parameters whose editors should be added to the parent
* composite
*/
protected void createEditors(Composite parent,
List<ICommandParameter> parameters) {
if (parameters == null) {
return;
}
// Use index to iterate to keep track of consecutive boolean editors
for (int createdElementIndex = 0; createdElementIndex < parameters
.size();) {
ICommandParameter parameter = parameters.get(createdElementIndex);
ParameterKind kind = parameter.getParameterDescriptor()
.getParameterKind();
if (kind == null) {
continue;
}
switch (kind) {
case COMPOSITE:
createCompositeEditor(parent,
(CompositeCommandParameter) parameter);
break;
default:
createdElementIndex = createEditor(parent, parameters,
createdElementIndex, null, true);
}
createdElementIndex++;
}
}
/**
* Creates a single Editor for the parameter instance referenced by the
* index argument, EXCEPT in the case of consecutive Boolean parameters.
* This method will create n number of Boolean editors that appear in
* consecutive order, and will return the index of the last created Boolean
* editor.
* <p>
* Example: if a list of parameters contains the following: 1 Java
* parameter, 3 Boolean Parameters, and 1 Combo parameter, in the stated
* order, this method is called 3 times, once for the java parameter, once
* for the 3 Boolean parameters, and once for the Combo parameter. The 3
* consecutive Boolean parameters are all handled in one call.
* </p>
*
* @param kind
* type of parameter editor to create
* @param parent
* Composite parent for the editor
* @param parameters
* list of parameter instances
* @param currentIndex
* index of the parameter instance that needs to be passed into
* the editor
* @param showLabel
* whether label controls should be shown for the editor.
* @return index of the last editor that was created
*/
protected int createEditor(Composite parent,
List<ICommandParameter> parameters, int currentIndex,
List<IParameterEditor> editorList, boolean showLabel) {
if (parameters != null && currentIndex >= 0
&& currentIndex < parameters.size()) {
ICommandParameter parameter = parameters.get(currentIndex);
IParameterEditor editor = null;
ParameterKind kind = parameter.getParameterDescriptor()
.getParameterKind();
switch (kind) {
case BOOLEAN:
// Add the boolean editors separately, as they are arranged
// differently
currentIndex = addBooleanEditors(parent, parameters,
currentIndex, editorList);
break;
case BASE:
editor = getTextEditor(parameter, showLabel);
break;
case JAVA_TYPE:
editor = getJavaEditor(parameter, showLabel);
break;
case COMBO:
editor = getComboEditor(parameter, showLabel);
break;
}
if (editor != null) {
addAndConfigureEditor(parent, editor, editorList);
}
}
return currentIndex;
}
/**
* Certain types of editors like base, Java and combo editors have labels
* that contain the parameter name. This method creates a label for each of
* these editors and sets the size of all the labels to a fixed width such
* that all labeled controls are properly aligned.
*
* @param editor
* @param parent
*/
protected void addLabel(IParameterEditor editor, Composite parent) {
if (editor == null || parent == null) {
return;
}
ICommandParameterDescriptor parameter = editor.getParameterDescriptor();
String parameterName = getControlLabelWithKeyboardShortcut(parameter
.getName());
Label parameterNameLabel = new Label(parent, SWT.READ_ONLY);
parameterNameLabel.setText(parameterName + ": ");
parameterNameLabel.setToolTipText(parameter.getDescription());
GridDataFactory.fillDefaults().grab(false, false)
.align(SWT.FILL, SWT.CENTER).applyTo(parameterNameLabel);
// Set the label dimensions based on the longest label string
Point labelSize = getLongestLabelSize();
if (labelSize != null) {
GridData data = (GridData) parameterNameLabel.getLayoutData();
int heightHint = labelSize.y;
if (heightHint > 0) {
data.heightHint = heightHint;
}
int widthHint = labelSize.x;
if (widthHint > 0) {
data.widthHint = widthHint;
}
}
}
/**
* Usually editors notify the page when values have been entered to allow
* the page to determine if the wizard can complete or not
*/
public void handleUIEvent(UIEvent event) {
if ((event.getType() & UIEvent.VALUE_SET) == UIEvent.VALUE_SET) {
checkPageComplete(true);
}
}
/**
*
* @param parent
* @param parameters
* @param currentIndex
* @param showLabel
* @return
*/
protected void createCompositeEditor(Composite parent,
CompositeCommandParameter compositeParameter) {
List<ICommandParameter> childParameters = compositeParameter
.getParameters();
if (!childParameters.isEmpty()) {
List<IParameterEditor> childEditors = new ArrayList<IParameterEditor>();
for (int lastCreatedIndex = 0; lastCreatedIndex < childParameters
.size();) {
boolean showLabel = lastCreatedIndex == 0 ? true : false;
lastCreatedIndex = createEditor(parent, childParameters,
lastCreatedIndex, childEditors, showLabel);
lastCreatedIndex++;
}
new CompositeParameterController(childEditors).start();
}
}
/**
* Inspects all editors to determine if any required parameters have their
* values filled. The wizard's finish button is disabled if any required
* parameters need to be filled in.
* <p>
* In addition, if the set error message flag is set to true, an error
* message will be printed to the wizard dialogue indicating which
* parameters still need to be completed.
* </p>
*
* @param setErrorMessage
*/
protected void checkPageComplete(boolean setErrorMessage) {
boolean isPageComplete = true;
setErrorMessage(null);
List<ICommandParameter> parameters = getCommand().getParameters();
if (parameters != null) {
StringBuffer bufferMessage = new StringBuffer();
bufferMessage.append("Missing required value for: ");
boolean first = true;
for (ICommandParameter parameter : parameters) {
if (parameter.getParameterDescriptor().isMandatory()
&& !parameter.hasValue()) {
if (first) {
first = false;
} else {
bufferMessage.append(", ");
}
bufferMessage.append(parameter.getParameterDescriptor()
.getName());
isPageComplete &= false;
}
}
if (!isPageComplete && setErrorMessage) {
setErrorMessage(bufferMessage.toString());
}
}
setPageComplete(isPageComplete);
}
/**
* Creates controls for boolean editors that appear in consecutive order
* starting from the given index.
* <p/>
* If there are n consecutive boolean editors, this will create n editors
* arranged in a composite with m columns.
* <p/>
* Returns the index of the last boolean editor created in the series of
* consecutive boolean editors, or -1 if no boolean editors are found
*
* @param parent
* @param parameters
* @param booleanEditorIndex
* @return
*/
protected int addBooleanEditors(Composite parent,
List<ICommandParameter> parameters, int booleanEditorIndex,
List<IParameterEditor> editors) {
if (parameters == null || booleanEditorIndex < 0
|| booleanEditorIndex >= parameters.size()) {
return -1;
}
if (parameters.get(booleanEditorIndex).getParameterDescriptor()
.getParameterKind() != ParameterKind.BOOLEAN) {
return -1;
}
Composite booleanArea = new Composite(parent, SWT.NONE);
// Indent the composite containing the boolean controls such that they
// are aligned with the text controls for other editors.
GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false)
.applyTo(booleanArea);
GridData booleanAreaData = new GridData(SWT.FILL, SWT.FILL, false,
false);
booleanAreaData.horizontalIndent = getNonLabelControlIndentation();
booleanArea.setLayoutData(booleanAreaData);
int consecutiveBooleanIndex = booleanEditorIndex;
for (; consecutiveBooleanIndex < parameters.size();) {
ICommandParameter parameter = parameters
.get(consecutiveBooleanIndex);
if (parameter.getParameterDescriptor().getParameterKind() == ParameterKind.BOOLEAN) {
// Indent the boolean editor by the longest label length
IParameterEditor editor = ParameterEditorFactory
.getBooleanParameterEditor(parameter);
if (editor == null) {
continue;
}
addAndConfigureEditor(booleanArea, editor, editors);
// assign current index before incrementing
booleanEditorIndex = consecutiveBooleanIndex++;
} else {
break;
}
}
// return index of last boolean editor created
return booleanEditorIndex;
}
/**
* Adds an editor to the given editor list.
*
* @param parent
* @param editor
* @param editorList
*/
protected void addAndConfigureEditor(Composite parent,
IParameterEditor editor, List<IParameterEditor> editorList) {
editor.addUIChangeListener(this);
createEditorControl(parent, editor);
// As Boolean editors do not have labels, but still should have
// keyboard shortcuts, configure the Boolean editors to have keyboard
// shortcuts
if (editor.getParameterDescriptor().getParameterKind() == ParameterKind.BOOLEAN) {
Button button = ((BooleanParameterEditor) editor)
.getButtonControl();
String buttonText = button.getText();
button.setText(getControlLabelWithKeyboardShortcut(buttonText));
}
if (editorList != null) {
editorList.add(editor);
}
}
/**
* Creates an editor with label and Text controls. It sets the size of the
* label control based on the longest label name it can find.
*
* @param parent
* @param parameter
* @return created editor, or null if not created.
*/
protected IParameterEditor getTextEditor(ICommandParameter parameter,
boolean showLabel) {
if (parameter == null) {
return null;
}
IParameterEditor editor = ParameterEditorFactory.getParameterEditor(
parameter, showLabel);
return editor;
}
protected IParameterEditor getJavaEditor(ICommandParameter parameter,
boolean showLabel) {
if (parameter == null) {
return null;
}
if (parameter.getParameterDescriptor().getParameterKind() != ParameterKind.JAVA_TYPE) {
return null;
}
GenericCommandWizard wizard = getGenericCommandWizard();
ICommandParameterDescriptor descriptor = parameter
.getParameterDescriptor();
JavaContentAssistUIAdapter adapter = wizard != null
&& (descriptor instanceof JavaParameterDescriptor) ? wizard
.getJavaContentAssistUIAdapter((JavaParameterDescriptor) descriptor)
: null;
IParameterEditor editor = ParameterEditorFactory
.getJavaParameterEditor(parameter, adapter, showLabel);
if (adapter instanceof IProjectSelectionChangeListener) {
IProjectSelectionChangeListener listener = (IProjectSelectionChangeListener) adapter;
projectSelectionListeners.add(listener);
// Set the current selection.
listener.projectSelectionChanged(wizard.getSelectedProject());
}
return editor;
}
protected void setProjectInWizard(IProject selectedProject) {
super.setProjectInWizard(selectedProject);
// notify listeners that a project selection has changed
for (IProjectSelectionChangeListener listener : projectSelectionListeners) {
listener.projectSelectionChanged(selectedProject);
}
}
/**
* Creates the editor controls. Each editor is created with a 1 column
* composite where all editor controls are displayed. In addition, a label
* control with the parameter name is added if the editor requests a name
* label to be created.
*
* @param parent
* @param editor
*/
protected void createEditorControl(Composite parent, IParameterEditor editor) {
if (editor == null) {
return;
}
Composite editorRow = new Composite(parent, SWT.NONE);
boolean requiresLabel = editor.requiresParameterNameLabel();
// One column should be reserved for the label
// the other column should contain the composite that
// in turn contains all of the editor controls
int columns = requiresLabel ? 2 : 1;
GridLayoutFactory.fillDefaults().numColumns(columns).margins(0, 0)
.spacing(getHorizontalEditorControlSpacing(), SWT.DEFAULT)
.applyTo(editorRow);
GridDataFactory.fillDefaults().grab(true, false).applyTo(editorRow);
GridData editorControlsGridData = new GridData(SWT.FILL, SWT.CENTER,
true, false);
if (editor.requiresParameterNameLabel()) {
addLabel(editor, editorRow);
} else if (editor.getParameterDescriptor().getParameterKind() != ParameterKind.BOOLEAN) {
// This handles the case where editors form part of a composite
// editor, and therefore
// have no labels of there own but still need to be indented the
// same distance as the label as to keep all controls, whether they
// have labels or not, propertly aligned.
// Boolean parameters don't need to be indented, as the
// composite containing the boolean parameters is already indented
editorControlsGridData.horizontalIndent = getNonLabelControlIndentation();
}
// Composite that contains all the editor controls.
Composite editorControls = new Composite(editorRow, SWT.NONE);
GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0)
.applyTo(editorControls);
editorControls.setLayoutData(editorControlsGridData);
editor.createControls(editorControls);
}
/**
* Return the indentation of all parameter controls that have no label, like
* boolean parameters, or parameters that are part of a composite parameter
*
* @return
*/
protected int getNonLabelControlIndentation() {
return getLongestLabelSize().x + getHorizontalEditorControlSpacing();
}
/**
* Creates and formats a combo editor.
*
* @param parent
* @param parameter
* @return
*/
protected IParameterEditor getComboEditor(ICommandParameter parameter,
boolean showLabel) {
IParameterEditor editor = ParameterEditorFactory.getParameterEditor(
parameter, showLabel);
return editor;
}
/**
* Given a list of parameters, find the parameter name that is the longest,
* as this will be used to compute the pixel equivalent width for the label
* column.
*
* @param parent
* @param parameters
* @return longest parameter name that is found in pixels.
*/
protected Point getLongestLabelSize() {
if (longestLabelWidth != null) {
return longestLabelWidth;
}
int length = SWT.DEFAULT;
int charLength = 0;
List<ICommandParameter> parameters = getCommand().getParameters();
if (parameters != null) {
for (ICommandParameter parameter : parameters) {
// only compute label length of Base and Java editors
ParameterKind kind = parameter.getParameterDescriptor()
.getParameterKind();
if (kind != ParameterKind.BOOLEAN) {
String name = parameter.getParameterDescriptor().getName();
if (name != null) {
int nameLength = name.length();
if (nameLength > charLength) {
charLength = nameLength;
}
}
}
}
}
if (charLength > 0) {
Control control = getShell();
GC gc = new GC(control);
Font requiredLabelFont = getRequiredParameterFont();
gc.setFont(requiredLabelFont != null ? requiredLabelFont : control
.getFont());
FontMetrics fontMetrics = gc.getFontMetrics();
// Increment the length by a few pixels to cover colon that may be
// appended
length = Dialog
.convertWidthInCharsToPixels(fontMetrics, charLength);
gc.dispose();
}
longestLabelWidth = new Point(length, -1);
longestLabelWidth.x += getLabelNameSeparatorOffset();
return longestLabelWidth;
}
/**
*
* @return optional font type to use (bold, italic, etc..) used for to
* highlight required parameters. Return null to use the default
* dialog font.
*/
protected Font getRequiredParameterFont() {
return JFaceResources.getFontRegistry().getBold(
JFaceResources.DIALOG_FONT);
}
/**
* Increase the label width enough to include separator characters like
* colon, etc..
*
* @return
*/
protected int getLabelNameSeparatorOffset() {
return 5;
}
/**
*
* @return width margin between the editor controls and the composite edge
*/
protected int getEditorAreaWidthMargin() {
return 5;
}
/**
*
* @return height margin between the editor controls and the parent
* composite edge
*/
protected int getEditorAreaHeightMargin() {
return 10;
}
public static class CompositeParameterController implements
IUIChangeListener {
private List<IParameterEditor> editors;
public CompositeParameterController(List<IParameterEditor> editors) {
this.editors = editors;
}
public void start() {
if (editors != null) {
for (IParameterEditor editor : editors) {
editor.addUIChangeListener(CompositeParameterController.this);
}
}
}
public void handleUIEvent(UIEvent event) {
if ((event.getType() & UIEvent.CLEAR_VALUE_EVENT) == UIEvent.CLEAR_VALUE_EVENT) {
IUIChangeListener notifier = event.getNotifier();
if (editors != null) {
UIEvent clearControlEvent = new UIEvent(null,
CompositeParameterController.this,
UIEvent.CLEAR_VALUE_EVENT);
for (IParameterEditor editor : editors) {
if (notifier != editor
&& editor instanceof IUIChangeListener) {
((IUIChangeListener) editor)
.handleUIEvent(clearControlEvent);
}
}
}
}
}
}
/**
* Horizontal spacing between the parameter label and the rest of the
* editor's controls
*
* @return spacing value. Default SWT value used if less than zero
*/
protected int getHorizontalEditorControlSpacing() {
return 4;
}
/**
* Vertical spacing between the editor rows.
*
* @return spacing value. Default SWT value used if less than zero
*/
protected int getVerticalEditorControlSpacing() {
return 5;
}
}