Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarin Wright2002-11-21 16:41:53 +0000
committerDarin Wright2002-11-21 16:41:53 +0000
commit17dfba30565cd64599266cd080fc0d539142c370 (patch)
treebfe4c9fbce3f9739b3578d5de0c53b307e14639f /org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java
parentc74282fb4de2518e5958122850b661b66f139c25 (diff)
downloadeclipse.platform.debug-17dfba30565cd64599266cd080fc0d539142c370.tar.gz
eclipse.platform.debug-17dfba30565cd64599266cd080fc0d539142c370.tar.xz
eclipse.platform.debug-17dfba30565cd64599266cd080fc0d539142c370.zip
bug 19674 - refactor LCD
Diffstat (limited to 'org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java')
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java1748
1 files changed, 1748 insertions, 0 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java
new file mode 100644
index 000000000..96552fe28
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java
@@ -0,0 +1,1748 @@
+package org.eclipse.debug.internal.ui.launchConfigurations;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+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.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
+import org.eclipse.debug.internal.ui.PixelConverter;
+import org.eclipse.debug.internal.ui.SWTUtil;
+import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.ControlEnableState;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.wizard.ProgressMonitorPart;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+
+/**
+ * The dialog used to edit and launch launch configurations.
+ */
+public class LaunchConfigurationsDialog extends TitleAreaDialog implements ILaunchConfigurationDialog {
+
+ /**
+ * Keep track of the currently visible dialog instance */
+ private static ILaunchConfigurationDialog fgCurrentlyVisibleLaunchConfigurationDialog;
+
+ /**
+ * The label appearing above tree of configs & config types.
+ */
+ private Label fTreeLabel;
+
+ /**
+ * The workbench context present when this dialog is opened.
+ */
+ private Object fContext;
+
+ /**
+ * The Composite used to insert an adjustable 'sash' between the tree and the tabs.
+ */
+ private SashForm fSashForm;
+
+ /**
+ * Default weights for the SashForm that specify how wide the selection and
+ * edit areas aree relative to each other.
+ */
+ private static final int[] DEFAULT_SASH_WEIGHTS = new int[] {11, 30};
+
+ /**
+ * The launch configuration selection area.
+ */
+ private Composite fSelectionArea;
+
+ /**
+ * Tree view of launch configurations
+ */
+ private LaunchConfigurationView fLaunchConfigurationView;
+
+ /**
+ * Tab edit area
+ */
+ private LaunchConfigurationTabGroupViewer fTabViewer;
+
+ /**
+ * True while setting the input to the tab viewer
+ */
+ private boolean fInitializingTabs;
+
+ /**
+ * The launch configuration edit area.
+ */
+ private Composite fEditArea;
+
+ /**
+ * The 'New configuration' action.
+ */
+ private ButtonAction fButtonActionNew;
+
+ /**
+ * The 'Delete configuration' action.
+ */
+ private ButtonAction fButtonActionDelete;
+
+ /**
+ * The 'cancel' button that appears when the in-dialog progress monitor is shown.
+ */
+ private Button fProgressMonitorCancelButton;
+
+ /**
+ * Flag indicating if the progress monitor part's Cancel button has been pressed.
+ */
+ private boolean fCancelButtonPressed;
+
+ /**
+ * Clients of this dialog may set an 'initial configuration type', which means that when
+ * the dialog is opened, a configuration of that type will be created, initialized, and
+ * saved. Note that the initial config type is ignored if single-click launching is enabled.
+ */
+ private ILaunchConfigurationType fInitialConfigType;
+
+ /**
+ * When this dialog is opened in <code>LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION</code>
+ * mode, this specifies the selection that is initially shown in the dialog.
+ */
+ private IStructuredSelection fInitialSelection;
+
+ private ProgressMonitorPart fProgressMonitorPart;
+ private Cursor waitCursor;
+ private Cursor arrowCursor;
+ private MessageDialog fWindowClosingDialog;
+
+ /**
+ * The number of 'long-running' operations currently taking place in this dialog
+ */
+ private long fActiveRunningOperations = 0;
+
+ /**
+ * The launch groupd being displayed
+ */
+ private LaunchGroupExtension fGroup;
+
+ /**
+ * Banner image
+ */
+ private Image fBannerImage;
+
+ /**
+ * Double-click action
+ */
+ private IAction fDoubleClickAction;
+
+ /**
+ * Id for 'Launch' button.
+ */
+ protected static final int ID_LAUNCH_BUTTON = IDialogConstants.CLIENT_ID + 1;
+
+ /**
+ * Id for 'Close' button.
+ */
+ protected static final int ID_CLOSE_BUTTON = IDialogConstants.CLIENT_ID + 2;
+
+ /**
+ * Id for 'Cancel' button.
+ */
+ protected static final int ID_CANCEL_BUTTON = IDialogConstants.CLIENT_ID + 3;
+
+ /**
+ * Constrant String used as key for setting and retrieving current Control with focus
+ */
+ private static final String FOCUS_CONTROL = "focusControl";//$NON-NLS-1$
+
+ /**
+ * The height in pixels of this dialog's progress indicator
+ */
+ private static int PROGRESS_INDICATOR_HEIGHT = 18;
+
+ /**
+ * Constant specifying how wide this dialog is allowed to get (as a percentage of
+ * total available screen width) as a result of tab labels in the edit area.
+ */
+ private static final float MAX_DIALOG_WIDTH_PERCENT = 0.75f;
+
+ /**
+ * Empty array
+ */
+ protected static final Object[] EMPTY_ARRAY = new Object[0];
+
+ protected static final String DEFAULT_NEW_CONFIG_NAME = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.New_configuration_1"); //$NON-NLS-1$
+
+ /**
+ * Size of this dialog if there is no preference specifying a size.
+ */
+ protected static final Point DEFAULT_INITIAL_DIALOG_SIZE = new Point(620, 560);
+
+ /**
+ * Status area messages
+ */
+ protected static final String LAUNCH_STATUS_OK_MESSAGE = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Ready_to_launch_2"); //$NON-NLS-1$
+ protected static final String LAUNCH_STATUS_STARTING_FROM_SCRATCH_MESSAGE
+ = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Select_a_configuration_to_launch_or_a_config_type_to_create_a_new_configuration_3"); //$NON-NLS-1$
+
+ /**
+ * Constant specifying that the launch configuration dialog should not actually open,
+ * but instead should attempt to re-launch the last configuration that was sucessfully
+ * launched in the workspace. If there is no last launched configuration, just open the dialog.
+ */
+ public static final int LAUNCH_CONFIGURATION_DIALOG_LAUNCH_LAST = 0;
+
+ /**
+ * Constant specifying that this dialog should be opened with the last configuration launched
+ * in the workspace selected.
+ */
+ public static final int LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED = 2;
+
+ /**
+ * Constant specifying that this dialog should be opened with the value specified via
+ * <code>setInitialSelection()</code> selected.
+ */
+ public static final int LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION = 3;
+
+ /**
+ * Constant specifying that a new launch configuration dialog was not opened. Instead
+ * an existing launch configuration dialog was used. */
+ public static final int LAUNCH_CONFIGURATION_DIALOG_REUSE_OPEN = 4;
+
+ /**
+ * Specifies how this dialog behaves when opened. Value is one of the
+ * 'LAUNCH_CONFIGURATION_DIALOG' constants defined in this class.
+ */
+ private int fOpenMode = LAUNCH_CONFIGURATION_DIALOG_LAUNCH_LAST;
+
+ /**
+ * Constructs a new launch configuration dialog on the given
+ * parent shell.
+ *
+ * @param shell the parent shell
+ * @param selection the selection used to initialize this dialog, typically the
+ * current workbench selection
+ * @param mode one of <code>ILaunchManager.RUN_MODE</code> or
+ * <code>ILaunchManager.DEBUG_MODE</code>
+ */
+ public LaunchConfigurationsDialog(Shell shell, IStructuredSelection selection, LaunchGroupExtension group) {
+ super(shell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ setLaunchGroup(group);
+ }
+
+ /**
+ * Set the flag indicating how this dialog behaves when the <code>open()</code> method is called.
+ * Valid values are defined by the LAUNCH_CONFIGURATION_DIALOG... constants in this class.
+ */
+ public void setOpenMode(int mode) {
+ fOpenMode = mode;
+ }
+
+ protected int getOpenMode() {
+ return fOpenMode;
+ }
+
+ /**
+ * A launch configuration dialog overrides this method
+ * to create a custom set of buttons in the button bar.
+ * This dialog has 'Launch' and 'Cancel'
+ * buttons.
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(Composite)
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, ID_LAUNCH_BUTTON, getLaunchButtonText(), true);
+ createButton(parent, ID_CLOSE_BUTTON, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Close_1"), false); //$NON-NLS-1$
+ }
+
+ /**
+ * Handle the 'save and launch' & 'launch' buttons here, all others are handled
+ * in <code>Dialog</code>
+ *
+ * @see Dialog#buttonPressed(int)
+ */
+ protected void buttonPressed(int buttonId) {
+ if (buttonId == ID_LAUNCH_BUTTON) {
+ handleLaunchPressed();
+ } else if (buttonId == ID_CLOSE_BUTTON) {
+ handleClosePressed();
+ } else {
+ super.buttonPressed(buttonId);
+ }
+ }
+
+ /**
+ * Returns the appropriate text for the launch button - run or debug.
+ */
+ private String getLaunchButtonText() {
+ if (getMode().equals(ILaunchManager.DEBUG_MODE)) {
+ return LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Deb&ug_4"); //$NON-NLS-1$
+ } else {
+ return LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.R&un_5"); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * @see Dialog#createContents(Composite)
+ */
+ protected Control createContents(Composite parent) {
+ Control contents = super.createContents(parent);
+ initializeBounds();
+ initializeSashForm();
+ ensureSelectionAreaWidth();
+ initializeWorkingSet();
+ doInitialTreeSelection();
+ return contents;
+ }
+
+ /**
+ * Initialize the relative weights (widths) of the 2 sides of the sash.
+ */
+ private void initializeSashForm() {
+ int[] sashWeights = DEFAULT_SASH_WEIGHTS;
+ String sashWeightString = getPreferenceStore().getString(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SASH_WEIGHTS);
+ if (sashWeightString.length() > 0) {
+ Point sashWeightPoint = parseCoordinates(sashWeightString);
+ if (sashWeightPoint != null) {
+ sashWeights[0] = sashWeightPoint.x;
+ sashWeights[1] = sashWeightPoint.y;
+ }
+ }
+ getSashForm().setWeights(sashWeights);
+ }
+
+ /**
+ * Retrieve the last working set in use and apply it to the tree.
+ */
+ private void initializeWorkingSet() {
+ String workingSetName = getPreferenceStore().getString(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_WORKING_SET_NAME);
+ IWorkingSet workingSet = getWorkingSetManager().getWorkingSet(workingSetName);
+ if (workingSet != null) {
+ getWorkingSetActionManager().setWorkingSet(workingSet, true);
+ }
+ }
+
+ /**
+ * Check if the selection area is currently wide enough so that both the 'New' &
+ * 'Delete' buttons are shown without truncation. If so, do nothing. Otherwise,
+ * increase the width of this dialog's Shell just enough so that both buttons
+ * are shown cleanly.
+ */
+ private void ensureSelectionAreaWidth() {
+ Button newButton = getButtonActionNew().getButton();
+ Button deleteButton = getButtonActionDelete().getButton();
+ int requiredWidth = newButton.getBounds().width + deleteButton.getBounds().width;
+ int marginWidth = ((GridLayout)getSelectionArea().getLayout()).marginWidth;
+ int horizontalSpacing = ((GridLayout)getSelectionArea().getLayout()).horizontalSpacing;
+ requiredWidth += (2 * marginWidth) + horizontalSpacing;
+ int currentWidth = getSelectionArea().getBounds().width;
+
+ if (requiredWidth > currentWidth) {
+ int[] newSashWeights = new int[2];
+ newSashWeights[0] = requiredWidth;
+ newSashWeights[1] = getEditArea().getBounds().width;
+ Shell shell= getShell();
+ Point shellSize= shell.getSize();
+ setShellSize(shellSize.x + (requiredWidth - currentWidth), shellSize.y);
+ getSashForm().setWeights(newSashWeights);
+ }
+ }
+
+ /**
+ * Set the initial selection in the tree.
+ */
+ public void doInitialTreeSelection() {
+ fLaunchConfigurationView.getViewer().setSelection(getInitialSelection());
+ }
+
+ /**
+ * Write out this dialog's Shell size, location & sash weights to the preference store.
+ */
+ private void persistShellGeometry() {
+ Point shellLocation = getShell().getLocation();
+ Point shellSize = getShell().getSize();
+ int[] sashWeights = getSashForm().getWeights();
+ String locationString = serializeCoords(shellLocation);
+ String sizeString = serializeCoords(shellSize);
+ String sashWeightString = serializeCoords(new Point(sashWeights[0], sashWeights[1]));
+ getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_LOCATION, locationString);
+ getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SIZE, sizeString);
+ getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SASH_WEIGHTS, sashWeightString);
+ }
+
+ /**
+ * Store the current working set.
+ */
+ private void persistWorkingSet() {
+ IWorkingSet workingSet = getWorkingSetActionManager().getWorkingSet();
+ if (workingSet != null) {
+ getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_WORKING_SET_NAME, workingSet.getName());
+ } else {
+ getPreferenceStore().setToDefault(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_WORKING_SET_NAME);
+ }
+ }
+
+ /**
+ * @see Window#close()
+ */
+ public boolean close() {
+ persistShellGeometry();
+ persistWorkingSet();
+ setCurrentlyVisibleLaunchConfigurationDialog(null);
+ getBannerImage().dispose();
+ fTabViewer.dispose();
+ fLaunchConfigurationView.dispose();
+ return super.close();
+ }
+
+ /**
+ * Determine the first configuration for this dialog. If single-click launching is
+ * enabled, launch the configuration WITHOUT realizing the dialog. If single-click
+ * launching was successful, this method returns
+ * <code>ILaunchConfigurationDialog.SINGLE_CLICK_LAUNCHED</code>. Otherwise, open the
+ * dialog in the specified mode.
+ *
+ * @see Window#open()
+ */
+ public int open() {
+ int mode = getOpenMode();
+ if (mode == LAUNCH_CONFIGURATION_DIALOG_LAUNCH_LAST) {
+ return doLastLaunchedConfig(true);
+ } else if (mode == LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED) {
+ return doLastLaunchedConfig(false);
+ } else if (mode == LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION) {
+ return openDialogOnSelection();
+ }
+ return super.open();
+ }
+
+ /**
+ * Retrieve the last launched configuration in the workspace. If <code>launch</code>
+ * is <code>true</code>, launch this configuration without showing the dialog, otherwise
+ * just set the initial selection in the dialog to the last launched configuration.
+ */
+ protected int doLastLaunchedConfig(boolean launch) {
+ ILaunchConfiguration lastLaunchedConfig = getLastLaunchedWorkbenchConfiguration();
+ if (launch) {
+ try {
+ if (lastLaunchedConfig != null) {
+ if (lastLaunchedConfig.supportsMode(getMode())) {
+ doLaunch(lastLaunchedConfig);
+ } else {
+ // If we're trying to launch, but the last launched config doesn't
+ // support the current mode of the dialog, show an error dialog
+ String configName = lastLaunchedConfig.getName();
+ String title = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cannot_relaunch_1"); //$NON-NLS-1$
+ String message = MessageFormat.format(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cannot_relaunch_[{1}]_because_it_does_not_support_{2}_mode_2"), new String[] {configName, getMode()}); //$NON-NLS-1$
+ MessageDialog.openError(getShell(), title, message);
+ }
+ return ILaunchConfigurationDialog.LAUNCHED_BEFORE_OPENING;
+ }
+ } catch(CoreException e) {
+ DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configuration_Error_6"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_processing_launch_configuration._See_log_for_more_information_7"), e); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ setCurrentlyVisibleLaunchConfigurationDialog(this);
+ if (lastLaunchedConfig != null) {
+ setInitialSelection(new StructuredSelection(lastLaunchedConfig));
+ }
+ return super.open();
+ }
+
+ /**
+ * Open this dialog with the selection set to the value specified by
+ * <code>setInitialSelection()</code>.
+ */
+ protected int openDialogOnSelection() {
+ // Nothing special is required, the dialog will open and whatever was specified
+ // via setInitialSelection() will be selected in the tree
+ setCurrentlyVisibleLaunchConfigurationDialog(this);
+ return super.open();
+ }
+
+ /**
+ * Return the last launched configuration in the workspace.
+ */
+ protected ILaunchConfiguration getLastLaunchedWorkbenchConfiguration() {
+ return DebugUIPlugin.getLaunchConfigurationManager().getLastLaunch(getLaunchGroup().getIdentifier());
+ }
+
+ /**
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(Composite)
+ */
+ protected Control createDialogArea(Composite parent) {
+ GridData gd;
+ Composite dialogComp = (Composite)super.createDialogArea(parent);
+ Composite topComp = new Composite(dialogComp, SWT.NONE);
+ gd = new GridData(GridData.FILL_BOTH);
+ topComp.setLayoutData(gd);
+ GridLayout topLayout = new GridLayout();
+ topLayout.numColumns = 2;
+ topLayout.marginHeight = 5;
+ topLayout.marginWidth = 0;
+ topComp.setLayout(topLayout);
+
+ // Set the things that TitleAreaDialog takes care of
+ setTitle(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Create,_manage,_and_run_launch_configurations_8")); //$NON-NLS-1$
+ setMessage(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Ready_to_launch_2")); //$NON-NLS-1$
+ setModeLabelState();
+
+ // Create the SashForm that contains the selection area on the left,
+ // and the edit area on the right
+ setSashForm(new SashForm(topComp, SWT.NONE));
+ getSashForm().setOrientation(SWT.HORIZONTAL);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 2;
+ getSashForm().setLayoutData(gd);
+
+ // Build the launch configuration selection area and put it into the composite.
+ Control launchConfigSelectionArea = createLaunchConfigurationSelectionArea(getSashForm());
+ gd = new GridData(GridData.FILL_VERTICAL);
+ launchConfigSelectionArea.setLayoutData(gd);
+
+ // Build the launch configuration edit area and put it into the composite.
+ Composite editAreaComp = createLaunchConfigurationEditArea(getSashForm());
+ setEditArea(editAreaComp);
+ gd = new GridData(GridData.FILL_BOTH);
+ editAreaComp.setLayoutData(gd);
+
+ // Build the separator line that demarcates the button bar
+ Label separator = new Label(topComp, SWT.HORIZONTAL | SWT.SEPARATOR);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ separator.setLayoutData(gd);
+
+ dialogComp.layout(true);
+
+ return dialogComp;
+ }
+
+ /**
+ * Set the title area image based on the mode this dialog was initialized with
+ */
+ protected void setModeLabelState() {
+ setTitleImage(getBannerImage());
+ }
+
+ /**
+ * Update buttons and message.
+ */
+ protected void refreshStatus() {
+ updateButtons();
+ updateMessage();
+ fTabViewer.refresh();
+ }
+
+ private Display getDisplay() {
+ Shell shell = getShell();
+ if (shell != null) {
+ return shell.getDisplay();
+ } else {
+ return Display.getDefault();
+ }
+ }
+
+ /**
+ * Creates the launch configuration selection area of the dialog.
+ * This area displays a tree of launch configurations that the user
+ * may select, and allows users to create new configurations, and
+ * delete and duplicate existing configurations.
+ *
+ * @return the composite used for launch configuration selection area
+ */
+ private Control createLaunchConfigurationSelectionArea(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ setSelectionArea(comp);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ layout.marginHeight = 0;
+ layout.marginWidth = 5;
+ comp.setLayout(layout);
+
+ setTreeLabel(new Label(comp, SWT.NONE));
+ GridData gd = new GridData();
+ gd.horizontalSpan = 3;
+ getTreeLabel().setLayoutData(gd);
+ getTreeLabel().setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Con&figurations__1")); //$NON-NLS-1$
+ // TODO: tooltip
+ //updateTreeLabelTooltip();
+
+ fLaunchConfigurationView = new LaunchConfigurationView(getLaunchGroup());
+ fLaunchConfigurationView.createLaunchDialogControl(comp);
+ Viewer viewer = fLaunchConfigurationView.getViewer();
+ Control control = viewer.getControl();
+
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 3;
+ // Set width hint to 0 to force tree to only be as wide as the combined
+ // width of the 'New' & 'Delete' buttons. Otherwise tree wants to be much wider.
+ gd.widthHint = 0;
+ control.setLayoutData(gd);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ /**
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ handleLaunchConfigurationSelectionChanged(event);
+ }
+ });
+
+ fDoubleClickAction = new DoubleClickAction();
+ fLaunchConfigurationView.setAction(IDebugView.DOUBLE_CLICK_ACTION, fDoubleClickAction);
+
+ Button newButton = SWTUtil.createPushButton(comp, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Ne&w_13"), null); //$NON-NLS-1$
+ setButtonActionNew(new ButtonActionNew(newButton.getText(), newButton));
+
+ Button deleteButton = SWTUtil.createPushButton(comp, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Dele&te_14"), null); //$NON-NLS-1$
+ setButtonActionDelete(new ButtonActionDelete(deleteButton.getText(), deleteButton));
+
+ AbstractLaunchConfigurationAction.IConfirmationRequestor requestor =
+ new AbstractLaunchConfigurationAction.IConfirmationRequestor() {
+ /**
+ * @see org.eclipse.debug.internal.ui.launchConfigurations.AbstractLaunchConfigurationAction.IConfirmationRequestor#getConfirmation()
+ */
+ public boolean getConfirmation() {
+ return canDiscardCurrentConfig();
+ }
+ };
+
+ // confirmation requestors
+ getDuplicateAction().setConfirmationRequestor(requestor);
+ getNewAction().setConfirmationRequestor(requestor);
+
+ return comp;
+ }
+
+ /**
+ * Creates the launch configuration edit area of the dialog.
+ * This area displays the name of the launch configuration
+ * currently being edited, as well as a tab folder of tabs
+ * that are applicable to the launch configuration.
+ *
+ * @return the composite used for launch configuration editing
+ */
+ private Composite createLaunchConfigurationEditArea(Composite parent) {
+ fTabViewer = new LaunchConfigurationTabGroupViewer(parent, this);
+ fTabViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ /**
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ handleTabSelectionChanged(event);
+ }
+ });
+ return (Composite)fTabViewer.getControl();
+ }
+
+ /**
+ * @see Dialog#createButtonBar(Composite)
+ */
+ protected Control createButtonBar(Composite parent) {
+ Composite composite= new Composite(parent, SWT.NULL);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ GridLayout pmLayout = new GridLayout();
+ pmLayout.numColumns = 3;
+ setProgressMonitorPart(new ProgressMonitorPart(composite, pmLayout, PROGRESS_INDICATOR_HEIGHT));
+ Button cancelButton = createButton(getProgressMonitorPart(), ID_CANCEL_BUTTON, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cancel_3"), true); //$NON-NLS-1$
+ setProgressMonitorCancelButton(cancelButton);
+ getProgressMonitorCancelButton().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ setCancelButtonPressed(true);
+ }
+ });
+ getProgressMonitorPart().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ getProgressMonitorPart().setVisible(false);
+
+ return super.createButtonBar(composite);
+ }
+
+ /**
+ * Sets the title for the dialog, and establishes the help context.
+ *
+ * @see org.eclipse.jface.window.Window#configureShell(Shell);
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ String title = getLaunchGroup().getLabel();
+ if (title == null) {
+ title = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configurations_18"); //$NON-NLS-1$
+ }
+ shell.setText(title);
+ WorkbenchHelp.setHelp(
+ shell,
+ IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG);
+ }
+
+ /**
+ * @see Window#getInitialLocation(Point)
+ */
+ protected Point getInitialLocation(Point initialSize) {
+ String locationString = getPreferenceStore().getString(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_LOCATION);
+ if (locationString.length() > 0) {
+ Point locationPoint = parseCoordinates(locationString);
+ if (locationPoint != null) {
+ return locationPoint;
+ }
+ }
+ return super.getInitialLocation(initialSize);
+ }
+
+ /**
+ * @see Window#getInitialSize()
+ */
+ protected Point getInitialSize() {
+ String sizeString = getPreferenceStore().getString(IDebugPreferenceConstants.PREF_LAUNCH_CONFIGURATION_DIALOG_SIZE);
+ if (sizeString.length() > 0) {
+ Point sizePoint = parseCoordinates(sizeString);
+ if (sizePoint != null) {
+ return sizePoint;
+ }
+ }
+ return DEFAULT_INITIAL_DIALOG_SIZE;
+ }
+
+ /**
+ * Given a coordinate String of the form "123x456" return a Point object whose
+ * X value is 123 and Y value is 456. Return <code>null</code> if the String
+ * is not in the specified form.
+ */
+ private Point parseCoordinates(String coordString) {
+ int byIndex = coordString.indexOf('x');
+ if (byIndex < 0) {
+ return null;
+ }
+
+ try {
+ int x = Integer.parseInt(coordString.substring(0, byIndex));
+ int y = Integer.parseInt(coordString.substring(byIndex + 1));
+ return new Point(x, y);
+ } catch (NumberFormatException nfe) {
+ return null;
+ }
+ }
+
+ /**
+ * Given a Point object, return a String of the form "XCoordxYCoord".
+ */
+ private String serializeCoords(Point coords) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(coords.x);
+ buffer.append('x');
+ buffer.append(coords.y);
+ return buffer.toString();
+ }
+
+ private void setSashForm(SashForm sashForm) {
+ fSashForm = sashForm;
+ }
+
+ private SashForm getSashForm() {
+ return fSashForm;
+ }
+
+ /**
+ * Returns the launch manager.
+ *
+ * @return the launch manager
+ */
+ private ILaunchManager getLaunchManager() {
+ return DebugPlugin.getDefault().getLaunchManager();
+ }
+
+ private IWorkingSetManager getWorkingSetManager() {
+ return PlatformUI.getWorkbench().getWorkingSetManager();
+ }
+
+ /**
+ * Returns whether this dialog is currently open
+ */
+ private boolean isVisible() {
+ return fEditArea != null;
+ }
+
+ /**
+ * Notification that selection has changed in the launch configuration tree.
+ * <p>
+ * If the currently displayed configuration is not saved,
+ * prompt for saving before moving on to the new selection.
+ * </p>
+ *
+ * @param event selection changed event
+ */
+ protected void handleLaunchConfigurationSelectionChanged(SelectionChangedEvent event) {
+
+ Object input = fTabViewer.getInput();
+ Object newInput = null;
+ ISelection selection = event.getSelection();
+ if (!selection.isEmpty()) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+ if (structuredSelection.size() == 1) {
+ newInput = structuredSelection.getFirstElement();
+ }
+ }
+ }
+ updateButtons();
+
+ if (!isEqual(input, newInput)) {
+ ILaunchConfigurationTabGroup group = getTabGroup();
+ if (fTabViewer.isDirty() && fTabViewer.getOriginal().exists()) {
+ boolean canReplace = showSaveChangesDialog();
+ if (!canReplace) {
+ // restore the original selection
+ IStructuredSelection sel = new StructuredSelection(fTabViewer.getOriginal());
+ fLaunchConfigurationView.getViewer().setSelection(sel);
+ return;
+ }
+ }
+ setInitializingTabs(true);
+ fTabViewer.setInput(newInput);
+ setInitializingTabs(false);
+ refreshStatus();
+ ILaunchConfigurationTabGroup newGroup = getTabGroup();
+ if (!isEqual(group, newGroup)) {
+ resize();
+ }
+ }
+ }
+
+ protected boolean isEqual(Object o1, Object o2) {
+ if (o1 == o2) {
+ return true;
+ } else if (o1 == null) {
+ return false;
+ } else {
+ return o1.equals(o2);
+ }
+ }
+
+
+ protected void resize() {
+ // determine the maximum tab dimensions
+ PixelConverter pixelConverter = new PixelConverter(getEditArea());
+ int runningTabWidth = 0;
+ ILaunchConfigurationTabGroup group = getTabGroup();
+ if (group == null) {
+ return;
+ }
+ ILaunchConfigurationTab[] tabs = group.getTabs();
+ Point contentSize = new Point(0, 0);
+ for (int i = 0; i < tabs.length; i++) {
+ String name = tabs[i].getName();
+ Image image = tabs[i].getImage();
+ runningTabWidth += pixelConverter.convertWidthInCharsToPixels(name.length() + 5);
+ if (image != null) {
+ runningTabWidth += image.getBounds().width;
+ }
+ Control control = tabs[i].getControl();
+ if (control != null) {
+ Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ if (size.x > contentSize.x) {
+ contentSize.x = size.x;
+ }
+ if (size.y > contentSize.y) {
+ contentSize.y = size.y;
+ }
+ }
+ }
+
+ // Determine if more space is needed to show all tab labels across the top of the
+ // tab folder. If so, only increase size of dialog to some percent of the available
+ // screen real estate.
+ if (runningTabWidth > contentSize.x) {
+ int maxAllowedWidth = (int) (getDisplay().getBounds().width * MAX_DIALOG_WIDTH_PERCENT);
+ int otherWidth = getSashForm().SASH_WIDTH + getSelectionArea().getBounds().width;
+ int totalWidth = runningTabWidth + otherWidth;
+ if (totalWidth > maxAllowedWidth) {
+ contentSize.x = maxAllowedWidth - otherWidth;
+ } else {
+ contentSize.x = runningTabWidth;
+ }
+ }
+
+ // Adjust the maximum tab dimensions to account for the extra space required for the tab labels
+ Rectangle tabFolderBoundingBox = getEditArea().computeTrim(0, 0, contentSize.x, contentSize.y);
+ contentSize.x = tabFolderBoundingBox.width;
+ contentSize.y = tabFolderBoundingBox.height;
+
+ // Force recalculation of sizes
+ getEditArea().layout(true);
+
+ // Calculate difference between required space for tab folder and current size,
+ // then increase size of this dialog's Shell by that amount
+ Rectangle rect = getEditArea().getClientArea();
+ Point containerSize= new Point(rect.width, rect.height);
+ int hdiff= contentSize.x - containerSize.x;
+ int vdiff= contentSize.y - containerSize.y;
+ // Only increase size of dialog, never shrink it
+ if (hdiff > 0 || vdiff > 0) {
+ int[] newSashWeights = null;
+ if (hdiff > 0) {
+ newSashWeights = calculateNewSashWeights(hdiff);
+ }
+ hdiff= Math.max(0, hdiff);
+ vdiff= Math.max(0, vdiff);
+ Shell shell= getShell();
+ Point shellSize= shell.getSize();
+ setShellSize(shellSize.x + hdiff, shellSize.y + vdiff);
+ // Adjust the sash weights so that all of the increase in width
+ // is given to the tab area
+ if (newSashWeights != null) {
+ getSashForm().setWeights(newSashWeights);
+ }
+ }
+ }
+
+ /**
+ * Notification that tab selection has changed.
+ *
+ * @param event selection changed event
+ */
+ protected void handleTabSelectionChanged(SelectionChangedEvent event) {
+ refreshStatus();
+ }
+
+ private void setInitializingTabs(boolean init) {
+ fInitializingTabs = init;
+ }
+
+ private boolean isInitializingTabs() {
+ return fInitializingTabs;
+ }
+
+ private void setProgressMonitorPart(ProgressMonitorPart part) {
+ fProgressMonitorPart = part;
+ }
+
+ private ProgressMonitorPart getProgressMonitorPart() {
+ return fProgressMonitorPart;
+ }
+
+ private void setProgressMonitorCancelButton(Button button) {
+ fProgressMonitorCancelButton = button;
+ }
+
+ private Button getProgressMonitorCancelButton() {
+ return fProgressMonitorCancelButton;
+ }
+
+ /**
+ * Calculate & return a 2 element integer array that specifies the relative
+ * weights of the selection area and the edit area, based on the specified
+ * increase in width of the owning shell. The point of this method is calculate
+ * sash weights such that when the shell gets wider, all of the increase in width
+ * is given to the edit area (tab folder), and the selection area (tree) stays
+ * the same width.
+ */
+ private int[] calculateNewSashWeights(int widthIncrease) {
+ int[] newWeights = new int[2];
+ newWeights[0] = getSelectionArea().getBounds().width;
+ newWeights[1] = getEditArea().getBounds().width + widthIncrease;
+ return newWeights;
+ }
+
+ /**
+ * Increase the size of this dialog's <code>Shell</code> by the specified amounts.
+ * Do not increase the size of the Shell beyond the bounds of the Display.
+ */
+ private void setShellSize(int width, int height) {
+ Rectangle bounds = getShell().getDisplay().getBounds();
+ getShell().setSize(Math.min(width, bounds.width), Math.min(height, bounds.height));
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#getMode()
+ */
+ public String getMode() {
+ return getLaunchGroup().getMode();
+ }
+
+ /**
+ * Returns the current tab group
+ *
+ * @return the current tab group, or <code>null</code> if none
+ */
+ public ILaunchConfigurationTabGroup getTabGroup() {
+ return fTabViewer.getTabGroup();
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#getTabs()
+ */
+ public ILaunchConfigurationTab[] getTabs() {
+ if (getTabGroup() == null) {
+ return null;
+ } else {
+ return getTabGroup().getTabs();
+ }
+ }
+
+ /**
+ * Return whether the current configuration can be discarded. This involves determining
+ * if it is dirty, and if it is, asking the user what to do.
+ */
+ private boolean canDiscardCurrentConfig() {
+ if (fTabViewer.isDirty()) {
+ return showUnsavedChangesDialog();
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Show the user a dialog appropriate to whether the unsaved changes in the current config
+ * can be saved or not. Return <code>true</code> if the user indicated that they wish to replace
+ * the current config, either by saving changes or by discarding the, return <code>false</code>
+ * otherwise.
+ */
+ private boolean showUnsavedChangesDialog() {
+ if (fTabViewer.canSave()) {
+ return showSaveChangesDialog();
+ } else {
+ return showDiscardChangesDialog();
+ }
+ }
+
+ /**
+ * Create and return a dialog that asks the user whether they want to save
+ * unsaved changes. Return <code>true </code> if they chose to save changes,
+ * <code>false</code> otherwise.
+ */
+ private boolean showSaveChangesDialog() {
+ StringBuffer buffer = new StringBuffer(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.The_configuration___29")); //$NON-NLS-1$
+ buffer.append(fTabViewer.getWorkingCopy().getName());
+ buffer.append(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.__has_unsaved_changes.__Do_you_wish_to_save_them__30")); //$NON-NLS-1$
+ MessageDialog dialog = new MessageDialog(getShell(),
+ LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Save_changes__31"), //$NON-NLS-1$
+ null,
+ buffer.toString(),
+ MessageDialog.QUESTION,
+ new String[] {LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Yes_32"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.No_33"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Cancel_34")}, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ 0);
+ // If user clicked 'Cancel' or closed dialog, return false
+ int selectedButton = dialog.open();
+ if ((selectedButton < 0) || (selectedButton == 2)) {
+ return false;
+ }
+
+ // If they hit 'Yes', save the working copy
+ if (selectedButton == 0) {
+ fTabViewer.handleApplyPressed();
+ } else {
+ // this will discard the changes
+ fTabViewer.inputChanged(fTabViewer.getInput());
+ }
+
+ return true;
+ }
+
+ /**
+ * Create and return a dialog that asks the user whether they want to discard
+ * unsaved changes. Return <code>true</code> if they chose to discard changes,
+ * <code>false</code> otherwise.
+ */
+ private boolean showDiscardChangesDialog() {
+ StringBuffer buffer = new StringBuffer(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.The_configuration___35")); //$NON-NLS-1$
+ buffer.append(fTabViewer.getWorkingCopy().getName());
+ buffer.append(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.__has_unsaved_changes_that_CANNOT_be_saved_because_of_the_following_error_36")); //$NON-NLS-1$
+ buffer.append(fTabViewer.getErrorMesssage());
+ buffer.append(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Do_you_wish_to_discard_changes_37")); //$NON-NLS-1$
+ MessageDialog dialog = new MessageDialog(getShell(),
+ LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Discard_changes__38"), //$NON-NLS-1$
+ null,
+ buffer.toString(),
+ MessageDialog.QUESTION,
+ new String[] {LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Yes_32"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.No_33")}, //$NON-NLS-1$ //$NON-NLS-2$
+ 1);
+ // If user clicked 'Yes', return true
+ int selectedButton = dialog.open();
+ if (selectedButton == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Notification the 'Close' button has been pressed.
+ */
+ protected void handleClosePressed() {
+ if (canDiscardCurrentConfig()) {
+ fTabViewer.dispose();
+ cancelPressed();
+ }
+ }
+
+ /**
+ * Notification the 'launch' button has been pressed.
+ * Save and launch.
+ */
+ protected void handleLaunchPressed() {
+ int result = CANCEL;
+ ILaunchConfiguration config = fTabViewer.getOriginal();
+ try {
+ if (fTabViewer.isDirty()) {
+ fTabViewer.handleApplyPressed();
+ }
+ result = doLaunch(config);
+ } catch (CoreException e) {
+ DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configuration_Error_6"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_while_launching_configuration._See_log_for_more_information_49"), e); //$NON-NLS-1$ //$NON-NLS-2$
+ return;
+ }
+ if (result == OK) {
+ try {
+ getPreferenceStore().setValue(IDebugPreferenceConstants.PREF_LAST_LAUNCH_CONFIGURATION_SELECTION, config.getMemento());
+ } catch (CoreException e) {
+ DebugUIPlugin.log(e);
+ }
+ close();
+ } else {
+ getShell().setFocus();
+ updateButtons();
+ }
+ }
+
+ /**
+ * Save the working copy if necessary, then launch the underlying configuration.
+ *
+ * @return one of CANCEL or OK
+ */
+ private int doLaunch(ILaunchConfiguration config) throws CoreException {
+
+ if (!DebugUITools.saveAndBuildBeforeLaunch()) {
+ return CANCEL;
+ }
+
+ // liftoff
+ ILaunch launch = launchWithProgress(config);
+
+ // If the launch was cancelled, get out. Otherwise, notify the tabs of the successful launch.
+ if (cancelButtonPressed()) {
+ launch.terminate();
+ return CANCEL;
+ } else if (launch != null) {
+ ILaunchConfigurationTabGroup group = getTabGroup();
+ if (group != null) {
+ group.launched(launch);
+ }
+ }
+
+ return OK;
+ }
+
+ /**
+ * @return the resulting launch, or <code>null</code> if cancelled.
+ * @exception CoreException if an exception occurrs launching
+ */
+ private ILaunch launchWithProgress(final ILaunchConfiguration config) throws CoreException {
+ final ILaunch[] launchResult = new ILaunch[1];
+ // Do the launch
+ IRunnableWithProgress runnable = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException {
+ try {
+ launchResult[0] = config.launch(getMode(), monitor);
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ };
+ try {
+ run(true, true, runnable);
+ } catch (InterruptedException e) {
+ return null;
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ if (t instanceof CoreException) {
+ throw (CoreException)t;
+ } else {
+ IStatus status = new Status(IStatus.ERROR, IDebugUIConstants.PLUGIN_ID, DebugException.INTERNAL_ERROR, LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_while_launching_50"), t); //$NON-NLS-1$
+ throw new CoreException(status);
+ }
+ } finally {
+ //remove any "error" launch
+ ILaunchManager manager= DebugPlugin.getDefault().getLaunchManager();
+ ILaunch[] launches= manager.getLaunches();
+ for (int i = 0; i < launches.length; i++) {
+ ILaunch iLaunch = launches[i];
+ if (!iLaunch.hasChildren()) {
+ manager.removeLaunch(iLaunch);
+ }
+ }
+ }
+
+ return launchResult[0];
+ }
+
+ private IPreferenceStore getPreferenceStore() {
+ return DebugUIPlugin.getDefault().getPreferenceStore();
+ }
+
+ /***************************************************************************************
+ *
+ * ProgressMonitor & IRunnableContext related methods
+ *
+ ***************************************************************************************/
+
+ /**
+ * @see IRunnableContext#run(boolean, boolean, IRunnableWithProgress)
+ */
+ public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
+ if (isVisible()) {
+ // The operation can only be canceled if it is executed in a separate thread.
+ // Otherwise the UI is blocked anyway.
+ Object state = aboutToStart();
+ fActiveRunningOperations++;
+ try {
+ ModalContext.run(runnable, fork, fProgressMonitorPart, getShell().getDisplay());
+ } finally {
+ fActiveRunningOperations--;
+ stopped(state);
+ }
+ } else {
+ ProgressMonitorDialog dialog = new ProgressMonitorDialog(DebugUIPlugin.getShell());
+ dialog.run(fork, cancelable, runnable);
+ }
+ }
+
+ /**
+ * About to start a long running operation triggered through
+ * the dialog. Shows the progress monitor and disables the dialog's
+ * buttons and controls.
+ *
+ * @return the saved UI state
+ */
+ private Object aboutToStart() {
+ Map savedState = null;
+ if (getShell() != null) {
+ // Save focus control
+ Control focusControl = getShell().getDisplay().getFocusControl();
+ if (focusControl != null && focusControl.getShell() != getShell()) {
+ focusControl = null;
+ }
+
+ // Set the busy cursor to all shells.
+ Display d = getShell().getDisplay();
+ waitCursor = new Cursor(d, SWT.CURSOR_WAIT);
+ setDisplayCursor(waitCursor);
+
+ // Set the arrow cursor to the cancel component.
+ arrowCursor= new Cursor(d, SWT.CURSOR_ARROW);
+ getProgressMonitorCancelButton().setCursor(arrowCursor);
+
+ // Deactivate shell
+ savedState = saveUIState();
+ if (focusControl != null) {
+ savedState.put(FOCUS_CONTROL, focusControl);
+ }
+
+ // Attach the progress monitor part to the cancel button
+ getProgressMonitorCancelButton().setEnabled(true);
+ setCancelButtonPressed(false);
+ getProgressMonitorPart().attachToCancelComponent(getProgressMonitorCancelButton());
+ getProgressMonitorPart().setVisible(true);
+ getProgressMonitorCancelButton().setFocus();
+ }
+ return savedState;
+ }
+
+ /**
+ * A long running operation triggered through the dialog
+ * was stopped either by user input or by normal end.
+ * Hides the progress monitor and restores the enable state
+ * of the dialog's buttons and controls.
+ *
+ * @param savedState the saved UI state as returned by <code>aboutToStart</code>
+ * @see #aboutToStart
+ */
+ private void stopped(Object savedState) {
+ if (getShell() != null) {
+ getProgressMonitorPart().setVisible(false);
+ getProgressMonitorPart().removeFromCancelComponent(getProgressMonitorCancelButton());
+ Map state = (Map)savedState;
+ restoreUIState(state);
+
+ setDisplayCursor(null);
+ waitCursor.dispose();
+ waitCursor = null;
+ arrowCursor.dispose();
+ arrowCursor = null;
+ Control focusControl = (Control)state.get(FOCUS_CONTROL);
+ if (focusControl != null) {
+ focusControl.setFocus();
+ }
+ }
+ }
+
+ /**
+ * Captures and returns the enabled/disabled state of the wizard dialog's
+ * buttons and the tree of controls for the currently showing page. All
+ * these controls are disabled in the process, with the possible excepton of
+ * the Cancel button.
+ *
+ * @return a map containing the saved state suitable for restoring later
+ * with <code>restoreUIState</code>
+ * @see #restoreUIState
+ */
+ private Map saveUIState() {
+ Map savedState= new HashMap(10);
+ saveEnableStateAndSet(getButtonActionNew().getButton(), savedState, "new", false);//$NON-NLS-1$
+ saveEnableStateAndSet(getButtonActionDelete().getButton(), savedState, "delete", false);//$NON-NLS-1$
+ saveEnableStateAndSet(getButton(ID_LAUNCH_BUTTON), savedState, "launch", false);//$NON-NLS-1$
+ saveEnableStateAndSet(getButton(ID_CLOSE_BUTTON), savedState, "close", false);//$NON-NLS-1$
+ savedState.put("editarea", ControlEnableState.disable(getEditArea()));//$NON-NLS-1$
+ return savedState;
+ }
+
+ /**
+ * Saves the enabled/disabled state of the given control in the
+ * given map, which must be modifiable.
+ *
+ * @param w the control, or <code>null</code> if none
+ * @param h the map (key type: <code>String</code>, element type:
+ * <code>Boolean</code>)
+ * @param key the key
+ * @param enabled <code>true</code> to enable the control,
+ * and <code>false</code> to disable it
+ * @see #restoreEnableStateAndSet
+ */
+ private void saveEnableStateAndSet(Control w, Map h, String key, boolean enabled) {
+ if (w != null) {
+ h.put(key, new Boolean(w.isEnabled()));
+ w.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * Restores the enabled/disabled state of the wizard dialog's
+ * buttons and the tree of controls for the currently showing page.
+ *
+ * @param state a map containing the saved state as returned by
+ * <code>saveUIState</code>
+ * @see #saveUIState
+ */
+ private void restoreUIState(Map state) {
+ restoreEnableState(getButtonActionNew().getButton(), state, "new");//$NON-NLS-1$
+ restoreEnableState(getButtonActionDelete().getButton(), state, "delete");//$NON-NLS-1$
+ restoreEnableState(getButton(ID_LAUNCH_BUTTON), state, "launch");//$NON-NLS-1$
+ restoreEnableState(getButton(ID_CLOSE_BUTTON), state, "close");//$NON-NLS-1$
+ ControlEnableState tabState = (ControlEnableState) state.get("editarea");//$NON-NLS-1$
+ tabState.restore();
+ }
+
+ /**
+ * Restores the enabled/disabled state of the given control.
+ *
+ * @param w the control
+ * @param h the map (key type: <code>String</code>, element type:
+ * <code>Boolean</code>)
+ * @param key the key
+ * @see #saveEnableStateAndSet
+ */
+ private void restoreEnableState(Control w, Map h, String key) {
+ if (w != null) {
+ Boolean b = (Boolean) h.get(key);
+ if (b != null)
+ w.setEnabled(b.booleanValue());
+ }
+ }
+
+ private void setCancelButtonPressed(boolean pressed) {
+ fCancelButtonPressed = pressed;
+ }
+
+ private boolean cancelButtonPressed() {
+ return fCancelButtonPressed;
+ }
+
+ /**
+ * Sets the given cursor for all shells currently active
+ * for this window's display.
+ *
+ * @param cursor the cursor
+ */
+ private void setDisplayCursor(Cursor cursor) {
+ Shell[] shells = getShell().getDisplay().getShells();
+ for (int i = 0; i < shells.length; i++)
+ shells[i].setCursor(cursor);
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#updateButtons()
+ */
+ public void updateButtons() {
+ if (isInitializingTabs()) {
+ return;
+ }
+
+ // New & Delete buttons
+ getButtonActionNew().setEnabled(getNewAction().isEnabled());
+ getButtonActionDelete().setEnabled(getDeleteAction().isEnabled());
+
+ // Launch button
+ getButton(ID_LAUNCH_BUTTON).setEnabled(fTabViewer.canLaunch());
+
+ fTabViewer.refresh();
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#getActiveTab()
+ */
+ public ILaunchConfigurationTab getActiveTab() {
+ return fTabViewer.getActiveTab();
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#updateMessage()
+ */
+ public void updateMessage() {
+ if (isInitializingTabs()) {
+ return;
+ }
+ setErrorMessage(fTabViewer.getErrorMesssage());
+ setMessage(fTabViewer.getMesssage());
+ }
+
+ /**
+ * Show the default informational message that explains how to create a new configuration.
+ */
+ private void setDefaultMessage() {
+ setMessage(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Select_a_type_of_configuration_to_create,_and_press___new__51")); //$NON-NLS-1$
+ }
+
+ /**
+ * Set the tooltip of the config tree label based on the current working set in effect.
+ */
+ private void updateTreeLabelTooltip() {
+ LaunchConfigurationWorkingSetActionManager mgr = getWorkingSetActionManager();
+ if (mgr != null) {
+ IWorkingSet workingSet = mgr.getWorkingSet();
+ if (workingSet != null) {
+ String newTooltip = MessageFormat.format(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Working_Set__{0}_1"), new String[] {workingSet.getName()} ); //$NON-NLS-1$
+ getTreeLabel().setToolTipText(newTooltip);
+ return;
+ }
+ }
+
+ // No working set, so don't show a tooltip
+ getTreeLabel().setToolTipText(null);
+ }
+
+ /**
+ * Returns the working set action manager
+ */
+ private LaunchConfigurationWorkingSetActionManager getWorkingSetActionManager() {
+ return fLaunchConfigurationView.getWorkingSetActionManager();
+ }
+
+ /**
+ * Returns the launch configuration selection area control.
+ *
+ * @return control
+ */
+ private Composite getSelectionArea() {
+ return fSelectionArea;
+ }
+
+ /**
+ * Sets the launch configuration selection area control.
+ *
+ * @param editArea control
+ */
+ private void setSelectionArea(Composite selectionArea) {
+ fSelectionArea = selectionArea;
+ }
+
+ /**
+ * Returns the launch configuration edit area control.
+ *
+ * @return control
+ */
+ private Composite getEditArea() {
+ return fEditArea;
+ }
+
+ /**
+ * Sets the launch configuration edit area control.
+ *
+ * @param editArea control
+ */
+ private void setEditArea(Composite editArea) {
+ fEditArea = editArea;
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#setName(String)
+ */
+ public void setName(String name) {
+ fTabViewer.setName(name);
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#generateName(String)
+ */
+ public String generateName(String name) {
+ if (name == null) {
+ name = ""; //$NON-NLS-1$
+ }
+ return getLaunchManager().generateUniqueLaunchConfigurationNameFrom(name);
+ }
+
+ /**
+ * Returns the initial launch configuration type, or <code>null</code> if none has been set.
+ */
+ private ILaunchConfigurationType getInitialConfigType() {
+ return fInitialConfigType;
+ }
+
+ /**
+ * Sets the initial launch configuration type to be used when this dialog is opened.
+ */
+ public void setInitialConfigType(ILaunchConfigurationType configType) {
+ fInitialConfigType = configType;
+ }
+
+ /**
+ * Returns the initial selection shown in this dialog when opened in
+ * <code>LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION</code> mode.
+ */
+ private IStructuredSelection getInitialSelection() {
+ return fInitialSelection;
+ }
+
+ /**
+ * Sets the initial selection for the dialog when opened in
+ * <code>LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION</code> mode.
+ */
+ public void setInitialSelection(IStructuredSelection selection) {
+ fInitialSelection = selection;
+ }
+
+ /**
+ * Handles key events in the tree viewer. Specifically
+ * when the delete key is pressed.
+ */
+ protected void handleTreeViewerKeyPressed(KeyEvent event) {
+ if (event.character == SWT.DEL && event.stateMask == 0) {
+ if (getButtonActionDelete().isEnabled()) {
+ getButtonActionDelete().run();
+ }
+ }
+ }
+
+ private void setButtonActionNew(ButtonAction action) {
+ fButtonActionNew = action;
+ }
+
+ private ButtonAction getButtonActionNew() {
+ return fButtonActionNew;
+ }
+
+ private void setButtonActionDelete(ButtonAction action) {
+ fButtonActionDelete = action;
+ }
+
+ private ButtonAction getButtonActionDelete() {
+ return fButtonActionDelete;
+ }
+
+ private void setTreeLabel(Label treeLabel) {
+ fTreeLabel = treeLabel;
+ }
+
+ private Label getTreeLabel() {
+ return fTreeLabel;
+ }
+
+ public static void setCurrentlyVisibleLaunchConfigurationDialog(ILaunchConfigurationDialog dialog) {
+ fgCurrentlyVisibleLaunchConfigurationDialog = dialog;
+ }
+
+ public static ILaunchConfigurationDialog getCurrentlyVisibleLaunchConfigurationDialog() {
+ return fgCurrentlyVisibleLaunchConfigurationDialog;
+ }
+
+ /**
+ * Extension of <code>Action</code> that manages a <code>Button</code>
+ * widget. This allows common handling for actions that must appear in
+ * a pop-up menu and also as a (non-toolbar) button in the UI.
+ */
+ private abstract class ButtonAction extends Action {
+
+ protected Button fButton;
+
+ /**
+ * Construct a ButtonAction handler. All details of the specified
+ * <code>Button</code>'s layout and appearance should be handled
+ * external to this class.
+ */
+ public ButtonAction(String text, Button button) {
+ super(text);
+ fButton = button;
+ if (fButton != null) {
+ fButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ ButtonAction.this.run();
+ }
+ });
+ }
+ }
+
+ public Button getButton() {
+ return fButton;
+ }
+
+ /**
+ * @see IAction#setEnabled(boolean)
+ */
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ if (fButton != null) {
+ fButton.setEnabled(enabled);
+ }
+ }
+ }
+
+ /**
+ * Handler for creating a new configuration.
+ */
+ private class ButtonActionNew extends ButtonAction {
+
+ public ButtonActionNew(String text, Button button) {
+ super(text, button);
+ }
+
+ public void run() {
+ getNewAction().run();
+ }
+ }
+
+ /**
+ * Handler for deleting a configuration.
+ */
+ private class ButtonActionDelete extends ButtonAction {
+
+ public ButtonActionDelete(String text, Button button) {
+ super(text, button);
+ }
+
+ public void run() {
+ getDeleteAction().run();
+ }
+ }
+
+ private class DoubleClickAction extends Action {
+ /**
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ IStructuredSelection selection = (IStructuredSelection)fLaunchConfigurationView.getViewer().getSelection();
+ Object target = selection.getFirstElement();
+ if (target instanceof ILaunchConfiguration) {
+ handleLaunchPressed();
+ } else {
+ getNewAction().run();
+ }
+ }
+
+ }
+
+ /**
+ * Returns the banner image to display in the title area */
+ protected Image getBannerImage() {
+ if (fBannerImage == null) {
+ ImageDescriptor descriptor = getLaunchGroup().getBannerImageDescriptor();
+ if (descriptor != null) {
+ fBannerImage = descriptor.createImage();
+ }
+ }
+ return fBannerImage;
+ }
+
+ /**
+ * Sets the launch group to display.
+ *
+ * @param group launch group
+ */
+ protected void setLaunchGroup(LaunchGroupExtension group) {
+ fGroup = group;
+ }
+
+ /**
+ * Returns the launch group being displayed.
+ *
+ * @return launch group */
+ public LaunchGroupExtension getLaunchGroup() {
+ return fGroup;
+ }
+
+ protected AbstractLaunchConfigurationAction getNewAction() {
+ return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(CreateLaunchConfigurationAction.ID_CREATE_ACTION);
+ }
+
+ protected AbstractLaunchConfigurationAction getDeleteAction() {
+ return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(DeleteLaunchConfigurationAction.ID_DELETE_ACTION);
+ }
+
+ protected AbstractLaunchConfigurationAction getDuplicateAction() {
+ return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(DuplicateLaunchConfigurationAction.ID_DUPLICATE_ACTION);
+ }
+
+} \ No newline at end of file

Back to the top