diff options
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te')
35 files changed, 5622 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseControl.java new file mode 100644 index 000000000..84aab28a0 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseControl.java @@ -0,0 +1,312 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.swt.widgets.Composite; + +/** + * Base implementation of a common UI control. + * <p> + * The control can be embedded into any UI container like dialogs, + * wizard pages or preference pages. + */ +public class BaseControl extends PlatformObject implements IMessageProvider { + + /** + * Reference to the parent control. + */ + private Composite parentControl; + + /** + * A message associated with the control. + */ + private String message = null; + + /** + * The message type of the associated message. + * @see IMessageProvider + */ + private int messageType = IMessageProvider.NONE; + + /** + * Flag to remember the controls enabled state + */ + private boolean enabled = true; + + /** + * Constructor. + */ + public BaseControl() { + super(); + } + + /** + * Returns if the <code>setupPanel(...)</code> method has been called at least once with + * a non-null parent control. + * + * @return <code>true</code> if the associated parent control is not <code>null</code>, <code>false</code> otherwise. + */ + public final boolean isControlCreated() { + return (parentControl != null); + } + + /** + * Returns the parent control of the control. + * + * @return The parent control or <code>null</code>. + */ + public final Composite getParentControl() { + return parentControl; + } + + /** + * Cleanup all resources the control might have been created. + */ + public void dispose() { + parentControl = null; + } + + /** + * Creates the controls UI elements. + * + * @param parent The parent control. Must not be <code>null</code>! + */ + public void setupPanel(Composite parent) { + Assert.isNotNull(parent); + parentControl = parent; + } + + /** + * Enables or disables all UI elements belonging to this control. The + * control remembers the last set enabled state to allow easy enabled checks. + * + * @param enabled <code>True</code> to enable the UI elements, <code>false</code> otherwise. + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + /** + * Returns the control is enabled or not. + */ + public final boolean isEnabled() { + return enabled; + } + + /** + * Validates the control and sets the message text and type so the parent + * page or control is able to display validation result informations. + * The validation should be done by implementations of WRValidator! + * The default implementation of this method does nothing. + * Use the isValid(WRBaseControl, boolean) method to validate child-controls. + * + * @return Result of validation. + */ + public boolean isValid() { + setMessage(null, IMessageProvider.NONE); + return true; + } + + /** + * Validates the given subcontrol and bitwise "AND" the subcontrols valid + * state to the passed in current valid state. If the subcontrol validation + * results into a message which has a higher message type than the currently + * set message, the message from the subcontrol is applied to the control itself. + * <p> + * <b>Note:</b> If the given subcontrol is <code>null</code>, the current validation + * state is returned unchanged. + * + * @param subControl The subcontrol instance or <code>null</code>. + * @param currentValidationState The current control validation state before the subcontrol is validated. + * + * @return The new controls validation state after the subcontrol has been validated. + */ + protected final boolean isSubControlValid(BaseControl subControl, boolean currentValidationState) { + if (subControl == null) return currentValidationState; + + // Validate the subcontrol and bitwise "AND" the result to the current validation state + currentValidationState &= subControl.isValid(); + // Check if the subcontrol has set a message which has a higher message + // type than the currently set message. + if (subControl.getMessageType() > getMessageType()) { + // Apply the message from the subcontrol to the control + setMessage(subControl.getMessage(), subControl.getMessageType()); + } + + // Returns the resulting validation state. + return currentValidationState; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage() + */ + @Override + public final String getMessage() { + return message; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType() + */ + @Override + public final int getMessageType() { + return messageType; + } + + /** + * Set the message and the message type this control wants to display in + * the outer control or panel. + * + * @param message The message from this control. + * @param messageType The type o the message (NONE, INFORMATION, WARNING, ERROR). + */ + protected final void setMessage(String message, int messageType) { + // Check if we should apply the default message instead. + if (message == null && getDefaultMessage() != null) { + message = getDefaultMessage(); + messageType = getDefaultMessageType(); + } + // Set the message and message type + this.message = message; + this.messageType = messageType; + } + + /** + * Returns the controls default message or <code>null</code> if none. + * + * @return The controls default message or <code>null</code>. + */ + public String getDefaultMessage() { + return null; + } + + /** + * Returns the controls default message type or {@link IMessageProvider#NONE} if none. + * + * @return The controls default message type. + */ + public int getDefaultMessageType() { + return IMessageProvider.INFORMATION; + } + + /** + * Returns the correctly prefixed dialog settings slot id. In case the given id + * suffix is <code>null</code> or empty, <code>id</code> is returned as is. + * + * @param settingsSlotId The dialog settings slot id to prefix. + * @param prefix The prefix. + * @return The correctly prefixed dialog settings slot id. + */ + public final String prefixDialogSettingsSlotId(String settingsSlotId, String prefix) { + if (settingsSlotId != null && prefix != null && prefix.trim().length() > 0) { + settingsSlotId = prefix + "." + settingsSlotId; //$NON-NLS-1$ + } + return settingsSlotId; + } + + /** + * Returns the parent section for the control dialog settings. The default implementation + * returns the passed in dialog settings instance unmodified. Overwrite to create additional + * subsections within the given dialog settings instance. + * + * @param settings The dialog settings instance. Must not be <code>null</code>. + * + * @return The parent section for the control dialog settings. Must never be <code>null</code>. + */ + protected IDialogSettings doGetParentSection(IDialogSettings settings) { + Assert.isNotNull(settings); + return settings; + } + + /** + * Restore the widget values from the dialog settings store to recreate the control history. + * <p> + * <b>Note:</b> + * The control is saving the widget values into a section equal to the class name {@link Class#getName()}. + * After the sections has been created, the method calls <code>doRestoreWidgetValues</code> for restoring + * the single properties from the dialog settings. Subclasses may override <code>doRestoreWidgetValues</code> + * only to deal with the single properties only or <code>restoreWidgetValues</code> when to override the + * creation of the subsections. + * + * @param settings The dialog settings object instance to restore the widget values from. Must not be <code>null</code>! + * @param idPrefix The prefix to use for every dialog settings slot keys. If <code>null</code>, the dialog settings slot keys are not to prefix. + */ + public final void restoreWidgetValues(IDialogSettings settings, String idPrefix) { + Assert.isNotNull(settings); + + // Get the parent section for the control dialog settings. + IDialogSettings parentSection = doGetParentSection(settings); + Assert.isNotNull(parentSection); + + // Store the settings of the control within it's own section. + IDialogSettings section = parentSection.getSection(this.getClass().getName()); + if (section == null) { + section = parentSection.addNewSection(this.getClass().getName()); + } + + // now, call the hook for actually reading the single properties from the dialog settings. + doRestoreWidgetValues(section, idPrefix); + } + + /** + * Hook to restore the widget values finally plain from the given dialog settings. This method should + * not fragment the given dialog settings any further. + * + * @param settings The dialog settings to restore the widget values from. Must not be <code>null</code>! + * @param idPrefix The prefix to use for every dialog settings slot keys. If <code>null</code>, the dialog settings slot keys are not to prefix. + */ + public void doRestoreWidgetValues(IDialogSettings settings, String idPrefix) { + Assert.isNotNull(settings); + } + + /** + * Saves the widget values to the dialog settings store for remembering the history. The control might + * be embedded within multiple pages multiple times handling different properties. Because the single + * controls should not mix up the history, we create subsections within the given dialog settings if + * they do not already exist. After the sections has been created, the method calls <code>doSaveWidgetValues</code> + * for saving the single properties to the dialog settings. Subclasses may override <code>doSaveWidgetValues</code> + * only to deal with the single properties only or <code>saveWidgetValues</code> when to override the + * creation of the subsections. + * + * @param settings The dialog settings object instance to save the widget values to. Must not be <code>null</code>! + * @param idPrefix The prefix to use for every dialog settings slot keys. If <code>null</code>, the dialog settings slot keys are not to prefix. + */ + public final void saveWidgetValues(IDialogSettings settings, String idPrefix) { + Assert.isNotNull(settings); + + // Get the parent section for the control dialog settings. + IDialogSettings parentSection = doGetParentSection(settings); + Assert.isNotNull(parentSection); + + // Store the settings of the control within it's own section. + IDialogSettings section = parentSection.getSection(this.getClass().getName()); + if (section == null) { + section = parentSection.addNewSection(this.getClass().getName()); + } + + // now, call the hook for actually writing the single properties to the dialog settings. + doSaveWidgetValues(section, idPrefix); + } + + /** + * Hook to save the widget values finally plain to the given dialog settings. This method should + * not fragment the given dialog settings any further. + * + * @param settings The dialog settings to save the widget values to. Must not be <code>null</code>! + * @param idPrefix The prefix to use for every dialog settings slot keys. If <code>null</code>, the dialog settings slot keys are not to prefix. + */ + public void doSaveWidgetValues(IDialogSettings settings, String idPrefix) { + Assert.isNotNull(settings); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseDialogPageControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseDialogPageControl.java new file mode 100644 index 000000000..f3d6acf5a --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseDialogPageControl.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.tcf.te.ui.controls.interfaces.IRunnableContextProvider; +import org.eclipse.tcf.te.ui.wizards.interfaces.IValidatableWizardPage; +import org.eclipse.ui.forms.widgets.FormToolkit; + + +/** + * Common UI control to be embedded within a dialog page. + */ +public class BaseDialogPageControl extends BaseControl implements IRunnableContextProvider { + // Reference to the parent page + private final IDialogPage parentPage; + // Reference to the form toolkit to be used to create the controls. + private FormToolkit toolkit = null; + + /** + * Constructor. + * + */ + public BaseDialogPageControl() { + this(null); + } + + /** + * Constructor. + * + * @param parentPage The parent dialog page this control is embedded in or + * <code>null</code> if the control is not embedded within + * a dialog page. + */ + public BaseDialogPageControl(IDialogPage parentPage) { + super(); + this.parentPage = parentPage; + } + + /** + * Returns the parent dialog page if this control is embedded within a page. + * + * @return The parent dialog page or <code>null</code> if the control is not embedded within a page. + */ + public final IDialogPage getParentPage() { + return parentPage; + } + + /** + * Returns the validatable wizard page instance. + * <p> + * The default implementation is testing the associated + * parent page to implement the {@link IValidatableWizardPage} interface. + * + * @return The validatable wizard page instance or <code>null</code>. + */ + public IValidatableWizardPage getValidatableWizardPage() { + IDialogPage parentPage = getParentPage(); + if (parentPage instanceof IValidatableWizardPage) { + return (IValidatableWizardPage)parentPage; + } + return null; + } + + /** + * Sets the form toolkit to be used for creating the control widgets. + * + * @param toolkit The form toolkit instance or <code>null</code>. + */ + public final void setFormToolkit(FormToolkit toolkit) { + this.toolkit = toolkit; + } + + /** + * Returns the form toolkit used for creating the control widgets. + * + * @return The form toolkit instance or <code>null</code>. + */ + public final FormToolkit getFormToolkit() { + return toolkit; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.interfaces.IRunnableContextProvider#getRunnableContext() + */ + @Override + public IRunnableContext getRunnableContext() { + return getParentPage() instanceof IRunnableContextProvider ? ((IRunnableContextProvider)getParentPage()).getRunnableContext() : null; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#doGetParentSection(org.eclipse.jface.dialogs.IDialogSettings) + */ + @Override + protected IDialogSettings doGetParentSection(IDialogSettings settings) { + Assert.isNotNull(settings); + + // We are going to create a subsection per parent page containing a subsection per control, + // if the parent page is set at all + IDialogSettings subsection = settings; + if (getParentPage() != null) { + subsection = settings.getSection(getParentPage().getClass().getName()); + if (subsection == null) { + subsection = settings.addNewSection(getParentPage().getClass().getName()); + } + } + + return subsection; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseDialogSelectionControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseDialogSelectionControl.java new file mode 100644 index 000000000..ba9d880b5 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseDialogSelectionControl.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Dialog; + +/** + * Base implementation of a control allowing to select + * the content of the edit field control from a dialog. The dialog is + * associated to the base edit browse text controls button. + */ +public class BaseDialogSelectionControl extends BaseEditBrowseTextControl { + private Dialog dialogControl; + private String dialogTitle; + + /** + * Constructor. + * + * @param parentPage The parent page this control is embedded in. + * Might be <code>null</code> if the control is not associated with a page. + */ + public BaseDialogSelectionControl(IDialogPage parentPage) { + super(parentPage); + setIsGroup(true); + setHasHistory(true); + setDialogTitle(null); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#isAdjustEditFieldControlWidthHint() + */ + @Override + protected boolean isAdjustEditFieldControlWidthHint() { + return true; + } + + /** + * Sets the dialogs title string. If the title string is <code>null</code>, the + * dialogs title string is set to an empty string. + * + * @param title The dialogs title or <code>null</code>. + */ + public void setDialogTitle(String title) { + if (title == null) { + dialogTitle = ""; //$NON-NLS-1$ + } else { + dialogTitle = title; + } + } + + /** + * Returns the dialogs title string. + * + * @return The dialogs string or an empty string. + */ + public String getDialogTitle() { + return dialogTitle; + } + + /** + * Returns the dialog control. + * + * @return The dialog control or <code>null</code> if the control has not been created yet. + */ + public Dialog getDialogControl() { + return dialogControl; + } + + /** + * The method is called to create the dialog control. Subclasses may override this method + * to create their own dialog control. The default implementation returns <code>null</code>. + * + * @param parent The parent control for the button control to create. Must not be <code>null</code>! + * @return The created button control. + */ + protected Dialog doCreateDialogControl(Composite parent) { + Assert.isNotNull(parent); + return null; + } + + /** + * Configure the controls associated dialog before the dialogs is opened. Subclasses may use + * this hook to configure the controls associated dialog for their specific needs. + * + * @param dialog The standard file dialog to configure. Must not be <code>null</code>! + */ + protected void configureDialogControl(Dialog dialog) { + Assert.isNotNull(dialog); + if (dialog != null) { + dialog.setText(getDialogTitle()); + } + } + + /** + * Opens the given dialog and wait till the user pressed either OK or cancel. In + * case the user pressed OK and have selected a element within the dialog, the + * selected element is returned as string. In case the user canceled the dialog, + * the method returns <code>null</code>. The default implementation opens nothing + * and returns <code>null</code>! + * + * @param dialog The dialog to open. Must not be <code>null</code>. + * @return The selected element or <code>null</code>. + */ + protected String doOpenDialogControl(Dialog dialog) { + Assert.isNotNull(dialog); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#onButtonControlSelected() + */ + @Override + protected void onButtonControlSelected() { + // create and configure the controls associated dialog + dialogControl = doCreateDialogControl(getParentControl()); + configureDialogControl(dialogControl); + + // open the dialog and get the user selected element + String selectedElement = doOpenDialogControl(dialogControl); + // apply the selected element in case the user pressed OK. + if (selectedElement != null) { + doApplyElementFromDialogControl(selectedElement); + } + + // finally, validate the control + isValid(); + } + + /** + * Apply the selected element returned from the controls associated dialog to the + * control. The default implementation applies the given element as is to the edit field + * control. Subclasses may override this method to run additional logic just before + * applying the selected element to the control. + * + * @param selectedElement The selected element from that controls associated dialog. Must not be <code>null</code>. + */ + protected void doApplyElementFromDialogControl(String selectedElement) { + Assert.isNotNull(selectedElement); + setEditFieldControlText(selectedElement); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseEditBrowseTextControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseEditBrowseTextControl.java new file mode 100644 index 000000000..5d47050c1 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseEditBrowseTextControl.java @@ -0,0 +1,1498 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.fieldassist.FieldDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +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.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Scrollable; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tcf.te.ui.controls.nls.Messages; +import org.eclipse.tcf.te.ui.controls.validator.Validator; +import org.eclipse.tcf.te.ui.swt.SWTControlUtil; +import org.eclipse.tcf.te.ui.wizards.interfaces.IValidatableWizardPage; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Base implementation of a common UI control providing an + * editable field or combo box to the user with the additional capability + * of browsing for the field value. + */ +public class BaseEditBrowseTextControl extends BaseDialogPageControl implements SelectionListener, ModifyListener { + private boolean isGroup = true; + private boolean hasHistroy = true; + private boolean isReadOnly = false; + private boolean labelIsButton = false; + private int labelButtonStyle = SWT.RADIO; + private boolean parentControlIsInnerPanel = false; + private boolean hideBrowseButton = false; + private boolean hideEditFieldControl = false; + private boolean hideEditFieldControlDecoration = false; + private boolean hideLabelControl = false; + private boolean adjustBackgroundColor = false; + boolean isInitializing = true; + + private String groupLabel = ""; //$NON-NLS-1$ + private String editFieldLabelTooltip = null; + private String editFieldLabel = ""; //$NON-NLS-1$ + private String buttonLabel = Messages.BaseEditBrowseTextControl_button_label; + + private Composite innerPanel; + private Control labelControl; + private Control editFieldControl; + private Button buttonControl; + private ControlDecoration controlDecoration; + + private String dialogSettingsSlotId; + + private Validator editFieldValidator; + + /** + * Constructor. + * + * @param parentPage The parent dialog page this control is embedded in. + * Might be <code>null</code> if the control is not associated with a page. + */ + public BaseEditBrowseTextControl(IDialogPage parentPage) { + super(parentPage); + } + + /** + * Set if or if not the control should be enclosed in an group control. + * + * @param isGroup Specify <code>true</code> to enclose the control into a group control, <code>false</code> otherwise. + */ + public final void setIsGroup(boolean isGroup) { + this.isGroup = isGroup; + } + + /** + * Returns if or if not the control is enclosed in an group control. + * + * @return <code>true</code> if the control is enclosed into a group control, <code>false</code> otherwise. + */ + public final boolean isGroup() { + return isGroup; + } + + /** + * Set if or if not this control should have a history or not. + * + * @param hasHistory Specify <code>true</code> if the control should have an history, <code>false</code> otherwise. + */ + public void setHasHistory(boolean hasHistory) { + this.hasHistroy = hasHistory; + } + + /** + * Returns if or if not this control has a history or not. + * + * @return <code>true</code> if the control should has an history, <code>false</code> otherwise. + */ + public final boolean hasHistory() { + return hasHistroy; + } + + /** + * Set if or if not this control can be edited by the user. + * + * @param readOnly Specify <code>true</code> if the control should be not editable by the user, <code>false</code> otherwise. + */ + public final void setReadOnly(boolean readOnly) { + this.isReadOnly = readOnly; + } + + /** + * Returns if or if not this control can be edited by the user. + * + * @return <code>true</code> if the control is editable by the user, <code>false</code> otherwise. + */ + public final boolean isReadOnly() { + return isReadOnly; + } + + /** + * Sets if of if not the label control should be hidden. + * + * @param hide <code>True</code> if to hide the label control, <code>false</code> otherwise. + */ + public final void setHideLabelControl(boolean hide) { + this.hideLabelControl = hide; + } + + /** + * Returns if or if not the label control is hidden. + * + * @return <code>True</code> if the label control is hidden, <code>false</code> otherwise. + */ + public final boolean isHideLabelControl() { + return hideLabelControl; + } + + /** + * Sets if of if not the edit field control should be hidden. + * <p> + * If set to <code>true</code>, the button control and the edit + * field control decoration are set to hidden automatically. + * + * @param hide <code>True</code> if to hide the edit field control, <code>false</code> otherwise. + */ + public final void setHideEditFieldControl(boolean hide) { + this.hideEditFieldControl = hide; + if (hide) { + setHideBrowseButton(hide); + setHideEditFieldControlDecoration(hide); + } + } + + /** + * Returns if or if not the edit field control is hidden. + * + * @return <code>True</code> if the edit field control is hidden, <code>false</code> otherwise. + */ + public final boolean isHideEditFieldControl() { + return hideEditFieldControl; + } + + + /** + * Sets if of if not the edit field control decoration should be hidden. + * + * @param hide <code>True</code> if to hide the edit field control, <code>false</code> otherwise. + */ + public final void setHideEditFieldControlDecoration(boolean hide) { + this.hideEditFieldControlDecoration = hide; + } + + /** + * Returns if or if not the edit field control decoration is hidden. + * + * @return <code>True</code> if the edit field control is hidden, <code>false</code> otherwise. + */ + public final boolean isHideEditFieldControlDecoration() { + return hideEditFieldControlDecoration; + } + + /** + * Set if or if not the button behind the edit field control should be hidden. + * + * @param hide <code>true</code> to hide the button behind the edit field control, <code>false</code> otherwise. + */ + public final void setHideBrowseButton(boolean hide) { + this.hideBrowseButton = hide; + } + + /** + * Returns if or if not the button behind the edit field control is hidden or not. + * + * @return <code>true</code> if the button behind the edit field control is hidden, <code>false</code> otherwise. + */ + public final boolean isHideBrowseButton() { + return hideBrowseButton; + } + + /** + * Sets if to adjusts the background color of the created UI elements. + * + * @param adjust <code>True</code> to adjust the background color, <code>false</code> otherwise. + */ + public final void setAdjustBackgroundColor(boolean adjust) { + this.adjustBackgroundColor = adjust; + } + + /** + * Returns if to adjust the background color of the created UI elements. + * + * @return <code>True</code> to adjust the background color, <code>false</code> otherwise. + */ + public final boolean isAdjustBackgroundColor() { + return adjustBackgroundColor; + } + + /** + * Enables or disables all UI elements belonging to this control. + * + * @param enabled <code>true</code> to enable the UI elements, <code>false</code> otherwise. + */ + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + + SWTControlUtil.setEnabled(getLabelControl(), enabled); + SWTControlUtil.setEnabled(getEditFieldControl(), enabled && (isLabelIsButton() ? isLabelControlSelected() : true)); + SWTControlUtil.setEnabled(getButtonControl(), enabled && (isLabelIsButton() ? isLabelControlSelected() : true)); + + // Hide or show the control decoration if one is available + if (getEditFieldControlDecoration() != null) { + if (enabled && getEditFieldControlDecoration().getDescriptionText() != null) { + getEditFieldControlDecoration().show(); + } else { + getEditFieldControlDecoration().hide(); + } + } + } + + /** + * Sets all UI elements belonging to this control visible or not. + * + * @param visible <code>True</code> to set all UI controls visible, <code>false</code> otherwise. + */ + public void setVisible(boolean visible) { + SWTControlUtil.setEnabled(getLabelControl(), visible); + SWTControlUtil.setEnabled(getEditFieldControl(), visible); + SWTControlUtil.setEnabled(getButtonControl(), visible); + } + + /** + * Sets if or if not the parent control, passed by <code>setupPanel(parentControl)</code> should + * be used directly as the controls inner panel. The associated parent controls layout <b>must</b> + * be a <code>org.eclipse.swt.layout.GridLayout</code>. The assumed number of columns is <code>3</code>. + * If the panel contains more than <code>3</code> columns, the edit field controls horizontal span value + * should be adjusted using <code>setEditFieldControlLayoutHorizontalSpan</code>. In all other cases, + * a new independent inner panel will create even if <code>isParentControlIsInnerPanel()</code> returns <code>true</code>! + * + * @param parentIsInnerPanel <code>true</code> if the passed parent control is used directly as the inner panel, <code>false</code> otherwise. + */ + public final void setParentControlIsInnerPanel(boolean parentIsInnerPanel) { + this.parentControlIsInnerPanel = parentIsInnerPanel; + } + + /** + * Returns if or if not the parent control, passed by <code>setupPanel(parentControl)</code> is + * used directly as the controls inner panel. + * + * @param parentIsInnerPanel <code>true</code> if the passed parent control is used directly as the inner panel, <code>false</code> otherwise. + */ + public final boolean isParentControlIsInnerPanel() { + return parentControlIsInnerPanel; + } + + /** + * Sets the label to use for the enclosing group. If <code>null</code>, the + * group label is set to an empty string. + * + * @param groupLabel The group label to use for the enclosing group or <code>null</code>. + */ + public final void setGroupLabel(String groupLabel) { + if (groupLabel != null) { + this.groupLabel = groupLabel; + } else { + this.groupLabel = ""; //$NON-NLS-1$ + } + } + + /** + * Returns the label used for the enclosing group. The method is called + * only if <code>isGroup()</code> returns <code>true</code>. + * + * @return The label used for the enclosing group. If not set, a empty string will be returned. + */ + public final String getGroupLabel() { + return groupLabel; + } + + /** + * Sets the tool tip to appear if the user hovers the mouse over the label control. + * + * @param tooltip The tool tip or <code>null</code> if none. + */ + public final void setEditFieldLabelTooltip(String tooltip) { + this.editFieldLabelTooltip = tooltip; + // Apply directly to the label control if created already. + SWTControlUtil.setToolTipText(getLabelControl(), editFieldLabelTooltip); + } + + /** + * Returns the tool tip to appear if the user hovers the mouse over the label control. + * + * @return The tool tip or <code>null</code> if none. + */ + public final String getEditFieldLabelTooltip() { + return editFieldLabelTooltip; + } + + /** + * Sets the label to use for the edit field. If <code>null</code>, the + * edit field label is set to an empty string. + * + * @param label The edit field label to use or <code>null</code>. + */ + public final void setEditFieldLabel(String label) { + if (label != null) { + this.editFieldLabel = label; + } else { + this.editFieldLabel = ""; //$NON-NLS-1$ + } + // Update the control as well if already created. + setLabelControlText(label); + } + + /** + * Returns the label used for the edit field. + * + * @return The label used for the edit field. If not set, a empty string will be returned. + */ + public final String getEditFieldLabel() { + return editFieldLabel; + } + + /** + * Sets the label to use for the button. If <code>null</code>, the + * button label is set to an empty string. + * + * @param label The button label to use or <code>null</code>. + */ + public final void setButtonLabel(String label) { + if (label != null) { + this.buttonLabel = label; + } else { + this.buttonLabel = ""; //$NON-NLS-1$ + } + } + + /** + * Returns the label used for the button. + * + * @return The label used for the button. If not set, a empty string will be returned. + */ + public final String getButtonLabel() { + return buttonLabel; + } + + /** + * Sets if or if not the label control should be an radio button control or not. + * If <code>true</code>, <code>configureLabelControl()</code> will automatically register + * a selection listener to the radio button control to enable/disable the edit field and + * button controls depending on the selection state of the radio button control. + * + * @param isRadioButton <code>true</code> if the label should be an radio button control, <code>false</code> otherwise. + */ + public final void setLabelIsButton(boolean isRadioButton) { + this.labelIsButton = isRadioButton; + } + + /** + * Returns if or if not the label control is an radio button control. + * + * @return <code>true</code> if the label control is an radio button control, <code>false</code> otherwise. + */ + public final boolean isLabelIsButton() { + return labelIsButton; + } + + /** + * Sets the button style to be used for the button in front of the label in case + * <code>isLabelIsButton()</code> returns <code>true</code>. The style to set is + * typically either <code>SWT.RADIO</code> or <code>SWT.CHECK</code>. The default + * is set to <code>SWT.RADIO</code>. + * + * @param style The button style to use. @see the <code>SWT</code> constants for details. + */ + public final void setLabelButtonStyle(int style) { + this.labelButtonStyle = style; + } + + /** + * Returns the button style used for the button in front of the label in case <code> + * isLabelIsButton()</code> returns <code>true</code>. + * + * @return The button style used. @see the <code>SWT</code> constants for details. + */ + public int getLabelButtonStyle() { + return labelButtonStyle; + } + + /** + * Returns the controls inner panel composite. + * + * @return The controls inner panel composite or <code>null</code> if the composite has not been created yet. + */ + public final Composite getInnerPanelComposite() { + return innerPanel; + } + + /** + * The method is called to create the controls inner panel composite during setup of + * the controls UI elements. Subclasses may override this method to create their own + * inner panel composite. + * + * @param parent The parent control for the inner panel composite to create. Must not be <code>null</code>! + * @return The created inner panel composite. + */ + protected Composite doCreateInnerPanelComposite(Composite parent) { + Assert.isNotNull(parent); + + Composite innerPanel = null; + FormToolkit toolkit = getFormToolkit(); + + if (isGroup()) { + innerPanel = new Group(parent, SWT.NONE); + if (toolkit != null) toolkit.adapt(innerPanel); + ((Group)innerPanel).setText(getGroupLabel()); + } else { + innerPanel = toolkit != null ? toolkit.createComposite(parent) : new Composite(parent, SWT.NONE); + } + + return innerPanel; + } + + /** + * Configure the given controls inner panel composite before the control is set visible. + * Subclasses may use this hook to configure the controls inner panel composite for their + * specific needs. + * + * @param innerPanel The inner panel composite to configure. Must not be <code>null</code>! + */ + protected void configureInnerPanelComposite(Composite innerPanel) { + Assert.isNotNull(innerPanel); + + if (isAdjustBackgroundColor()) { + SWTControlUtil.setBackground(innerPanel, innerPanel.getParent().getBackground()); + } + + // Calculate the number of columns within the grid + int numColumns = 3; + if (isHideLabelControl()) { + numColumns--; + } + if (isHideEditFieldControl()) { + numColumns--; + } + if (isHideBrowseButton()) { + numColumns--; + } + + GridLayout layout = new GridLayout(numColumns, false); + // if the inner panel is not a group (group is a composite as well, so we cannot test for + // the composite directly), set the layouts margins to 0. + if (!(innerPanel instanceof Group)) { + // We assume a plain composite here and set back the layout margins to 0 + layout.marginHeight = 0; layout.marginWidth = 0; + } + + innerPanel.setLayout(layout); + innerPanel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + } + + /** + * Adjust the inner panel layout if necessary. The method is called + * before the sub controls are added to the inner panel and only if the + * inner panel is using a {@link GridLayout}. + * + * @param layout The grid layout. Must not be <code>null</code> + */ + protected void doAdjustInnerPanelLayout(GridLayout layout) { + Assert.isNotNull(layout); + } + + /** + * Returns the label control. This control might be a label, a simple text, a radio button + * or any other SWT control. + * + * @return The label control or <code>null</code> if the control has not been created yet. + */ + public Control getLabelControl() { + return labelControl; + } + + /** + * The method is called to create the label control during setup of the + * controls UI elements. Subclasses may override this method to create their + * own SWT control to be used as label. + * + * @param parent The parent control for the label control to create. Must not be <code>null</code>! + * @return The created label control. + */ + protected Control doCreateLabelControl(Composite parent) { + Assert.isNotNull(parent); + + Control labelControl = null; + FormToolkit toolkit = getFormToolkit(); + + if (!isLabelIsButton()) { + labelControl = toolkit != null ? toolkit.createLabel(parent, null) : new Label(parent, SWT.NONE); + } else { + labelControl = toolkit != null ? toolkit.createButton(parent, null, getLabelButtonStyle() | SWT.NO_FOCUS) : new Button(parent, getLabelButtonStyle() | SWT.NO_FOCUS); + SWTControlUtil.setSelection((Button)labelControl, false); + } + SWTControlUtil.setText(labelControl, getEditFieldLabel()); + + return labelControl; + } + + /** + * Configure the given label control before the control is set visible. Subclasses may use + * this hook to configure the label control for their specific needs and to register any + * required listener to the control. + * + * @param button The label control to configure. Must not be <code>null</code>! + */ + protected void configureLabelControl(final Control label) { + Assert.isNotNull(label); + if (isAdjustBackgroundColor()) { + SWTControlUtil.setBackground(label, label.getParent().getBackground()); + } + if (isLabelIsButton() && label instanceof Button) { + ((Button)labelControl).addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onLabelControlSelectedChanged(); + } + }); + } + SWTControlUtil.setToolTipText(label, getEditFieldLabelTooltip()); + } + + /** + * This method is called from {@link #configureEditFieldControl(Control)} after the + * edit field has been configured. Reconfigure the label control layout data if + * necessary based on the just created edit field control settings. + * <p> + * The default implementation is aligning the label control on top of the cell in + * case the edit field control has the {@link SWT#MULTI} attribute set. + */ + protected void doAdjustLabelControlLayoutData() { + // Get the edit field control style bits + int style = getEditFieldControl().getStyle(); + // If SWT.MULTI is set, we have to align the control label on top of the cell. + if ((style & SWT.MULTI) != 0) { + Object data = getLabelControl().getLayoutData(); + if (data == null || data instanceof GridData) { + GridData layoutData = data != null ? (GridData)data : new GridData(); + layoutData.verticalAlignment = SWT.TOP; + getLabelControl().setLayoutData(layoutData); + } + } + } + + /** + * This method is called either from <code>setLabelControlSelection(...)</code> or + * from the registered controls selection listener. The method enables/disables the + * edit field and button control depending on the selection state if <code>isLabelIsRadioButton()</code> + * returns <code>true</code> and the label control is an button. In all other cases, + * the method will do nothing. + */ + protected void onLabelControlSelectedChanged() { + if (isLabelIsButton() && labelControl instanceof Button) { + if (((Button)labelControl).getSelection()) { + SWTControlUtil.setEnabled(getEditFieldControl(), true); + SWTControlUtil.setEnabled(getButtonControl(), true); + } else { + SWTControlUtil.setEnabled(getEditFieldControl(), false); + SWTControlUtil.setEnabled(getButtonControl(), false); + } + + // validate the page + IValidatableWizardPage validatable = getValidatableWizardPage(); + if (validatable != null) validatable.validatePage(); + } + } + + /** + * In case the label control is an button and <code>isLabelIsRadioButton()</code> + * returns <code>true</code>, the selection state of the radio button is changed + * to the given state. In all other cases, the method will do nothing. + * + * @param selected The selection state of the radio button to set. + */ + public void setLabelControlSelection(boolean selected) { + if (isLabelIsButton() && labelControl instanceof Button) { + SWTControlUtil.setSelection((Button)labelControl, selected); + onLabelControlSelectedChanged(); + } + } + + /** + * Returns <code>true</code> if <code>isLabelIsRadioButton()</code> returns + * <code>true</code> and the label control is an button and the control is + * selected. In all other cases, the method will return <code>true</code>, + * because a label always indicates a "selected" edit field. + * + * @return <code>true</code> if the label control is a label or a selected radio button, <code>false</code> otherwise. + */ + public boolean isLabelControlSelected() { + if (isLabelIsButton() && labelControl instanceof Button) { + return SWTControlUtil.getSelection((Button)labelControl); + } + return true; + } + + /** + * Returns the current set text from the label control.<br> + * Override if using custom label controls. + * + * @return The label controls text or an empty string. + */ + public String getLabelControlText() { + String value = SWTControlUtil.getText(labelControl); + if (value == null) value = ""; //$NON-NLS-1$ + return value; + } + + /** + * Sets the text to show within the label control. This method can handle + * <code>Label</code>, <code>Text</code>, <code>Button</code> and <code>Combo</code> + * SWT controls only by default. If subclasses use different edit field controls than + * these, the subclass must override this method in order to apply the given text + * correctly to the label control. + * + * @param text The text to set within the label control. Must not be <code>null</code>. + */ + public void setLabelControlText(String text) { + SWTControlUtil.setText(labelControl, text); + } + + /** + * Returns the edit field control. This control might be an text or combobox + * or any other SWT control. + * + * @return The edit field control or <code>null</code> if the control has not been created yet. + */ + public Control getEditFieldControl() { + return editFieldControl; + } + + /** + * The method is called from default implementation of <code>doCreateEditFieldControl</code> + * in order to allow overrides to adjust the edit field control creation style bits finally. + * Whatever this method will return is used to create the edit field control. The default + * implementation returns the passed in style bits completely unmodified. + * + * @param style The default style bits to apply to create the edit field control. + * @return The possibly modified style bits to apply to create the edit field control. + */ + protected int doAdjustEditFieldControlStyles(int style) { + return style; + } + + /** + * The method is called from default implementation of {@link #doCreateEditFieldControl(Composite)} + * in order to allow overrider to adjust the edit field control layout data bits finally. + * Whatever this method sets to the passed in layout data, will be associated with the + * the edit field control. + * <p> + * If {@link #isAdjustEditFieldControlWidthHint()} returns <code>true</code>, the default implementation + * calculates a width hint for the edit field control as following: + * <ul> + * <li>Set default width hint to the width of approximately 50 characters in the current dialog font.</li> + * <li>If a parent control is associated, recalculate the width hint to be 85% of parent controls horizontal size.</li> + * </ul> + * + * @param layoutData The layout data to apply to the edit field control. Must not be <code>null</code>. + */ + protected void doAdjustEditFieldControlLayoutData(GridData layoutData) { + Assert.isNotNull(layoutData); + + // adjust the control indentation + if (getEditFieldControlDecoration() != null) { + layoutData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(); + } + + // adjust the horizontal span. + layoutData.horizontalSpan = calculateEditFieldControlHorizontalSpan(); + + // adjust the controls width hint within the given layout data + if (isAdjustEditFieldControlWidthHint()) { + layoutData.widthHint = SWTControlUtil.convertWidthInCharsToPixels(getEditFieldControl(), 50); + + Composite parent = getParentControl(); + if (parent != null) { + // Calculate the size of the parent. We are interested to get the width of the parent control. + int wHint = parent.getLayoutData() instanceof GridData ? ((GridData)parent.getLayoutData()).widthHint : SWT.DEFAULT; + Point parentSize = parent.computeSize(wHint, SWT.DEFAULT, false); + if (parentSize != null) { + // Calculate the child widthHint to be 85% of the parent + layoutData.widthHint = (85 * parentSize.x) / 100; + // Update the parent layout width hint if calculated once + if (parent.getLayoutData() instanceof GridData) { + ((GridData)parent.getLayoutData()).widthHint = parentSize.x; + } + } + } + } + } + + /** + * Controls whether {@link #doAdjustEditFieldControlLayoutData(GridData)} is adjusting + * the layout data width hint for the edit field control or not. + * <p> + * The default implementation returns <code>false</code>. + * + * @return <code>True</code> to adjust the edit field controls layout data width hint attributed, <code>false</code> for not to adjust. + */ + protected boolean isAdjustEditFieldControlWidthHint() { + return false; + } + + /** + * The method is called to create the edit field control during setup of the + * controls UI elements. Subclasses may override this method to create their + * own SWT control to be used as edit field. + * + * @param parent The parent control for the edit field control to create. Must not be <code>null</code>! + * @return The created edit field control. + */ + protected Control doCreateEditFieldControl(Composite parent) { + Assert.isNotNull(parent); + + final Scrollable editField; + FormToolkit toolkit = getFormToolkit(); + + if (hasHistory()) { + // if the control should have an history, the edit field control is an combobox + int style = SWT.DROP_DOWN; + if (isReadOnly()) { + style |= SWT.READ_ONLY; + } + editField = new Combo(parent, doAdjustEditFieldControlStyles(style)); + if (toolkit != null) toolkit.adapt((Combo)editField); + ((Combo)editField).addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (!isInitializing) { // do not call this unless the boundaries of the control are calculated yet + SWTControlUtil.setValueToolTip(editField); + } + } + }); + ((Combo)editField).addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (!isInitializing) { // do not call this unless the boundaries of the control are calculated yet + SWTControlUtil.setValueToolTip(editField); + } + } + }); + // make sure that after resizing a control, the necessity of showing the tool tip is recalculated + ((Combo)editField).addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + if (!isInitializing) { // do not call this unless the boundaries of the control are calculated yet + SWTControlUtil.setValueToolTip(editField); + } + }}); + } else { + int style = SWT.SINGLE; + if (isReadOnly()) { + style |= SWT.READ_ONLY; + } + editField = toolkit != null ? toolkit.createText(parent, null, doAdjustEditFieldControlStyles(SWT.BORDER | style)) : new Text(parent, doAdjustEditFieldControlStyles(SWT.BORDER | style)); + ((Text)editField).addModifyListener(new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + if (!isInitializing) { // do not call this unless the boundaries of the control are calculated yet + SWTControlUtil.setValueToolTip(editField); + } + } + }); + // make sure that after resizing a control, the necessity of showing the tool tip is recalculated + ((Text)editField).addPaintListener(new PaintListener() { + @Override + public void paintControl(PaintEvent e) { + if (!isInitializing) { // do not call this unless the boundaries of the control are calculated yet + SWTControlUtil.setValueToolTip(editField); + } + }}); + } + + return editField; + } + + /** + * Configure the given edit field control before the control is set visible. Subclasses may use + * this hook to configure the edit field control for their specific needs and to register any + * required listener to the control. + * + * @param control The edit field control to configure. Must not be <code>null</code>! + */ + protected void configureEditFieldControl(Control control) { + Assert.isNotNull(control); + + // the edit field control expands within the inner composite + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + doAdjustEditFieldControlLayoutData(layoutData); + control.setLayoutData(layoutData); + + // The edit field can influence the layout data of the label control (SWT.MULTI). + // Give the label control the chance to reconfigure after the edit field control + // got created and the control style bits can be queried. + doAdjustLabelControlLayoutData(); + + // register the modification and selection listener if they are available. + ModifyListener modifyListener = doGetEditFieldControlModifyListener(); + VerifyListener verifyListener = doGetEditFieldControlVerifyListener(); + SelectionListener selectionListener = doGetEditFieldControlSelectionListener(); + + if (control instanceof Text) { + if (modifyListener != null) { + ((Text)control).addModifyListener(modifyListener); + } + if (verifyListener != null) { + ((Text)control).addVerifyListener(verifyListener); + } + } + if (control instanceof Combo) { + if (modifyListener != null) { + ((Combo)control).addModifyListener(modifyListener); + } + if (verifyListener != null) { + ((Combo)control).addVerifyListener(verifyListener); + } + if (selectionListener != null) { + ((Combo)control).addSelectionListener(selectionListener); + } + } + // if the label control is an button control, trigger an initial onLabelControlSelectedChanged to + // enable/disable the edit field control correctly initially. + if (isLabelIsButton()) { + onLabelControlSelectedChanged(); + } + } + + /** + * Returns the horizontal span value which is set to the edit field controls grid + * layout data. + */ + public int calculateEditFieldControlHorizontalSpan() { + // Default horizontal span is always 1. + int span = 1; + + if (getEditFieldControl() != null && getEditFieldControl().getParent() != null) { + // Get the parent control of the edit field + Composite parent = getEditFieldControl().getParent(); + // Determine the number of columns within the parent + int numColumns = parent.getLayout() instanceof GridLayout ? ((GridLayout)parent.getLayout()).numColumns : 1; + // Calculate the number of columns consumed + int consumed = 0; + if (!isHideLabelControl()) { + consumed++; // The label + } + if (!isHideEditFieldControl()) { + consumed++; // The edit field control + } + if (!isHideBrowseButton()) { + consumed++; // The browse button + } + // In case there are more columns available than consumed, + // make the edit field control spanning over all the remaining columns. + if (numColumns > consumed) { + span = numColumns - consumed + 1; + } + } + + return span; + } + + /** + * Creates a new instance of a {@link ControlDecoration} object associated with + * the given edit field control. The method is called after the edit field control + * has been created. + * + * @param control The edit field control. Must not be <code>null</code>. + * @return The control decoration object instance. + */ + protected ControlDecoration doCreateEditFieldControlDecoration(Control control) { + Assert.isNotNull(control); + return new ControlDecoration(control, doGetEditFieldControlDecorationPosition()); + } + + /** + * Returns the edit field control decoration position. The default is + * {@link SWT#TOP} | {@link SWT#LEFT}. + * + * @return The edit field control position. + */ + protected int doGetEditFieldControlDecorationPosition() { + return SWT.TOP | SWT.LEFT; + } + + /** + * Configure the given edit field control decoration. + * + * @param decoration The edit field control decoration. Must not be <code>null</code>. + */ + protected void configureEditFieldControlDecoration(ControlDecoration decoration) { + Assert.isNotNull(decoration); + decoration.setShowOnlyOnFocus(false); + } + + /** + * Updates the given edit field control decoration to represent the given + * message and message type. + * + * @param decoration The control decoration. Must not be <code>null</code>. + * @param message The message. Must not be <code>null</code>. + * @param messageType The message type. + */ + protected void updateEditFieldControlDecorationForMessage(ControlDecoration decoration, String message, int messageType) { + Assert.isNotNull(decoration); + Assert.isNotNull(message); + + // The description is the same as the message + decoration.setDescriptionText(message); + + // The icon depends on the message type + FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault(); + + // Determine the id of the decoration to show + String decorationId = FieldDecorationRegistry.DEC_INFORMATION; + if (messageType == IMessageProvider.ERROR) { + decorationId = FieldDecorationRegistry.DEC_ERROR; + } else if (messageType == IMessageProvider.WARNING) { + decorationId = FieldDecorationRegistry.DEC_WARNING; + } + + // Get the field decoration + FieldDecoration fieldDeco = registry.getFieldDecoration(decorationId); + if (fieldDeco != null) { + decoration.setImage(fieldDeco.getImage()); + } + } + + /** + * Returns the edit field control decoration. + * + * @return The edit field control decoration instance or <code>null</code> if not yet created. + */ + public final ControlDecoration getEditFieldControlDecoration() { + return controlDecoration; + } + + /** + * Returns the modification listener instance to be registered for the edit field + * control if not <code>null</code>. The default implementation returns always <code> + * null</code>. Subclasses may override this method to provide a suitable modification + * listener for the edit field control. + * + * @return The modification listener to register to the edit field control or <code>null</code>. + */ + protected ModifyListener doGetEditFieldControlModifyListener() { + return this; + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + @Override + public void modifyText(ModifyEvent e) { + // validate the page + IValidatableWizardPage validatable = getValidatableWizardPage(); + if (validatable != null) validatable.validatePage(); + } + + /** + * Returns the verify listener instance to be registered for the edit field + * control if not <code>null</code>. The default implementation returns always <code> + * null</code>. Subclasses may override this method to provide a suitable verify + * listener for the edit field control. + * + * @return The verify listener to register to the edit field control or <code>null</code>. + */ + protected VerifyListener doGetEditFieldControlVerifyListener() { + return null; + } + + /** + * Returns the selection listener instance to be registered for the edit field + * control if not <code>null</code>. The default implementation returns always <code> + * null</code>. Subclasses may override this method to provide a suitable selection + * listener for the edit field control. + * + * @return The modification listener to register to the edit field control or <code>null</code>. + */ + protected SelectionListener doGetEditFieldControlSelectionListener() { + if (getEditFieldControl() instanceof Combo) { + return this; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(SelectionEvent e) { + // validate the page + IValidatableWizardPage validatable = getValidatableWizardPage(); + if (validatable != null) validatable.validatePage(); + } + + /** + * Returns the current set text from the edit field control. + * + * @return The edit field controls text or an empty string, but never <code>null</code>. + */ + public String getEditFieldControlText() { + String value = SWTControlUtil.getText(editFieldControl); + if (value == null) value = ""; //$NON-NLS-1$ + return value; + } + + /** + * The content of the edit field control might require preparation before it + * can be validated at all. By default, this method returns the same value as + * a call to <code>getEditFieldControlText()</code>. + * + * @return The edit field control text to validate. + */ + public String getEditFieldControlTextForValidation() { + return getEditFieldControlText(); + } + + /** + * Sets the text to show within the edit field control. This method can handle + * <code>Text</code> and <code>Combo</code> SWT controls only by default. If subclasses + * use different edit field controls than these two, the subclass must override + * this method in order to apply the given text correctly to the edit field control. + * + * @param text The text to set within the edit field control. Must not be <code>null</code>. + */ + public void setEditFieldControlText(String text) { + if (text == null) { + text = ""; //$NON-NLS-1$ + } + String oldText = SWTControlUtil.getText(editFieldControl); + if (!text.equals(oldText)) { + SWTControlUtil.setText(editFieldControl, text); + // If the edit field control is not a combobox, next statement will do nothing + SWTControlUtil.add(editFieldControl, text); + } + } + + /** + * Set the edit field control history to the given history entries if <code> + * hasHistory()</code> returns <code>true</code> and the edit field control + * is an SWT <code>Combo</code> control. If subclasses use different edit field + * controls, the subclass must override this method if the used control supports + * history lists. Duplicated history entries, empty history entries or <code>null</code> + * values are not applied to the history. + * + * @param historyEntries The history entries to set. Must not be <code>null</code>! + */ + public void setEditFieldControlHistory(String[] historyEntries) { + Assert.isNotNull(historyEntries); + if (hasHistory() && getEditFieldControl() instanceof Combo) { + Combo combo = (Combo)getEditFieldControl(); + List<String> oldItems = new ArrayList<String>(Arrays.asList(SWTControlUtil.getItems(combo))); + List<String> newItems = new ArrayList<String>(); + + String oldSelectedItem = getEditFieldControlText(); + + // we add the entries one by one to filter out duplicates, empty strings and null values. + for (String entry : historyEntries) { + if (entry == null || entry.trim().length() == 0 || newItems.contains(entry)) { + continue; + } + newItems.add(entry); + } + + // Create the array of new items to apply before sorting the + // new items list. Otherwise we will loose the order of the + // items in which the clients wants to set them to the control + final String[] newItemsArray = newItems.toArray(new String[newItems.size()]); + + // The two lists must be in the same order to compare them with equals + Collections.sort(oldItems); + Collections.sort(newItems); + + if (!newItems.equals(oldItems)) SWTControlUtil.setItems(combo, newItemsArray); + + // Restore the previously selected item if still available + if (newItems.contains(oldSelectedItem)) setEditFieldControlText(oldSelectedItem); + } + } + + /** + * Adds the given string to the edit field control history if <code> + * hasHistory()</code> returns <code>true</code> and the edit field control + * is an SWT <code>Combo</code> control. If subclasses use different edit field + * controls, the subclass must override this method if the used control supports + * history lists. Duplicated history entries, empty history entries or <code>null</code> + * values are not applied to the history. + * + * @param entry + */ + public void addToEditFieldControlHistory(String entry) { + if (hasHistory() && getEditFieldControl() instanceof Combo) { + Combo combo = (Combo)getEditFieldControl(); + if (entry != null && entry.trim().length() > 0 && combo.indexOf(entry) == -1) { + combo.add(entry); + } + } + } + + /** + * The method is called to create an edit field validator during setup. + * Subclasses have to override this method to create the right validator. + * The default validator is <code>null</code> and so it isn't used. + * + * @return The new created edit field validator. + */ + protected Validator doCreateEditFieldValidator() { + return null; + } + + /** + * Configure the edit field validator. + * Subclasses should override this method to configure the validator. + * + * @param validator The validator to be configured. + */ + protected void configureEditFieldValidator(Validator validator) { + // do nothing + } + + /** + * Returns the button control. + * + * @return The button control or <code>null</code> if the control has not been created yet. + */ + public Button getButtonControl() { + return buttonControl; + } + + /** + * The method is called to create the button control during setup of the controls + * UI elements. Subclasses may override this method to create their own button control. + * + * @param parent The parent control for the button control to create. Must not be <code>null</code>! + * @return The created button control. + */ + protected Button doCreateButtonControl(Composite parent) { + Assert.isNotNull(parent); + + FormToolkit toolkit = getFormToolkit(); + + Button button = toolkit != null ? toolkit.createButton(parent, null, SWT.PUSH) : new Button(parent, SWT.PUSH); + // add a whitespace at the beginning and at the end of the button text to make the + // button visibly broader than the label itself. + button.setText(" " + getButtonLabel().trim() + " "); //$NON-NLS-1$ //$NON-NLS-2$ + + return button; + } + + /** + * Configure the given button control before the control is set visible. Subclasses may use + * this hook to configure the button control for their specific needs and to register any + * required listener to the control. + * + * @param button The button control to configure. Must not be <code>null</code>! + */ + protected void configureButtonControl(Button button) { + Assert.isNotNull(button); + // add the selection listener to open the file dialog if the user pressed the button + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + onButtonControlSelected(); + } + }); + + // If not yet set, assure that the buttons fill in the available space + if (button.getLayoutData() == null) { + button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + } + } + + /** + * Called if the user pressed the button control. Subclasses may override + * this method to plugin the desired functionality. + */ + protected void onButtonControlSelected() { + } + + /** + * Returns the layout data to be used for the top most controls composite. Because this + * top most composite is directly embedded into the parent control, it cannot be predicted + * which layout data object class must be associated to the top most controls composite. Subclasses + * must override this method if the layout of the parent object is not a <code>org.eclipse.swt.layout.GridLayout</code>! + * + * @param parentLayout The associated layout of the parent composite of the top most controls composite. Might be <code>null</code>! + * @return The layout data object to be associated to the top most controls composite. Must be never <code>null</code>! + */ + protected Object getTopMostCompositeLayoutData(Layout parentLayout) { + GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false); + if (parentLayout instanceof GridLayout) { + layoutData.horizontalSpan = ((GridLayout)parentLayout).numColumns; + } + return layoutData; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#setupPanel(org.eclipse.swt.widgets.Composite) + */ + @Override + public void setupPanel(Composite parent) { + isInitializing = true; + super.setupPanel(parent); + + FormToolkit toolkit = getFormToolkit(); + + // do we need a group or a plain composite + if (!isParentControlIsInnerPanel() || !(parent.getLayout() instanceof GridLayout)) { + // create the control most enclosing composite + Composite composite = toolkit != null ? toolkit.createComposite(parent) : new Composite(parent, SWT.NONE); + if (isAdjustBackgroundColor()) { + SWTControlUtil.setBackground(composite, parent.getBackground()); + } + composite.setLayoutData(getTopMostCompositeLayoutData(parent.getLayout())); + + // within the top most controls composite, the layout management is + // in our own hands again. + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; layout.marginWidth = 0; + composite.setLayout(layout); + + innerPanel = doCreateInnerPanelComposite(composite); + // give the subclasses the chance to reconfigure the inner panel composite for specific needs. + configureInnerPanelComposite(innerPanel); + } else { + innerPanel = parent; + } + + // Adjust the inner panel layout data. This is the final point in time + // to influence the inner panel layout. + if (innerPanel.getLayout() instanceof GridLayout) { + doAdjustInnerPanelLayout((GridLayout)innerPanel.getLayout()); + } + + // now, the label control for the edit field control comes first + if (!isHideLabelControl()) { + labelControl = doCreateLabelControl(innerPanel); + // give the subclasses the chance to reconfigure the label control for specific needs + configureLabelControl(labelControl); + } + + // In case, the button is not hidden and the inner panel to use + // has only 2 columns, we need an additional inner inner panel to + // squeeze the edit field control and the button into such panel + Composite innerInnerPanel = innerPanel; + if (((GridLayout)innerInnerPanel.getLayout()).numColumns == 2 && !isHideBrowseButton() && !isHideEditFieldControl()) { + innerInnerPanel = toolkit != null ? toolkit.createComposite(innerPanel) : new Composite(innerPanel, SWT.NONE); + if (isAdjustBackgroundColor()) { + SWTControlUtil.setBackground(innerInnerPanel, innerPanel.getBackground()); + } + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = 0; layout.marginWidth = 0; + innerInnerPanel.setLayout(layout); + innerInnerPanel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + } + + if (!isHideEditFieldControl()) { + // Create the edit field control itself. The result of + // doCreateEditFieldControl(...) must be always not null! + editFieldControl = doCreateEditFieldControl(innerInnerPanel); + Assert.isNotNull(editFieldControl); + + // Once the edit field got created, the control decoration must + // be created and configured _before_ the edit field itself is + // configured. Otherwise, the layout data for the edit field may + // not be configured correctly. + if (!isHideEditFieldControlDecoration()) { + controlDecoration = doCreateEditFieldControlDecoration(editFieldControl); + Assert.isNotNull(controlDecoration); + configureEditFieldControlDecoration(controlDecoration); + } + + // Configure the edit field control (including layout data) + configureEditFieldControl(editFieldControl); + + // before validation, create the edit field validator + setEditFieldValidator(doCreateEditFieldValidator()); + // now configure the edit field validator + configureEditFieldValidator(getEditFieldValidator()); + } + + if (!isHideBrowseButton()) { + // finally, the button most right end. + buttonControl = doCreateButtonControl(innerInnerPanel); + // give the subclasses the chance to reconfigure the button control for specific needs + configureButtonControl(buttonControl); + } + + // validate the control before setting the control visible + isValid(); + isInitializing = false; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#dispose() + */ + @Override + public void dispose() { + super.dispose(); + + labelControl = null; + editFieldControl = null; + buttonControl = null; + } + + /** + * Set the dialog settings slot id to use for saving and restoring the controls history + * to and from a given dialog settings instance. If the slot id is set to <code>null</code>, + * the edit field control label is used as slot id! + * + * @param settingsSlotId The dialog settings slot id to use or <code>null</code> to use the edit field control label as slot id. + */ + public void setDialogSettingsSlotId(String settingsSlotId) { + dialogSettingsSlotId = settingsSlotId; + } + + /** + * Returns the dialog settings slot id to use for saving and restoring the controls history + * to and from a given dialog settings instance. The returned dialog settings slot id is + * automatically prefixed if the given prefix is not <code>null</code> or empty. + * + * @param prefix The dialog settings slot id prefix or <code>null</code>. + * @return The dialog settings slot id to use. Must be never <code>null</code>! + */ + public String getDialogSettingsSlotId(String prefix) { + String settingsSlotId = dialogSettingsSlotId; + if (settingsSlotId == null) { + settingsSlotId = getEditFieldLabel().replace(':', ' ').trim().replace(' ', '_'); + } + return prefixDialogSettingsSlotId(settingsSlotId, prefix); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#doRestoreWidgetValues(org.eclipse.jface.dialogs.IDialogSettings, java.lang.String) + */ + @Override + public void doRestoreWidgetValues(IDialogSettings settings, String idPrefix) { + String[] historyEntries = getHistory(settings, idPrefix); + if (historyEntries.length > 0) { + setEditFieldControlHistory(historyEntries); + if ("".equals(getEditFieldControlText())) setEditFieldControlText(historyEntries[0]); //$NON-NLS-1$ + } + } + + /** + * Get the history entries from the dialog setting. + * @param settings The dialog setting. + * @param idPrefix The prefix for the dialog setting slot id + * @return The history entries or an empty array. Will never return <code>null</code>! + */ + protected String[] getHistory(IDialogSettings settings, String idPrefix) { + Assert.isNotNull(settings); + if (settings != null && getDialogSettingsSlotId(idPrefix) != null) { + return DialogSettingsUtil.getSettingsArraySafe(settings, getDialogSettingsSlotId(idPrefix)); + } + + return new String[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#doSaveWidgetValues(org.eclipse.jface.dialogs.IDialogSettings, java.lang.String) + */ + @Override + public void doSaveWidgetValues(IDialogSettings settings, String idPrefix) { + Assert.isNotNull(settings); + if (settings != null && getDialogSettingsSlotId(idPrefix) != null) { + String[] historyEntries = DialogSettingsUtil.getSettingsArraySafe(settings, getDialogSettingsSlotId(idPrefix)); + historyEntries = DialogSettingsUtil.addToHistory(historyEntries, getEditFieldControlText()); + settings.put(getDialogSettingsSlotId(idPrefix), historyEntries); + } + } + + /** + * Returns the validator for the edit field. + * + * @return The edit field validator. + */ + public final Validator getEditFieldValidator() { + return editFieldValidator; + } + + /** + * Set the validator for the edit field. + * This method should be overwritten to check whether the validator type is + * valid for the edit field. + * + * @param editFieldValidator The validator for the edit field. + */ + public void setEditFieldValidator(Validator editFieldValidator) { + this.editFieldValidator = editFieldValidator; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#isValid() + */ + @Override + public boolean isValid() { + if (isInitializing) { + return true; + } + boolean valid = super.isValid(); + + if (getEditFieldValidator() != null && + getEditFieldControl() != null && + !getEditFieldControl().isDisposed() && + SWTControlUtil.isEnabled(getEditFieldControl()) && + !isReadOnly() && + isLabelControlSelected()) { + + valid = getEditFieldValidator().isValid(getEditFieldControlTextForValidation()); + setMessage(getEditFieldValidator().getMessage(), getEditFieldValidator().getMessageType()); + } + + if (getEditFieldControlDecoration() != null) { + // Setup and show the control decoration if necessary + if (isEnabled() && (!valid || (getMessage() != null && getMessageType() != IMessageProvider.NONE))) { + // Update the control decorator + ControlDecoration decoration = getEditFieldControlDecoration(); + updateEditFieldControlDecorationForMessage(decoration, getMessage(), getMessageType()); + + // And show the decoration + decoration.show(); + } else { + ControlDecoration decoration = getEditFieldControlDecoration(); + // Control is valid and no message is set -> hide the decoration + decoration.hide(); + decoration.setDescriptionText(null); + } + } + + return valid; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseJFaceDialogSelectionControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseJFaceDialogSelectionControl.java new file mode 100644 index 000000000..79545dc93 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseJFaceDialogSelectionControl.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.swt.widgets.Composite; + +/** + * Base implementation of a common control allowing to select + * the content of the edit field control from a dialog. The dialog is associated + * to the base edit browse text controls button. + */ +public class BaseJFaceDialogSelectionControl extends BaseEditBrowseTextControl { + private Dialog dialogControl; + + /** + * Constructor. + * + * @param parentPage The parent page this control is embedded in. + * Might be <code>null</code> if the control is not associated with a page. + */ + public BaseJFaceDialogSelectionControl(IDialogPage parentPage) { + super(parentPage); + setIsGroup(true); + setHasHistory(true); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#isAdjustEditFieldControlWidthHint() + */ + @Override + protected boolean isAdjustEditFieldControlWidthHint() { + return true; + } + + /** + * Returns the dialog control. + * + * @return The dialog control or <code>null</code> if the control has not been created yet. + */ + public Dialog getDialogControl() { + return dialogControl; + } + + /** + * The method is called to create the dialog control. Subclasses may override this method + * to create their own dialog control. The default implementation returns <code>null</code>. + * + * @param parent The parent control for the button control to create. Must not be <code>null</code>! + * @return The created button control. + */ + protected Dialog doCreateDialogControl(Composite parent) { + Assert.isNotNull(parent); + return null; + } + + /** + * Configure the controls associated dialog before the dialogs is opened. Subclasses may use + * this hook to configure the controls associated dialog for their specific needs. + * + * @param dialog The dialog to configure. Must not be <code>null</code>! + */ + protected void configureDialogControl(Dialog dialog) { + Assert.isNotNull(dialog); + } + + /** + * Opens the given dialog and wait till the user pressed either OK or cancel. In + * case the user pressed OK and have selected a element within the dialog, the + * selected element is returned as string. In case the user canceled the dialog, + * the method returns <code>null</code>. The default implementation opens nothing + * and returns <code>null</code>! + * + * @param dialog The dialog to open. Must not be <code>null</code>. + * @return The selected element or <code>null</code>. + */ + protected String doOpenDialogControl(Dialog dialog) { + Assert.isNotNull(dialog); + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#onButtonControlSelected() + */ + @Override + protected void onButtonControlSelected() { + // create and configure the controls associated dialog + dialogControl = doCreateDialogControl(getParentControl()); + configureDialogControl(dialogControl); + + // open the dialog and get the user selected element + String selectedElement = doOpenDialogControl(dialogControl); + // apply the selected element in case the user pressed OK. + if (selectedElement != null) { + doApplyElementFromDialogControl(selectedElement); + } + + // finally, validate the control + isValid(); + } + + /** + * Apply the selected element returned from the controls associated dialog to the + * control. The default implementation applies the given element as is to the edit field + * control. Subclasses may override this method to run additional logic just before + * applying the selected element to the control. + * + * @param selectedElement The selected element from that controls associated dialog. Must not be <code>null</code>. + */ + protected void doApplyElementFromDialogControl(String selectedElement) { + Assert.isNotNull(selectedElement); + setEditFieldControlText(selectedElement); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseWizardConfigurationPanelControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseWizardConfigurationPanelControl.java new file mode 100644 index 000000000..a98acd581 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseWizardConfigurationPanelControl.java @@ -0,0 +1,222 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Base control to deal with wizard or property page controls + * which should share the same UI space. + */ +public class BaseWizardConfigurationPanelControl extends BaseDialogPageControl { + private final Map<String, IWizardConfigurationPanel> configurationPanels = new Hashtable<String, IWizardConfigurationPanel>(); + + private boolean isGroup; + + private Composite panel; + private StackLayout panelLayout; + + /** + * Constructor. + * + * @param parentPage The parent dialog page this control is embedded in. + * Might be <code>null</code> if the control is not associated with a page. + */ + public BaseWizardConfigurationPanelControl(IDialogPage parentPage) { + super(parentPage); + clear(); + setPanelIsGroup(false); + } + + /** + * Sets if or if not the controls panel is a <code>Group</code>. + * + * @param isGroup <code>True</code> if the controls panel is a group, <code>false</code> otherwise. + */ + public void setPanelIsGroup(boolean isGroup) { + this.isGroup = isGroup; + } + + /** + * Returns if or if not the controls panel is a <code>Group</code>. + * + * @return <code>True</code> if the controls panel is a group, <code>false</code> otherwise. + */ + public boolean isPanelIsGroup() { + return isGroup; + } + + /** + * Returns the controls panel. + * + * @return The controls panel or <code>null</code>. + */ + public Composite getPanel() { + return panel; + } + + /** + * Returns the label text to set for the group (if the panel is a group). + * + * @return The label text to apply or <code>null</code>. + */ + public String getGroupLabel() { + return null; + } + + /** + * To be called from the embedding control to setup the controls UI elements. + * + * @param parent The parent control. Must not be <code>null</code>! + * @param toolkit The form toolkit. Must not be <code>null</code>. + */ + public void setupPanel(Composite parent, String[] configurationPanelKeys, FormToolkit toolkit) { + Assert.isNotNull(parent); + Assert.isNotNull(toolkit); + + if (isPanelIsGroup()) { + panel = new Group(parent, SWT.NONE); + if (getGroupLabel() != null) ((Group)panel).setText(getGroupLabel()); + } else { + panel = new Composite(parent, SWT.NONE); + } + Assert.isNotNull(panel); + panel.setFont(parent.getFont()); + panel.setBackground(parent.getBackground()); + + panelLayout = new StackLayout(); + panel.setLayout(panelLayout); + + setupConfigurationPanels(panel, configurationPanelKeys, toolkit); + } + + /** + * Removes all configuration panels. + */ + public void clear() { + configurationPanels.clear(); + } + + /** + * Returns a unsorted list of all registered wizard configuration + * panel id's. + * + * @return A list of registered wizard configuration panel id's. + */ + public String[] getConfigurationPanelIds() { + return configurationPanels.keySet().toArray(new String[configurationPanels.keySet().size()]); + } + + /** + * Returns the wizard configuration panel instance registered for the given configuration panel key. + * + * @param key The key to get the wizard configuration panel for. Must not be <code>null</code>! + * @return The wizard configuration panel instance or <code>null</code> if the key is unknown. + */ + public IWizardConfigurationPanel getConfigurationPanel(String key) { + if (key == null) return null; + return configurationPanels.get(key); + } + + /** + * Adds the given wizard configuration panel under the given configuration panel key to the + * list of known panels. If the given configuration panel is <code>null</code>, any configuration + * panel stored under the given key is removed from the list of known panels. + * + * @param key The key to get the wizard configuration panel for. Must not be <code>null</code>! + * @param panel The wizard configuration panel instance or <code>null</code>. + */ + public void addConfigurationPanel(String key, IWizardConfigurationPanel panel) { + if (key == null) return; + if (panel != null) { + configurationPanels.put(key, panel); + } else { + configurationPanels.remove(key); + } + } + + /** + * Setup the wizard configuration panels for being presented to the user. This method is called by the + * controls <code>doSetupPanel(...)</code> and initialize all possible wizard configuration panels to show. + * The default implementation iterates over the given list of configuration panel keys and calls + * <code>setupPanel(...)</code> for each of them. + * + * @param parent The parent composite to use for the wizard configuration panels. Must not be <code>null</code>! + * @param configurationPanelKeys The list of configuration panels to initialize. Might be <code>null</code> or empty! + * @param toolkit The form toolkit. Must not be <code>null</code>. + */ + public void setupConfigurationPanels(Composite parent, String[] configurationPanelKeys, FormToolkit toolkit) { + Assert.isNotNull(parent); + Assert.isNotNull(toolkit); + + if (configurationPanelKeys != null) { + for (int i = 0; i < configurationPanelKeys.length; i++) { + IWizardConfigurationPanel configPanel = getConfigurationPanel(configurationPanelKeys[i]); + if (configPanel != null) configPanel.setupPanel(parent, toolkit); + } + } + } + + /** + * Make the wizard configuration panel registered under the given configuration panel key the + * most top configuration panel. If no configuration panel is registered under the given key, + * nothing will happen. + * + * @param key The key to get the wizard configuration panel for. Must not be <code>null</code>! + */ + public void showConfigurationPanel(String key) { + if (key == null) return; + + IWizardConfigurationPanel configPanel = getConfigurationPanel(key); + if (configPanel != null && configPanel.getControl() != null) { + panelLayout.topControl = configPanel.getControl(); + panel.layout(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#doSaveWidgetValues(org.eclipse.jface.dialogs.IDialogSettings, java.lang.String) + */ + @Override + public void doSaveWidgetValues(IDialogSettings settings, String idPrefix) { + super.doSaveWidgetValues(settings, idPrefix); + if (settings != null) { + for (String key : configurationPanels.keySet()) { + IWizardConfigurationPanel configPanel = getConfigurationPanel(key); + if (configPanel != null) configPanel.doSaveWidgetValues(settings, idPrefix); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseControl#doRestoreWidgetValues(org.eclipse.jface.dialogs.IDialogSettings, java.lang.String) + */ + @Override + public void doRestoreWidgetValues(IDialogSettings settings, String idPrefix) { + super.doRestoreWidgetValues(settings, idPrefix); + if (settings != null) { + for (String key : configurationPanels.keySet()) { + IWizardConfigurationPanel configPanel = getConfigurationPanel(key); + if (configPanel != null) configPanel.doRestoreWidgetValues(settings, idPrefix); + } + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/DialogSettingsUtil.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/DialogSettingsUtil.java new file mode 100644 index 000000000..301e7ee9e --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/DialogSettingsUtil.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogSettings; + +/** + * Utility class providing static methods to centralize + * common operations to perform on JFace dialog settings. + */ +public class DialogSettingsUtil { + + /** + * Default number of entries within the combo box history. + */ + public static final int COMBO_HISTORY_LENGTH = 5; + + /** + * Empty array to be returned by {@link #getSettingsArraySafe(IDialogSettings, String)}. + */ + public static final String[] NO_ELEMENTS = new String[0]; + + /** + * Add the given new history entry to the given array of existing history entries. + * Empty history entries or <code>null</code> values will be ignored and not added. + * + * @param history The array containing the existing history entries. Must not be <code>null</code>! + * @param newEntry The new entry to add to the history list. + * + * @return The new list of history entries. + */ + public static String[] addToHistory(String[] history, String newEntry) { + Assert.isNotNull(history); + + // We have to create a new ArrayList from the transformed array. Otherwise + // modification of the list would not be supported (java.lang.UnsupportedOperationException). + List<String> historyList = new ArrayList<String>(Arrays.asList(history)); + addToHistory(historyList, newEntry); + history = historyList.toArray(new String[historyList.size()]); + + return history; + } + + /** + * Adds the given history entry to the given list of history entries at index 0. + * Consistency checks are performed for the resulting list. + */ + private static void addToHistory(List<String> history, String newEntry) { + // just ignore values and do not add them to the history. Null values cannot + // be handle by SWT controls (like Combobox). However, do not assert null values! + if (newEntry != null && newEntry.trim().length() > 0) { + // remove all entries which just are prefixes of the newEntry + // Avoid to flood the history with partial typed entries for early finish supporting connections! + StringBuffer entry = new StringBuffer(newEntry); + while (entry.length() > 0) { + history.remove(entry.toString()); + entry.deleteCharAt(entry.length() - 1); + } + history.add(0, newEntry); + + // since only one new item was added, we can be over the limit + // by at most one item + if (history.size() > COMBO_HISTORY_LENGTH) history.remove(COMBO_HISTORY_LENGTH); + } + } + + /** + * Return a string array from given dialog settings. <code>Null</code> values + * will be filtered out. + * + * @param settings The dialog settings. Must not be <code>null</code>. + * @param key The dialog settings attribute key. Must not be <code>null</code>. + * + * @return The string array or an empty array. + */ + public static String[] getSettingsArraySafe(IDialogSettings settings, String key) { + Assert.isNotNull(settings); + Assert.isNotNull(key); + + String[] result = null; + + String[] values = settings.getArray(key); + if (values != null && values.length > 0) { + boolean filtered = false; + List<String> filteredValue = new ArrayList<String>(values.length); + for (String value : values) { + if (value != null && value.trim().length() > 0) { + filteredValue.add(value); + } else { + filtered = true; + } + } + if (filtered) { + if (!filteredValue.isEmpty()) { + result = filteredValue.toArray(new String[filteredValue.size()]); + } + } else { + result = values; + } + } + return result != null ? result : NO_ELEMENTS; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/DirectorySelectionControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/DirectorySelectionControl.java new file mode 100644 index 000000000..2c8417cd1 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/DirectorySelectionControl.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.tcf.te.ui.controls.nls.Messages; +import org.eclipse.tcf.te.ui.controls.validator.DirectoryNameValidator; +import org.eclipse.tcf.te.ui.controls.validator.Validator; +import org.osgi.framework.Bundle; + + +/** + * Base implementation of a simple directory selection control. + * <p> + * The control supports direct editing by the user or browsing for the directory. By + * default, the control has a history of recently selected directories. + */ +public class DirectorySelectionControl extends BaseDialogSelectionControl { + private String dialogMessage = ""; //$NON-NLS-1$ + + /** + * Constructor. + * + * @param parentPage The parent dialog page this control is embedded in. + * Might be <code>null</code> if the control is not associated with a page. + */ + public DirectorySelectionControl(IDialogPage parentPage) { + super(parentPage); + setDialogTitle(Messages.DirectorySelectionControl_title); + setGroupLabel(Messages.DirectorySelectionControl_group_label); + setEditFieldLabel(Messages.DirectorySelectionControl_editfield_label); + } + + /** + * Sets the dialogs description message. If the given message is <code>null</code>, the + * dialogs description message is set to an empty string. + * + * @param message The dialogs description message or <code>null</code>. + */ + public void setDialogMessage(String message) { + if (message == null) { + this.dialogMessage = ""; //$NON-NLS-1$ + } else { + this.dialogMessage = message; + } + } + + /** + * Returns the dialogs description message. + * + * @return The dialogs description message or an empty string. + */ + public String getDialogMessage() { + return dialogMessage; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseDialogSelectionControl#doCreateDialogControl(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Dialog doCreateDialogControl(Composite parent) { + Assert.isNotNull(parent); + + Dialog dialog = new DirectoryDialog(parent.getShell()); + return dialog; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseDialogSelectionControl#configureDialogControl(org.eclipse.swt.widgets.Dialog) + */ + @Override + protected void configureDialogControl(Dialog dialog) { + super.configureDialogControl(dialog); + + // We do expect a directory dialog here. + if (dialog instanceof DirectoryDialog) { + DirectoryDialog directoryDialog = (DirectoryDialog)dialog; + // the dialog should open within the directory of the currently selected + // directory. If no directory has been currently selected, it should open + // within the last browsed directory. + String selectedDirectory = doGetSelectedDirectory(); + if (selectedDirectory != null && selectedDirectory.trim().length() > 0) { + directoryDialog.setFilterPath(selectedDirectory); + } else if (Platform.getBundle("org.eclipse.core.resources") != null //$NON-NLS-1$ + && Platform.getBundle("org.eclipse.core.resources").getState() == Bundle.ACTIVE) { //$NON-NLS-1$ + directoryDialog.setFilterPath(org.eclipse.core.resources.ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString()); + } + // set the dialogs description message + directoryDialog.setMessage(getDialogMessage()); + } + } + + /** + * Returns the directory to set as initial directory. This method + * is called from {@link #configureDialogControl(Dialog)} in case the dialog + * is a {@link DirectoryDialog}. + * + * @return The initial directory to set to the directory dialog or <code>null</code> if none. + */ + protected String doGetSelectedDirectory() { + return getEditFieldControlText(); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#doCreateEditFieldValidator() + */ + @Override + protected Validator doCreateEditFieldValidator() { + return new DirectoryNameValidator( + Validator.ATTR_MANDATORY | + DirectoryNameValidator.ATTR_MUST_EXIST | + DirectoryNameValidator.ATTR_CAN_READ | + DirectoryNameValidator.ATTR_CAN_WRITE); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#setEditFieldValidator(org.eclipse.tcf.te.ui.controls.validator.Validator) + */ + @Override + public void setEditFieldValidator(Validator editFieldValidator) { + Assert.isTrue(editFieldValidator instanceof DirectoryNameValidator); + + if (editFieldValidator instanceof DirectoryNameValidator) { + super.setEditFieldValidator(editFieldValidator); + } + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseDialogSelectionControl#doOpenDialogControl(org.eclipse.swt.widgets.Dialog) + */ + @Override + protected String doOpenDialogControl(Dialog dialog) { + Assert.isNotNull(dialog); + + // We do expect a directory dialog here. + if (dialog instanceof DirectoryDialog) { + DirectoryDialog directoryDialog = (DirectoryDialog)dialog; + return directoryDialog.open(); + } + + return null; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/FileSelectionControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/FileSelectionControl.java new file mode 100644 index 000000000..b656d06fd --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/FileSelectionControl.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.tcf.te.ui.controls.nls.Messages; +import org.eclipse.tcf.te.ui.controls.validator.FileNameValidator; +import org.eclipse.tcf.te.ui.controls.validator.Validator; +import org.osgi.framework.Bundle; + + +/** + * Base implementation of a simple file selection control. + * <p> + * The control supports direct editing by the user or browsing for the file. By + * default, the control has a history of recently selected files. + */ +public class FileSelectionControl extends BaseDialogSelectionControl { + private String[] filterExtensions; + private String[] filterNames; + + /** + * Constructor. + * + * @param parentPage The parent dialog page this control is embedded in. + * Might be <code>null</code> if the control is not associated with a page. + */ + public FileSelectionControl(IDialogPage parentPage) { + super(parentPage); + setDialogTitle(Messages.FileSelectionControl_title_open); + setGroupLabel(Messages.FileSelectionControl_group_label); + setEditFieldLabel(Messages.FileSelectionControl_editfield_label); + } + + /** + * Set the filter extensions string array used by the standard file dialog. If set + * to <code>null</code>, not filter extensions will be given to the file dialog. + * + * @param filterExtensions The filter extensions string array to use or <code>null</code>. + */ + public void setFilterExtensions(String[] filterExtensions) { + this.filterExtensions = filterExtensions; + if (getEditFieldValidator() != null && filterExtensions != null) { + ((FileNameValidator)getEditFieldValidator()).setFileExtensions(filterExtensions); + } + } + + /** + * Returns the filter extensions string array used by the standard file dialog. + * + * @return The filter extensions string array or <code>null</code>. + */ + public String[] getFilterExtensions() { + return filterExtensions; + } + + + /** + * Set the filter names string array used by the standard file dialog. If set + * to <code>null</code>, not filter names will be given to the file dialog. + * + * @param filterExtensions The filter names string array to use or <code>null</code>. + */ + public void setFilterNames(String[] filterNames) { + this.filterNames = filterNames; + } + + /** + * Returns the filter names string array used by the standard file dialog. + * + * @return The filter names string array or <code>null</code>. + */ + public String[] getFilterNames() { + return filterNames; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseDialogSelectionControl#doCreateDialogControl(org.eclipse.swt.widgets.Composite) + */ + @Override + protected Dialog doCreateDialogControl(Composite parent) { + Assert.isNotNull(parent); + + // create a standard file dialog + FileDialog dialog = new FileDialog(parent.getShell(), SWT.OPEN); + return dialog; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseDialogSelectionControl#configureDialogControl(org.eclipse.swt.widgets.Dialog) + */ + @Override + protected void configureDialogControl(Dialog dialog) { + super.configureDialogControl(dialog); + + // we do expect a FileDialog here + if (dialog instanceof FileDialog) { + FileDialog fileDialog = (FileDialog)dialog; + + // set the file dialog filter extensions if available. + if (getFilterExtensions() != null) { + fileDialog.setFilterExtensions(getFilterExtensions()); + } + + // set the file dialog filter names if available. + if (getFilterNames() != null) { + fileDialog.setFilterNames(getFilterNames()); + } + + // the dialog should open within the directory of the currently selected + // file. If no file has been currently selected, it should open within the + // last browsed directory. + String selectedFile = doGetSelectedFile(); + if (selectedFile != null && selectedFile.trim().length() > 0) { + IPath filePath = new Path(selectedFile); + // If the selected file points to an directory, use the directory as is + IPath filterPath = filePath.toFile().isDirectory() ? filePath : filePath.removeLastSegments(1); + String filterFileName = filePath.toFile().isDirectory() || !filePath.toFile().exists() ? null : filePath.lastSegment(); + + if (!filterPath.isEmpty()) fileDialog.setFilterPath(filterPath.toString()); + if (filterFileName != null) fileDialog.setFileName(filterFileName); + } else if (Platform.getBundle("org.eclipse.core.resources") != null //$NON-NLS-1$ + && Platform.getBundle("org.eclipse.core.resources").getState() == Bundle.ACTIVE) { //$NON-NLS-1$ + fileDialog.setFilterPath(org.eclipse.core.resources.ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString()); + } + } + } + + /** + * Returns the file from which to set the initial directory. This method + * is called from {@link #configureDialogControl(Dialog)} in case the dialog + * is a {@link FileDialog}. + * <p> + * <b>Note:</b> The method may return a directory to use as initial directory + * in case the selected file cannot be determined. + * + * @return The file to set the initial directory to the file dialog or <code>null</code> if none. + */ + protected String doGetSelectedFile() { + return getEditFieldControlText(); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#doCreateEditFieldValidator() + */ + @Override + protected Validator doCreateEditFieldValidator() { + return new FileNameValidator(Validator.ATTR_MANDATORY | + FileNameValidator.ATTR_MUST_EXIST | + FileNameValidator.ATTR_CAN_READ | + FileNameValidator.ATTR_CAN_WRITE); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#configureEditFieldValidator(org.eclipse.tcf.te.ui.controls.validator.Validator) + */ + @Override + protected void configureEditFieldValidator(Validator editFieldValidator) { + if (editFieldValidator instanceof FileNameValidator) { + if (getFilterExtensions() != null) { + ((FileNameValidator)editFieldValidator).setFileExtensions(getFilterExtensions()); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseDialogSelectionControl#doOpenDialogControl(org.eclipse.swt.widgets.Dialog) + */ + @Override + protected String doOpenDialogControl(Dialog dialog) { + Assert.isNotNull(dialog); + + // We do expect a file dialog here. + if (dialog instanceof FileDialog) { + FileDialog fileDialog = (FileDialog)dialog; + return fileDialog.open(); + } + + return null; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/activator/UIPlugin.java new file mode 100644 index 000000000..337e09912 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/activator/UIPlugin.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.activator; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class UIPlugin extends AbstractUIPlugin { + // The shared instance + private static UIPlugin plugin; + + /** + * The constructor + */ + public UIPlugin() { + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static UIPlugin getDefault() { + return plugin; + } + + /** + * Convenience method which returns the unique identifier of this plugin. + */ + public static String getUniqueIdentifier() { + if (getDefault() != null && getDefault().getBundle() != null) { + return getDefault().getBundle().getSymbolicName(); + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/interfaces/IRunnableContextProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/interfaces/IRunnableContextProvider.java new file mode 100644 index 000000000..69b6ceb11 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/interfaces/IRunnableContextProvider.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.interfaces; + +import org.eclipse.jface.operation.IRunnableContext; + +/** + * Public interface of a runnable context provider. + */ +public interface IRunnableContextProvider { + + /** + * Returns the associated runnable context. + * + * @return The runnable context or <code>null</code> if none. + */ + public IRunnableContext getRunnableContext(); +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/interfaces/IWizardConfigurationPanel.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/interfaces/IWizardConfigurationPanel.java new file mode 100644 index 000000000..c919013b6 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/interfaces/IWizardConfigurationPanel.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.interfaces; + +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.swt.events.TypedEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; +import org.eclipse.ui.forms.widgets.FormToolkit; + +/** + * Target explorer: Interface to deal with the replaceable wizard configuration panels. + */ +public interface IWizardConfigurationPanel extends IMessageProvider { + + /** + * Creates the wizard configuration panel UI elements within the given parent composite. + * Wizard configuration panels should always create another composite within the given + * composite, which is the panel top control. The top control is queried later from the + * stack layout to show the different panels if the backend selection is changing. + * + * @param parent The parent composite to create the UI elements in. Must not be <code>null</code>. + * @param toolkit The form toolkit. Must not be <code>null</code>. + */ + public void setupPanel(Composite parent, FormToolkit toolkit); + + /** + * Cleanup all resources the wizard configuration panel might have been created. + */ + public void dispose(); + + /** + * Returns the wizard configuration panels top control, typically a composite control. + * This control is requested every time the stack layout is required to set a new top control + * because the backend selection had been changed. + * + * @return The wizard configuration panels top control or <code>null</code> if the configuration panel has been not setup yet. + */ + public Composite getControl(); + + /** + * Validates the control and sets the message text and type so the parent + * page or control is able to display validation result informations. + * The validation should be done by implementations of {@link WRValidator}! + * The default implementation of this method does nothing. + * + * @return Result of validation. + */ + public boolean isValid(); + + /** + * Called from external to query if the panel control values have changed + * compared to the given data. + * + * @param data The data. Must not be <code>null</code>. + * @param e The event which triggered the invocation or <code>null</code>. + * + * @return <code>True</code> if the panel control values are different to the given reference data, <code>false</code> otherwise. + */ + public boolean dataChanged(IPropertiesContainer data, TypedEvent e); + + /** + * Restore the widget values plain from the given dialog settings. This method should + * not fragment the given dialog settings any further. + * + * @param settings The dialog settings to restore the widget values from. Must not be <code>null</code>! + * @param idPrefix The prefix to use for every dialog settings slot keys. If <code>null</code>, the dialog settings slot keys are not to prefix. + */ + public void doRestoreWidgetValues(IDialogSettings settings, String idPrefix); + + /** + * Save the widget values plain to the given dialog settings. This method should + * not fragment the given dialog settings any further. + * + * @param settings The dialog settings to save the widget values to. Must not be <code>null</code>! + * @param idPrefix The prefix to use for every dialog settings slot keys. If <code>null</code>, the dialog settings slot keys are not to prefix. + */ + public void doSaveWidgetValues(IDialogSettings settings, String idPrefix); + + /** + * Called to adjust the wizard configuration panels child controls enablement. + */ + public void adjustControlEnablement(); +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/net/RemoteHostAddressControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/net/RemoteHostAddressControl.java new file mode 100644 index 000000000..897f90b5e --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/net/RemoteHostAddressControl.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.net; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetAddress; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.DialogPage; +import org.eclipse.jface.dialogs.IDialogPage; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.widgets.Control; +import org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl; +import org.eclipse.tcf.te.ui.controls.activator.UIPlugin; +import org.eclipse.tcf.te.ui.controls.nls.Messages; +import org.eclipse.tcf.te.ui.controls.validator.NameOrIPValidator; +import org.eclipse.tcf.te.ui.controls.validator.NameOrIPVerifyListener; +import org.eclipse.tcf.te.ui.controls.validator.Validator; + + +/** + * Basic remote host name or IP-address control. + */ +public class RemoteHostAddressControl extends BaseEditBrowseTextControl { + + /** + * Constructor. + * + * @param parentPage The parent dialog page this control is embedded in. Must not be <code>null</code>! + */ + public RemoteHostAddressControl(IDialogPage parentPage) { + super(parentPage); + setIsGroup(false); + setHasHistory(false); + setEditFieldLabel(Messages.RemoteHostAddressControl_label); + setButtonLabel(Messages.RemoteHostAddressControl_button_label); + setAdjustBackgroundColor(parentPage != null); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#onButtonControlSelected() + */ + @Override + protected void onButtonControlSelected() { + onCheckAddress(); + getButtonControl().setEnabled(false); + // Reset the validation message. + if (getMessage() != null && getMessage().equals(getUserInformationTextCheckNameAddress())) { + setMessage(null, IMessageProvider.NONE); + if (getEditFieldControlDecoration() != null) { + getEditFieldControlDecoration().hide(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#doCreateEditFieldValidator() + */ + @Override + protected Validator doCreateEditFieldValidator() { + return new NameOrIPValidator( + Validator.ATTR_MANDATORY | + NameOrIPValidator.ATTR_IP | + NameOrIPValidator.ATTR_NAME | + NameOrIPValidator.ATTR_CHECK_AVAILABLE); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#configureEditFieldValidator(org.eclipse.tcf.te.ui.controls.validator.Validator) + */ + @Override + protected void configureEditFieldValidator(Validator validator) { + if (validator != null && validator instanceof NameOrIPValidator) { + validator.setMessageText(NameOrIPValidator.INFO_MISSING_NAME_OR_IP, Messages.RemoteHostAddressControl_information_missingTargetNameAddress); + validator.setMessageText(NameOrIPValidator.ERROR_INVALID_NAME_OR_IP, Messages.RemoteHostAddressControl_error_invalidTargetNameAddress); + validator.setMessageText(NameOrIPValidator.ERROR_INVALID_NAME, Messages.RemoteHostAddressControl_error_invalidTargetNameAddress); + validator.setMessageText(NameOrIPValidator.ERROR_INVALID_IP, Messages.RemoteHostAddressControl_error_invalidTargetIpAddress); + validator.setMessageText(NameOrIPValidator.INFO_CHECK_NAME, getUserInformationTextCheckNameAddress()); + } + } + + private VerifyListener verifyListener; + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#doGetEditFieldControlVerifyListener() + */ + @Override + protected VerifyListener doGetEditFieldControlVerifyListener() { + if (verifyListener == null) { + verifyListener = + new NameOrIPVerifyListener( + NameOrIPVerifyListener.ATTR_IP | + NameOrIPVerifyListener.ATTR_NAME); + } + return verifyListener; + } + + /** + * Returns the human readable text to present to the user in case of the edit field control + * content should be checked by user action (pressing the check button). + * + * @return The user information text or an empty string. Must be never <code>null</code>. + */ + protected String getUserInformationTextCheckNameAddress() { + return Messages.RemoteHostAddressControl_information_checkNameAddressUserInformation; + } + + /** + * Returns the human readable text to present to the user as task name if checking if or if not + * the edit field content can be resolved to an IP-address. + * + * @return The task name for checking the host name. Must be never <code>null</code>. + */ + protected String getTaskNameCheckNameAddress() { + return Messages.RemoteHostAddressControl_information_checkNameAddressField; + } + + /** + * Returns the human readable text to present to the user if the edit field content resolving to + * an IP-address succeeded. + * + * @return The information text. Must be never <code>null</code>. + */ + protected String getInformationTextCheckNameAddressSuccess() { + return Messages.RemoteHostAddressControl_information_checkNameAddressFieldOk; + } + + /** + * Returns the human readable text to present to the user if the edit field content resolving to + * an IP-address failed. + * + * @return The error text. Must be never <code>null</code>. + */ + protected String getErrorTextCheckNameAddressFailed() { + return Messages.RemoteHostAddressControl_error_targetNameNotResolveable; + } + + /** + * If the user entered a host name, we have to validate that we can really resolve the name + * to an IP address. Because this may really take a while, give the user the feedback what + * we are actually doing. + */ + private void onCheckAddress() { + ProgressMonitorDialog dialog = new ProgressMonitorDialog(getParentControl().getShell()); + try { + dialog.run(false, false, new IRunnableWithProgress() { + private final String address = getEditFieldControlText(); + private final Control control = getEditFieldControl(); + private final IDialogPage parentPage = getParentPage(); + + /* (non-Javadoc) + * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor) + */ + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + try { + monitor.setTaskName(getTaskNameCheckNameAddress()); + InetAddress[] addresses = InetAddress.getAllByName(address); + if (Platform.inDebugMode() && addresses != null) { + String message = "RemoteHostAddressControl: Name '" + address + "' resolves to: "; //$NON-NLS-1$ //$NON-NLS-2$ + for (InetAddress address : addresses) { + message += address.getHostAddress() + ", "; //$NON-NLS-1$ + } + + IStatus status = new Status(IStatus.WARNING, UIPlugin.getUniqueIdentifier(), message); + UIPlugin.getDefault().getLog().log(status); + } + + setCheckResultMessage(IMessageProvider.INFORMATION, getInformationTextCheckNameAddressSuccess()); + } catch (Exception e) { + setCheckResultMessage(IMessageProvider.WARNING, getErrorTextCheckNameAddressFailed()); + control.setFocus(); + } finally { + // Trigger the wizard container update + IWizardContainer container = null; + + try { + // Try to get the wizard container from the parent page + Class<?>[] paramTypes = new Class[0]; + Object[] args = new Object[0]; + Method method = parentPage.getClass().getMethod("getContainer", paramTypes); //$NON-NLS-1$ + if (!method.isAccessible()) { + method.setAccessible(true); + } + Object result = method.invoke(parentPage, args); + if (result instanceof IWizardContainer) { + container = (IWizardContainer)result; + } + } catch (Exception e) { + // If the object does not have a "getContainer()" method, + // or the invocation fails or the access to the method + // is denied, we are done here and break the loop + container = null; + } + + if (container != null) { + container.updateButtons(); + container.updateMessage(); + } + } + } + }); + } catch (Exception e) {} + } + + protected void setCheckResultMessage(int severity, String message) { + setMessage(message, severity); + if (getParentPage() instanceof DialogPage) { + ((DialogPage)getParentPage()).setMessage(message, severity); + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/net/RemoteHostPortControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/net/RemoteHostPortControl.java new file mode 100644 index 000000000..672170e15 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/net/RemoteHostPortControl.java @@ -0,0 +1,62 @@ +/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.controls.net;
+
+import org.eclipse.jface.dialogs.IDialogPage;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl;
+import org.eclipse.tcf.te.ui.controls.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.validator.PortNumberValidator;
+import org.eclipse.tcf.te.ui.controls.validator.PortNumberVerifyListener;
+import org.eclipse.tcf.te.ui.controls.validator.Validator;
+
+/**
+ * Basic remote host port control.
+ */
+public class RemoteHostPortControl extends BaseEditBrowseTextControl {
+
+ /**
+ * Constructor.
+ *
+ * @param parentPage The parent dialog page this control is embedded in.
+ * Might be <code>null</code> if the control is not associated with a page.
+ */
+ public RemoteHostPortControl(IDialogPage parentPage) {
+ super(parentPage);
+ setIsGroup(false);
+ setHasHistory(false);
+ setHideBrowseButton(true);
+ setEditFieldLabel(Messages.RemoteHostPortControl_label);
+ setAdjustBackgroundColor(parentPage != null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#doCreateEditFieldValidator()
+ */
+ @Override
+ protected Validator doCreateEditFieldValidator() {
+ return new PortNumberValidator(PortNumberValidator.ATTR_DECIMAL | PortNumberValidator.ATTR_HEX);
+ }
+
+ private VerifyListener verifyListener;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl#doGetEditFieldControlVerifyListener()
+ */
+ @Override
+ protected VerifyListener doGetEditFieldControlVerifyListener() {
+ if (verifyListener == null) {
+ verifyListener =
+ new PortNumberVerifyListener(PortNumberVerifyListener.ATTR_DECIMAL | PortNumberVerifyListener.ATTR_HEX);
+ }
+ return verifyListener;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/nls/Messages.java new file mode 100644 index 000000000..634743748 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/nls/Messages.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.nls; + +import java.lang.reflect.Field; + +import org.eclipse.osgi.util.NLS; + +/** + * Common Controls plug-in externalized strings management. + */ +public class Messages extends NLS { + + // The plug-in resource bundle name + private static final String BUNDLE_NAME = "org.eclipse.tcf.te.ui.controls.nls.Messages"; //$NON-NLS-1$ + + /** + * Static constructor. + */ + static { + // Load message values from bundle file + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + /** + * Returns if or if not this NLS manager contains a constant for + * the given externalized strings key. + * + * @param key The externalized strings key or <code>null</code>. + * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise. + */ + public static boolean hasString(String key) { + if (key != null) { + try { + Field field = Messages.class.getDeclaredField(key); + return field != null; + } catch (NoSuchFieldException e) { /* ignored on purpose */ } + } + + return false; + } + + /** + * Returns the corresponding string for the given externalized strings + * key or <code>null</code> if the key does not exist. + * + * @param key The externalized strings key or <code>null</code>. + * @return The corresponding string or <code>null</code>. + */ + public static String getString(String key) { + if (key != null) { + try { + Field field = Messages.class.getDeclaredField(key); + if (field != null) { + return (String)field.get(null); + } + } catch (Exception e) { /* ignored on purpose */ } + } + + return null; + } + + // **** Declare externalized string id's down here ***** + + public static String BaseEditBrowseTextControl_button_label; + public static String BaseEditBrowseTextControl_validationJob_name; + + public static String DirectorySelectionControl_title; + public static String DirectorySelectionControl_group_label; + public static String DirectorySelectionControl_editfield_label; + + public static String FileSelectionControl_title_open; + public static String FileSelectionControl_title_save; + public static String FileSelectionControl_group_label; + public static String FileSelectionControl_editfield_label; + + public static String RemoteHostAddressControl_label; + public static String RemoteHostAddressControl_button_label; + public static String RemoteHostAddressControl_information_checkNameAddressUserInformation; + public static String RemoteHostAddressControl_information_checkNameAddressField; + public static String RemoteHostAddressControl_information_checkNameAddressFieldOk; + public static String RemoteHostAddressControl_information_missingTargetNameAddress; + public static String RemoteHostAddressControl_error_invalidTargetNameAddress; + public static String RemoteHostAddressControl_error_invalidTargetIpAddress; + public static String RemoteHostAddressControl_error_targetNameNotResolveable; + + public static String RemoteHostPortControl_label; + + public static String NameOrIPValidator_Information_MissingNameOrIP; + public static String NameOrIPValidator_Information_MissingName; + public static String NameOrIPValidator_Information_MissingIP; + public static String NameOrIPValidator_Information_CheckName; + public static String NameOrIPValidator_Error_InvalidNameOrIP; + public static String NameOrIPValidator_Error_InvalidName; + public static String NameOrIPValidator_Error_InvalidIP; + + public static String PortNumberValidator_Information_MissingPortNumber; + public static String PortNumberValidator_Error_InvalidPortNumber; + public static String PortNumberValidator_Error_PortNumberNotInRange; + + public static String FileNameValidator_Information_MissingName; + public static String FileNameValidator_Error_InvalidName; + public static String FileNameValidator_Error_IsDirectory; + public static String FileNameValidator_Error_MustExist; + public static String FileNameValidator_Error_ReadOnly; + public static String FileNameValidator_Error_NoAccess; + public static String FileNameValidator_Error_IsRelativ; + public static String FileNameValidator_Error_IsAbsolut; + public static String FileNameValidator_Error_HasSpaces; + + public static String DirectoryNameValidator_Information_MissingName; + public static String DirectoryNameValidator_Error_IsFile; + public static String DirectoryNameValidator_Error_MustExist; + public static String DirectoryNameValidator_Error_ReadOnly; + public static String DirectoryNameValidator_Error_NoAccess; + public static String DirectoryNameValidator_Error_IsRelativ; + public static String DirectoryNameValidator_Error_IsAbsolut; + + public static String RegexValidator_Information_MissingValue; + public static String RegexValidator_Error_InvalidValue; + + public static String HexValidator_Error_InvalidValueRange; + + public static String WorkspaceContainerValidator_Information_MissingValue; + public static String WorkspaceContainerValidator_Error_InvalidValue; + + public static String NumberValidator_Error_InvalidRange; +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/nls/Messages.properties new file mode 100644 index 000000000..ff4d2580a --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/nls/Messages.properties @@ -0,0 +1,69 @@ +# +# org.eclipse.tcf.te.ui.controls +# Externalized Strings. +# + +BaseEditBrowseTextControl_button_label=Browse... +BaseEditBrowseTextControl_validationJob_name={0} validation job + +DirectorySelectionControl_title=Browse for Folder +DirectorySelectionControl_group_label=Select directory +DirectorySelectionControl_editfield_label=Directory: + +FileSelectionControl_title_open=Open File +FileSelectionControl_title_save=Save File +FileSelectionControl_group_label=Select file +FileSelectionControl_editfield_label=File: + +RemoteHostAddressControl_label=Target name or address: +RemoteHostAddressControl_button_label=Check... +RemoteHostAddressControl_information_checkNameAddressUserInformation=The target name can be validated by pressing the check button. +RemoteHostAddressControl_information_checkNameAddressField=Trying to resolve target name to a valid IP address. +RemoteHostAddressControl_information_checkNameAddressFieldOk=Target name can be resolved and seems to be OK. +RemoteHostAddressControl_information_missingTargetNameAddress=Please enter a valid target name or IP address. +RemoteHostAddressControl_error_invalidTargetNameAddress=Target name or IP address is not valid. +RemoteHostAddressControl_error_invalidTargetIpAddress=Target IP address is not valid. +RemoteHostAddressControl_error_targetNameNotResolveable=Cannot resolve the target name to a valid IP address. + +RemoteHostPortControl_label=Port: + +NameOrIPValidator_Information_MissingNameOrIP=Please enter a hostname or IP address. +NameOrIPValidator_Information_MissingName=Please enter a hostname. +NameOrIPValidator_Information_MissingIP=Please enter an IP address. +NameOrIPValidator_Information_CheckName=Please check the hostname by selecting check. +NameOrIPValidator_Error_InvalidNameOrIP=Hostname or IP address contains illegal characters. +NameOrIPValidator_Error_InvalidName=Hostname is not valid. +NameOrIPValidator_Error_InvalidIP=IP address is not valid. + +PortNumberValidator_Information_MissingPortNumber=Please enter a port number. +PortNumberValidator_Error_InvalidPortNumber=The port number is not valid. +PortNumberValidator_Error_PortNumberNotInRange=The port number exceeds the valid range. + +FileNameValidator_Information_MissingName=Please enter a file name. +FileNameValidator_Error_InvalidName=The file name you entered is not valid. +FileNameValidator_Error_IsDirectory=The name you entered is an existing directory. +FileNameValidator_Error_MustExist=The file you entered doesn't exist. +FileNameValidator_Error_ReadOnly=The file you entered is read only. +FileNameValidator_Error_NoAccess=The file you entered cannot be accessed. +FileNameValidator_Error_IsRelativ=The file path you entered cannot be relative. +FileNameValidator_Error_IsAbsolut=The file path you entered cannot be absolute. +FileNameValidator_Error_HasSpaces=The file path you entered contains spaces. + +DirectoryNameValidator_Information_MissingName=Please enter a directory name. +DirectoryNameValidator_Error_IsFile=The name you entered is an existing file. +DirectoryNameValidator_Error_MustExist=The directory you entered doesn't exist. +DirectoryNameValidator_Error_ReadOnly=The directory you entered is read only. +DirectoryNameValidator_Error_NoAccess=The directory you entered cannot be accessed. +DirectoryNameValidator_Error_IsRelativ=The directory path you entered cannot be relative. +DirectoryNameValidator_Error_IsAbsolut=The directory path you entered cannot be absolute. + +RegexValidator_Information_MissingValue=Please enter a value. +RegexValidator_Error_InvalidValue=The value you entered is not valid. + +HexValidator_Error_InvalidValueRange=The value you entered is not in the valid range. + +WorkspaceContainerValidator_Information_MissingValue=Please enter a workspace container path. +WorkspaceContainerValidator_Error_InvalidValue=The entered workspace container path is invalid. {0} + +NumberValidator_Error_InvalidRange=Entered number is out of the valid range {0} - {1}. Please \ +enter a number within the range. diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/panels/AbstractWizardConfigurationPanel.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/panels/AbstractWizardConfigurationPanel.java new file mode 100644 index 000000000..67f341e64 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/panels/AbstractWizardConfigurationPanel.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.panels; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tcf.te.ui.controls.BaseDialogPageControl; +import org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel; + +/** + * Abstract base implementation of the <code>IWizardConfigurationPanel</code> interface. + */ +public abstract class AbstractWizardConfigurationPanel implements IWizardConfigurationPanel { + private final BaseDialogPageControl parentControl; + private Composite topControl = null; + + private String message = null; + private int messageType = IMessageProvider.NONE; + + /** + * Constructor. + * + * @param parentControl The parent control. Must not be <code>null</code>! + */ + public AbstractWizardConfigurationPanel(BaseDialogPageControl parentControl) { + super(); + Assert.isNotNull(parentControl); + this.parentControl = parentControl; + } + + /** + * Returns the associated parent control. + * + * @return The associated parent control. Must be never <code>null</code>! + */ + public BaseDialogPageControl getParentControl() { + return parentControl; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage() + */ + @Override + public final String getMessage() { + return message; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType() + */ + @Override + public final int getMessageType() { + return messageType; + } + + /** + * Set the message and the message type this control wants to display in + * the outer control or panel. + * + * @param message The message from this control. + * @param messageType The type o the message (NONE, INFORMATION, WARNING, ERROR). + */ + protected final void setMessage(String message, int messageType) { + this.message = message; + this.messageType = messageType; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#dispose() + */ + @Override + public void dispose() { + } + + /** + * Sets the top control. + * + * @param topControl The top control or <code>null</code>. + */ + protected void setControl(Composite topControl) { + this.topControl = topControl; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#getControl() + */ + @Override + public Composite getControl() { + return topControl; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#doRestoreWidgetValues(org.eclipse.jface.dialogs.IDialogSettings, java.lang.String) + */ + @Override + public void doRestoreWidgetValues(IDialogSettings settings, String idPrefix) { + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#doSaveWidgetValues(org.eclipse.jface.dialogs.IDialogSettings, java.lang.String) + */ + @Override + public void doSaveWidgetValues(IDialogSettings settings, String idPrefix) { + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#adjustControlEnablement() + */ + @Override + public void adjustControlEnablement() { + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#isValid() + */ + @Override + public boolean isValid() { + return true; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/DirectoryNameValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/DirectoryNameValidator.java new file mode 100644 index 000000000..480603fd2 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/DirectoryNameValidator.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import java.io.File; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + + +/** + * Input validator for files or directories. + */ +public class DirectoryNameValidator extends Validator { + + // keys for info messages file + public static final String INFO_MISSING_DIR_NAME = "DirectoryNameValidator_Information_MissingName"; //$NON-NLS-1$ + + // keys for error messages directory + public static final String ERROR_IS_FILE = "DirectoryNameValidator_Error_IsFile"; //$NON-NLS-1$ + public static final String ERROR_MUST_EXIST = "DirectoryNameValidator_Error_MustExist"; //$NON-NLS-1$ + public static final String ERROR_READ_ONLY = "DirectoryNameValidator_Error_ReadOnly"; //$NON-NLS-1$ + public static final String ERROR_NO_ACCESS = "DirectoryNameValidator_Error_NoAccess"; //$NON-NLS-1$ + public static final String ERROR_IS_RELATIV = "DirectoryNameValidator_Error_IsRelativ"; //$NON-NLS-1$ + public static final String ERROR_IS_ABSOLUT = "DirectoryNameValidator_Error_IsAbsolut"; //$NON-NLS-1$ + + // arguments + public static final int ATTR_MUST_EXIST = 2; + public static final int ATTR_CAN_READ = 4; + public static final int ATTR_CAN_WRITE = 8; + // if both attributes not set accept relative and absolute directories + public static final int ATTR_ABSOLUT = 16; + public static final int ATTR_RELATIV = 32; + /** + * Set this attribute if the path to validate is not on a local file system. + * Setting this attribute does unset ATTR_MUST_EXIST, ATTR_CAN_READ and ATTR_CAN_WRITE. + */ + public static final int ATTR_REMOTE_PATH = 64; + // next attribute should start with 2^7 + + // value attributes + private boolean isDir; + private boolean exists; + private boolean canRead; + private boolean canWrite; + private boolean absolute; + + /** + * Constructor + * @attributes attributes The validator attributes. + */ + public DirectoryNameValidator(int attributes) { + super(attributes); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#init() + */ + @Override + protected void init() { + super.init(); + isDir = false; + exists = false; + canRead = false; + canWrite = false; + absolute = false; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String newFile) { + init(); + + // info message when value is empty and mandatory + if (newFile == null || newFile.trim().length() == 0) { + if (isAttribute(ATTR_MANDATORY)) { + setMessage(getMessageText(INFO_MISSING_DIR_NAME), getMessageTextType(INFO_MISSING_DIR_NAME, INFORMATION)); + return false; + } + return true; + } + + newFile = newFile.trim(); + + IPath path = new Path(newFile); + File dir = path.toFile(); + + // If the path is an remote path, use the IPath object to validate + // if or if not it is an absolute path + absolute = isAttribute(ATTR_REMOTE_PATH) ? path.isAbsolute() : dir.isAbsolute(); + + // Validate all other attributes via the File object + exists = dir.exists(); + isDir = dir.isDirectory() || !exists; + + // To determine canRead and canWrite, we have to find the first existing parent directory + File parentDir = dir.getParentFile(); + while (parentDir != null && !parentDir.exists()) { + parentDir = parentDir.getParentFile(); + } + + canRead = dir.canRead() || (!exists && parentDir != null && parentDir.canWrite()); + canWrite = dir.canWrite() || (!exists && parentDir != null && parentDir.canWrite()); + + if (!isAttribute(ATTR_REMOTE_PATH) && isAttribute(ATTR_MUST_EXIST) && !exists) { + setMessage(getMessageText(ERROR_MUST_EXIST), getMessageTextType(ERROR_MUST_EXIST, ERROR)); + } + else if (isAttribute(ATTR_ABSOLUT) && !isAttribute(ATTR_RELATIV) && !absolute) { + setMessage(getMessageText(ERROR_IS_RELATIV), getMessageTextType(ERROR_IS_RELATIV, ERROR)); + } + else if (isAttribute(ATTR_RELATIV) && !isAttribute(ATTR_ABSOLUT) && absolute) { + setMessage(getMessageText(ERROR_IS_ABSOLUT), getMessageTextType(ERROR_IS_ABSOLUT, ERROR)); + } + else if (exists && !isDir) { + setMessage(getMessageText(ERROR_IS_FILE), getMessageTextType(ERROR_IS_FILE, ERROR)); + } + else if (!isAttribute(ATTR_REMOTE_PATH) && isAttribute(ATTR_CAN_READ) && !canRead) { + setMessage(getMessageText(ERROR_NO_ACCESS), getMessageTextType(ERROR_NO_ACCESS, ERROR)); + } + else if (!isAttribute(ATTR_REMOTE_PATH) && isAttribute(ATTR_CAN_WRITE) && !canWrite) { + setMessage(getMessageText(ERROR_READ_ONLY), getMessageTextType(ERROR_READ_ONLY, ERROR)); + } + + return getMessageType() != ERROR; + } + + /** + * Validated value is a directory. + * @return + */ + public boolean isDirectory() { + return isDir; + } + + /** + * Validated directory exists. + * @return + */ + public boolean exists() { + return exists; + } + + /** + * Validated directory can be read. + * @return + */ + public boolean canRead() { + return canRead; + } + + /** + * Validated directory be written. + * @return + */ + public boolean canWrite() { + return canWrite; + } + + /** + * Validated directory path is absolute. + * @return + */ + public boolean isAbsolute() { + return absolute; + } + + /** + * Validated directory path is relative. + * @return + */ + public boolean isRelative() { + return !absolute; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/DoubleNumberVerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/DoubleNumberVerifyListener.java new file mode 100644 index 000000000..11bd4708a --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/DoubleNumberVerifyListener.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import org.eclipse.swt.events.VerifyEvent; + +/** + * Verify listener for text widgets to receive floating point numbers. + */ +public class DoubleNumberVerifyListener extends RegexVerifyListener { + + /** + * Constructor. + */ + public DoubleNumberVerifyListener() { + super(NO_ATTR, null); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.RegexVerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) + */ + @Override + public void verifyText(VerifyEvent e) { + super.verifyText(e); + String fullText = getFullText(e); + if (e.doit && fullText != null && fullText.length() > 0) { + // append dummy digit to make it possible to enter '.' and 'e' at all + if (fullText.endsWith("-") || fullText.endsWith("+") || //$NON-NLS-1$ //$NON-NLS-2$ + fullText.endsWith(".") || fullText.endsWith("e") || fullText.endsWith("E")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + fullText += "0"; //$NON-NLS-1$ + } + try { + Double.parseDouble(fullText); + } + catch (Exception ex) { + e.doit = false; + } + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/FileNameValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/FileNameValidator.java new file mode 100644 index 000000000..38508de9a --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/FileNameValidator.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import java.io.File; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + + +/** + * Input validator for files. + */ +public class FileNameValidator extends Validator { + + // keys for info messages file + public static final String INFO_MISSING_FILE_NAME = "FileNameValidator_Information_MissingName"; //$NON-NLS-1$ + + // keys for error messages file + public static final String ERROR_INVALID_FILE_NAME = "FileNameValidator_Error_InvalidName"; //$NON-NLS-1$ + public static final String ERROR_IS_DIRECTORY = "FileNameValidator_Error_IsDirectory"; //$NON-NLS-1$ + public static final String ERROR_MUST_EXIST = "FileNameValidator_Error_MustExist"; //$NON-NLS-1$ + public static final String ERROR_READ_ONLY = "FileNameValidator_Error_ReadOnly"; //$NON-NLS-1$ + public static final String ERROR_NO_ACCESS = "FileNameValidator_Error_NoAccess"; //$NON-NLS-1$ + public static final String ERROR_IS_RELATIV = "FileNameValidator_Error_IsRelativ"; //$NON-NLS-1$ + public static final String ERROR_IS_ABSOLUT = "FileNameValidator_Error_IsAbsolut"; //$NON-NLS-1$ + public static final String ERROR_HAS_SPACES = "FileNameValidator_Error_HasSpaces"; //$NON-NLS-1$ + + // arguments + private List<String> fileExtensions; + + public static final int ATTR_MUST_EXIST = 2; + public static final int ATTR_CAN_READ = 4; + public static final int ATTR_CAN_WRITE = 8; + // if both attributes not set accept relative and absolute files + public static final int ATTR_ABSOLUT = 16; + public static final int ATTR_RELATIV = 32; + public static final int ATTR_NO_SPACES = 64; + // next attribute should start with 2^7 + + // value attributes + private boolean isFile; + private boolean exists; + private boolean canRead; + private boolean canWrite; + private boolean absolute; + private boolean spaces; + + /** + * Constructor + * @param attributes The validator attributes. + */ + public FileNameValidator(int attributes) { + super(attributes); + } + + /** + * Constructor + * @param attributes The validator attributes. + */ + public FileNameValidator(int attributes, String[] fileExtensions) { + super(attributes); + setFileExtensions(fileExtensions); + } + + /** + * Set the valid file extensions for attribute ATTR_FILE. + * @param fileExtensions The valid file extensions. + */ + public void setFileExtensions(String[] fileExtensions) { + this.fileExtensions = Arrays.asList(fileExtensions); + } + + /** + * Return the valid file extensions for attribute ATTR_FILE. + * @return + */ + public String[] getFileExtensions() { + if (fileExtensions != null) { + return fileExtensions.toArray(new String[fileExtensions.size()]); + } + return new String[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#init() + */ + @Override + protected void init() { + super.init(); + isFile = false; + exists = false; + canRead = false; + canWrite = false; + absolute = false; + spaces = false; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String newFile) { + init(); + + // info message when value is empty and mandatory + if (newFile == null || newFile.trim().length() == 0) { + if (isAttribute(ATTR_MANDATORY)) { + setMessage(getMessageText(INFO_MISSING_FILE_NAME), getMessageTextType(INFO_MISSING_FILE_NAME, INFORMATION)); + return false; + } + return true; + } + + newFile = newFile.trim(); + File file = new File(newFile); + exists = file.exists(); + isFile = file.isFile() || !exists; + absolute = file.isAbsolute(); + + // To determine canRead and canWrite, we have to find the first existing parent directory + File parentFile = file.getParentFile(); + while (parentFile != null && !parentFile.exists()) { + parentFile = parentFile.getParentFile(); + } + + canRead = file.canRead() || (!exists && parentFile != null && parentFile.canRead()); + // *** Note: *** + // canWrite() may return false on some special folders on Windows like "My Documents". + // This is bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4939819. + canWrite = file.canWrite() || (!exists && parentFile != null && parentFile.canWrite()); + spaces = file.toString().trim().indexOf(' ') > 0; + + // Highest priority is MUST_EXIST + if (isAttribute(ATTR_MUST_EXIST) && !exists) { + setMessage(getMessageText(ERROR_MUST_EXIST), getMessageTextType(ERROR_MUST_EXIST, ERROR)); + } + // Second test on spaces. If disallowed, the user should be told despite the other conditions + else if (isAttribute(ATTR_NO_SPACES) && spaces) { + setMessage(getMessageText(ERROR_HAS_SPACES), getMessageTextType(ERROR_HAS_SPACES, ERROR)); + } + // Third: all the rest + else if (isAttribute(ATTR_ABSOLUT) && !isAttribute(ATTR_RELATIV) && !absolute) { + setMessage(getMessageText(ERROR_IS_RELATIV), getMessageTextType(ERROR_IS_RELATIV, ERROR)); + } + else if (isAttribute(ATTR_RELATIV) && !isAttribute(ATTR_ABSOLUT) && absolute) { + setMessage(getMessageText(ERROR_IS_ABSOLUT), getMessageTextType(ERROR_IS_ABSOLUT, ERROR)); + } + else if (exists && !isFile) { + setMessage(getMessageText(ERROR_IS_DIRECTORY), getMessageTextType(ERROR_IS_DIRECTORY, ERROR)); + } + else if (isFile && !hasValidExtension(newFile)) { + setMessage(getMessageText(ERROR_INVALID_FILE_NAME), getMessageTextType(ERROR_INVALID_FILE_NAME, ERROR)); + } + else if (isAttribute(ATTR_CAN_READ) && !canRead) { + setMessage(getMessageText(ERROR_NO_ACCESS), getMessageTextType(ERROR_NO_ACCESS, ERROR)); + } + else if (isAttribute(ATTR_CAN_WRITE) && !canWrite) { + setMessage(getMessageText(ERROR_READ_ONLY), getMessageTextType(ERROR_READ_ONLY, ERROR)); + } + + return getMessageType() != ERROR; + } + + private boolean hasValidExtension(String newFile) { + if (fileExtensions != null && fileExtensions.size() > 0) { + Iterator<String> i = fileExtensions.iterator(); + while (i.hasNext()) { + String ex = i.next().toLowerCase(); + if (newFile.toLowerCase().endsWith(ex) || + ex.equals("*") || ex.equals("*.*") || ex.equals(".*")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return true; + } + } + return false; + } + return true; + } + + /** + * Validated value is a file. + * @return + */ + public boolean isFile() { + return isFile; + } + + /** + * Validated file exists. + * @return + */ + public boolean exists() { + return exists; + } + + /** + * Validated file can be read. + * @return + */ + public boolean canRead() { + return canRead; + } + + /** + * Validated file can be written. + * @return + */ + public boolean canWrite() { + return canWrite; + } + + /** + * Validated file path is absolute. + * @return + */ + public boolean isAbsolute() { + return absolute; + } + + /** + * Validated file path is relative. + * @return + */ + public boolean isRelative() { + return !absolute; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/HexValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/HexValidator.java new file mode 100644 index 000000000..0b9a1d211 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/HexValidator.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.Assert; + +/** + * Validator for hex values. + */ +public class HexValidator extends RegexValidator { + + /** + * Allows entering decimal numbers. + */ + public static final int ATTR_ALLOW_DECIMAL = 2; + + /** + * Enables negative decimal numbers. Has effect only if {@link #ATTR_ALLOW_DECIMAL} + * is set as well. + */ + public static final int ATTR_ALLOW_NEGATIVE_DECIMAL = 4; + + /** + * Enables negative hexadecimal numbers. + */ + public static final int ATTR_ALLOW_NEGATIVE_HEX = 8; + // next attribute should start with 2^4 + + // keys for error messages + public static final String ERROR_INVALID_VALUE_RANGE = "HexValidator_Error_InvalidValueRange"; //$NON-NLS-1$ + + // regular expressions + protected static final String HEX_REGEX = "@NEGATIVE@(0(x|X)[0-9a-fA-F]{@BYTES_MIN@,@BYTES_MAX@})|0"; //$NON-NLS-1$ + protected static final String NUMBER_REGEX = "@NEGATIVE@([0-9]*)"; //$NON-NLS-1$ + + private int minBytes = 0; + private int maxBytes = 8; + + private boolean isHex = false; + private boolean isDecimal = false; + + /** + * Constructor. + * @param attributes + */ + public HexValidator(int attributes, int minBytes, int maxBytes) { + super(attributes, getRegEx(attributes, minBytes, maxBytes)); + + this.minBytes = minBytes; + this.maxBytes = maxBytes; + } + + /** + * Constructor. + * @param attributes + */ + public HexValidator(int attributes, int bytes) { + super(attributes, getRegEx(attributes, bytes, bytes)); + + this.minBytes = bytes; + this.maxBytes = bytes; + } + + /* + * Static method to generate regular expression for constructor super call. + */ + private static String getRegEx(int attributes, int minBytes, int maxBytes) { + String regex = (isAttribute(ATTR_ALLOW_DECIMAL, attributes) + ? NUMBER_REGEX.replaceAll("@NEGATIVE@", isAttribute(ATTR_ALLOW_NEGATIVE_DECIMAL, attributes) ? "-?" : "") + "|" //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + : "") + HEX_REGEX; //$NON-NLS-1$ + regex = regex.replaceAll("@NEGATIVE@", isAttribute(ATTR_ALLOW_NEGATIVE_HEX, attributes) ? "-?" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + regex = regex.replaceAll("@BYTES_MIN@", "" + minBytes); //$NON-NLS-1$ //$NON-NLS-2$ + regex = regex.replaceAll("@BYTES_MAX@", "" + maxBytes); //$NON-NLS-1$ //$NON-NLS-2$ + return regex; + } + + /** + * Adjust the values for minimum bytes and maximum byte allowed. + * + * @param minBytes The minimum number of bytes. Must be non-negative. + * @param maxBytes The maximum number of bytes. Must be non-negative. + */ + public void setBounds(int minBytes, int maxBytes) { + Assert.isTrue(minBytes >= 0 && maxBytes >= 0 && minBytes <= maxBytes); + setRegularExpression(getRegEx(getAttributes(), minBytes, maxBytes)); + this.minBytes = minBytes; + this.maxBytes = maxBytes; + } + + /** + * Returns if the validator is currently working in hex mode. + * + * @return <code>true</code> if in hex mode, <code>false</code> otherwise. + */ + public boolean isHex() { + return isHex; + } + + /** + * Returns if the validator is currently working in decimal mode. + * + * @return <code>true</code> if in decimal mode, <code>false</code> otherwise. + */ + public boolean isDecimal() { + return isDecimal; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.RegexValidator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String newText) { + isHex = false; + isDecimal = false; + + boolean valid = super.isValid(newText); + + if (valid) { + String hexRegex = HEX_REGEX; + hexRegex = hexRegex.replaceAll("@NEGATIVE@", isAttribute(ATTR_ALLOW_NEGATIVE_HEX) ? "-?" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + hexRegex = hexRegex.replaceAll("@BYTES_MIN@", "" + minBytes); //$NON-NLS-1$ //$NON-NLS-2$ + hexRegex = hexRegex.replaceAll("@BYTES_MAX@", "" + maxBytes); //$NON-NLS-1$ //$NON-NLS-2$ + + String numberRegex = NUMBER_REGEX; + numberRegex = numberRegex.replaceAll("@NEGATIVE@", isAttribute(ATTR_ALLOW_NEGATIVE_DECIMAL) ? "-?" : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + isHex = newText.matches(hexRegex); + isDecimal = newText.matches(numberRegex); + } + + if (valid && isAttribute(ATTR_ALLOW_DECIMAL) && isDecimal()) { + BigInteger min = minBytes > 1 ? BigInteger.valueOf(16).pow(minBytes-1) : BigInteger.ZERO; + BigInteger max = BigInteger.valueOf(16).pow(maxBytes); + + BigInteger value = !"".equals(newText) ? decode(newText) : BigInteger.ZERO; //$NON-NLS-1$ + if (value == null || value.abs().compareTo(min) < 0 || value.abs().compareTo(max) > 0) { + setMessage(getMessageText(ERROR_INVALID_VALUE_RANGE), getMessageTextType(ERROR_INVALID_VALUE_RANGE, ERROR)); + valid = getMessageType() != ERROR; + } + } + + return valid; + } + + /** + * Decodes a given string into a <code>BigInteger</code> representation. + * + * @param value The value to decode. Must not be <code>null</code>! + * @return The big integer representation or <code>null</code> if the decoding failed. + */ + public final static BigInteger decode(String value) { + Assert.isNotNull(value); + BigInteger result = null; + if (value != null) { + try { + if (value.trim().toUpperCase().startsWith("0X")) { //$NON-NLS-1$ + // we have to cut away the leading 0x. + result = new BigInteger(value.substring(2), 16); + } else { + result = new BigInteger(value, 10); + } + } catch (NumberFormatException e) { /* ignored on purpose */ + } + } + + return result; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/HexVerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/HexVerifyListener.java new file mode 100644 index 000000000..348e2a0aa --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/HexVerifyListener.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.swt.events.VerifyEvent; + +/** + * Verify listener for text widgets to receive hex values. + */ +public class HexVerifyListener extends RegexVerifyListener { + + // arguments (binary coded) + public static final int ATTR_TO_UPPER_CASE = 1; + public static final int ATTR_ALLOW_DECIMAL = 2; + + /** + * Enables negative decimal numbers. Has effect on if {@link #ATTR_ALLOW_DECIMAL} + * is set as well. + */ + public static final int ATTR_ALLOW_NEGATIVE_DECIMAL = 4; + + /** + * Enables negative hexadecimal numbers. + */ + public static final int ATTR_ALLOW_NEGATIVE_HEX = 8; + // next attribute should start with 2^4 + + // regular expressions + protected static final String HEX_REGEX = "@NEGATIVE@(0((x|X)[0-9a-fA-F]{0,@BYTES@})?)?"; //$NON-NLS-1$ + protected static final String NUMBER_REGEX = "@NEGATIVE@([0-9]*)"; //$NON-NLS-1$ + + /** + * Constructor + * @param bytes The number of bytes (hex digits) allowed. + */ + public HexVerifyListener(int attributes, int bytes) { + super(attributes, getRegEx(attributes, bytes)); + } + + /* + * Static method to generate regular expression for constructor super call. + */ + private static String getRegEx(int attributes, int bytes) { + return (isAttribute(ATTR_ALLOW_DECIMAL, attributes) + ? NUMBER_REGEX.replaceAll("@NEGATIVE@", isAttribute(ATTR_ALLOW_NEGATIVE_DECIMAL, attributes) ? "-?" : "") + "|" //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + : "") + HEX_REGEX.replaceAll("@BYTES@", "" + bytes) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + .replaceAll("@NEGATIVE@", isAttribute(ATTR_ALLOW_NEGATIVE_HEX, attributes) ? "-?" : ""); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * Adjust the value for maximum byte allowed. + * + * @param maxBytes The maximum number of bytes. Must be non-negative. + */ + public void setBounds(int maxBytes) { + Assert.isTrue(maxBytes >= 0); + setRegularExpression(getRegEx(getAttributes(), maxBytes)); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.RegexVerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) + */ + @Override + public void verifyText(VerifyEvent e) { + super.verifyText(e); + if (e.doit && isAttribute(ATTR_TO_UPPER_CASE)) { + e.text = e.text.toUpperCase().replace('X', 'x'); + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NameOrIPValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NameOrIPValidator.java new file mode 100644 index 000000000..dbddd8623 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NameOrIPValidator.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + + +/** + * Input validator for hostnames id IP addresses. + */ +public class NameOrIPValidator extends Validator { + + // regular expressions for validator + private static final String IP_CHARACTERS_REGEX = "[0-9\\.]+"; //$NON-NLS-1$ + public static final String IP_REGEX = NameOrIPVerifyListener.IP_FRAGMENT_REGEX + "(\\." + //$NON-NLS-1$ + NameOrIPVerifyListener.IP_FRAGMENT_REGEX + "){3}"; //$NON-NLS-1$ + + // RFC 1034 - ftp://ftp.rfc-editor.org/in-notes/std/std13.txt + private static final String NAME_CHARACTERS_REGEX = "[0-9a-zA-Z\\-_\\.]+"; //$NON-NLS-1$ + public static final String NAME_REGEX = NameOrIPVerifyListener.NAME_FRAGMENT_REGEX + "(\\." + //$NON-NLS-1$ + NameOrIPVerifyListener.NAME_FRAGMENT_REGEX + ")*"; //$NON-NLS-1$ + + // keys for info messages + public static final String INFO_MISSING_NAME_OR_IP = "NameOrIPValidator_Information_MissingNameOrIP"; //$NON-NLS-1$ + public static final String INFO_MISSING_NAME = "NameOrIPValidator_Information_MissingName"; //$NON-NLS-1$ + public static final String INFO_MISSING_IP = "NameOrIPValidator_Information_MissingIP"; //$NON-NLS-1$ + public static final String INFO_CHECK_NAME = "NameOrIPValidator_Information_CheckName"; //$NON-NLS-1$ + + // keys for error messages + public static final String ERROR_INVALID_NAME_OR_IP = "NameOrIPValidator_Error.InvalidNameOrIP"; //$NON-NLS-1$ + public static final String ERROR_INVALID_IP = "NameOrIPValidator_Error_InvalidIP"; //$NON-NLS-1$ + public static final String ERROR_INVALID_NAME = "NameOrIPValidator_Error_InvalidName"; //$NON-NLS-1$ + + // arguments + public static final int ATTR_NAME = 2; + public static final int ATTR_IP = 4; + public static final int ATTR_CHECK_AVAILABLE = 8; + // next attribute should start with 2^4 + + + // value attributes + private boolean isIP; + private boolean isName; + + /** + * Constructor + * @attributes attributes The validator attributes. + */ + public NameOrIPValidator(int attributes) { + super(attributes); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#init() + */ + @Override + protected void init() { + super.init(); + isIP = false; + isName = false; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String ipOrHostName) { + init(); + + // info message when value is empty + if (ipOrHostName == null || ipOrHostName.trim().length() == 0) { + if (isAttribute(ATTR_MANDATORY)) { + if (isAttribute(ATTR_IP) && !isAttribute(ATTR_NAME)) { + setMessage(getMessageText(INFO_MISSING_IP), getMessageTextType(INFO_MISSING_IP, INFORMATION)); + } + else if (isAttribute(ATTR_NAME) && !isAttribute(ATTR_IP)) { + setMessage(getMessageText(INFO_MISSING_NAME), getMessageTextType(INFO_MISSING_NAME, INFORMATION)); + } + else { + setMessage(getMessageText(INFO_MISSING_NAME_OR_IP), getMessageTextType(INFO_MISSING_NAME_OR_IP, INFORMATION)); + } + return false; + } + return true; + } + ipOrHostName = ipOrHostName.trim(); + // check IP address when only numeric values and '.' are entered + if (ipOrHostName.matches(IP_CHARACTERS_REGEX)) { + isIP = true; + // error message when IP not correct + if (!isAttribute(ATTR_IP) && isAttribute(ATTR_NAME)) { + setMessage(getMessageText(ERROR_INVALID_NAME), getMessageTextType(ERROR_INVALID_NAME, ERROR)); + } + else if (!ipOrHostName.matches(IP_REGEX)) { + setMessage(getMessageText(ERROR_INVALID_IP), getMessageTextType(ERROR_INVALID_IP, ERROR)); + } + } + else if (ipOrHostName.matches(NAME_CHARACTERS_REGEX)) { + isName = true; + if (!isAttribute(ATTR_NAME) && isAttribute(ATTR_IP)) { + setMessage(getMessageText(ERROR_INVALID_IP), getMessageTextType(ERROR_INVALID_IP, ERROR)); + } + else if (!ipOrHostName.matches(NAME_REGEX)) { + setMessage(getMessageText(ERROR_INVALID_NAME), getMessageTextType(ERROR_INVALID_NAME, ERROR)); + } + else if (isAttribute(ATTR_CHECK_AVAILABLE)){ + // info message when name was entered to check + setMessage(getMessageText(INFO_CHECK_NAME), getMessageTextType(INFO_CHECK_NAME, INFORMATION)); + } + } + else { + if (isAttribute(ATTR_IP) && !isAttribute(ATTR_NAME)) { + setMessage(getMessageText(ERROR_INVALID_IP), getMessageTextType(ERROR_INVALID_IP, ERROR)); + } + else if (isAttribute(ATTR_NAME) && !isAttribute(ATTR_IP)) { + setMessage(getMessageText(ERROR_INVALID_NAME), getMessageTextType(ERROR_INVALID_NAME, ERROR)); + } + else { + setMessage(getMessageText(ERROR_INVALID_NAME_OR_IP), getMessageTextType(ERROR_INVALID_NAME_OR_IP, ERROR)); + } + } + + return getMessageType() != ERROR; + } + + /** + * Validated value is IP address. + * @return + */ + public boolean isIP() { + return isIP; + } + + /** + * Validated value is alphanumeric host name. + * @return + */ + public boolean isName() { + return isName; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NameOrIPVerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NameOrIPVerifyListener.java new file mode 100644 index 000000000..1c3e1fd21 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NameOrIPVerifyListener.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +/** + * Verify listener for text widgets to receive host names or IP addresses. + */ +public class NameOrIPVerifyListener extends RegexVerifyListener { + + // regular expressions + // characters that can be set at the beginning + private static final String NAME_START_REGEX = "[a-zA-Z]"; //$NON-NLS-1$ + // characters that can be set after the starting character + private static final String NAME_FOLLOW_REGEX = "[a-zA-Z0-9]"; //$NON-NLS-1$ + // allowed separators in fragments + private static final String NAME_SEPERATOR_REGEX = "(\\-|_)"; //$NON-NLS-1$ + // complete name fragment + public static final String NAME_FRAGMENT_REGEX = + "(" + NAME_START_REGEX + NAME_FOLLOW_REGEX + "*" + //$NON-NLS-1$ //$NON-NLS-2$ + "(" + NAME_SEPERATOR_REGEX + NAME_FOLLOW_REGEX + "+)*)"; //$NON-NLS-1$ //$NON-NLS-2$ + // open name fragment during typing + private static final String OPEN_NAME_FRAGMENT_REGEX = + "(" + NAME_FRAGMENT_REGEX + NAME_SEPERATOR_REGEX + "?)"; //$NON-NLS-1$ //$NON-NLS-2$ + // multiple + public static final String OPEN_NAME_REGEX = + "((" + NAME_FRAGMENT_REGEX + "\\.)*" + OPEN_NAME_FRAGMENT_REGEX + "?)?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + public static final String IP_FRAGMENT_REGEX = "([0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])"; //$NON-NLS-1$ + public static final String OPEN_IP_REGEX = "((" + IP_FRAGMENT_REGEX + "?\\.){0,3}" + IP_FRAGMENT_REGEX + "?)?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + public static final String OPEN_TIPC_REGEX = "((" + IP_FRAGMENT_REGEX + "?\\.){0,2}" + IP_FRAGMENT_REGEX + "?)?"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + // arguments + public static final int ATTR_NAME = 1; + public static final int ATTR_IP = 2; + public static final int ATTR_TIPC = 4; + + /** + * Constructor + * @param decimal true if decimal value is allowed + * @param hex true if hex value (0x####) is allowed + */ + public NameOrIPVerifyListener(int attributes) { + super(attributes, getRegEx(attributes)); + } + + /* + * Static method to generate regular expression for constructor super call. + */ + private static String getRegEx(int attributes) { + String regex = null; + + if (isAttribute(ATTR_TIPC, attributes)) { + regex = OPEN_TIPC_REGEX; + } + else { + if (isAttribute(ATTR_NAME, attributes) || !isAttribute(ATTR_IP, attributes)) { + regex = OPEN_NAME_REGEX; + } + if (isAttribute(ATTR_IP, attributes) || !isAttribute(ATTR_NAME, attributes)) { + regex = (regex != null) ? (regex + "|" + OPEN_IP_REGEX) : OPEN_IP_REGEX; //$NON-NLS-1$ + } + } + + return regex; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NetMaskValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NetMaskValidator.java new file mode 100644 index 000000000..3e12c3a5f --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NetMaskValidator.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +/** + * Netmask validator. + */ +public class NetMaskValidator extends NameOrIPValidator { + + /** + * Constructor. + * + * @param attributes Attributes for the validator. + */ + public NetMaskValidator(int attributes) { + super(ATTR_IP); + if (isAttribute(ATTR_MANDATORY, attributes)) { + addAttribute(ATTR_MANDATORY); + } + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.NameOrIPValidator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String netMask) { + if (super.isValid(netMask)) { + // check the netmask + String[] bytes = netMask.split("."); //$NON-NLS-1$ + int oldByte = 255; + int actByte; + for (int i=0; i<bytes.length; i++) { + actByte = Integer.parseInt(bytes[i]); + if ((oldByte < 255 && actByte > 0) || + (oldByte == 255 && !isValidNetMaskByte(actByte))) { + return false; + } + oldByte = actByte; + } + return true; + } + return false; + } + + /** + * Check one byte of a netmask if valid. + * A valid netmask byte should match the regular expression 1*0* and + * so can only be a value in the set {0,128,192,224,240,248,252,254,255}. + */ + private boolean isValidNetMaskByte(int netMaskByte) { + switch (netMaskByte) { + case 0: + case 128: + case 192: + case 224: + case 240: + case 248: + case 252: + case 254: + case 255: + return true; + default: + return false; + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NetMaskVerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NetMaskVerifyListener.java new file mode 100644 index 000000000..40429b6dc --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NetMaskVerifyListener.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +/** + * Netmask verify listener. + */ +public class NetMaskVerifyListener extends NameOrIPVerifyListener { + + /** + * @param attributes + */ + public NetMaskVerifyListener() { + super(ATTR_IP); + } + +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NumberValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NumberValidator.java new file mode 100644 index 000000000..9178c2dd9 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NumberValidator.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import java.text.MessageFormat; + +/** + * Positive integer number validator for text widgets. + */ +public class NumberValidator extends RegexValidator { + + // keys for error messages + public static final String ERROR_INVALID_RANGE = "NumberValidator_Error_InvalidRange"; //$NON-NLS-1$ + + // regular expressions + protected static final String NUMBER_REGEX = "([0-9]*)"; //$NON-NLS-1$ + + private int min = 0; + private int max = Integer.MAX_VALUE; + + /** + * Constructor + */ + public NumberValidator() { + this(-1, -1); + } + + /** + * Constructor + * + * @param min The lower boundary of the allowed input range. + * If less than zero the value is set to 0. + * @param max The upper boundary of the allowed input range. + * If less than zero the value is set to INTEGER.MAX_VALUE. + */ + public NumberValidator(int min, int max) { + this(NO_ATTR, NUMBER_REGEX, min, max); + } + + /** + * Constructor + * + * @param attributes The verify listener attributes. + * @param regEx The regular expression. + * @param min The minimum allowed input. + * If less than zero the value is set to 0. + * @param max The maximum allowed input. + * If less than zero the value is set to INTEGER.MAX_VALUE. + */ + public NumberValidator(int attributes, String regEx, int min, int max) { + super(attributes, regEx); + setBounds(min, max); + } + + /** + * Sets the lower and upper value boundary. + * + * @param min The minimum allowed input. + * If less than zero the value is set to 0. + * @param max The maximum allowed input. + * If less than zero the value is set to INTEGER.MAX_VALUE. + */ + public void setBounds(int min, int max) { + min = (min >= 0) ? min : 0; + max = (max >= 0) ? max : Integer.MAX_VALUE; + this.min = Math.min(min, max); + this.max = Math.max(min, max); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.RegexValidator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String newText) { + boolean valid = super.isValid(newText); + + // If the value is a valid number matching the regex, check if + // the range is valid + if (valid) { + try { + // Decode the string into an integer object + int value = Integer.decode(newText).intValue(); + if (value < min || value > max) { + // Value is out of range -> set error message + setMessage(MessageFormat.format(getMessageText(ERROR_INVALID_RANGE), Integer.valueOf(min), Integer.valueOf(max)), getMessageTextType(ERROR_INVALID_RANGE, ERROR)); + valid = getMessageType() != ERROR; + } + } catch (NumberFormatException e) { /* ignored on purpose */ } + } + + return valid; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NumberVerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NumberVerifyListener.java new file mode 100644 index 000000000..b970d7917 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/NumberVerifyListener.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import org.eclipse.swt.events.VerifyEvent; + +/** + * Verify listener for text widgets to receive numbers. + */ +public class NumberVerifyListener extends RegexVerifyListener { + + // regular expressions + protected static final String NUMBER_REGEX = "([0-9]*)"; //$NON-NLS-1$ + + private int min = 0; + private int max = Integer.MAX_VALUE; + + /** + * Constructor + */ + public NumberVerifyListener() { + this(-1, -1); + } + + /** + * Constructor + * + * @param min The minimum allowed input. + * If less than zero the value is set to 0. + * @param max The maximum allowed input. + * If less than zero the value is set to INTEGERE.MAX_VALUE. + */ + public NumberVerifyListener(int min, int max) { + this(NO_ATTR, NUMBER_REGEX, min, max); + } + + /** + * Constructor + * + * @param attributes The verify listener attributes. + * @param regEx The regular expression. + * @param min The minimum allowed input. + * If less than zero the value is set to 0. + * @param max The maximum allowed input. + * If less than zero the value is set to INTEGERE.MAX_VALUE. + */ + public NumberVerifyListener(int attributes, String regEx, int min, int max) { + super(attributes, regEx); + min = (min >= 0) ? min : 0; + max = (max >= 0) ? max : Integer.MAX_VALUE; + this.min = Math.min(min, max); + this.max = Math.max(min, max); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.RegexVerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent) + */ + @Override + public void verifyText(VerifyEvent e) { + super.verifyText(e); + String fullText = getFullText(e); + if (e.doit && fullText != null && fullText.length() > 0 && !fullText.equalsIgnoreCase("0x")) { //$NON-NLS-1$ + try { + int value = Integer.decode(fullText).intValue(); + if (value < min || value > max) { + e.doit = false; + } + } + catch (Exception ex) { + e.doit = false; + } + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/PortNumberValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/PortNumberValidator.java new file mode 100644 index 000000000..fa1b402f4 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/PortNumberValidator.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + + +/** + * Input validator for port numbers. + * <p> + * Valid formats are decimal and, if allowed, hex (0xFFFF). + */ +public class PortNumberValidator extends NumberValidator { + + // regular expressions for validator + protected static final String PORT_REGEX_DEC = "([0-9]{1,5})"; //$NON-NLS-1$ + protected static final String PORT_REGEX_HEX = "(0(x|X)[0-9a-fA-F]{1,4})"; //$NON-NLS-1$ + + public static final int ATTR_HEX = 2; + public static final int ATTR_DECIMAL = 4; + // next attribute should start with 2^3 + + /** + * Constructor + */ + public PortNumberValidator() { + this(ATTR_MANDATORY | ATTR_DECIMAL); + } + + /** + * Constructor + * @attributes attributes The validator attributes. + */ + public PortNumberValidator(int attributes) { + this(attributes, 0, 65535); + } + + /** + * Constructor + * + * @param attributes The verify listener attributes. + * @param min The minimum allowed input. + * If less than zero the value is set to 0. + * @param max The maximum allowed input. + * If less than zero the value is set to INTEGERE.MAX_VALUE. + */ + public PortNumberValidator(int attributes, int min, int max) { + super(attributes, getRegEx(attributes), min, max); + + setMessageText(RegexValidator.INFO_MISSING_VALUE, getString("PortNumberValidator_Information_MissingPortNumber")); //$NON-NLS-1$ + setMessageText(RegexValidator.ERROR_INVALID_VALUE, getString("PortNumberValidator_Error_InvalidPortNumber")); //$NON-NLS-1$ + setMessageText(NumberValidator.ERROR_INVALID_RANGE, getString("PortNumberValidator_Error_PortNumberNotInRange")); //$NON-NLS-1$ + } + + /* + * Static method to generate regular expression for constructor super call. + */ + private static String getRegEx(int attributes) { + String regex = null; + + if (isAttribute(ATTR_DECIMAL, attributes) || !isAttribute(ATTR_HEX, attributes)) { + regex = PORT_REGEX_DEC; + } + if (isAttribute(ATTR_HEX, attributes) || !isAttribute(ATTR_DECIMAL, attributes)) { + regex = (regex != null) ? (regex + "|" + PORT_REGEX_HEX) : PORT_REGEX_HEX; //$NON-NLS-1$ + } + + return regex; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/PortNumberVerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/PortNumberVerifyListener.java new file mode 100644 index 000000000..8bd055bca --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/PortNumberVerifyListener.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +/** + * Verify listener for text widgets to receive port numbers. + */ +public class PortNumberVerifyListener extends NumberVerifyListener { + + // regular expression for hex validation + protected static final String PORT_REGEX_DEC = "([0-9]{0,5})"; //$NON-NLS-1$ + protected static final String PORT_REGEX_HEX = "(0((x|X)[0-9a-fA-F]{0,4})?)"; //$NON-NLS-1$ + + // arguments + public static final int ATTR_DECIMAL = 1; + public static final int ATTR_HEX = 2; + + /** + * Constructor + * @param decimal true if decimal value is allowed + * @param hex true if hex value (0x####) is allowed + */ + public PortNumberVerifyListener(int attributes) { + super(attributes, getRegEx(attributes), 0, 65535); + } + + /* + * Static method to generate regular expression for constructor super call. + */ + private static String getRegEx(int attributes) { + String regex = null; + + if (isAttribute(ATTR_DECIMAL, attributes) || !isAttribute(ATTR_HEX, attributes)) { + regex = PORT_REGEX_DEC; + } + if (isAttribute(ATTR_HEX, attributes) || !isAttribute(ATTR_DECIMAL, attributes)) { + regex = (regex != null) ? (regex + "|" + PORT_REGEX_HEX) : PORT_REGEX_HEX; //$NON-NLS-1$ + } + + return regex; + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/RegexValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/RegexValidator.java new file mode 100644 index 000000000..1cb5f1d13 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/RegexValidator.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + + +/** + * Validator using regular expression. + */ +public class RegexValidator extends Validator { + + // keys for info messages + public static final String INFO_MISSING_VALUE = "RegexValidator_Information_MissingValue"; //$NON-NLS-1$ + + // keys for error messages + public static final String ERROR_INVALID_VALUE = "RegexValidator_Error_InvalidValue"; //$NON-NLS-1$ + + // arguments + private String regex; + + /** + * Constructor. + * @param attributes + */ + public RegexValidator(int attributes, String regex) { + super(attributes); + this.regex = regex; + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String newText) { + init(); + + // info message when value is empty and mandatory + if (newText == null || newText.trim().length() == 0) { + if (isAttribute(ATTR_MANDATORY)) { + setMessage(getMessageText(INFO_MISSING_VALUE), getMessageTextType(INFO_MISSING_VALUE, INFORMATION)); + return false; + } + return true; + } + + if (!newText.matches(regex)) { + setMessage(getMessageText(ERROR_INVALID_VALUE), getMessageTextType(ERROR_INVALID_VALUE, ERROR)); + return getMessageType() != ERROR; + } + + return true; + } + + /** + * Returns the regular expression. + * @return + */ + protected String getRegularExpression() { + return regex; + } + + /** + * Set the regular expression. + * @param regex + */ + protected void setRegularExpression(String regex) { + if (regex != null && regex.length() > 0) { + this.regex = regex; + } + else { + this.regex = ".*"; //$NON-NLS-1$ + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/RegexVerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/RegexVerifyListener.java new file mode 100644 index 000000000..2b45b41cb --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/RegexVerifyListener.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Text; +import org.eclipse.tcf.te.ui.controls.activator.UIPlugin; + + +/** + * Verify listener using regular expression to check the input. + */ +public class RegexVerifyListener extends VerifyListener { + + private String regex; + + /** + * Constructor + * @param regex Regular expression to verify input. + */ + public RegexVerifyListener(int attributes, String regex) { + super(attributes); + setRegularExpression(regex); + } + + /** + * Generates the full text to check whether the result is valid. + * @param e + * @return + */ + protected String getFullText(VerifyEvent e) { + StringBuffer fulltext = new StringBuffer(); + if (e.widget instanceof Text) { + Text text = (Text)e.widget; + fulltext.append(text.getText()); + } + else if (e.widget instanceof Combo) { + Combo combo = (Combo)e.widget; + fulltext.append(combo.getText()); + } + + try { + if (e.end > e.start) { + fulltext.replace(e.start, e.end, e.text); + } else if (e.end >= 0) { + fulltext.insert(e.end, e.text); + } + } catch (StringIndexOutOfBoundsException exc) { + IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), + exc.getLocalizedMessage() + ", VerifyEvent(" + e.toString() + ")", exc); //$NON-NLS-1$ //$NON-NLS-2$ + UIPlugin.getDefault().getLog().log(status); + } + + return fulltext.toString(); + } + + /** + * Verify the full text. + * The result is set in <code>e.doit</code>. + */ + @Override + public void verifyText(VerifyEvent e) { + e.doit = getFullText(e).matches(regex); + } + + /** + * Returns the regular expression. + * @return + */ + protected String getRegularExpression() { + return regex; + } + + /** + * Set the regular expression. + * @param regex + */ + protected void setRegularExpression(String regex) { + if (regex != null && regex.length() > 0) { + this.regex = regex; + } + else { + this.regex = ".*"; //$NON-NLS-1$ + } + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/Validator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/Validator.java new file mode 100644 index 000000000..3bb3b1fce --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/Validator.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.viewers.ICellEditorValidator; +import org.eclipse.tcf.te.ui.controls.nls.Messages; + + +/** + * Input validator and message provider. + */ +public abstract class Validator implements IMessageProvider, ICellEditorValidator { + + // message text, set in isValid(String) + private String message = null; + // message type, set in isValid(String) + private int messageType = NONE; + // map with all message texts + private Map<String, String> messages = new HashMap<String, String>(); + // map with all message text types + private Map<String, Integer> messageTypes = new HashMap<String, Integer>(); + + // arguments (binary coded) + public static final int NO_ATTR = 0; + public static final int ATTR_MANDATORY = 1; + // next attribute should start with 2^1 + + // binary coded arguments + private int attributes; + + /** + * Constructor + * @param attributes The validator attributes. + */ + public Validator(int attributes) { + setAttributes(attributes); + } + + /** + * Set the attributes for the validator. + * @param attributes The validator attributes. + */ + public void setAttributes(int attributes) { + this.attributes = attributes; + } + + /** + * Add an attribute. + * @param attribute The validator attribute to add. + */ + public void addAttribute(int attribute) { + if (!isAttribute(attribute)) { + this.attributes |= attribute; + } + } + + /** + * Remove an attribute. + * @param attribute The validator attribute to remove. + */ + public void delAttribute(int attribute) { + if (isAttribute(attribute)) { + this.attributes -= attribute; + } + } + + /** + * Returns the attributes. + * @return + */ + public int getAttributes() { + return attributes; + } + + /** + * Returns true if the argument is set. + * @param attribute The argument to ask for. + * @return + */ + public boolean isAttribute(int attribute) { + return isAttribute(attribute, attributes); + } + + /** + * Returns true is argument is set. + * This static method can be used in the constructor or other static methods + * to check attributes. + * @param attribute The attribute to ask for + * @param attributes The binary coded attribute list + * @return + */ + public static boolean isAttribute(int attribute, int attributes) { + return ((attributes & attribute) == attribute); + } + + /** + * Initialize the validator. + * Should always be called in isValid(String) before validation is done. + * Doesn't reset message texts! + */ + protected void init() { + setMessage(null); + setMessageType(NONE); + } + + /** + * Validates the given text. + * A message text could be set even when the text is valid! + * @param newText text to validate + * @return true if text is valid + */ + public abstract boolean isValid(String newText); + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ICellEditorValidator#isValid(java.lang.Object) + */ + @Override + public final String isValid(Object newValue) { + String strValue = (newValue != null) ? newValue.toString() : null; + if (!isValid(strValue)) { + return (getMessage()); + } + return null; + } + + /** + * Sets the message text and type. + * @param message message + * @param messageType type for message + */ + protected final void setMessage(String message, int messageType) { + setMessage(message); + setMessageType(messageType); + } + + /** + * Sets the message. + * @param message message + */ + protected final void setMessage(String message) { + this.message = message; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessage() + */ + @Override + public final String getMessage() { + return message; + } + + /** + * Sets the message type. + * @param messageType type for message + */ + protected final void setMessageType(int messageType) { + this.messageType = messageType; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.dialogs.IMessageProvider#getMessageType() + */ + @Override + public final int getMessageType() { + return messageType; + } + + /** + * Returns the message text for the given key. + * The key always points to the default text. + * @param key message key + * @return message text + */ + protected final String getMessageText(String key) { + String message = messages.get(key); + if (message == null) { + message = getString(key); + setMessageText(key, message); + } + return message; + } + + /** + * Returns the message type for the given key. If not set, the + * proposed message type is returned. + * + * @param key The message key. + * @param proposedType The proposed message type. + * + * @return The message type. + */ + protected final int getMessageTextType(String key, int proposedType) { + Integer type = messageTypes.get(key); + if (type == null || type.intValue() == -1) type = Integer.valueOf(proposedType); + return type.intValue(); + } + + /** + * Sets an alternate message text for an info, warning or error on isValid(String). + * + * @param key property key of default text + * @param text alternate message text, if null the default text for this key is taken + */ + public final void setMessageText(String key, String text) { + setMessageText(key, text, -1); + } + + /** + * Sets an alternate message text for an info, warning or error on isValid(String). + * + * @param key property key of default text + * @param text alternate message text, if null the default text for this key is taken + * @param type alternate message type, if -1 the default type for this key is taken + */ + public final void setMessageText(String key, String text, int type) { + if (key != null) { + if (text != null) { + this.messages.put(key, text); + } else { + this.messages.put(key, getString(key)); + } + if (type != -1) { + this.messageTypes.put(key, Integer.valueOf(type)); + } else { + this.messageTypes.remove(key); + } + } + } + + /** + * Returns the externalized string value for the given key. + * + * @param key The key. Must not be <code>null</code>. + * @return The string value or <code>null</code> + */ + protected String getString(String key) { + Assert.isNotNull(key); + return Messages.getString(key); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/VerifyListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/VerifyListener.java new file mode 100644 index 000000000..f93cc8e20 --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/VerifyListener.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +/** + * Base class for verify listener. + */ +public abstract class VerifyListener implements org.eclipse.swt.events.VerifyListener { + + // arguments (binary coded) + public static final int NO_ATTR = 0; + // next attribute should start with 2^0 + + // binary coded arguments + private int attributes; + + /** + * Constructor + * @param attributes The validator attributes. + */ + public VerifyListener(int attributes) { + setAttributes(attributes); + } + + /** + * Set the attributes for the validator. + * @param attributes The validator attributes. + */ + public void setAttributes(int attributes) { + this.attributes = attributes; + } + + /** + * Add an attribute. + * @param attribute The validator attribute to add. + */ + public void addAttribute(int attribute) { + if (!isAttribute(attribute)) { + this.attributes |= attribute; + } + } + + /** + * Remove an attribute. + * @param attribute The validator attribute to remove. + */ + public void delAttribute(int attribute) { + if (isAttribute(attribute)) { + this.attributes -= attribute; + } + } + + /** + * Returns the attributes. + * @return + */ + public int getAttributes() { + return attributes; + } + + /** + * Returns true if the argument is set. + * @param attribute The argument to ask for. + * @return + */ + public boolean isAttribute(int attribute) { + return isAttribute(attribute, attributes); + } + + /** + * Returns true is argument is set. + * This static method can be used in the constructor or other static methods + * to check attributes. + * @param attribute The attribute to ask for + * @param attributes The binary coded attribute list + * @return + */ + public static boolean isAttribute(int attribute, int attributes) { + return ((attributes & attribute) == attribute); + } +} diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/WorkspaceContainerValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/WorkspaceContainerValidator.java new file mode 100644 index 000000000..a690b7ccb --- /dev/null +++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/validator/WorkspaceContainerValidator.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.tcf.te.ui.controls.validator; + +import java.text.MessageFormat; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; + +/** + * Validates a given path to be a workspace path. + * <p> + * <b>Note:</b> This validator is useful only if the Eclipse resources plugin is installed. + */ +public class WorkspaceContainerValidator extends Validator { + + // keys for info messages + public static final String INFO_MISSING_VALUE = "WorkspaceContainerValidator_Information_MissingValue"; //$NON-NLS-1$ + + // keys for error messages + public static final String ERROR_INVALID_VALUE = "WorkspaceContainerValidator_Error_InvalidValue"; //$NON-NLS-1$ + + /** + * Constructor + * + * @param attributes The validator attributes. + */ + public WorkspaceContainerValidator(int attributes) { + super(attributes); + } + + /* (non-Javadoc) + * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String) + */ + @Override + public boolean isValid(String newText) { + init(); + + // info message when value is empty and mandatory + if (newText == null || newText.trim().length() == 0) { + if (isAttribute(ATTR_MANDATORY)) { + setMessage(getMessageText(INFO_MISSING_VALUE), getMessageTextType(INFO_MISSING_VALUE, INFORMATION)); + return false; + } + return true; + } + + if (Platform.getBundle("org.eclipse.core.resources") != null //$NON-NLS-1$ + && Platform.getBundle("org.eclipse.core.resources").getState() == Bundle.ACTIVE) { //$NON-NLS-1$ + IStatus status = org.eclipse.core.resources.ResourcesPlugin.getWorkspace().validatePath(newText.trim(), org.eclipse.core.resources.IResource.FOLDER | org.eclipse.core.resources.IResource.PROJECT); + if (status.getSeverity() != IStatus.OK) { + // Try to format the returned message with the information returned + // to use by the status object. + setMessage(MessageFormat.format(getMessageText(ERROR_INVALID_VALUE), new Object[] { status.getMessage() }), getMessageTextType(ERROR_INVALID_VALUE, ERROR)); + return getMessageType() != ERROR; + } + } + + return true; + } +} |