summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorTobias Schwarz2012-03-16 02:04:09 (EDT)
committer Uwe Stieber2012-03-16 02:04:09 (EDT)
commit8220fd0591dea7f869b9d33c6279d6ca270c447f (patch)
tree045797ed768b67a66838f5e06373f9d4e064aae2
parentbfe7fb32f8519d321367ab9e090961353e5ead2a (diff)
downloadorg.eclipse.tcf-8220fd0591dea7f869b9d33c6279d6ca270c447f.zip
org.eclipse.tcf-8220fd0591dea7f869b9d33c6279d6ca270c447f.tar.gz
org.eclipse.tcf-8220fd0591dea7f869b9d33c6279d6ca270c447f.tar.bz2
Target Explorer: Linux application launch UI work
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/steps/AbstractLaunchStep.java13
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/AbstractFormsLaunchConfigurationTab.java51
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/LaunchConfigurationTabGroup.java4
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java1511
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorControl.java (renamed from target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/StepContextSelectorControl.java)31
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorSection.java (renamed from target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java)21
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorTab.java (renamed from target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorTab.java)6
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/META-INF/MANIFEST.MF3
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.properties1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.xml46
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/interfaces/ILinuxAppLaunchAttributes.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/steps/LaunchProcessStep.java83
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/META-INF/MANIFEST.MF56
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTab.java40
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTabSection.java194
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationTabGroup.java19
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.java70
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.properties15
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/editor/sections/GeneralInformationSection.java51
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/AbstractDecoratedDialogPageControl.java120
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/BaseEditBrowseTextControl.java2939
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/net/RemoteHostAddressControl.java458
22 files changed, 3141 insertions, 2624 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/steps/AbstractLaunchStep.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/steps/AbstractLaunchStep.java
index 8b425d9..0eede62 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/steps/AbstractLaunchStep.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.core/src/org/eclipse/tcf/te/launch/core/steps/AbstractLaunchStep.java
@@ -8,6 +8,7 @@ package org.eclipse.tcf.te.launch.core.steps;
import org.eclipse.core.runtime.Assert;
import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.tcf.te.launch.core.lm.interfaces.IContextSelectorLaunchAttributes;
import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
@@ -43,4 +44,16 @@ public abstract class AbstractLaunchStep extends AbstractStep {
Assert.isTrue(context instanceof IModelNode);
return (IModelNode)context;
}
+
+ /**
+ * Returns the uses launch configuration.
+ *
+ * @param context The step context.
+ * @return
+ */
+ protected ILaunchConfiguration getLaunchConfiguration(IStepContext context) {
+ ILaunch launch = getLaunch(context);
+ Assert.isNotNull(launch);
+ return launch.getLaunchConfiguration();
+ }
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/AbstractFormsLaunchConfigurationTab.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/AbstractFormsLaunchConfigurationTab.java
index f2ac191..1a46bbf 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/AbstractFormsLaunchConfigurationTab.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/AbstractFormsLaunchConfigurationTab.java
@@ -12,6 +12,7 @@ package org.eclipse.tcf.te.launch.ui.tabs;
import org.eclipse.core.runtime.Assert;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
@@ -41,21 +42,21 @@ public abstract class AbstractFormsLaunchConfigurationTab extends AbstractLaunch
private static class TabForm extends ManagedForm {
/**
- * Constructor.
- *
- * @param parentTab The parent launch configuration tab. Must not be <code>null</code>.
- * @param form The scrolled form. Must not be <code>null</code>.
- */
- public TabForm(AbstractFormsLaunchConfigurationTab parentTab, ScrolledForm form) {
- super(parentTab.getFormToolkit().getFormToolkit(), form);
- setContainer(parentTab);
- }
-
- /**
- * Returns the parent launch configuration tab.
- *
- * @return The parent launch configuration tab.
- */
+ * Constructor.
+ *
+ * @param parentTab The parent launch configuration tab. Must not be <code>null</code>.
+ * @param form The scrolled form. Must not be <code>null</code>.
+ */
+ public TabForm(AbstractFormsLaunchConfigurationTab parentTab, ScrolledForm form) {
+ super(parentTab.getFormToolkit().getFormToolkit(), form);
+ setContainer(parentTab);
+ }
+
+ /**
+ * Returns the parent launch configuration tab.
+ *
+ * @return The parent launch configuration tab.
+ */
public AbstractFormsLaunchConfigurationTab getParentTab() {
return (AbstractFormsLaunchConfigurationTab)getContainer();
}
@@ -64,7 +65,7 @@ public abstract class AbstractFormsLaunchConfigurationTab extends AbstractLaunch
* @see org.eclipse.ui.forms.ManagedForm#dirtyStateChanged()
*/
@SuppressWarnings("synthetic-access")
- @Override
+ @Override
public void dirtyStateChanged() {
getParentTab().updateLaunchConfigurationDialog();
}
@@ -73,7 +74,7 @@ public abstract class AbstractFormsLaunchConfigurationTab extends AbstractLaunch
* @see org.eclipse.ui.forms.ManagedForm#staleStateChanged()
*/
@SuppressWarnings("synthetic-access")
- @Override
+ @Override
public void staleStateChanged() {
getParentTab().updateLaunchConfigurationDialog();
}
@@ -146,7 +147,7 @@ public abstract class AbstractFormsLaunchConfigurationTab extends AbstractLaunch
// Create the form content
BusyIndicator.showWhile(parent.getDisplay(), new Runnable() {
@Override
- public void run() {
+ public void run() {
createFormContent(mform);
}
});
@@ -247,7 +248,9 @@ public abstract class AbstractFormsLaunchConfigurationTab extends AbstractLaunch
*/
@Override
public boolean isValid(ILaunchConfiguration configuration) {
- boolean valid = super.isValid(configuration);
+ boolean valid = super.isValid(configuration);
+
+ String errorMessage = null;
if (mform != null) {
// Get all registered form parts
@@ -255,11 +258,17 @@ public abstract class AbstractFormsLaunchConfigurationTab extends AbstractLaunch
for (IFormPart part : parts) {
if (part instanceof ILaunchConfigurationTabFormPart) {
valid &= ((ILaunchConfigurationTabFormPart)part).isValid(configuration);
- if (!valid) break;
+ if (!valid) {
+ if (part instanceof IMessageProvider && errorMessage == null) {
+ errorMessage = ((IMessageProvider)part).getMessage();
+ }
+ }
}
}
}
- return valid;
+ setErrorMessage(errorMessage);
+
+ return valid;
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/LaunchConfigurationTabGroup.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/LaunchConfigurationTabGroup.java
index dc53293..0cfb14e 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/LaunchConfigurationTabGroup.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/LaunchConfigurationTabGroup.java
@@ -15,7 +15,7 @@ import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
-import org.eclipse.tcf.te.launch.ui.tabs.selector.ContextSelectorTab;
+import org.eclipse.tcf.te.launch.ui.tabs.selector.LaunchContextSelectorTab;
/**
* Default launch configuration tab group implementation.
@@ -53,7 +53,7 @@ public class LaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabG
public void createContextSelectorTab(ILaunchConfigurationDialog dialog, List<ILaunchConfigurationTab> tabs, String mode) {
Assert.isNotNull(tabs);
- ILaunchConfigurationTab tab = new ContextSelectorTab();
+ ILaunchConfigurationTab tab = new LaunchContextSelectorTab();
tabs.add(tab);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java
index 2dad81d..2201106 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorControl.java
@@ -1,749 +1,762 @@
-/*******************************************************************************
- * Copyright (c) 2012 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.launch.ui.tabs.selector;
-
-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.core.runtime.AssertionFailedException;
-import org.eclipse.jface.dialogs.IDialogPage;
-import org.eclipse.jface.viewers.CheckStateChangedEvent;
-import org.eclipse.jface.viewers.CheckboxTreeViewer;
-import org.eclipse.jface.viewers.ICheckStateListener;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.jface.viewers.ViewerSorter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Item;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.swt.widgets.Widget;
-import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
-import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
-import org.eclipse.tcf.te.runtime.properties.PropertiesContainer;
-import org.eclipse.tcf.te.runtime.services.ServiceManager;
-import org.eclipse.tcf.te.runtime.services.interfaces.IPropertiesAccessService;
-import org.eclipse.tcf.te.ui.controls.BaseDialogPageControl;
-import org.eclipse.tcf.te.ui.jface.interfaces.IValidatingContainer;
-import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
-import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
-import org.eclipse.tcf.te.ui.views.internal.ViewRoot;
-import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
-import org.eclipse.ui.internal.navigator.NavigatorContentService;
-import org.eclipse.ui.navigator.CommonViewerSorter;
-
-/**
- * Context selector control.
- * <p>
- * Allows to present a configurable set of elements from the data model from which the user can
- * select one or more elements.
- * <p>
- * Default properties:
- * <ul>
- * <li>PROPERTY_SHOW_GHOST_MODEL_NODES = false</li>
- * </ul>
- */
-@SuppressWarnings("restriction")
-public class ContextSelectorControl extends BaseDialogPageControl implements ISelectionProvider {
-
- /**
- * Property: If set to <code>true</code>, ghost model nodes will be shown within the tree.
- */
- public static final String PROPERTY_SHOW_GHOST_MODEL_NODES = "showGhostModelNodes"; //$NON-NLS-1$
-
- /**
- * List of selection changed listeners.
- */
- private final List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
-
- /**
- * Control properties. See predefined property constants within the class and subclass
- * implementations. Property changes are not notified.
- */
- private final IPropertiesContainer properties = new PropertiesContainer();
-
- // Reference to the tree viewer control used.
- private TreeViewer viewer;
- // The current selection within the tree viewer.
- /* default */ ISelection selection;
-
- // Reference to the navigator content service used
- private NavigatorContentService contentService;
-
- /**
- * Constant to return an empty viewer filter array.
- */
- protected final static ViewerFilter[] NO_FILTERS = new ViewerFilter[0];
-
- /**
- * Constant to return an empty selected model context array.
- */
- protected final static IModelNode[] NO_CONTEXTS = new IModelNode[0];
-
- // Currently active set of viewer filters.
- private ViewerFilter[] filters;
- // Currently active checkbox tree viewer check state listener
- private ICheckStateListener listener;
-
- /**
- * Default implementation of the context selector controls tree viewer.
- */
- protected class ContextSelectorTreeViewer extends ContainerCheckedTreeViewer {
-
- /**
- * Constructor.
- *
- * @param parent The parent control.
- * @param style The SWT style bits used to create the tree.
- */
- public ContextSelectorTreeViewer(Composite parent, int style) {
- // make sure that the passed in style bits are not contaminated
- // by the CheckboxTreeViewer.
- this(new Tree(parent, style));
- }
-
- /**
- * Constructor.
- *
- * @param parent The parent control.
- */
- public ContextSelectorTreeViewer(Composite parent) {
- super(parent);
- }
-
- /**
- * Constructor.
- *
- * @param tree The tree control.
- */
- public ContextSelectorTreeViewer(Tree tree) {
- super(tree);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.TreeViewer#isExpandable(java.lang.Object)
- */
- @Override
- public boolean isExpandable(Object element) {
- boolean expandable = super.isExpandable(element);
- // adjust the expandable state if the element does not have
- // children after the filtering.
- if (expandable) expandable = getFilteredChildren(element).length > 0;
- return expandable;
- }
-
- /**
- * Returns the child items for the given element if any.
- *
- * @param element The element.
- * @return The child items of the element or <code>null</code> if none.
- */
- public Item[] getChildren(Object element) {
- Widget item = findItem(element);
- return getChildren(item);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ui.dialogs.ContainerCheckedTreeViewer#doCheckStateChanged(java.lang.Object)
- */
- @Override
- protected void doCheckStateChanged(Object element) {
- // Our ghost model elements requires some special handling, as
- // these elements should be never checked fully. Try to determine
- // if we have to double check on the parents state.
- boolean skipDoubleCheckParentState = false;
-
- // If the element isn't one of our model elements, pass on to
- // to super implementation
- skipDoubleCheckParentState |= !(element instanceof IModelNode);
-
- // If the element is one of our model elements and it is not
- // a ghost node, the parent can't be a ghost node either.
- if (!skipDoubleCheckParentState) {
- skipDoubleCheckParentState |= !isGhost((IModelNode) element);
- }
-
- // If the element is a ghost model element, then we have to check
- // on the parent as well.
- if (!skipDoubleCheckParentState) {
- skipDoubleCheckParentState |= ((IModelNode) element).getParent() == null || !isGhost(((IModelNode) element).getParent());
- }
-
- // Call the super implementation to check the item and
- // updating parents and children the first time
- super.doCheckStateChanged(element);
-
- if (!skipDoubleCheckParentState) {
- // Get the tree item for the element and check the parent items
- // for being associated with ghost model elements.
- Widget item = findItem(element);
- if (item instanceof TreeItem) {
- TreeItem treeItem = ((TreeItem) item).getParentItem();
- while (treeItem != null) {
- Object data = treeItem.getData();
-
- // If a child item is checked, otherwise we wouldn't come here, and this
- // parent item isn't expanded, we must(!) expand the item now here by force,
- // otherwise we will loose the checked states of the children elements!
- if (!treeItem.getExpanded()) treeItem.setExpanded(true);
-
- // Decide if we shall gray the checked state.
- // --> The checked state is grayed if the item is a ghost.
- boolean isGhost = data instanceof IModelNode && isGhost((IModelNode) data);
- if (!treeItem.getGrayed() && isGhost) treeItem.setGrayed(true);
-
- // go one level up in the hierarchy
- treeItem = treeItem.getParentItem();
- }
- }
- }
- }
- }
-
- /**
- * Returns if or if not the given model node is a ghost node.
- *
- * @param node The model node. Must not be <code>null</code>.
- * @return <code>True</code> if the node is a ghost node, <code>false</code> otherwise.
- */
- /* default */ boolean isGhost(IModelNode node) {
- Assert.isNotNull(node);
-
- IPropertiesAccessService service = ServiceManager.getInstance().getService(node, IPropertiesAccessService.class);
- if (service != null) {
- Object value = service.getProperty(node, IModelNode.PROPERTY_IS_GHOST);
- if (value instanceof Boolean) {
- return ((Boolean)value).booleanValue();
- } else if (value instanceof String) {
- return Boolean.valueOf((String)value).booleanValue();
- }
- return false;
- }
-
- try {
- return node.isProperty(IModelNode.PROPERTY_IS_GHOST, true);
- } catch (AssertionFailedException e) { /* ignored on purpose */ }
-
- return false;
- }
-
- /**
- * Default implementation of the context selector controls check state listener.
- */
- protected class ContextSelectedCheckStateListener implements ICheckStateListener {
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
- */
- @Override
- public void checkStateChanged(CheckStateChangedEvent event) {
- Object element = event.getElement();
- if (element instanceof IModelNode) {
- onModelNodeCheckStateChanged((IModelNode) element, event.getChecked());
- }
- }
- }
-
- /**
- * Default implementation of the context selector controls viewer filter.
- */
- protected class ContextSelectorViewerFilter extends ViewerFilter {
-
- /**
- * Returns if or if not ghost model elements should be visible within the model context
- * selector controls tree viewer. Default is not to show the ghost model elements.
- *
- * @return <code>True</code> to show the ghost model elements, <code>false</code> otherwise.
- */
- protected boolean doShowGhostModelElements() {
- return getPropertiesContainer().getBooleanProperty(PROPERTY_SHOW_GHOST_MODEL_NODES);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
- */
- @Override
- public boolean select(Viewer viewer, Object parentElement, Object element) {
- if (element instanceof IModelNode) {
- if (isGhost((IModelNode) element)) {
- return doShowGhostModelElements();
- }
- }
-
- return true;
- }
- }
-
- /**
- * Constructor.
- *
- * @param parentPage The parent target connection page this control is embedded in. Might be
- * <code>null</code> if the control is not associated with a page.
- */
- public ContextSelectorControl(IDialogPage parentPage) {
- super(parentPage);
- selectionListeners.clear();
- // initialize the properties
- initializeProperties(getPropertiesContainer());
- }
-
- /**
- * Returns the properties container associated with this control.
- *
- * @return The properties container.
- */
- public final IPropertiesContainer getPropertiesContainer() {
- return properties;
- }
-
- /**
- * Initialize the properties associated with this control.
- *
- * @param properties The properties container. Must not be <code>null</code>.
- */
- protected void initializeProperties(IPropertiesContainer properties) {
- Assert.isNotNull(properties);
- properties.setProperty(PROPERTY_SHOW_GHOST_MODEL_NODES, false);
- }
-
- /**
- * Returns the default title text which should be used by the enclosing controls or windows if
- * these controls do need to set a title.
- * <p>
- * The default implementation returns <code>null</code>.
- *
- * @return The default title text or <code>null</code> if none.
- */
- public String getDefaultTitle() {
- return null;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.ui.controls.BaseControl#dispose()
- */
- @Override
- public void dispose() {
- // Dispose the navigator content service
- if (contentService != null) {
- contentService.dispose();
- contentService = null;
- }
-
- viewer = null;
-
- super.dispose();
- }
-
- /**
- * Returns the list of checked model node contexts. The elements are in the order they appear
- * within the tree from top to bottom. The client of the control is in charge detecting any type
- * of hierarchy or other relationships between the elements.
- *
- * @return The list of checked model node contexts or an empty list of none.
- */
- public IModelNode[] getCheckedModelContexts() {
- // This method does return something useful only if it is a checkable
- // tree viewer and the check style is set for the tree.
- if (getViewer() instanceof ContainerCheckedTreeViewer && (getTreeViewerStyle() & SWT.CHECK) != 0) {
- ContainerCheckedTreeViewer viewer = (ContainerCheckedTreeViewer) getViewer();
- // Get the list of checked elements. Checked elements includes the grayed elements
- List<?> checked = viewer.getCheckedElements() != null ? Arrays.asList(viewer.getCheckedElements()) : Collections.emptyList();
- // Get the list of grayed elements.
- List<?> grayed = viewer.getGrayedElements() != null ? Arrays.asList(viewer.getGrayedElements()) : Collections.emptyList();
-
- // There must be at least one element checked
- if (!checked.isEmpty()) {
- List<IModelNode> contexts = new ArrayList<IModelNode>();
- for (Object element : checked) {
- // If the context is a model node and the parent container node is fully
- // checked, drop the model node and the use the container node only.
- if (element instanceof IModelNode) {
- IModelNode node = (IModelNode) element;
-
- // Determine the parent node
- IPropertiesAccessService service = ServiceManager.getInstance().getService(node, IPropertiesAccessService.class);
- IModelNode parent = service != null ? (IModelNode)service.getParent(node) : node.getParent();
-
- if (parent != null && checked.contains(parent) && !grayed.contains(parent)) {
- continue;
- }
- }
-
- // If the element is a model node and not grayed,
- // add the element to the list of checked contexts.
- if (element instanceof IModelNode && !grayed.contains(element)) {
- contexts.add((IModelNode) element);
- }
- }
- return contexts.toArray(new IModelNode[contexts.size()]);
- }
- }
- return NO_CONTEXTS;
- }
-
- /**
- * Sets the list of checked model node contexts.
- *
- * @param contexts The list of model node contexts. Must not be <code>null</code>.
- */
- public void setCheckedModelContexts(IModelNode[] contexts) {
- Assert.isNotNull(contexts);
-
- // This method does nothing if the tree viewer isn't a checkable tree viewer.
- if (getViewer() instanceof ContainerCheckedTreeViewer && (getTreeViewerStyle() & SWT.CHECK) != 0) {
- ContainerCheckedTreeViewer viewer = (ContainerCheckedTreeViewer) getViewer();
- // Set the checked elements. This will trigger the validation of the
- // checked state of all the parent and children elements.
- viewer.setCheckedElements(contexts);
- // Make sure that at least the first checked element is visible to the user
- if (contexts.length > 0) {
- viewer.setSelection(new StructuredSelection(contexts[0]), true);
- }
- }
- }
-
- /**
- * Returns the controls associated tree viewer.
- *
- * @return The tree viewer instance or <code>null</code> if not created yet.
- */
- public final TreeViewer getViewer() {
- return viewer;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.ui.controls.BaseControl#setupPanel(org.eclipse.swt.widgets.Composite)
- */
- @Override
- public void setupPanel(Composite parent) {
- super.setupPanel(parent);
-
- // Create the container composite for the tree control.
- Composite composite = doCreateTopContainerComposite(parent);
- Assert.isNotNull(composite);
-
- // Create the viewer
- viewer = createTreeViewerControl(composite);
-
- // And now configure the listeners
- configureControlListener();
-
- // Trigger a selection changed event to give listeners
- // a chance to initialize their enabled state correctly
- viewer.setSelection(viewer.getSelection());
- }
-
- /**
- * Create the top container composite.
- *
- * @param parent The parent composite. Must not be <code>null</code>.
- * @return The top container composite. Must not be <code>null</code>.
- */
- protected Composite doCreateTopContainerComposite(Composite parent) {
- Assert.isNotNull(parent);
-
- // Set the default layout data attributes for the composite
- int style = GridData.FILL_BOTH;
- int heightHint = SWT.DEFAULT;
-
- // Fallback to standard non-form controls and create a composite which extends
- // in both directions and has no margins
- Composite composite = new Composite(parent, SWT.NONE);
- GridLayout layout = new GridLayout();
- layout.marginHeight = 0;
- layout.marginWidth = 0;
- composite.setLayout(layout);
- GridData layoutData = new GridData(style);
- layoutData.heightHint = heightHint;
- composite.setLayoutData(layoutData);
-
- return composite;
- }
-
- /**
- * Creates the tree viewer control. Override to return a custom tree viewer implementation.
- *
- * @param parent The parent composite of the tree viewer. Must not be <code>null</code>.
- * @return The tree viewer control. Must be never <code>null</code>.
- */
- protected TreeViewer createTreeViewerControl(Composite parent) {
- Assert.isNotNull(parent);
-
- CheckboxTreeViewer viewer = doCreateNewTreeViewerControl(parent, getTreeViewerStyle());
- doConfigureTreeViewerControl(viewer);
-
- viewer.setInput(getInitialViewerInput());
- doEnableControl(viewer);
-
- return viewer;
- }
-
- /**
- * Creates a new instance of the tree viewer control to use. This method will be called from
- * {@link #createTreeViewerControl(Composite)} if creating the tree viewer instance.
- *
- * @param parent The parent composite of the tree viewer. Must not be <code>null</code>.
- * @param style The SWT style bits.
- *
- * @return The tree viewer instance. Must not be <code>null</code>.
- */
- protected CheckboxTreeViewer doCreateNewTreeViewerControl(Composite parent, int style) {
- return new ContextSelectorTreeViewer(parent, style);
- }
-
- /**
- * Configure the tree viewer control.
- *
- * @param viewer The tree viewer instance. Must not be <code>null</code>.
- */
- protected void doConfigureTreeViewerControl(CheckboxTreeViewer viewer) {
- Assert.isNotNull(viewer);
-
- viewer.setUseHashlookup(true);
-
- doConfigureTreeLayoutData(viewer.getTree());
-
- // Create the navigator content service
- contentService = new NavigatorContentService(IUIConstants.ID_EXPLORER, viewer);
- Assert.isNotNull(contentService);
-
- viewer.setContentProvider(contentService.createCommonContentProvider());
- viewer.setLabelProvider(contentService.createCommonLabelProvider());
- viewer.setSorter(doCreateViewerSorter());
-
- if ((getTreeViewerStyle() & SWT.CHECK) != 0 && getViewerCheckStateListener(viewer) != null) {
- viewer.addCheckStateListener(getViewerCheckStateListener(viewer));
- }
-
- if (hasViewerFilters()) viewer.setFilters(getViewerFilters());
- viewer.addSelectionChangedListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent event) {
- selection = event.getSelection();
- fireSelectionChanged();
- }
- });
- }
-
- /**
- * Configure the tree's layout data. The layout data set to the tree must be of type
- * <code>GridData</code>.
- *
- * @param tree The tree to configure. Must not be <code>null</code>.
- */
- protected void doConfigureTreeLayoutData(Tree tree) {
- GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
- layoutData.heightHint = 150;
- tree.setLayoutData(layoutData);
- }
-
- /**
- * Returns the style bits to apply to the tree viewer.
- * <p>
- * The default set tree viewer style bits are:
- * <ul>
- * <li>SWT.SINGLE</li>
- * <li>SWT.H_SCROLL</li>
- * <li>SWT.V_SCROLL</li>
- * <li>SWT.BORDER</li>
- *
- * @return The style bits to apply to the tree viewer.
- */
- protected int getTreeViewerStyle() {
- return SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER;
- }
-
- /**
- * Creates the viewer sorter instance to associated to the controls tree viewer.
- *
- * @return The viewer sorter to associate or <code>null</code> if none.
- */
- protected ViewerSorter doCreateViewerSorter() {
- return new CommonViewerSorter();
- }
-
- /**
- * Returns if or if not to associate viewer filters to the controls tree viewer. If this method
- * returns <code>true</code>, {@link #doCreateViewerFilters()} must return not null!
- *
- * @return <code>True</code> if to associate viewer filters, <code>false</code> otherwise.
- */
- protected boolean hasViewerFilters() {
- return true;
- }
-
- /**
- * Creates a returns a new set of the viewer filters to associated to the controls tree viewer.
- * This method will be called from {@link #getViewerFilters()} in case the method
- * {@link #hasViewerFilters()} returns <code>true</code> and no viewer filters got created
- * before.
- *
- * @return The viewer filters to associate or <code>null</code> if none.
- */
- protected ViewerFilter[] doCreateViewerFilters() {
- return new ViewerFilter[] { new ContextSelectorViewerFilter() };
- }
-
- /**
- * Returns the associated viewer filters of the controls tree viewer. If the control does have
- * viewer filters ({@link #hasViewerFilters()} returns <code>true</code>) and the viewer filters
- * had not yet been created, the method calls {@link #doCreateViewerFilters()}.
- *
- * @return The associated viewer filters of the controls tree viewer or the constant
- * {@link #NO_FILTERS}.
- */
- protected ViewerFilter[] getViewerFilters() {
- if (filters == null && hasViewerFilters()) filters = doCreateViewerFilters();
- return filters != null ? filters : NO_FILTERS;
- }
-
- /**
- * Creates a new checkbox tree viewer check state listener. This method will be called from
- * {@link #getViewerCheckStateListener()} in case the listener did not got created before.
- *
- * @param viewer The checkbox tree viewer. Must not be <code>null</code>.
- * @return The checkbox tree viewer check state listener or <code>null</code> if none.
- */
- protected ICheckStateListener doCreateViewerCheckStateListener(CheckboxTreeViewer viewer) {
- Assert.isNotNull(viewer);
- return new ContextSelectedCheckStateListener();
- }
-
- /**
- * Returns the associated checkbox tree viewer check state listener. If the listener had not yet
- * been created, the method calls {@link #doCreateLabelProvider()}.
- *
- * @param viewer The checkbox tree viewer. Must not be <code>null</code>.
- * @return The associated checkbox tree viewer check state listener or <code>null</code> if
- * none.
- */
- protected ICheckStateListener getViewerCheckStateListener(CheckboxTreeViewer viewer) {
- Assert.isNotNull(viewer);
- if (listener == null) listener = doCreateViewerCheckStateListener(viewer);
- return listener;
- }
-
- /**
- * Called from the default check state listener implementation if the checked state of the
- * passed in model node has changed.
- *
- * @param node The model node. Must not be <code>null</code>.
- * @param checked <code>True</code> if the model node has been checked, <code>false</code> if
- * unchecked.
- */
- protected void onModelNodeCheckStateChanged(IModelNode node, boolean checked) {
- // validate the parent page if there is one set
- if (getParentPage() instanceof IValidatingContainer) {
- ((IValidatingContainer) getParentPage()).validate();
- }
- }
-
- /**
- * Returns the initial input object to set to the controls tree viewer.
- *
- * @return The initial viewer input to set or <code>null</code> if none.
- */
- protected Object getInitialViewerInput() {
- return ViewRoot.getInstance();
- }
-
- /**
- * Enables the tree control.
- *
- * @param viewer The tree viewer object. Must not be <code>null</code>.
- */
- protected void doEnableControl(TreeViewer viewer) {
- Assert.isNotNull(viewer);
- SWTControlUtil.setEnabled(viewer.getTree(), viewer.getTree().getItemCount() > 0);
- }
-
- /**
- * Refresh the controls viewer and check the viewers enablement. This method is called by the
- * standard refresh toolbar item, if the control has a toolbar.
- */
- public void refresh() {
- if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) {
- viewer.refresh(true);
- doEnableControl(viewer);
- }
- }
-
- /**
- * Called from {@link #setupPanel(Composite)} before returning the control to the caller.
- * Override to plug-in and configure any custom listener the subclassed control might need.
- */
- protected void configureControlListener() {
- }
-
- /**
- * Sets the given selection to the viewer.
- *
- * @param selection The selection to set. Must not be <code>null</code>.
- */
- @Override
- public void setSelection(ISelection selection) {
- Assert.isNotNull(selection);
- this.selection = selection;
- if (viewer != null) {
- viewer.setSelection(selection, true);
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
- */
- @Override
- public ISelection getSelection() {
- return selection;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
- */
- @Override
- public void addSelectionChangedListener(ISelectionChangedListener listener) {
- if (listener != null && !selectionListeners.contains(listener)) {
- selectionListeners.add(listener);
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
- */
- @Override
- public void removeSelectionChangedListener(ISelectionChangedListener listener) {
- if (listener != null) {
- selectionListeners.remove(listener);
- }
- }
-
- /**
- * Fire the selection changed event to the registered listeners.
- */
- /* default */ void fireSelectionChanged() {
- if (selection != null) {
- SelectionChangedEvent event = new SelectionChangedEvent(this, selection);
- for (ISelectionChangedListener listener : selectionListeners) {
- listener.selectionChanged(event);
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2012 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.launch.ui.tabs.selector;
+
+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.core.runtime.AssertionFailedException;
+import org.eclipse.jface.dialogs.IDialogPage;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.properties.PropertiesContainer;
+import org.eclipse.tcf.te.runtime.services.ServiceManager;
+import org.eclipse.tcf.te.runtime.services.interfaces.IPropertiesAccessService;
+import org.eclipse.tcf.te.ui.controls.AbstractDecoratedDialogPageControl;
+import org.eclipse.tcf.te.ui.jface.interfaces.IValidatingContainer;
+import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.internal.ViewRoot;
+import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
+import org.eclipse.ui.internal.navigator.NavigatorContentService;
+import org.eclipse.ui.navigator.CommonViewerSorter;
+
+/**
+ * Context selector control.
+ * <p>
+ * Allows to present a configurable set of elements from the data model from which the user can
+ * select one or more elements.
+ * <p>
+ * Default properties:
+ * <ul>
+ * <li>PROPERTY_SHOW_GHOST_MODEL_NODES = false</li>
+ * </ul>
+ */
+@SuppressWarnings("restriction")
+public class ContextSelectorControl extends AbstractDecoratedDialogPageControl implements ISelectionProvider {
+
+ /**
+ * Property: If set to <code>true</code>, ghost model nodes will be shown within the tree.
+ */
+ public static final String PROPERTY_SHOW_GHOST_MODEL_NODES = "showGhostModelNodes"; //$NON-NLS-1$
+
+ /**
+ * List of selection changed listeners.
+ */
+ private final List<ISelectionChangedListener> selectionListeners = new ArrayList<ISelectionChangedListener>();
+
+ /**
+ * Control properties. See predefined property constants within the class and subclass
+ * implementations. Property changes are not notified.
+ */
+ private final IPropertiesContainer properties = new PropertiesContainer();
+
+ // Reference to the tree viewer control used.
+ private TreeViewer viewer;
+ // The current selection within the tree viewer.
+ /* default */ ISelection selection;
+
+ // Reference to the navigator content service used
+ private NavigatorContentService contentService;
+
+ /**
+ * Constant to return an empty viewer filter array.
+ */
+ protected final static ViewerFilter[] NO_FILTERS = new ViewerFilter[0];
+
+ /**
+ * Constant to return an empty selected model context array.
+ */
+ protected final static IModelNode[] NO_CONTEXTS = new IModelNode[0];
+
+ // Currently active set of viewer filters.
+ private ViewerFilter[] filters;
+ // Currently active checkbox tree viewer check state listener
+ private ICheckStateListener listener;
+
+ /**
+ * Default implementation of the context selector controls tree viewer.
+ */
+ protected class ContextSelectorTreeViewer extends ContainerCheckedTreeViewer {
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent control.
+ * @param style The SWT style bits used to create the tree.
+ */
+ public ContextSelectorTreeViewer(Composite parent, int style) {
+ // make sure that the passed in style bits are not contaminated
+ // by the CheckboxTreeViewer.
+ this(new Tree(parent, style));
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parent The parent control.
+ */
+ public ContextSelectorTreeViewer(Composite parent) {
+ super(parent);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param tree The tree control.
+ */
+ public ContextSelectorTreeViewer(Tree tree) {
+ super(tree);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.TreeViewer#isExpandable(java.lang.Object)
+ */
+ @Override
+ public boolean isExpandable(Object element) {
+ boolean expandable = super.isExpandable(element);
+ // adjust the expandable state if the element does not have
+ // children after the filtering.
+ if (expandable) {
+ expandable = getFilteredChildren(element).length > 0;
+ }
+ return expandable;
+ }
+
+ /**
+ * Returns the child items for the given element if any.
+ *
+ * @param element The element.
+ * @return The child items of the element or <code>null</code> if none.
+ */
+ public Item[] getChildren(Object element) {
+ Widget item = findItem(element);
+ return getChildren(item);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.dialogs.ContainerCheckedTreeViewer#doCheckStateChanged(java.lang.Object)
+ */
+ @Override
+ protected void doCheckStateChanged(Object element) {
+ // Our ghost model elements requires some special handling, as
+ // these elements should be never checked fully. Try to determine
+ // if we have to double check on the parents state.
+ boolean skipDoubleCheckParentState = false;
+
+ // If the element isn't one of our model elements, pass on to
+ // to super implementation
+ skipDoubleCheckParentState |= !(element instanceof IModelNode);
+
+ // If the element is one of our model elements and it is not
+ // a ghost node, the parent can't be a ghost node either.
+ if (!skipDoubleCheckParentState) {
+ skipDoubleCheckParentState |= !isGhost((IModelNode) element);
+ }
+
+ // If the element is a ghost model element, then we have to check
+ // on the parent as well.
+ if (!skipDoubleCheckParentState) {
+ skipDoubleCheckParentState |= ((IModelNode) element).getParent() == null || !isGhost(((IModelNode) element).getParent());
+ }
+
+ // Call the super implementation to check the item and
+ // updating parents and children the first time
+ super.doCheckStateChanged(element);
+
+ if (!skipDoubleCheckParentState) {
+ // Get the tree item for the element and check the parent items
+ // for being associated with ghost model elements.
+ Widget item = findItem(element);
+ if (item instanceof TreeItem) {
+ TreeItem treeItem = ((TreeItem) item).getParentItem();
+ while (treeItem != null) {
+ Object data = treeItem.getData();
+
+ // If a child item is checked, otherwise we wouldn't come here, and this
+ // parent item isn't expanded, we must(!) expand the item now here by force,
+ // otherwise we will loose the checked states of the children elements!
+ if (!treeItem.getExpanded()) {
+ treeItem.setExpanded(true);
+ }
+
+ // Decide if we shall gray the checked state.
+ // --> The checked state is grayed if the item is a ghost.
+ boolean isGhost = data instanceof IModelNode && isGhost((IModelNode) data);
+ if (!treeItem.getGrayed() && isGhost) {
+ treeItem.setGrayed(true);
+ }
+
+ // go one level up in the hierarchy
+ treeItem = treeItem.getParentItem();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns if or if not the given model node is a ghost node.
+ *
+ * @param node The model node. Must not be <code>null</code>.
+ * @return <code>True</code> if the node is a ghost node, <code>false</code> otherwise.
+ */
+ /* default */ boolean isGhost(IModelNode node) {
+ Assert.isNotNull(node);
+
+ IPropertiesAccessService service = ServiceManager.getInstance().getService(node, IPropertiesAccessService.class);
+ if (service != null) {
+ Object value = service.getProperty(node, IModelNode.PROPERTY_IS_GHOST);
+ if (value instanceof Boolean) {
+ return ((Boolean)value).booleanValue();
+ } else if (value instanceof String) {
+ return Boolean.valueOf((String)value).booleanValue();
+ }
+ return false;
+ }
+
+ try {
+ return node.isProperty(IModelNode.PROPERTY_IS_GHOST, true);
+ } catch (AssertionFailedException e) { /* ignored on purpose */ }
+
+ return false;
+ }
+
+ /**
+ * Default implementation of the context selector controls check state listener.
+ */
+ protected class ContextSelectedCheckStateListener implements ICheckStateListener {
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
+ */
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ Object element = event.getElement();
+ if (element instanceof IModelNode) {
+ onModelNodeCheckStateChanged((IModelNode) element, event.getChecked());
+ }
+ }
+ }
+
+ /**
+ * Default implementation of the context selector controls viewer filter.
+ */
+ protected class ContextSelectorViewerFilter extends ViewerFilter {
+
+ /**
+ * Returns if or if not ghost model elements should be visible within the model context
+ * selector controls tree viewer. Default is not to show the ghost model elements.
+ *
+ * @return <code>True</code> to show the ghost model elements, <code>false</code> otherwise.
+ */
+ protected boolean doShowGhostModelElements() {
+ return getPropertiesContainer().getBooleanProperty(PROPERTY_SHOW_GHOST_MODEL_NODES);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (element instanceof IModelNode) {
+ if (isGhost((IModelNode) element)) {
+ return doShowGhostModelElements();
+ }
+ }
+
+ return true;
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentPage The parent target connection page this control is embedded in. Might be
+ * <code>null</code> if the control is not associated with a page.
+ */
+ public ContextSelectorControl(IDialogPage parentPage) {
+ super(parentPage);
+ selectionListeners.clear();
+ // initialize the properties
+ initializeProperties(getPropertiesContainer());
+ }
+
+ /**
+ * Returns the properties container associated with this control.
+ *
+ * @return The properties container.
+ */
+ public final IPropertiesContainer getPropertiesContainer() {
+ return properties;
+ }
+
+ /**
+ * Initialize the properties associated with this control.
+ *
+ * @param properties The properties container. Must not be <code>null</code>.
+ */
+ protected void initializeProperties(IPropertiesContainer properties) {
+ Assert.isNotNull(properties);
+ properties.setProperty(PROPERTY_SHOW_GHOST_MODEL_NODES, false);
+ }
+
+ /**
+ * Returns the default title text which should be used by the enclosing controls or windows if
+ * these controls do need to set a title.
+ * <p>
+ * The default implementation returns <code>null</code>.
+ *
+ * @return The default title text or <code>null</code> if none.
+ */
+ public String getDefaultTitle() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.BaseControl#dispose()
+ */
+ @Override
+ public void dispose() {
+ // Dispose the navigator content service
+ if (contentService != null) {
+ contentService.dispose();
+ contentService = null;
+ }
+
+ viewer = null;
+
+ super.dispose();
+ }
+
+ /**
+ * Returns the list of checked model node contexts. The elements are in the order they appear
+ * within the tree from top to bottom. The client of the control is in charge detecting any type
+ * of hierarchy or other relationships between the elements.
+ *
+ * @return The list of checked model node contexts or an empty list of none.
+ */
+ public IModelNode[] getCheckedModelContexts() {
+ // This method does return something useful only if it is a checkable
+ // tree viewer and the check style is set for the tree.
+ if (getViewer() instanceof ContainerCheckedTreeViewer && (getTreeViewerStyle() & SWT.CHECK) != 0) {
+ ContainerCheckedTreeViewer viewer = (ContainerCheckedTreeViewer) getViewer();
+ // Get the list of checked elements. Checked elements includes the grayed elements
+ List<?> checked = viewer.getCheckedElements() != null ? Arrays.asList(viewer.getCheckedElements()) : Collections.emptyList();
+ // Get the list of grayed elements.
+ List<?> grayed = viewer.getGrayedElements() != null ? Arrays.asList(viewer.getGrayedElements()) : Collections.emptyList();
+
+ // There must be at least one element checked
+ if (!checked.isEmpty()) {
+ List<IModelNode> contexts = new ArrayList<IModelNode>();
+ for (Object element : checked) {
+ // If the context is a model node and the parent container node is fully
+ // checked, drop the model node and the use the container node only.
+ if (element instanceof IModelNode) {
+ IModelNode node = (IModelNode) element;
+
+ // Determine the parent node
+ IPropertiesAccessService service = ServiceManager.getInstance().getService(node, IPropertiesAccessService.class);
+ IModelNode parent = service != null ? (IModelNode)service.getParent(node) : node.getParent();
+
+ if (parent != null && checked.contains(parent) && !grayed.contains(parent)) {
+ continue;
+ }
+ }
+
+ // If the element is a model node and not grayed,
+ // add the element to the list of checked contexts.
+ if (element instanceof IModelNode && !grayed.contains(element)) {
+ contexts.add((IModelNode) element);
+ }
+ }
+ return contexts.toArray(new IModelNode[contexts.size()]);
+ }
+ }
+ return NO_CONTEXTS;
+ }
+
+ /**
+ * Sets the list of checked model node contexts.
+ *
+ * @param contexts The list of model node contexts. Must not be <code>null</code>.
+ */
+ public void setCheckedModelContexts(IModelNode[] contexts) {
+ Assert.isNotNull(contexts);
+
+ // This method does nothing if the tree viewer isn't a checkable tree viewer.
+ if (getViewer() instanceof ContainerCheckedTreeViewer && (getTreeViewerStyle() & SWT.CHECK) != 0) {
+ ContainerCheckedTreeViewer viewer = (ContainerCheckedTreeViewer) getViewer();
+ // Set the checked elements. This will trigger the validation of the
+ // checked state of all the parent and children elements.
+ viewer.setCheckedElements(contexts);
+ // Make sure that at least the first checked element is visible to the user
+ if (contexts.length > 0) {
+ viewer.setSelection(new StructuredSelection(contexts[0]), true);
+ }
+ }
+ }
+
+ /**
+ * Returns the controls associated tree viewer.
+ *
+ * @return The tree viewer instance or <code>null</code> if not created yet.
+ */
+ public final TreeViewer getViewer() {
+ return viewer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.BaseControl#setupPanel(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void setupPanel(Composite parent) {
+ super.setupPanel(parent);
+
+ // Create the container composite for the tree control.
+ Composite composite = doCreateTopContainerComposite(parent);
+ Assert.isNotNull(composite);
+
+ // Create the viewer
+ viewer = createTreeViewerControl(composite);
+
+ // And now configure the listeners
+ configureControlListener();
+
+ // Trigger a selection changed event to give listeners
+ // a chance to initialize their enabled state correctly
+ viewer.setSelection(viewer.getSelection());
+ }
+
+ /**
+ * Create the top container composite.
+ *
+ * @param parent The parent composite. Must not be <code>null</code>.
+ * @return The top container composite. Must not be <code>null</code>.
+ */
+ protected Composite doCreateTopContainerComposite(Composite parent) {
+ Assert.isNotNull(parent);
+
+ // Set the default layout data attributes for the composite
+ int style = GridData.FILL_BOTH;
+ int heightHint = SWT.DEFAULT;
+
+ // Fallback to standard non-form controls and create a composite which extends
+ // in both directions and has no margins
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ GridData layoutData = new GridData(style);
+ layoutData.heightHint = heightHint;
+ composite.setLayoutData(layoutData);
+
+ return composite;
+ }
+
+ /**
+ * Creates the tree viewer control. Override to return a custom tree viewer implementation.
+ *
+ * @param parent The parent composite of the tree viewer. Must not be <code>null</code>.
+ * @return The tree viewer control. Must be never <code>null</code>.
+ */
+ protected TreeViewer createTreeViewerControl(Composite parent) {
+ Assert.isNotNull(parent);
+
+ CheckboxTreeViewer viewer = doCreateNewTreeViewerControl(parent, getTreeViewerStyle());
+ doConfigureTreeViewerControl(viewer);
+
+ viewer.setInput(getInitialViewerInput());
+ doEnableControl(viewer);
+
+ return viewer;
+ }
+
+ /**
+ * Creates a new instance of the tree viewer control to use. This method will be called from
+ * {@link #createTreeViewerControl(Composite)} if creating the tree viewer instance.
+ *
+ * @param parent The parent composite of the tree viewer. Must not be <code>null</code>.
+ * @param style The SWT style bits.
+ *
+ * @return The tree viewer instance. Must not be <code>null</code>.
+ */
+ protected CheckboxTreeViewer doCreateNewTreeViewerControl(Composite parent, int style) {
+ return new ContextSelectorTreeViewer(parent, style);
+ }
+
+ /**
+ * Configure the tree viewer control.
+ *
+ * @param viewer The tree viewer instance. Must not be <code>null</code>.
+ */
+ protected void doConfigureTreeViewerControl(CheckboxTreeViewer viewer) {
+ Assert.isNotNull(viewer);
+
+ viewer.setUseHashlookup(true);
+
+ doConfigureTreeLayoutData(viewer.getTree());
+
+ // Create the navigator content service
+ contentService = new NavigatorContentService(IUIConstants.ID_EXPLORER, viewer);
+ Assert.isNotNull(contentService);
+
+ viewer.setContentProvider(contentService.createCommonContentProvider());
+ viewer.setLabelProvider(contentService.createCommonLabelProvider());
+ viewer.setSorter(doCreateViewerSorter());
+
+ if ((getTreeViewerStyle() & SWT.CHECK) != 0 && getViewerCheckStateListener(viewer) != null) {
+ viewer.addCheckStateListener(getViewerCheckStateListener(viewer));
+ }
+
+ if (hasViewerFilters()) {
+ viewer.setFilters(getViewerFilters());
+ }
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ selection = event.getSelection();
+ fireSelectionChanged();
+ }
+ });
+ doCreateControlDecoration(viewer.getTree());
+ }
+
+ /**
+ * Configure the tree's layout data. The layout data set to the tree must be of type
+ * <code>GridData</code>.
+ *
+ * @param tree The tree to configure. Must not be <code>null</code>.
+ */
+ protected void doConfigureTreeLayoutData(Tree tree) {
+ GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
+ layoutData.heightHint = 150;
+ tree.setLayoutData(layoutData);
+ }
+
+ /**
+ * Returns the style bits to apply to the tree viewer.
+ * <p>
+ * The default set tree viewer style bits are:
+ * <ul>
+ * <li>SWT.SINGLE</li>
+ * <li>SWT.H_SCROLL</li>
+ * <li>SWT.V_SCROLL</li>
+ * <li>SWT.BORDER</li>
+ *
+ * @return The style bits to apply to the tree viewer.
+ */
+ protected int getTreeViewerStyle() {
+ return SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER;
+ }
+
+ /**
+ * Creates the viewer sorter instance to associated to the controls tree viewer.
+ *
+ * @return The viewer sorter to associate or <code>null</code> if none.
+ */
+ protected ViewerSorter doCreateViewerSorter() {
+ return new CommonViewerSorter();
+ }
+
+ /**
+ * Returns if or if not to associate viewer filters to the controls tree viewer. If this method
+ * returns <code>true</code>, {@link #doCreateViewerFilters()} must return not null!
+ *
+ * @return <code>True</code> if to associate viewer filters, <code>false</code> otherwise.
+ */
+ protected boolean hasViewerFilters() {
+ return true;
+ }
+
+ /**
+ * Creates a returns a new set of the viewer filters to associated to the controls tree viewer.
+ * This method will be called from {@link #getViewerFilters()} in case the method
+ * {@link #hasViewerFilters()} returns <code>true</code> and no viewer filters got created
+ * before.
+ *
+ * @return The viewer filters to associate or <code>null</code> if none.
+ */
+ protected ViewerFilter[] doCreateViewerFilters() {
+ return new ViewerFilter[] { new ContextSelectorViewerFilter() };
+ }
+
+ /**
+ * Returns the associated viewer filters of the controls tree viewer. If the control does have
+ * viewer filters ({@link #hasViewerFilters()} returns <code>true</code>) and the viewer filters
+ * had not yet been created, the method calls {@link #doCreateViewerFilters()}.
+ *
+ * @return The associated viewer filters of the controls tree viewer or the constant
+ * {@link #NO_FILTERS}.
+ */
+ protected ViewerFilter[] getViewerFilters() {
+ if (filters == null && hasViewerFilters()) {
+ filters = doCreateViewerFilters();
+ }
+ return filters != null ? filters : NO_FILTERS;
+ }
+
+ /**
+ * Creates a new checkbox tree viewer check state listener. This method will be called from
+ * {@link #getViewerCheckStateListener()} in case the listener did not got created before.
+ *
+ * @param viewer The checkbox tree viewer. Must not be <code>null</code>.
+ * @return The checkbox tree viewer check state listener or <code>null</code> if none.
+ */
+ protected ICheckStateListener doCreateViewerCheckStateListener(CheckboxTreeViewer viewer) {
+ Assert.isNotNull(viewer);
+ return new ContextSelectedCheckStateListener();
+ }
+
+ /**
+ * Returns the associated checkbox tree viewer check state listener. If the listener had not yet
+ * been created, the method calls {@link #doCreateLabelProvider()}.
+ *
+ * @param viewer The checkbox tree viewer. Must not be <code>null</code>.
+ * @return The associated checkbox tree viewer check state listener or <code>null</code> if
+ * none.
+ */
+ protected ICheckStateListener getViewerCheckStateListener(CheckboxTreeViewer viewer) {
+ Assert.isNotNull(viewer);
+ if (listener == null) {
+ listener = doCreateViewerCheckStateListener(viewer);
+ }
+ return listener;
+ }
+
+ /**
+ * Called from the default check state listener implementation if the checked state of the
+ * passed in model node has changed.
+ *
+ * @param node The model node. Must not be <code>null</code>.
+ * @param checked <code>True</code> if the model node has been checked, <code>false</code> if
+ * unchecked.
+ */
+ protected void onModelNodeCheckStateChanged(IModelNode node, boolean checked) {
+ // validate the parent page if there is one set
+ if (getParentPage() instanceof IValidatingContainer) {
+ ((IValidatingContainer) getParentPage()).validate();
+ }
+ }
+
+ /**
+ * Returns the initial input object to set to the controls tree viewer.
+ *
+ * @return The initial viewer input to set or <code>null</code> if none.
+ */
+ protected Object getInitialViewerInput() {
+ return ViewRoot.getInstance();
+ }
+
+ /**
+ * Enables the tree control.
+ *
+ * @param viewer The tree viewer object. Must not be <code>null</code>.
+ */
+ protected void doEnableControl(TreeViewer viewer) {
+ Assert.isNotNull(viewer);
+ SWTControlUtil.setEnabled(viewer.getTree(), viewer.getTree().getItemCount() > 0);
+ }
+
+ /**
+ * Refresh the controls viewer and check the viewers enablement. This method is called by the
+ * standard refresh toolbar item, if the control has a toolbar.
+ */
+ public void refresh() {
+ if (viewer != null && viewer.getControl() != null && !viewer.getControl().isDisposed()) {
+ viewer.refresh(true);
+ doEnableControl(viewer);
+ }
+ }
+
+ /**
+ * Called from {@link #setupPanel(Composite)} before returning the control to the caller.
+ * Override to plug-in and configure any custom listener the subclassed control might need.
+ */
+ protected void configureControlListener() {
+ }
+
+ /**
+ * Sets the given selection to the viewer.
+ *
+ * @param selection The selection to set. Must not be <code>null</code>.
+ */
+ @Override
+ public void setSelection(ISelection selection) {
+ Assert.isNotNull(selection);
+ this.selection = selection;
+ if (viewer != null) {
+ viewer.setSelection(selection, true);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
+ */
+ @Override
+ public ISelection getSelection() {
+ return selection;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+ */
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ if (listener != null && !selectionListeners.contains(listener)) {
+ selectionListeners.add(listener);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
+ */
+ @Override
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ if (listener != null) {
+ selectionListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Fire the selection changed event to the registered listeners.
+ */
+ /* default */ void fireSelectionChanged() {
+ if (selection != null) {
+ SelectionChangedEvent event = new SelectionChangedEvent(this, selection);
+ for (ISelectionChangedListener listener : selectionListeners) {
+ listener.selectionChanged(event);
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/StepContextSelectorControl.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorControl.java
index ec91500..2985c78 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/StepContextSelectorControl.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorControl.java
@@ -30,7 +30,7 @@ import org.eclipse.tcf.te.ui.jface.interfaces.IValidatingContainer;
* <li>PROPERTY_MULTI_CONTEXT_SELECTOR = true</li>
* </ul>
*/
-public class StepContextSelectorControl extends ContextSelectorControl {
+public class LaunchContextSelectorControl extends ContextSelectorControl {
/**
* Property: If set to <code>true</code>, the control will be created as multi
* context control. That means that more than one tree item will be
@@ -45,18 +45,18 @@ public class StepContextSelectorControl extends ContextSelectorControl {
private boolean requireSelection = true;
/**
- * Constructor.
+ * Constructor.
*
* @param parentPage The parent target connection page this control is embedded in. Might be
* <code>null</code> if the control is not associated with a page.
- */
- public StepContextSelectorControl(IDialogPage parentPage) {
- super(parentPage);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.tcf.te.launch.ui.tabs.selector.ContextSelectorControl#initializeProperties(org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer)
- */
+ */
+ public LaunchContextSelectorControl(IDialogPage parentPage) {
+ super(parentPage);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.launch.ui.tabs.selector.ContextSelectorControl#initializeProperties(org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer)
+ */
@Override
protected void initializeProperties(IPropertiesContainer properties) {
super.initializeProperties(properties);
@@ -169,6 +169,17 @@ public class StepContextSelectorControl extends ContextSelectorControl {
}
}
+ if (getControlDecoration() != null) {
+ // Setup and show the control decoration if necessary
+ if (isEnabled() && (!valid || (getMessage() != null && getMessageType() != IMessageProvider.NONE))) {
+ // Update the control decorator
+ updateControlDecoration(getMessage(), getMessageType());
+ } else {
+ updateControlDecoration(null, IMessageProvider.NONE);
+ }
+ }
+
+
return valid;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorSection.java
index 0a3692f..032d921 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorSection.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorSection.java
@@ -36,9 +36,9 @@ import org.eclipse.ui.forms.widgets.Section;
/**
* Context selector section implementation.
*/
-public class ContextSelectorSection extends AbstractSection implements ILaunchConfigurationTabFormPart {
+public class LaunchContextSelectorSection extends AbstractSection implements ILaunchConfigurationTabFormPart {
// Reference to the section sub controls
- /* default */ StepContextSelectorControl selector;
+ /* default */ LaunchContextSelectorControl selector;
/**
* Context selector control refresh action implementation.
@@ -71,7 +71,7 @@ public class ContextSelectorSection extends AbstractSection implements ILaunchCo
* @param form The parent managed form. Must not be <code>null</code>.
* @param parent The parent composite. Must not be <code>null</code>.
*/
- public ContextSelectorSection(IManagedForm form, Composite parent) {
+ public LaunchContextSelectorSection(IManagedForm form, Composite parent) {
super(form, parent, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED);
getSection().setBackground(parent.getBackground());
createClient(getSection(), form.getToolkit());
@@ -99,9 +99,9 @@ public class ContextSelectorSection extends AbstractSection implements ILaunchCo
createSectionToolbar(section, toolkit);
// Create the section sub controls
- selector = new StepContextSelectorControl(null) {
+ selector = new LaunchContextSelectorControl(null) {
/* (non-Javadoc)
- * @see org.eclipse.tcf.te.launch.ui.tabs.selector.StepContextSelectorControl#onModelNodeCheckStateChanged(org.eclipse.tcf.te.runtime.model.interfaces.IModelNode, boolean)
+ * @see org.eclipse.tcf.te.launch.ui.tabs.selector.LaunchContextSelectorControl#onModelNodeCheckStateChanged(org.eclipse.tcf.te.runtime.model.interfaces.IModelNode, boolean)
*/
@Override
protected void onModelNodeCheckStateChanged(IModelNode node, boolean checked) {
@@ -180,6 +180,15 @@ public class ContextSelectorSection extends AbstractSection implements ILaunchCo
*/
@Override
public boolean isValid(ILaunchConfiguration configuration) {
- return true;
+ boolean valid = super.isValid();
+
+ if (valid) {
+ valid = selector.isValid();
+ if (!valid) {
+ setMessage(selector.getMessage(), selector.getMessageType());
+ }
+ }
+
+ return valid;
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorTab.java b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorTab.java
index 949692b..5bf16c7 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/ContextSelectorTab.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.launch.ui/src/org/eclipse/tcf/te/launch/ui/tabs/selector/LaunchContextSelectorTab.java
@@ -22,9 +22,9 @@ import org.eclipse.ui.forms.widgets.TableWrapLayout;
/**
* Context selector launch configuration tab implementation.
*/
-public class ContextSelectorTab extends AbstractFormsLaunchConfigurationTab {
+public class LaunchContextSelectorTab extends AbstractFormsLaunchConfigurationTab {
// References to the tab sub sections
- private ContextSelectorSection selectorSection;
+ private LaunchContextSelectorSection selectorSection;
/* (non-Javadoc)
* @see org.eclipse.tcf.te.launch.ui.tabs.AbstractFormsLaunchConfigurationTab#dispose()
@@ -52,7 +52,7 @@ public class ContextSelectorTab extends AbstractFormsLaunchConfigurationTab {
panel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
panel.setBackground(parent.getBackground());
- selectorSection = new ContextSelectorSection(getManagedForm(), panel);
+ selectorSection = new LaunchContextSelectorSection(getManagedForm(), panel);
selectorSection.getSection().setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP));
getManagedForm().addPart(selectorSection);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/META-INF/MANIFEST.MF
index 4e38dde..70bfcef 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/META-INF/MANIFEST.MF
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/META-INF/MANIFEST.MF
@@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
org.eclipse.tcf.te.core;bundle-version="1.0.0",
org.eclipse.tcf.te.launch.core;bundle-version="1.0.0",
org.eclipse.tcf.te.tcf.core;bundle-version="1.0.0",
- org.eclipse.tcf.te.tcf.locator;bundle-version="1.0.0"
+ org.eclipse.tcf.te.tcf.locator;bundle-version="1.0.0",
+ org.eclipse.tcf.te.tcf.processes.core;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.properties
index 72d7d64..628facd 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.properties
@@ -22,4 +22,5 @@ LaunchStepGroup.Linux.App.name=Remote Linux Application
# ***** Launch Steps *****
LaunchStep.OpenChannel.name=Open TCF Channel
+LaunchStep.LaunchProcess.name=Launch Process
LaunchStep.CloseChannel.name=Close TCF Channel
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.xml
index 89eed92..a34fbb9 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.xml
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/plugin.xml
@@ -69,33 +69,17 @@
label="%LaunchStepGroup.Linux.App.name"
locked="false">
<references>
- <reference
- id="org.eclipse.tcf.te.tcf.launch.core.openChannelStep"
- disable="false"
- hidden="false"
- removable="false"
- singleton="true">
- </reference>
- <reference
- id="org.eclipse.tcf.te.tcf.launch.core.closeChannelStep"
- disable="false"
- hidden="false"
- removable="false"
- singleton="true">
- </reference>
- <reference
- id="org.eclipse.tcf.te.launch.core.removeLaunchStep"
- disable="false"
- hidden="false"
- removable="false"
- singleton="true">
- <enablement>
- <with variable="context">
- <not>
- <test property="org.eclipse.tcf.te.launch.core.launchMode" value="debug"/>
- </not>
- </with>
- </enablement>
+ <reference id="org.eclipse.tcf.te.tcf.launch.core.openChannelStep"/>
+ <reference id="org.eclipse.tcf.te.tcf.launch.core.launchProcessStep"/>
+ <reference id="org.eclipse.tcf.te.tcf.launch.core.closeChannelStep"/>
+ <reference id="org.eclipse.tcf.te.launch.core.removeLaunchStep">
+ <enablement>
+ <with variable="context">
+ <not>
+ <test property="org.eclipse.tcf.te.launch.core.launchMode" value="debug"/>
+ </not>
+ </with>
+ </enablement>
</reference>
</references>
</stepGroup>
@@ -109,6 +93,14 @@
label="%LaunchStep.OpenChannel.name">
</step>
<step
+ class="org.eclipse.tcf.te.tcf.launch.core.steps.LaunchProcessStep"
+ id="org.eclipse.tcf.te.tcf.launch.core.launchProcessStep"
+ label="%LaunchStep.LaunchProcess.name">
+ <requires
+ id="org.eclipse.tcf.te.tcf.launch.core.openChannelStep">
+ </requires>
+ </step>
+ <step
class="org.eclipse.tcf.te.tcf.launch.core.steps.CloseChannelStep"
id="org.eclipse.tcf.te.tcf.launch.core.closeChannelStep"
label="%LaunchStep.CloseChannel.name">
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/interfaces/ILinuxAppLaunchAttributes.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/interfaces/ILinuxAppLaunchAttributes.java
new file mode 100644
index 0000000..cf03064
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/interfaces/ILinuxAppLaunchAttributes.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.launch.core.interfaces;
+
+import org.eclipse.tcf.te.launch.core.lm.interfaces.ICommonLaunchAttributes;
+
+/**
+ * Defines the launch configuration attribute id's to access the launch step contexts.
+ */
+public interface ILinuxAppLaunchAttributes {
+
+ /**
+ * Define the prefix used by all other attribute id's as prefix.
+ */
+ public static final String ATTR_PREFIX = "org.eclipse.tcf.te.tcf.launch"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute: The process image.
+ */
+ public static final String ATTR_PROCESS_IMAGE = ICommonLaunchAttributes.ATTR_PREFIX + ".process_image"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute: The process arguments.
+ */
+ public static final String ATTR_PROCESS_ARGUMENTS = ICommonLaunchAttributes.ATTR_PREFIX + ".process_arguments"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/steps/LaunchProcessStep.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/steps/LaunchProcessStep.java
new file mode 100644
index 0000000..1e784e6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.core/src/org/eclipse/tcf/te/tcf/launch/core/steps/LaunchProcessStep.java
@@ -0,0 +1,83 @@
+/*
+ * LaunchProcessStep.java
+ * Created on 02.03.2012
+ *
+ * Copyright 2012 Wind River Systems Inc. All rights reserved.
+ */
+package org.eclipse.tcf.te.tcf.launch.core.steps;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tcf.te.core.utils.text.StringUtil;
+import org.eclipse.tcf.te.launch.core.persistence.DefaultPersistenceDelegate;
+import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
+import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer;
+import org.eclipse.tcf.te.runtime.properties.PropertiesContainer;
+import org.eclipse.tcf.te.runtime.services.interfaces.constants.ITerminalsConnectorConstants;
+import org.eclipse.tcf.te.runtime.stepper.StepperAttributeUtil;
+import org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId;
+import org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext;
+import org.eclipse.tcf.te.tcf.launch.core.activator.CoreBundleActivator;
+import org.eclipse.tcf.te.tcf.launch.core.interfaces.ILinuxAppLaunchAttributes;
+import org.eclipse.tcf.te.tcf.processes.core.interfaces.launcher.IProcessLauncher;
+import org.eclipse.tcf.te.tcf.processes.core.launcher.ProcessLauncher;
+
+/**
+ * LaunchProcessStep
+ * @author tobias.schwarz@windriver.com
+ */
+public class LaunchProcessStep extends AbstractTcfLaunchStep {
+
+ /**
+ * Constructor.
+ */
+ public LaunchProcessStep() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IExtendedStep#validateExecute(org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void validateExecute(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId, IProgressMonitor monitor) throws CoreException {
+ String processImage = DefaultPersistenceDelegate.getAttribute(getLaunchConfiguration(context), ILinuxAppLaunchAttributes.ATTR_PROCESS_IMAGE, (String)null);
+ if (processImage != null && processImage.trim().length() > 0) {
+ StepperAttributeUtil.setProperty(ILinuxAppLaunchAttributes.ATTR_PROCESS_IMAGE, fullQualifiedId, data, processImage);
+ }
+ else {
+ throw new CoreException(new Status(IStatus.ERROR, CoreBundleActivator.getUniqueIdentifier(), "missing process image name"));
+ }
+
+ String processArguments = DefaultPersistenceDelegate.getAttribute(getLaunchConfiguration(context), ILinuxAppLaunchAttributes.ATTR_PROCESS_ARGUMENTS, (String)null);
+ StepperAttributeUtil.setProperty(ILinuxAppLaunchAttributes.ATTR_PROCESS_ARGUMENTS, fullQualifiedId, data, processArguments);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.stepper.interfaces.IStep#execute(org.eclipse.tcf.te.runtime.stepper.interfaces.IStepContext, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.tcf.te.runtime.stepper.interfaces.IFullQualifiedId, org.eclipse.core.runtime.IProgressMonitor, org.eclipse.tcf.te.runtime.interfaces.callback.ICallback)
+ */
+ @Override
+ public void execute(IStepContext context, IPropertiesContainer data, IFullQualifiedId fullQualifiedId, IProgressMonitor monitor, final ICallback callback) {
+ // Construct the launcher object
+ ProcessLauncher launcher = new ProcessLauncher();
+
+ Map<String, Object> launchAttributes = new HashMap<String, Object>();
+
+ launchAttributes.put(IProcessLauncher.PROP_PROCESS_PATH, StepperAttributeUtil.getStringProperty(ILinuxAppLaunchAttributes.ATTR_PROCESS_IMAGE, fullQualifiedId, data));
+
+ String arguments = StepperAttributeUtil.getStringProperty(ILinuxAppLaunchAttributes.ATTR_PROCESS_ARGUMENTS, fullQualifiedId, data);
+ String[] args = arguments != null && !"".equals(arguments.trim()) ? StringUtil.tokenize(arguments, 0, true) : null; //$NON-NLS-1$
+ launchAttributes.put(IProcessLauncher.PROP_PROCESS_ARGS, args);
+
+ launchAttributes.put(ITerminalsConnectorConstants.PROP_LOCAL_ECHO, Boolean.FALSE);
+ launchAttributes.put(IProcessLauncher.PROP_PROCESS_ASSOCIATE_CONSOLE, Boolean.TRUE);
+
+ // Launch the process
+ IPropertiesContainer container = new PropertiesContainer();
+ container.setProperties(launchAttributes);
+ launcher.launch(getActivePeerModel(data).getPeer(), container, callback);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/META-INF/MANIFEST.MF
index 8618963..136e23c 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/META-INF/MANIFEST.MF
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/META-INF/MANIFEST.MF
@@ -1,25 +1,31 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: %pluginName
-Bundle-SymbolicName: org.eclipse.tcf.te.tcf.launch.ui;singleton:=true
-Bundle-Version: 1.0.0.qualifier
-Bundle-Activator: org.eclipse.tcf.te.tcf.launch.ui.activator.UIPlugin
-Bundle-Vendor: %providerName
-Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
- org.eclipse.debug.ui;bundle-version="3.7.101",
- org.eclipse.ui;bundle-version="3.7.0",
- org.eclipse.tcf.core;bundle-version="1.0.0",
- org.eclipse.tcf.te.runtime;bundle-version="1.0.0",
- org.eclipse.tcf.te.launch.core;bundle-version="1.0.0",
- org.eclipse.tcf.te.launch.ui;bundle-version="1.0.0",
- org.eclipse.tcf.te.ui.swt;bundle-version="1.0.0",
- org.eclipse.tcf.te.tcf.core;bundle-version="1.0.0",
- org.eclipse.tcf.te.tcf.launch.core;bundle-version="1.0.0",
- org.eclipse.tcf.te.tcf.locator;bundle-version="1.0.0"
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ActivationPolicy: lazy
-Bundle-Localization: plugin
-Export-Package: org.eclipse.tcf.te.tcf.launch.ui.activator;x-internal:=true,
- org.eclipse.tcf.te.tcf.launch.ui.help,
- org.eclipse.tcf.te.tcf.launch.ui.linux.app,
- org.eclipse.tcf.te.tcf.launch.ui.nls;x-internal:=true
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tcf.te.tcf.launch.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.tcf.te.tcf.launch.ui.activator.UIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
+ org.eclipse.debug.ui;bundle-version="3.7.101",
+ org.eclipse.ui;bundle-version="3.7.0",
+ org.eclipse.tcf.core;bundle-version="1.0.0",
+ org.eclipse.tcf.te.runtime;bundle-version="1.0.0",
+ org.eclipse.tcf.te.launch.core;bundle-version="1.0.0",
+ org.eclipse.tcf.te.launch.ui;bundle-version="1.0.0",
+ org.eclipse.tcf.te.ui.swt;bundle-version="1.0.0",
+ org.eclipse.tcf.te.tcf.core;bundle-version="1.0.0",
+ org.eclipse.tcf.te.tcf.launch.core;bundle-version="1.0.0",
+ org.eclipse.tcf.te.tcf.locator;bundle-version="1.0.0",
+ org.eclipse.tcf.te.ui.forms;bundle-version="1.0.0",
+ org.eclipse.ui.forms;bundle-version="3.5.100",
+ org.eclipse.tcf.te.tcf.filesystem;bundle-version="1.0.0",
+ org.eclipse.tcf.te.tcf.processes.core;bundle-version="1.0.0",
+ org.eclipse.tcf.te.ui.controls;bundle-version="1.0.0",
+ org.eclipse.tcf.te.runtime.model;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tcf.te.tcf.launch.ui.activator;x-internal:=true,
+ org.eclipse.tcf.te.tcf.launch.ui.help,
+ org.eclipse.tcf.te.tcf.launch.ui.linux.app,
+ org.eclipse.tcf.te.tcf.launch.ui.nls;x-internal:=true
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTab.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTab.java
new file mode 100644
index 0000000..ea5104f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTab.java
@@ -0,0 +1,40 @@
+/*
+ * LaunchConfigurationMainTab.java
+ * Created on 02.03.2012
+ *
+ * Copyright 2012 Wind River Systems Inc. All rights reserved.
+ */
+package org.eclipse.tcf.te.tcf.launch.ui.linux.app;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tcf.te.launch.ui.tabs.selector.LaunchContextSelectorTab;
+import org.eclipse.tcf.te.ui.forms.CustomFormToolkit;
+
+/**
+ * LaunchConfigurationMainTab
+ * @author tobias.schwarz@windriver.com
+ */
+public class LaunchConfigurationMainTab extends LaunchContextSelectorTab {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.launch.ui.tabs.selector.LaunchContextSelectorTab#doCreateFormContent(org.eclipse.swt.widgets.Composite, org.eclipse.tcf.te.ui.forms.CustomFormToolkit)
+ */
+ @Override
+ protected void doCreateFormContent(Composite parent, CustomFormToolkit toolkit) {
+ super.doCreateFormContent(parent, toolkit);
+
+ // Setup the main panel (using the table wrap layout)
+ Composite panel = toolkit.getFormToolkit().createComposite(parent);
+ GridLayout layout = new GridLayout(1, false);
+ panel.setLayout(layout);
+ panel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ panel.setBackground(parent.getBackground());
+
+ LaunchConfigurationMainTabSection section = new LaunchConfigurationMainTabSection(getManagedForm(), panel);
+ section.getSection().setLayoutData(new GridData(GridData.FILL_BOTH));
+ getManagedForm().addPart(section);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTabSection.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTabSection.java
new file mode 100644
index 0000000..0829114
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationMainTabSection.java
@@ -0,0 +1,194 @@
+/*
+ * LaunchConfigurationMainTabSection.java
+ * Created on 02.03.2012
+ *
+ * Copyright 2012 Wind River Systems Inc. All rights reserved.
+ */
+package org.eclipse.tcf.te.tcf.launch.ui.linux.app;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tcf.te.launch.core.persistence.ContextSelectorPersistenceDelegate;
+import org.eclipse.tcf.te.launch.core.persistence.DefaultPersistenceDelegate;
+import org.eclipse.tcf.te.launch.ui.interfaces.ILaunchConfigurationTabFormPart;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.tcf.filesystem.dialogs.FSOpenFileDialog;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.launch.core.interfaces.ILinuxAppLaunchAttributes;
+import org.eclipse.tcf.te.tcf.launch.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl;
+import org.eclipse.tcf.te.ui.forms.parts.AbstractSection;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * LaunchConfigurationMainTabSection
+ * @author tobias.schwarz@windriver.com
+ */
+public class LaunchConfigurationMainTabSection extends AbstractSection implements ILaunchConfigurationTabFormPart {
+
+ BaseEditBrowseTextControl processImage;
+ BaseEditBrowseTextControl processArguments;
+ IModelNode firstSelection = null;
+
+ /**
+ * Contructor.
+ *
+ * @param form The parent managed form. Must not be <code>null</code>.
+ * @param parent The parent composite. Must not be <code>null</code>.
+ */
+ public LaunchConfigurationMainTabSection(IManagedForm form, Composite parent) {
+ super(form, parent, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED);
+ getSection().setBackground(parent.getBackground());
+ createClient(getSection(), form.getToolkit());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.forms.parts.AbstractSection#createClient(org.eclipse.ui.forms.widgets.Section, org.eclipse.ui.forms.widgets.FormToolkit)
+ */
+ @Override
+ protected void createClient(final Section section, FormToolkit toolkit) {
+ Assert.isNotNull(section);
+ Assert.isNotNull(toolkit);
+
+ // Configure the section
+ section.setText(Messages.LaunchConfigurationMainTabSection_title);
+ section.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL, SWT.CENTER, true, false));
+
+ // Create the section client
+ Composite client = createClientContainer(section, 3, toolkit);
+ Assert.isNotNull(client);
+ section.setClient(client);
+ client.setBackground(section.getBackground());
+
+ // Create a toolbar for the section
+ createSectionToolbar(section, toolkit);
+
+ // Create the section sub controls
+ processImage = new BaseEditBrowseTextControl(null) {
+ @Override
+ protected void onButtonControlSelected() {
+ if (firstSelection != null) {
+ FSOpenFileDialog dialog = new FSOpenFileDialog(section.getShell());
+ dialog.setInput(firstSelection);
+ if (dialog.open() == Window.OK) {
+ Object candidate = dialog.getFirstResult();
+ if (candidate instanceof FSTreeNode) {
+ String absPath = ((FSTreeNode) candidate).getLocation();
+ if (absPath != null) {
+ processImage.setEditFieldControlText(absPath);
+ }
+ }
+ }
+ }
+ }
+ @Override
+ public void modifyText(ModifyEvent e) {
+ super.modifyText(e);
+ getManagedForm().dirtyStateChanged();
+ }
+ };
+ processImage.setEditFieldLabel(Messages.ProcessImageSelectorControl_label);
+ processImage.setIsGroup(false);
+ processImage.setHideBrowseButton(false);
+ processImage.setAdjustBackgroundColor(true);
+ processImage.setParentControlIsInnerPanel(true);
+ processImage.setFormToolkit(toolkit);
+ processImage.setupPanel(client);
+ processImage.doCreateControlDecoration(processImage.getEditFieldControl());
+
+ processArguments = new BaseEditBrowseTextControl(null) {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ super.modifyText(e);
+ getManagedForm().dirtyStateChanged();
+ }
+ };
+ processArguments.setEditFieldLabel(Messages.LaunchConfigurationMainTabSection_processArguments_label);
+ processArguments.setIsGroup(false);
+ processArguments.setHideBrowseButton(true);
+ processArguments.setAdjustBackgroundColor(true);
+ processArguments.setParentControlIsInnerPanel(true);
+ processArguments.setFormToolkit(toolkit);
+ processArguments.setupPanel(client);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.launch.ui.interfaces.ILaunchConfigurationTabFormPart#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ Assert.isNotNull(configuration);
+
+ if (processImage != null) {
+ String image = DefaultPersistenceDelegate.getAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_IMAGE, ""); //$NON-NLS-1$
+ processImage.setEditFieldControlText(image);
+ }
+
+ if (processArguments != null) {
+ String arguments = DefaultPersistenceDelegate.getAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_ARGUMENTS, ""); //$NON-NLS-1$
+ processArguments.setEditFieldControlText(arguments);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.launch.ui.interfaces.ILaunchConfigurationTabFormPart#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+ */
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ Assert.isNotNull(configuration);
+
+ if (processImage != null) {
+ String image = processImage.getEditFieldControlText();
+
+ if (image != null && image.trim().length() > 0) {
+ DefaultPersistenceDelegate.setAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_IMAGE, image);
+ } else {
+ DefaultPersistenceDelegate.setAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_IMAGE, (String)null);
+ }
+ } else {
+ DefaultPersistenceDelegate.setAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_IMAGE, (String)null);
+ }
+
+ if (processArguments != null) {
+ String arguments = processArguments.getEditFieldControlText();
+
+ if (arguments != null && arguments.trim().length() > 0) {
+ DefaultPersistenceDelegate.setAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_ARGUMENTS, arguments);
+ } else {
+ DefaultPersistenceDelegate.setAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_ARGUMENTS, (String)null);
+ }
+ } else {
+ DefaultPersistenceDelegate.setAttribute(configuration, ILinuxAppLaunchAttributes.ATTR_PROCESS_ARGUMENTS, (String)null);
+ }
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration configuration) {
+ firstSelection = null;
+ IModelNode[] contexts = ContextSelectorPersistenceDelegate.getLaunchContexts(configuration);
+ if (contexts != null && contexts.length > 0) {
+ firstSelection = contexts[0];
+ }
+ processImage.getButtonControl().setEnabled(firstSelection != null);
+
+ if (processImage.getEditFieldControlText().trim().length() > 0) {
+ setMessage(null, IMessageProvider.NONE);
+ }
+ else {
+ setMessage(Messages.ProcessImageSelectorControl_error_missingProcessImage, IMessageProvider.ERROR);
+ }
+ processImage.updateControlDecoration(getMessage(), getMessageType());
+
+ return processImage.getEditFieldControlText().trim().length() > 0;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationTabGroup.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationTabGroup.java
index 762fbbc..592d8a8 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationTabGroup.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/linux/app/LaunchConfigurationTabGroup.java
@@ -9,11 +9,30 @@
*******************************************************************************/
package org.eclipse.tcf.te.tcf.launch.ui.linux.app;
+import java.util.List;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
/**
* Remote linux application launch configuration tab group implementation.
*/
public class LaunchConfigurationTabGroup extends org.eclipse.tcf.te.launch.ui.tabs.LaunchConfigurationTabGroup {
+ /**
+ * Create the context processImage tab.
+ *
+ * @param dialog The launch configuration dialog this tab group is contained in.
+ * @param tabs The list of launch configuration tabs. Must not be <code>null</code>.
+ * @param mode The mode the launch configuration dialog was opened in.
+ */
+ @Override
+ public void createContextSelectorTab(ILaunchConfigurationDialog dialog, List<ILaunchConfigurationTab> tabs, String mode) {
+ Assert.isNotNull(tabs);
+
+ ILaunchConfigurationTab tab = new LaunchConfigurationMainTab();
+
+ tabs.add(tab);
+ }
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.java
index 5556123..dca5414 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.java
@@ -1,32 +1,38 @@
-/*******************************************************************************
- * 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.tcf.launch.ui.nls;
-
-import org.eclipse.osgi.util.NLS;
-
-/**
- * TCF Launch UI 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.tcf.launch.ui.nls.Messages"; //$NON-NLS-1$
-
- /**
- * Static constructor.
- */
- static {
- // Load message values from bundle file
- NLS.initializeMessages(BUNDLE_NAME, Messages.class);
- }
-
- // **** Declare externalized string id's down here *****
-
-}
+/*******************************************************************************
+ * 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.tcf.launch.ui.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * TCF Launch UI 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.tcf.launch.ui.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ // **** Declare externalized string id's down here *****
+
+ public static String LaunchConfigurationMainTabSection_title;
+ public static String LaunchConfigurationMainTabSection_processArguments_label;
+
+ public static String ProcessImageSelectorControl_label;
+ public static String ProcessImageSelectorControl_error_missingProcessImage;
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.properties
index 3c7310c..1cf47ce 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.launch.ui/src/org/eclipse/tcf/te/tcf/launch/ui/nls/Messages.properties
@@ -1,5 +1,10 @@
-#
-# org.eclipse.tcf.te.tcf.launch.ui
-# Externalized Strings.
-#
-
+#
+# org.eclipse.tcf.te.tcf.launch.ui
+# Externalized Strings.
+#
+
+LaunchConfigurationMainTabSection_title = Process
+LaunchConfigurationMainTabSection_processArguments_label = Arguments:
+
+ProcessImageSelectorControl_label = Process Image:
+ProcessImageSelectorControl_error_missingProcessImage = Please select or enter a process image.
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/editor/sections/GeneralInformationSection.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/editor/sections/GeneralInformationSection.java
index f60350c..118d052 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/editor/sections/GeneralInformationSection.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/editor/sections/GeneralInformationSection.java
@@ -97,7 +97,7 @@ public class GeneralInformationSection extends AbstractSection {
if (InfoSectionPeerNameControl.class.equals(adapter)) {
return nameControl;
}
- return super.getAdapter(adapter);
+ return super.getAdapter(adapter);
}
/* (non-Javadoc)
@@ -143,7 +143,7 @@ public class GeneralInformationSection extends AbstractSection {
layout.marginHeight = 0; layout.marginWidth = 0; layout.horizontalSpacing = 0;
panel.setLayout(new GridLayout(2, false));
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
- if (nameControl.getEditFieldControlDecoration() != null) {
+ if (nameControl.getControlDecoration() != null) {
layoutData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth() / 2;
}
panel.setLayoutData(layoutData);
@@ -173,7 +173,7 @@ public class GeneralInformationSection extends AbstractSection {
if (active) {
// Leave everything unchanged if the page is in dirty state
if (getManagedForm().getContainer() instanceof AbstractEditorPage
- && !((AbstractEditorPage)getManagedForm().getContainer()).isDirty()) {
+ && !((AbstractEditorPage)getManagedForm().getContainer()).isDirty()) {
Object node = ((AbstractEditorPage)getManagedForm().getContainer()).getEditorInputNode();
if (node instanceof IPeerModel) {
setupData((IPeerModel)node);
@@ -199,7 +199,9 @@ public class GeneralInformationSection extends AbstractSection {
wc.clearProperties();
// If no data is available, we are done
- if (node == null) return;
+ if (node == null) {
+ return;
+ }
// Thread access to the model is limited to the executors thread.
// Copy the data over to the working copy to ease the access.
@@ -262,7 +264,9 @@ public class GeneralInformationSection extends AbstractSection {
*/
public void extractData(final IPeerModel node) {
// If no data is available, we are done
- if (node == null) return;
+ if (node == null) {
+ return;
+ }
// Extract the widget data into the working copy
if (idControl != null) {
@@ -293,8 +297,12 @@ public class GeneralInformationSection extends AbstractSection {
try {
uri = persistenceService.getURI(attributes);
} catch (IOException e) { /* ignored on purpose */ }
- if (uri != null) attributes.put(IPersistableNodeProperties.PROPERTY_URI, uri.toString());
- else attributes.remove(IPersistableNodeProperties.PROPERTY_URI);
+ if (uri != null) {
+ attributes.put(IPersistableNodeProperties.PROPERTY_URI, uri.toString());
+ }
+ else {
+ attributes.remove(IPersistableNodeProperties.PROPERTY_URI);
+ }
}
}
// Create the new peer
@@ -302,7 +310,9 @@ public class GeneralInformationSection extends AbstractSection {
// Update the peer node instance (silently)
boolean changed = node.setChangeEventsEnabled(false);
node.setProperty(IPeerModelProperties.PROP_INSTANCE, newPeer);
- if (changed) node.setChangeEventsEnabled(true);
+ if (changed) {
+ node.setChangeEventsEnabled(true);
+ }
}
});
}
@@ -313,7 +323,7 @@ public class GeneralInformationSection extends AbstractSection {
*/
@Override
public boolean isValid() {
- boolean valid = super.isValid();
+ boolean valid = super.isValid();
if (idControl != null) {
valid &= idControl.isValid();
@@ -338,10 +348,12 @@ public class GeneralInformationSection extends AbstractSection {
// Remember the current dirty state
boolean needsSaving = isDirty();
// Call the super implementation (resets the dirty state)
- super.commit(onSave);
+ super.commit(onSave);
// Nothing to do if not on save or saving is not needed
- if (!onSave || !needsSaving) return;
+ if (!onSave || !needsSaving) {
+ return;
+ }
// Remember the old name
String oldName = odc.getStringProperty(IPeer.ATTR_NAME);
@@ -353,7 +365,10 @@ public class GeneralInformationSection extends AbstractSection {
try {
// Get the persistence service
IPersistenceService persistenceService = ServiceManager.getInstance().getService(IPersistenceService.class);
- if (persistenceService == null) throw new IOException("Persistence service instance unavailable."); //$NON-NLS-1$
+ if (persistenceService == null)
+ {
+ throw new IOException("Persistence service instance unavailable."); //$NON-NLS-1$
+ }
// Remove the old persistence storage using the original data copy
persistenceService.delete(odc.getProperties());
// Save the peer node to the new persistence storage
@@ -414,7 +429,9 @@ public class GeneralInformationSection extends AbstractSection {
final Object input = getManagedForm().getInput();
// The id control is always read-only
- if (idControl != null) SWTControlUtil.setEnabled(idControl.getEditFieldControl(), false);
+ if (idControl != null) {
+ SWTControlUtil.setEnabled(idControl.getEditFieldControl(), false);
+ }
// The name control is enabled for static peers
if (nameControl != null) {
@@ -432,8 +449,12 @@ public class GeneralInformationSection extends AbstractSection {
}
}
};
- if (Protocol.isDispatchThread()) runnable.run();
- else Protocol.invokeAndWait(runnable);
+ if (Protocol.isDispatchThread()) {
+ runnable.run();
+ }
+ else {
+ Protocol.invokeAndWait(runnable);
+ }
SWTControlUtil.setEnabled(nameControl.getEditFieldControl(), isStatic.get() && !isRemote.get());
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/AbstractDecoratedDialogPageControl.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/AbstractDecoratedDialogPageControl.java
new file mode 100644
index 0000000..db3abfe
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.controls/src/org/eclipse/tcf/te/ui/controls/AbstractDecoratedDialogPageControl.java
@@ -0,0 +1,120 @@
+/*
+ * AbstractDecoratedDialogPageControl.java
+ * Created on 05.03.2012
+ *
+ * Copyright 2012 Wind River Systems Inc. All rights reserved.
+ */
+package org.eclipse.tcf.te.ui.controls;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.IDialogPage;
+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.widgets.Control;
+
+/**
+ * AbstractDecoratedDialogPageControl
+ * @author tobias.schwarz@windriver.com
+ */
+public abstract class AbstractDecoratedDialogPageControl extends BaseDialogPageControl {
+
+ private ControlDecoration controlDecoration;
+
+ /**
+ * Constructor.
+ */
+ public AbstractDecoratedDialogPageControl() {
+ }
+
+ /**
+ * Constructor.
+ * @param parentPage
+ */
+ public AbstractDecoratedDialogPageControl(IDialogPage parentPage) {
+ super(parentPage);
+ }
+
+ /**
+ * Creates a new instance of a {@link ControlDecoration} object associated with
+ * the given control. The method is called after the control has been created.
+ *
+ * @param control The control. Must not be <code>null</code>.
+ * @return The control decoration object instance.
+ */
+ public ControlDecoration doCreateControlDecoration(Control control) {
+ Assert.isNotNull(control);
+ controlDecoration = new ControlDecoration(control, doGetControlDecorationPosition());
+ return controlDecoration;
+ }
+
+ /**
+ * Returns the control decoration position. The default is
+ * {@link SWT#TOP} | {@link SWT#LEFT}.
+ *
+ * @return The control position.
+ */
+ protected int doGetControlDecorationPosition() {
+ return SWT.TOP | SWT.LEFT;
+ }
+
+ /**
+ * Configure the given control decoration.
+ *
+ * @param decoration The control decoration. Must not be <code>null</code>.
+ */
+ protected void configureControlDecoration(ControlDecoration decoration) {
+ Assert.isNotNull(decoration);
+ decoration.setShowOnlyOnFocus(false);
+ }
+
+ /**
+ * Updates the control decoration to represent the given message and message type.
+ * If the message is <code>null</code> or the message type is IMessageProvider.NONE,
+ * no decoration will be shown.
+ *
+ * @param message The message.
+ * @param messageType The message type.
+ */
+ public void updateControlDecoration(String message, int messageType) {
+ if (getControlDecoration() != null) {
+ // The description is the same as the message
+ getControlDecoration().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) {
+ getControlDecoration().setImage(fieldDeco.getImage());
+ }
+
+ if (message == null || messageType == IMessageProvider.NONE) {
+ getControlDecoration().hide();
+ }
+ else {
+ getControlDecoration().show();
+ }
+ }
+ }
+
+ /**
+ * Returns the control decoration.
+ *
+ * @return The control decoration instance or <code>null</code> if not yet created.
+ */
+ public final ControlDecoration getControlDecoration() {
+ return controlDecoration;
+ }
+}
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
index b978d3d..c6b6a2c 100644
--- 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
@@ -1,1499 +1,1440 @@
-/*******************************************************************************
- * 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.jface.interfaces.IValidatingContainer;
-import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
-import org.eclipse.tcf.te.ui.utils.DialogSettingsUtil;
-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
- IValidatingContainer validatingContainer = getValidatingContainer();
- if (validatingContainer != null) validatingContainer.validate();
- }
- }
-
- /**
- * 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
- IValidatingContainer validatingContainer = getValidatingContainer();
- if (validatingContainer != null) validatingContainer.validate();
- }
-
- /**
- * 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
- IValidatingContainer validatingContainer = getValidatingContainer();
- if (validatingContainer != null) validatingContainer.validate();
- }
-
- /**
- * 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;
- }
-}
+/*******************************************************************************
+ * 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.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.jface.interfaces.IValidatingContainer;
+import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
+import org.eclipse.tcf.te.ui.utils.DialogSettingsUtil;
+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 AbstractDecoratedDialogPageControl 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 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 (getControlDecoration() != null) {
+ if (enabled && getControlDecoration().getDescriptionText() != null) {
+ getControlDecoration().show();
+ } else {
+ getControlDecoration().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
+ IValidatingContainer validatingContainer = getValidatingContainer();
+ if (validatingContainer != null) {
+ validatingContainer.validate();
+ }
+ }
+ }
+
+ /**
+ * 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 (getControlDecoration() != 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;
+ }
+
+ /**
+ * 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
+ IValidatingContainer validatingContainer = getValidatingContainer();
+ if (validatingContainer != null) {
+ validatingContainer.validate();
+ }
+ }
+
+ /**
+ * 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
+ IValidatingContainer validatingContainer = getValidatingContainer();
+ if (validatingContainer != null) {
+ validatingContainer.validate();
+ }
+ }
+
+ /**
+ * 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);
+ if (isAdjustBackgroundColor()) {
+ SWTControlUtil.setBackground(button, button.getParent().getBackground());
+ }
+ // 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 controlDecoration = doCreateControlDecoration(editFieldControl);
+ Assert.isNotNull(controlDecoration);
+ configureControlDecoration(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())) { //$NON-NLS-1$
+ setEditFieldControlText(historyEntries[0]);
+ }
+ }
+ }
+
+ /**
+ * 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 (getControlDecoration() != null) {
+ // Setup and show the control decoration if necessary
+ if (isEnabled() && (!valid || (getMessage() != null && getMessageType() != IMessageProvider.NONE))) {
+ // Update the control decorator
+ updateControlDecoration(getMessage(), getMessageType());
+ } else {
+ updateControlDecoration(null, IMessageProvider.NONE);
+ }
+ }
+
+ return valid;
+ }
+}
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
index 5a013bb..efa4435 100644
--- 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
@@ -1,229 +1,229 @@
-/*******************************************************************************
- * 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
- if (parentPage != null) {
- 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);
- }
- }
-}
+/*******************************************************************************
+ * 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 (getControlDecoration() != null) {
+ getControlDecoration().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
+ if (parentPage != null) {
+ 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);
+ }
+ }
+}