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
parentc74282fb4de2518e5958122850b661b66f139c25 (diff)
downloadeclipse.platform.debug-17dfba30565cd64599266cd080fc0d539142c370.tar.gz
eclipse.platform.debug-17dfba30565cd64599266cd080fc0d539142c370.tar.xz
eclipse.platform.debug-17dfba30565cd64599266cd080fc0d539142c370.zip
bug 19674 - refactor LCD
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java1
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ExecutionAction.java14
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenDebugConfigurations.java5
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenLaunchConfigurationsAction.java49
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenRunConfigurations.java5
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchLastAction.java20
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/AbstractLaunchConfigurationAction.java115
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java85
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DeleteLaunchConfigurationAction.java78
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DuplicateLaunchConfigurationAction.java56
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationDialog.java2
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTabGroupViewer.java1024
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java268
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationWorkingSetActionManager.java2
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationsDialog.java1748
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/ui/AbstractDebugView.java4
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java28
17 files changed, 3404 insertions, 100 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java
index 354e02925..f95d14ad9 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/IDebugHelpContextIds.java
@@ -38,6 +38,7 @@ public interface IDebugHelpContextIds {
public static final String BREAKPOINT_VIEW = PREFIX + "breakpoint_view_context"; //$NON-NLS-1$
public static final String CONSOLE_VIEW = PREFIX + "console_view_context"; //$NON-NLS-1$
public static final String EXPRESSION_VIEW = PREFIX + "expression_view_context"; //$NON-NLS-1$
+ public static final String LAUNCH_CONFIGURATION_VIEW = PREFIX + "launch_configuration_view_context"; //$NON-NLS-1$
// Preference pages
public static final String DEBUG_PREFERENCE_PAGE = PREFIX + "debug_preference_page_context"; //$NON-NLS-1$
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ExecutionAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ExecutionAction.java
index b7db3d2c1..b44e2fbc2 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ExecutionAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/ExecutionAction.java
@@ -6,14 +6,8 @@ package org.eclipse.debug.internal.ui.actions;
*/
import org.eclipse.debug.internal.ui.DebugUIPlugin;
-import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationDialog;
-import org
- .eclipse
- .debug
- .internal
- .ui
- .launchConfigurations
- .LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Event;
@@ -41,8 +35,8 @@ public abstract class ExecutionAction implements IActionDelegateWithEvent {
return;
}
IStructuredSelection selection= DebugUIPlugin.resolveSelection(dwindow);
- LaunchConfigurationDialog dialog = new LaunchConfigurationDialog(DebugUIPlugin.getShell(), selection, LaunchConfigurationManager.getDefault().getDefaultLanuchGroup(getMode()));
- dialog.setOpenMode(LaunchConfigurationDialog.LAUNCH_CONFIGURATION_DIALOG_LAUNCH_LAST);
+ LaunchConfigurationsDialog dialog = new LaunchConfigurationsDialog(DebugUIPlugin.getShell(), selection, LaunchConfigurationManager.getDefault().getDefaultLanuchGroup(getMode()));
+ dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_LAUNCH_LAST);
dialog.open();
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenDebugConfigurations.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenDebugConfigurations.java
index 2ea872e4a..dfc4514ae 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenDebugConfigurations.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenDebugConfigurations.java
@@ -1,6 +1,5 @@
package org.eclipse.debug.internal.ui.actions;
-import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchManager;
/*
@@ -16,10 +15,6 @@ public class OpenDebugConfigurations extends OpenLaunchConfigurationsAction {
public OpenDebugConfigurations() {
super();
}
-
- public OpenDebugConfigurations(ILaunchConfigurationType configType) {
- super(configType);
- }
/**
* @see OpenLaunchConfigurationsAction#getMode()
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenLaunchConfigurationsAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenLaunchConfigurationsAction.java
index 552b89fad..fdc662db5 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenLaunchConfigurationsAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenLaunchConfigurationsAction.java
@@ -9,14 +9,8 @@ import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.internal.ui.DebugPluginImages;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
-import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationDialog;
-import org
- .eclipse
- .debug
- .internal
- .ui
- .launchConfigurations
- .LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
@@ -28,14 +22,11 @@ import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
/**
- * Abstract action for opening the launch configuration dialog in run or debug mode.
- * This class is used in two ways: to simply open the dialog, and to open the dialog and
- * create a new configuration of a specified type.
+ * Abstract action for opening the launch configuration dialog in run or debug
+ * mode.
*/
public abstract class OpenLaunchConfigurationsAction extends Action implements IWorkbenchWindowActionDelegate {
- private boolean fCreateNewConfigMode;
-
/**
* The launch configuration type this action will cause to be created in the launch
* configuration dialog.
@@ -49,7 +40,6 @@ public abstract class OpenLaunchConfigurationsAction extends Action implements I
public OpenLaunchConfigurationsAction() {
super();
- fCreateNewConfigMode = false;
setConfigType(null);
ImageDescriptor imageDescriptor = null;
if (getMode() == ILaunchManager.DEBUG_MODE) {
@@ -60,28 +50,6 @@ public abstract class OpenLaunchConfigurationsAction extends Action implements I
setText(getLabelText());
setImageDescriptor(imageDescriptor);
}
-
- /**
- * Initialize this action from the specified <code>ILaunchConfigurationType</code>.
- */
- protected OpenLaunchConfigurationsAction(ILaunchConfigurationType configType) {
- fCreateNewConfigMode = true;
- setConfigType(configType);
- setText(configType.getName());
-
- ImageDescriptor descriptor = DebugPluginImages.getImageDescriptor(configType.getIdentifier());
- if (descriptor == null) {
- if (getMode().equals(ILaunchManager.DEBUG_MODE)) {
- descriptor= DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_ACT_DEBUG);
- } else {
- descriptor= DebugPluginImages.getImageDescriptor(IDebugUIConstants.IMG_ACT_RUN);
- }
- }
-
- if (descriptor != null) {
- setImageDescriptor(descriptor);
- }
- }
/**
* @see IWorkbenchWindowActionDelegate#init(IWorkbenchWindow)
@@ -129,13 +97,8 @@ public abstract class OpenLaunchConfigurationsAction extends Action implements I
} else {
ss = new StructuredSelection();
}
- LaunchConfigurationDialog dialog = new LaunchConfigurationDialog(window.getShell(), ss, LaunchConfigurationManager.getDefault().getDefaultLanuchGroup(getMode()));
- if (fCreateNewConfigMode) {
- dialog.setOpenMode(LaunchConfigurationDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_NEW_CONFIG_OF_TYPE);
- dialog.setInitialConfigType(getConfigType());
- } else {
- dialog.setOpenMode(LaunchConfigurationDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED);
- }
+ LaunchConfigurationsDialog dialog = new LaunchConfigurationsDialog(window.getShell(), ss, LaunchConfigurationManager.getDefault().getDefaultLanuchGroup(getMode()));
+ dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED);
dialog.open();
}
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenRunConfigurations.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenRunConfigurations.java
index 97023dbdb..d692a883b 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenRunConfigurations.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/OpenRunConfigurations.java
@@ -1,6 +1,5 @@
package org.eclipse.debug.internal.ui.actions;
-import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchManager;
/*
@@ -17,10 +16,6 @@ public class OpenRunConfigurations extends OpenLaunchConfigurationsAction {
super();
}
- public OpenRunConfigurations(ILaunchConfigurationType configType) {
- super(configType);
- }
-
/**
* @see OpenLaunchConfigurationsAction#getMode()
*/
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchLastAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchLastAction.java
index a300b9560..125d639b0 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchLastAction.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/RelaunchLastAction.java
@@ -10,20 +10,8 @@ import java.text.MessageFormat;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
-import org
- .eclipse
- .debug
- .internal
- .ui
- .launchConfigurations
- .LaunchConfigurationDialog;
-import org
- .eclipse
- .debug
- .internal
- .ui
- .launchConfigurations
- .LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
@@ -86,8 +74,8 @@ public abstract class RelaunchLastAction implements IWorkbenchWindowActionDelega
return;
}
IStructuredSelection selection= DebugUIPlugin.resolveSelection(dwindow);
- LaunchConfigurationDialog dialog = new LaunchConfigurationDialog(DebugUIPlugin.getShell(), selection, LaunchConfigurationManager.getDefault().getDefaultLanuchGroup(getMode()));
- dialog.setOpenMode(LaunchConfigurationDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED);
+ LaunchConfigurationsDialog dialog = new LaunchConfigurationsDialog(DebugUIPlugin.getShell(), selection, LaunchConfigurationManager.getDefault().getDefaultLanuchGroup(getMode()));
+ dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED);
dialog.open();
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/AbstractLaunchConfigurationAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/AbstractLaunchConfigurationAction.java
new file mode 100644
index 000000000..cb320c9a6
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/AbstractLaunchConfigurationAction.java
@@ -0,0 +1,115 @@
+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 org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.actions.SelectionListenerAction;
+
+/**
+ * Common function/behavior for launch configuration view actions
+ */
+public abstract class AbstractLaunchConfigurationAction extends SelectionListenerAction {
+
+ /**
+ * Allows a requestor to abort this action.
+ */
+ public interface IConfirmationRequestor {
+ /**
+ * Returns whether this action should proceed. Confirmation is requested
+ * when an action is run.
+ *
+ * @return whether this action should proceed
+ */
+ public boolean getConfirmation();
+ }
+
+ /**
+ * This action's confirmation requestor or <code>null</code> if none
+ */
+ private IConfirmationRequestor fConfirmationRequestor;
+
+ /**
+ * The viewer this action is working on
+ */
+ private Viewer fViewer;
+
+ /**
+ * Constructor for AbstractLaunchConfigurationAction.
+ * @param text
+ */
+ public AbstractLaunchConfigurationAction(String text, Viewer viewer) {
+ super(text);
+ fViewer = viewer;
+ fViewer.addSelectionChangedListener(this);
+ }
+
+ /**
+ * Returns the shell this action is contained in.
+ *
+ * @return the shell this action is contained in
+ */
+ protected Shell getShell() {
+ return getViewer().getControl().getShell();
+ }
+
+ /**
+ * Returns the viewer this action is working on
+ *
+ * @return the viewer this action is working on
+ */
+ protected Viewer getViewer() {
+ return fViewer;
+ }
+
+ /**
+ * Performs this action once confirmation has been aquired. Subclasses
+ * should override this method.
+ */
+ protected abstract void performAction();
+
+ /**
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public final void run() {
+ if (fConfirmationRequestor != null) {
+ if (!fConfirmationRequestor.getConfirmation()) {
+ return;
+ }
+ }
+ performAction();
+ }
+
+ /**
+ * Sets this action's confirmation requestor.
+ *
+ * @param confirmationRequestor
+ */
+ public void setConfirmationRequestor(IConfirmationRequestor confirmationRequestor) {
+ fConfirmationRequestor = confirmationRequestor;
+ }
+
+ /**
+ * Disposes this action
+ */
+ public void dispose() {
+ fViewer.removeSelectionChangedListener(this);
+ }
+
+ /**
+ * Show an error dialog on the given exception.
+ *
+ * @param exception
+ */
+ protected void errorDialog(CoreException exception) {
+ ErrorDialog.openError(getShell(), null, null, exception.getStatus());
+ }
+
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java
new file mode 100644
index 000000000..85f657fb5
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/CreateLaunchConfigurationAction.java
@@ -0,0 +1,85 @@
+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 org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Creates a new launch configuration based on the selection.
+ */
+public class CreateLaunchConfigurationAction extends AbstractLaunchConfigurationAction {
+
+ /**
+ * Action identifier for IDebugView#getAction(String)
+ */
+ public static final String ID_CREATE_ACTION = DebugUIPlugin.getUniqueIdentifier() + ".ID_CREATE_ACTION";
+
+ /**
+ * Constructs an action to create a launch configuration
+ */
+ public CreateLaunchConfigurationAction(Viewer viewer) {
+ super("Ne&w", viewer);
+ }
+
+ /**
+ * @see AbstractLaunchConfigurationAction#performAction()
+ */
+ protected void performAction() {
+ Object object = getStructuredSelection().getFirstElement();
+ ILaunchConfigurationType type= null;
+ // Construct a new config of the selected type
+ if (object instanceof ILaunchConfiguration) {
+ ILaunchConfiguration config= (ILaunchConfiguration) object;
+ try {
+ type = config.getType();
+ } catch (CoreException e) {
+ errorDialog(e);
+ return;
+ }
+ } else {
+ type = (ILaunchConfigurationType) object;
+ }
+
+ try {
+ ILaunchConfigurationWorkingCopy wc = type.newInstance(null, DebugPlugin.getDefault().getLaunchManager().generateUniqueLaunchConfigurationNameFrom("New_configuration"));
+ ILaunchConfigurationTabGroup tabGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(wc.getType());
+ // this only works because this action is only present when the dialog is open
+ ILaunchConfigurationDialog dialog = LaunchConfigurationsDialog.getCurrentlyVisibleLaunchConfigurationDialog();
+ tabGroup.createTabs(dialog, dialog.getMode());
+ ILaunchConfigurationTab[] tabs = tabGroup.getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ ILaunchConfigurationTab tab = tabs[i];
+ tab.setLaunchConfigurationDialog(dialog);
+ }
+ tabGroup.setDefaults(wc);
+ tabGroup.dispose();
+ wc.doSave();
+ } catch (CoreException e) {
+ errorDialog(e);
+ return;
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.actions.SelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
+ */
+ protected boolean updateSelection(IStructuredSelection selection) {
+ return selection.size() == 1;
+ }
+
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DeleteLaunchConfigurationAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DeleteLaunchConfigurationAction.java
new file mode 100644
index 000000000..479eb9f58
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DeleteLaunchConfigurationAction.java
@@ -0,0 +1,78 @@
+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.util.Iterator;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Deletes the selected launch configuration(s).
+ */
+public class DeleteLaunchConfigurationAction extends AbstractLaunchConfigurationAction {
+
+ /**
+ * Action identifier for IDebugView#getAction(String)
+ */
+ public static final String ID_DELETE_ACTION = DebugUIPlugin.getUniqueIdentifier() + ".ID_DELETE_ACTION";
+
+ /**
+ * Constructs an action to delete launch configuration(s)
+ */
+ public DeleteLaunchConfigurationAction(Viewer viewer) {
+ super("Dele&te", viewer);
+ }
+
+ /**
+ * @see AbstractLaunchConfigurationAction#performAction()
+ */
+ protected void performAction() {
+ IStructuredSelection selection = getStructuredSelection();
+
+ // Make the user confirm the deletion
+ String dialogMessage = selection.size() > 1 ? LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Do_you_wish_to_delete_the_selected_launch_configurations__1") : LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Do_you_wish_to_delete_the_selected_launch_configuration__2"); //$NON-NLS-1$ //$NON-NLS-2$
+ boolean ok = MessageDialog.openQuestion(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Confirm_Launch_Configuration_Deletion_3"), dialogMessage); //$NON-NLS-1$
+ if (!ok) {
+ return;
+ }
+
+ getViewer().getControl().setRedraw(false);
+ Iterator iterator = selection.iterator();
+ while (iterator.hasNext()) {
+ ILaunchConfiguration configuration = (ILaunchConfiguration)iterator.next();
+ try {
+ configuration.delete();
+ } catch (CoreException e) {
+ errorDialog(e);
+ }
+ }
+ getViewer().getControl().setRedraw(true);
+ }
+
+ /**
+ * @see org.eclipse.ui.actions.SelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
+ */
+ protected boolean updateSelection(IStructuredSelection selection) {
+ if (selection.isEmpty()) {
+ return false;
+ }
+ Iterator items = selection.iterator();
+ while (items.hasNext()) {
+ if (!(items.next() instanceof ILaunchConfiguration)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DuplicateLaunchConfigurationAction.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DuplicateLaunchConfigurationAction.java
new file mode 100644
index 000000000..a3512ac95
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/DuplicateLaunchConfigurationAction.java
@@ -0,0 +1,56 @@
+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 org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Duplicates the selected launch configuration.
+ */
+public class DuplicateLaunchConfigurationAction extends AbstractLaunchConfigurationAction {
+
+ /**
+ * Action identifier for IDebugView#getAction(String)
+ */
+ public static final String ID_DUPLICATE_ACTION = DebugUIPlugin.getUniqueIdentifier() + ".ID_DUPLICATE_ACTION";
+
+ /**
+ * Constructs an action to duplicate a launch configuration
+ */
+ public DuplicateLaunchConfigurationAction(Viewer viewer) {
+ super("&Duplicate", viewer);
+ }
+
+ /**
+ * @see AbstractLaunchConfigurationAction#performAction()
+ */
+ protected void performAction() {
+ ILaunchConfiguration original = (ILaunchConfiguration)getStructuredSelection().getFirstElement();
+ String newName = DebugPlugin.getDefault().getLaunchManager().generateUniqueLaunchConfigurationNameFrom(original.getName());
+ try {
+ ILaunchConfigurationWorkingCopy newWorkingCopy = original.copy(newName);
+ newWorkingCopy.doSave();
+ } catch (CoreException e) {
+ errorDialog(e);
+ }
+ }
+
+ /**
+ * @see org.eclipse.ui.actions.SelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
+ */
+ protected boolean updateSelection(IStructuredSelection selection) {
+ return selection.size() == 1 && selection.getFirstElement() instanceof ILaunchConfiguration;
+ }
+
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationDialog.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationDialog.java
index 8796919e3..2fa842b4b 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationDialog.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationDialog.java
@@ -99,6 +99,8 @@ import org.eclipse.ui.model.WorkbenchViewerSorter;
/**
* The dialog used to edit and launch launch configurations.
+ *
+ * @deprecated use LaunchConfigurationsDialog instead
*/
public class LaunchConfigurationDialog extends TitleAreaDialog
implements ISelectionChangedListener,
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTabGroupViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTabGroupViewer.java
new file mode 100644
index 000000000..ebcfeff82
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationTabGroupViewer.java
@@ -0,0 +1,1024 @@
+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.text.MessageFormat;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.internal.ui.DebugUIPlugin;
+import org.eclipse.debug.internal.ui.SWTUtil;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTabGroup;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.viewers.ISelection;
+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.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A viewer that displays tabs for a launch configuration, with apply and revert
+ * buttons.
+ */
+public class LaunchConfigurationTabGroupViewer extends Viewer {
+
+ /**
+ * Containing launch dialog
+ */
+ private ILaunchConfigurationDialog fDialog;
+
+ /**
+ * The this viewer's input
+ */
+ private Object fInput;
+
+ /**
+ * The launch configuration (original) being edited
+ */
+ private ILaunchConfiguration fOriginal;
+
+ /**
+ * The working copy of the original
+ */
+ private ILaunchConfigurationWorkingCopy fWorkingCopy;
+
+ /**
+ * This view's control, which contains a composite area of controls
+ */
+ private Composite fViewerControl;
+
+ /**
+ * Composite area containing all this viewer's controls, which can be
+ * hidden/shown.
+ */
+ private Composite fViewerArea;
+
+ /**
+ * Name text widget
+ */
+ private Text fNameWidget;
+
+ /**
+ * Composite containing the launch config tab widgets
+ */
+ private Composite fTabComposite;
+
+ /**
+ * Tab folder
+ */
+ private TabFolder fTabFolder;
+
+ /**
+ * The current tab group being displayed
+ */
+ private ILaunchConfigurationTabGroup fTabGroup;
+
+ /**
+ * The type of config tabs are currently displayed
+ * for
+ */
+ private ILaunchConfigurationType fTabType;
+
+ /**
+ * Index of the active tab
+ */
+ private int fCurrentTabIndex = -1;
+
+ /**
+ * Apply & Rever buttons
+ */
+ private Button fApplyButton;
+ private Button fRevertButton;
+
+ /**
+ * Whether tabs are currently being disposed or initialized
+ */
+ private boolean fDisposingTabs = false;
+ private boolean fInitializingTabs = false;
+
+ /**
+ * Constructs a viewer in the given composite, contained by the given
+ * launch configuration dialog.
+ *
+ * @param parent composite containing this viewer
+ * @param dialog containing launch configuration dialog
+ */
+ public LaunchConfigurationTabGroupViewer(Composite parent, ILaunchConfigurationDialog dialog) {
+ super();
+ fDialog = dialog;
+ createControl(parent);
+ }
+
+ public void dispose() {
+ disposeExistingTabs();
+ }
+
+ /**
+ * Creates this viewer's control 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 void createControl(Composite parent) {
+ fViewerControl = new Composite(parent, SWT.NONE);
+ GridLayout outerCompLayout = new GridLayout();
+ outerCompLayout.numColumns = 1;
+ outerCompLayout.marginHeight = 0;
+ outerCompLayout.marginWidth = 0;
+ fViewerControl.setLayout(outerCompLayout);
+
+ Composite comp = new Composite(fViewerControl, SWT.NONE);
+ setViewerArea(comp);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginHeight = 0;
+ layout.marginWidth = 5;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(gd);
+
+ Label nameLabel = new Label(comp, SWT.HORIZONTAL | SWT.LEFT);
+ nameLabel.setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.&Name__16")); //$NON-NLS-1$
+ gd = new GridData(GridData.BEGINNING);
+ nameLabel.setLayoutData(gd);
+
+ Text nameText = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ nameText.setLayoutData(gd);
+ setNameWidget(nameText);
+
+ getNameWidget().addModifyListener(
+ new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ handleNameModified();
+ }
+ }
+ );
+
+ Label spacer = new Label(comp, SWT.NONE);
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ spacer.setLayoutData(gd);
+
+ fTabComposite = new Composite(comp, SWT.NONE);
+ GridLayout outerTabCompositeLayout = new GridLayout();
+ outerTabCompositeLayout.marginHeight = 0;
+ outerTabCompositeLayout.marginWidth = 0;
+ fTabComposite.setLayout(outerTabCompositeLayout);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.horizontalSpan = 2;
+ fTabComposite.setLayoutData(gd);
+
+ TabFolder tabFolder = new TabFolder(fTabComposite, SWT.NONE);
+ setTabFolder(tabFolder);
+ gd = new GridData(GridData.FILL_BOTH);
+ tabFolder.setLayoutData(gd);
+ getTabFolder().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent event) {
+ if (!isInitializingTabs()) {
+ handleTabSelected();
+ }
+ }
+ });
+
+ Composite buttonComp = new Composite(comp, SWT.NONE);
+ GridLayout buttonCompLayout = new GridLayout();
+ buttonCompLayout.numColumns = 2;
+ buttonComp.setLayout(buttonCompLayout);
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ gd.horizontalSpan = 2;
+ buttonComp.setLayoutData(gd);
+
+ setApplyButton(new Button(buttonComp, SWT.PUSH));
+ getApplyButton().setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.&Apply_17")); //$NON-NLS-1$
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ getApplyButton().setLayoutData(gd);
+ SWTUtil.setButtonDimensionHint(getApplyButton());
+ getApplyButton().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ handleApplyPressed();
+ }
+ });
+
+ setRevertButton(new Button(buttonComp, SWT.PUSH));
+ getRevertButton().setText(LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Revert_2")); //$NON-NLS-1$
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ getRevertButton().setLayoutData(gd);
+ SWTUtil.setButtonDimensionHint(getRevertButton());
+ getRevertButton().addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent evt) {
+ handleRevertPressed();
+ }
+ });
+
+ }
+
+ /**
+ * Sets the apply button
+ */
+ private void setApplyButton(Button button) {
+ fApplyButton = button;
+ }
+
+ /**
+ * Returns the apply button
+ */
+ protected Button getApplyButton() {
+ return fApplyButton;
+ }
+
+ /**
+ * Sets the revert button
+ */
+ private void setRevertButton(Button button) {
+ fRevertButton = button;
+ }
+
+ /**
+ * Returns the revert button
+ */
+ protected Button getRevertButton() {
+ return fRevertButton;
+ }
+
+ /**
+ * Sets the tab folder
+ */
+ private void setTabFolder(TabFolder tabFolder) {
+ fTabFolder = tabFolder;
+ }
+
+ /**
+ * Sets the tab folder
+ */
+ private TabFolder getTabFolder() {
+ return fTabFolder;
+ }
+
+ /**
+ * Returns the name widget
+ */
+ private Text getNameWidget() {
+ return fNameWidget;
+ }
+
+ /**
+ * Sets the name widget
+ */
+ private void setNameWidget(Text nameText) {
+ fNameWidget = nameText;
+ }
+
+ /**
+ * Sets the current name
+ */
+ public void setName(String name) {
+ if (getWorkingCopy() != null) {
+ if (name == null) {
+ name = ""; //$NON-NLS-1$
+ }
+ getNameWidget().setText(name.trim());
+ refreshStatus();
+ }
+ }
+
+ /**
+ * Sets the control that contains all of this viewer's controls which can be
+ * hidden/shown.
+ *
+ * @param comp
+ */
+ private void setViewerArea(Composite comp) {
+ fViewerArea = comp;
+ }
+
+ /**
+ * Returns the control that contains all of this viewer's controls which can
+ * be hidden/shown.
+ */
+ protected Composite getViewerArea() {
+ return fViewerArea;
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.Viewer#getControl()
+ */
+ public Control getControl() {
+ return fViewerControl;
+ }
+
+ /**
+ * Returns the shell this viewer is contained in.
+ */
+ protected Shell getShell() {
+ return getControl().getShell();
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.IInputProvider#getInput()
+ */
+ public Object getInput() {
+ return fInput;
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
+ */
+ public ISelection getSelection() {
+ if (getActiveTab() == null) {
+ return new StructuredSelection();
+ } else {
+ return new StructuredSelection(getActiveTab());
+ }
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.Viewer#refresh()
+ */
+ public void refresh() {
+ if (!isInitializingTabs()) {
+ boolean dirty = isDirty();
+ getApplyButton().setEnabled(dirty && canSave());
+ getRevertButton().setEnabled(dirty);
+ // update error ticks
+ ILaunchConfigurationTab[] tabs = getTabs();
+ if (tabs == null) {
+ return;
+ }
+ TabFolder folder = getTabFolder();
+ for (int i = 0; i < tabs.length; i++) {
+ ILaunchConfigurationTab tab = tabs[i];
+ boolean error = tab.getErrorMessage() != null;
+ TabItem item = folder.getItem(i);
+ setTabIcon(item, error, tab);
+ }
+ }
+ }
+
+ /**
+ * Set the specified tab item's icon to an error icon if <code>error</code> is true,
+ * or a transparent icon of the same size otherwise.
+ */
+ private void setTabIcon(TabItem tabItem, boolean error, ILaunchConfigurationTab tab) {
+ Image image = null;
+ if (error) {
+ image = LaunchConfigurationManager.getDefault().getErrorTabImage(tab);
+ } else {
+ image = tab.getImage();
+ }
+ tabItem.setImage(image);
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.Viewer#setInput(java.lang.Object)
+ */
+ public void setInput(Object input) {
+ if (input == null) {
+ if (fInput == null) {
+ return;
+ } else {
+ inputChanged(input);
+ }
+ } else {
+ if (!input.equals(fInput)) {
+ inputChanged(input);
+ }
+ }
+ }
+
+ /**
+ * The input has changed to the given object, possibly <code>null</code>.
+ *
+ * @param input the new input, possibly <code>null</code>
+ */
+ protected void inputChanged(Object input) {
+ fInput = input;
+ if (input instanceof ILaunchConfiguration) {
+ ILaunchConfiguration configuration = (ILaunchConfiguration)input;
+ setOriginal(configuration);
+ try {
+ setWorkingCopy(configuration.getWorkingCopy());
+ } catch (CoreException e) {
+ errorDialog(e);
+ }
+ displayTabs();
+ } else {
+ setOriginal(null);
+ setWorkingCopy(null);
+ getViewerArea().setVisible(false);
+ disposeExistingTabs();
+ }
+ }
+
+ /**
+ * Displays tabs for the current working copy
+ */
+ protected void displayTabs() {
+ // Turn on initializing flag to ignore message updates
+ setInitializingTabs(true);
+
+ ILaunchConfigurationType type = null;
+ try {
+ type = getWorkingCopy().getType();
+ showTabsFor(type);
+ } catch (CoreException e) {
+ errorDialog(e);
+ setInitializingTabs(false);
+ return;
+ }
+
+ // Update the name field before to avoid verify error
+ getNameWidget().setText(getWorkingCopy().getName());
+
+ // Retrieve the current tab group. If there is none, clean up and leave
+ ILaunchConfigurationTabGroup tabGroup = getTabGroup();
+ if (tabGroup == null) {
+ IStatus status = new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), 0, MessageFormat.format("No tabs defined for launch configuration type {0}", new String[]{type.getName()}), null);
+ CoreException e = new CoreException(status);
+ errorDialog(e);
+ setInitializingTabs(false);
+ return;
+ }
+
+ // Update the tabs with the new working copy
+ tabGroup.initializeFrom(getWorkingCopy());
+
+ // Update the name field after in case client changed it
+ getNameWidget().setText(getWorkingCopy().getName());
+
+ // Turn off initializing flag to update message
+ setInitializingTabs(false);
+
+ refreshStatus();
+ }
+
+ /**
+ * Populate the tabs in the configuration edit area to be appropriate to the current
+ * launch configuration type.
+ */
+ private void showTabsFor(ILaunchConfigurationType configType) {
+
+ // Don't do any work if the current tabs are for the current config type
+ if (getTabType() != null && getTabType().equals(configType)) {
+ return;
+ }
+
+ // Avoid flicker
+ getViewerArea().setVisible(false);
+
+ // Dispose the current tabs
+ disposeExistingTabs();
+
+ // Build the new tabs
+ ILaunchConfigurationTabGroup group = null;
+ try {
+ group = createGroup(configType);
+ setTabGroup(group);
+ } catch (CoreException ce) {
+ DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Error_19"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_creating_launch_configuration_tabs_27"),ce); //$NON-NLS-1$ //$NON-NLS-2$
+ return;
+ }
+
+ // Create the Control for each tab
+ ILaunchConfigurationTab[] tabs = group.getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ TabItem tab = new TabItem(getTabFolder(), SWT.NONE);
+ String name = tabs[i].getName();
+ if (name == null) {
+ name = LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.unspecified_28"); //$NON-NLS-1$
+ }
+ tab.setText(name);
+ Image image = tabs[i].getImage();
+ tab.setImage(image);
+ tabs[i].createControl(tab.getParent());
+ Control control = tabs[i].getControl();
+ if (control != null) {
+ tab.setControl(control);
+ }
+ }
+
+ setTabGroup(group);
+ setTabType(configType);
+ getViewerArea().setVisible(true);
+ }
+
+ /**
+ * Returns tab group for the given type of launch configuration.
+ * Tabs are initialized to be contained in this dialog.
+ *
+ * @exception CoreException if unable to instantiate a tab group
+ */
+ protected ILaunchConfigurationTabGroup createGroup(final ILaunchConfigurationType configType) throws CoreException {
+ // Use a final Object array to store the tab group and any exception that
+ // results from the Runnable
+ final Object[] finalArray = new Object[2];
+ Runnable runnable = new Runnable() {
+ public void run() {
+ ILaunchConfigurationTabGroup tabGroup = null;
+ try {
+ tabGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(configType);
+ finalArray[0] = tabGroup;
+ } catch (CoreException ce) {
+ finalArray[1] = ce;
+ return;
+ }
+ tabGroup.createTabs(getLaunchConfigurationDialog(), getLaunchConfigurationDialog().getMode());
+ ILaunchConfigurationTab[] tabs = tabGroup.getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ tabs[i].setLaunchConfigurationDialog(getLaunchConfigurationDialog());
+ }
+ }
+ };
+
+ // Creating the tabs can result in plugin loading, so we show the busy cursor
+ BusyIndicator.showWhile(getControl().getDisplay(), runnable);
+
+ // Re-throw any CoreException if there was one
+ if (finalArray[1] != null) {
+ throw (CoreException)finalArray[1];
+ }
+
+ // Otherwise return the tab group
+ return (ILaunchConfigurationTabGroup)finalArray[0];
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.Viewer#setSelection(org.eclipse.jface.viewers.ISelection, boolean)
+ */
+ public void setSelection(ISelection selection, boolean reveal) {
+ if (getWorkingCopy() != null) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+ Object object = structuredSelection.getFirstElement();
+ if (object instanceof ILaunchConfigurationTab) {
+ ILaunchConfigurationTab[] tabs = getTabs();
+ for (int i = 0; i < tabs.length; i++) {
+ ILaunchConfigurationTab tab = tabs[i];
+ if (tab.equals(object)) {
+ fCurrentTabIndex = i;
+ getTabFolder().setSelection(i);
+ }
+ return;
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Returns the tabs currently being displayed, or
+ * <code>null</code> if none.
+ *
+ * @return currently displayed tabs, or <code>null</code>
+ */
+ public ILaunchConfigurationTab[] getTabs() {
+ if (getTabGroup() != null) {
+ return getTabGroup().getTabs();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the currently active <code>ILaunchConfigurationTab</code>
+ * being displayed, or <code>null</code> if there is none.
+ *
+ * @return currently active <code>ILaunchConfigurationTab</code>, or <code>null</code>.
+ */
+ public ILaunchConfigurationTab getActiveTab() {
+ TabFolder folder = getTabFolder();
+ ILaunchConfigurationTab[] tabs = getTabs();
+ if (folder != null && tabs != null) {
+ int pageIndex = folder.getSelectionIndex();
+ if (pageIndex >= 0) {
+ return tabs[pageIndex];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether the launch configuration being edited is dirty (i.e.
+ * needs saving)
+ *
+ * @return whether the launch configuration being edited needs saving
+ */
+ public boolean isDirty() {
+ ILaunchConfigurationWorkingCopy workingCopy = getWorkingCopy();
+ if (workingCopy == null) {
+ return false;
+ }
+
+ // Working copy hasn't been saved
+ if (workingCopy.getOriginal() == null) {
+ return true;
+ }
+
+ updateWorkingCopyFromPages();
+ ILaunchConfiguration original = getOriginal();
+ return !original.contentsEqual(workingCopy);
+ }
+
+ /**
+ * Update apply & revert buttons, as well as buttons and message on the
+ * launch config dialog.
+ */
+ protected void refreshStatus() {
+ getLaunchConfigurationDialog().updateButtons();
+ getLaunchConfigurationDialog().updateMessage();
+ }
+
+ /**
+ * Returns the containing launch dialog
+ */
+ protected ILaunchConfigurationDialog getLaunchConfigurationDialog() {
+ return fDialog;
+ }
+
+ /**
+ * Sets the launch configuration being displayed/edited, possilby
+ * <code>null</code>.
+ */
+ private void setOriginal(ILaunchConfiguration configuration) {
+ fOriginal = configuration;
+ }
+
+ /**
+ * Returns the original launch configuration being edited, possibly
+ * <code>null</code>.
+ *
+ * @return ILaunchConfiguration
+ */
+ protected ILaunchConfiguration getOriginal() {
+ return fOriginal;
+ }
+
+ /**
+ * Sets the working copy used to edit the original.
+ */
+ private void setWorkingCopy(ILaunchConfigurationWorkingCopy workingCopy) {
+ fWorkingCopy = workingCopy;
+ }
+
+ /**
+ * Returns the working copy used to edit the original, possibly
+ * <code>null</code>.
+ */
+ protected ILaunchConfigurationWorkingCopy getWorkingCopy() {
+ return fWorkingCopy;
+ }
+
+ /**
+ * Return whether the current configuration can be saved.
+ * <p>
+ * Note this is NOT the same thing as the config simply being valid. It
+ * is possible to save a config that does not validate. This method
+ * determines whether the config can be saved without causing a serious
+ * error. For example, a shared config that has no specified location would
+ * cause this method to return <code>false</code>.
+ * </p>
+ */
+ public boolean canSave() {
+ // First make sure that name doesn't prevent saving the config
+ try {
+ verifyName();
+ } catch (CoreException ce) {
+ return false;
+ }
+
+ // Next, make sure none of the tabs object to saving the config
+ ILaunchConfigurationTab[] tabs = getTabs();
+ if (tabs == null) {
+ return false;
+ }
+ for (int i = 0; i < tabs.length; i++) {
+ if (!tabs[i].canSave()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @see ILaunchConfigurationDialog#canLaunch()
+ */
+ public boolean canLaunch() {
+ if (getWorkingCopy() == null) {
+ return false;
+ }
+ try {
+ verifyName();
+ } catch (CoreException e) {
+ return false;
+ }
+
+ ILaunchConfigurationTab[] tabs = getTabs();
+ if (tabs == null) {
+ return false;
+ }
+ for (int i = 0; i < tabs.length; i++) {
+ if (!tabs[i].isValid(getWorkingCopy())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns the current error message or <code>null</code> if none.
+ */
+ public String getErrorMesssage() {
+ if (getWorkingCopy() == null) {
+ return null;
+ }
+ try {
+ verifyName();
+ } catch (CoreException ce) {
+ return ce.getStatus().getMessage();
+ }
+
+ String message = null;
+ ILaunchConfigurationTab activeTab = getActiveTab();
+ if (activeTab == null) {
+ return null;
+ } else {
+ activeTab.isValid(getWorkingCopy());
+ message = activeTab.getErrorMessage();
+ }
+ if (message != null) {
+ return message;
+ }
+
+ ILaunchConfigurationTab[] allTabs = getTabs();
+ for (int i = 0; i < allTabs.length; i++) {
+ ILaunchConfigurationTab tab = allTabs[i];
+ if (tab == activeTab) {
+ continue;
+ }
+ tab.isValid(getWorkingCopy());
+ message = tab.getErrorMessage();
+ if (message != null) {
+ message = '[' + removeAmpersandsFrom(tab.getName()) + "]: " + message; //$NON-NLS-1$
+ return message;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return a copy of the specified string without ampersands.
+ */
+ private String removeAmpersandsFrom(String string) {
+ String newString = new String(string);
+ int index = newString.indexOf('&');
+ while (index != -1) {
+ newString = string.substring(0, index) + newString.substring(index + 1, newString.length());
+ index = newString.indexOf('&');
+ }
+ return newString;
+ }
+
+ /**
+ * Returns the current message or <code>null</code> if none.
+ */
+ public String getMesssage() {
+ ILaunchConfigurationTab tab = getActiveTab();
+ if (tab == null) {
+ return null;
+ } else {
+ return tab.getMessage();
+ }
+ }
+
+ /**
+ * Verify that the launch configuration name is valid.
+ */
+ protected void verifyName() throws CoreException {
+ String currentName = getNameWidget().getText().trim();
+
+ // If there is no name, complain
+ if (currentName.length() < 1) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ DebugUIPlugin.getUniqueIdentifier(),
+ 0,
+ LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Name_required_for_launch_configuration_11"), //$NON-NLS-1$
+ null));
+ }
+
+ // See if name contains any 'illegal' characters
+ IStatus status = ResourcesPlugin.getWorkspace().validateName(currentName, IResource.FILE);
+ if (status.getCode() != IStatus.OK) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ DebugUIPlugin.getDefault().getDescriptor().getUniqueIdentifier(),
+ 0,
+ status.getMessage(),
+ null));
+ }
+
+ // Otherwise, if there's already a config with the same name, complain
+ if (!getOriginal().getName().equals(currentName)) {
+ if (getLaunchManager().isExistingLaunchConfigurationName(currentName)) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ DebugUIPlugin.getDefault().getDescriptor().getUniqueIdentifier(),
+ 0,
+ LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_configuration_already_exists_with_this_name_12"), //$NON-NLS-1$
+ null));
+ }
+ }
+ }
+
+ private void setDisposingTabs(boolean disposing) {
+ fDisposingTabs = disposing;
+ }
+
+ private boolean isDisposingTabs() {
+ return fDisposingTabs;
+ }
+
+ private void setInitializingTabs(boolean initializing) {
+ fInitializingTabs = initializing;
+ }
+
+ private boolean isInitializingTabs() {
+ return fInitializingTabs;
+ }
+
+ private void disposeExistingTabs() {
+ setDisposingTabs(true);
+ TabItem[] oldTabs = getTabFolder().getItems();
+ for (int i = 0; i < oldTabs.length; i++) {
+ oldTabs[i].dispose();
+ }
+ if (getTabGroup() != null) {
+ getTabGroup().dispose();
+ }
+ setTabGroup(null);
+ setTabType(null);
+ setDisposingTabs(false);
+ }
+
+ private ILaunchManager getLaunchManager() {
+ return DebugPlugin.getDefault().getLaunchManager();
+ }
+
+ /**
+ * Returns the type that tabs are currently displayed
+ * for, or <code>null</code> if none.
+ *
+ * @return launch configuration type or <code>null</code>
+ */
+ private ILaunchConfigurationType getTabType() {
+ return fTabType;
+ }
+
+ /**
+ * Sets the type that tabs are currently displayed
+ * for, or <code>null</code> if none.
+ *
+ * @param tabType launch configuration type
+ */
+ private void setTabType(ILaunchConfigurationType tabType) {
+ fTabType = tabType;
+ }
+
+ /**
+ * Sets the current tab group being displayed
+ *
+ * @param group the current tab group being displayed
+ */
+ private void setTabGroup(ILaunchConfigurationTabGroup group) {
+ fTabGroup = group;
+ }
+
+ /**
+ * Returns the current tab group
+ *
+ * @return the current tab group, or <code>null</code> if none
+ */
+ public ILaunchConfigurationTabGroup getTabGroup() {
+ return fTabGroup;
+ }
+
+ /**
+ * Notification that a tab has been selected
+ *
+ * Disallow tab changing when the current tab is invalid.
+ * Update the config from the tab being left, and refresh
+ * the tab being entered.
+ */
+ protected void handleTabSelected() {
+ if (isDisposingTabs()) {
+ return;
+ }
+ ILaunchConfigurationTab[] tabs = getTabs();
+ if (fCurrentTabIndex == getTabFolder().getSelectionIndex() || tabs == null || tabs.length == 0 || fCurrentTabIndex > (tabs.length - 1)) {
+ return;
+ }
+ if (fCurrentTabIndex != -1) {
+ ILaunchConfigurationTab tab = tabs[fCurrentTabIndex];
+ ILaunchConfigurationWorkingCopy wc = getWorkingCopy();
+ if (wc != null) {
+ // apply changes when leaving a tab
+ tab.performApply(wc);
+ // re-initialize a tab when entering it
+ getActiveTab().initializeFrom(wc);
+ }
+ }
+ fCurrentTabIndex = getTabFolder().getSelectionIndex();
+ SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
+ fireSelectionChanged(event);
+ }
+
+ /**
+ * Notification the name field has been modified
+ */
+ protected void handleNameModified() {
+ if (getWorkingCopy() != null) {
+ try {
+ verifyName();
+ getWorkingCopy().rename(getNameWidget().getText().trim());
+ } catch (CoreException ce) {
+ // verification failed
+ }
+ // fire selection changed so the launch dialog will update
+ fireSelectionChanged(new SelectionChangedEvent(this, getSelection()));
+ }
+ }
+
+ /**
+ * Notification that the 'Apply' button has been pressed
+ */
+ protected void handleApplyPressed() {
+ try {
+ // trim name
+ Text widget = getNameWidget();
+ widget.setText(widget.getText().trim());
+ if (isDirty()) {
+ getWorkingCopy().doSave();
+ }
+ } catch (CoreException e) {
+ DebugUIPlugin.errorDialog(getShell(), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Launch_Configuration_Error_46"), LaunchConfigurationsMessages.getString("LaunchConfigurationDialog.Exception_occurred_while_saving_launch_configuration_47"), e); //$NON-NLS-1$ //$NON-NLS-2$
+ return;
+ }
+ refresh();
+ }
+
+ /**
+ * Notification that the 'Revert' button has been pressed
+ */
+ protected void handleRevertPressed() {
+ inputChanged(getOriginal());
+ }
+
+ /**
+ * Iterate over the pages to update the working copy
+ */
+ private void updateWorkingCopyFromPages() {
+ ILaunchConfigurationWorkingCopy workingCopy = getWorkingCopy();
+ if (getTabGroup() != null) {
+ getTabGroup().performApply(workingCopy);
+ }
+ }
+
+ /**
+ * Show an error dialog on the given exception.
+ *
+ * @param exception
+ */
+ protected void errorDialog(CoreException exception) {
+ ErrorDialog.openError(getShell(), null, null, exception.getStatus());
+ }
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java
new file mode 100644
index 000000000..78de2de02
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationView.java
@@ -0,0 +1,268 @@
+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 org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationListener;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
+import org.eclipse.debug.ui.AbstractDebugView;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.IWorkingSetManager;
+import org.eclipse.ui.help.WorkbenchHelp;
+import org.eclipse.ui.model.WorkbenchViewerSorter;
+
+/**
+ * A tree view of launch configurations
+ */
+public class LaunchConfigurationView extends AbstractDebugView implements ILaunchConfigurationListener {
+
+ private Viewer fViewer;
+
+ /**
+ * The launch group to display
+ */
+ private LaunchGroupExtension fLaunchGroup;
+
+ /**
+ * Actions
+ */
+ private CreateLaunchConfigurationAction fCreateAction;
+ private DeleteLaunchConfigurationAction fDeleteAction;
+ private DuplicateLaunchConfigurationAction fDuplicateAction;
+
+ /**
+ * Manager for working set related a actions.
+ */
+ private LaunchConfigurationWorkingSetActionManager fWorkingSetActionManager;
+
+ /**
+ * Constructs a launch configuration view for the given launch group
+ */
+ public LaunchConfigurationView(LaunchGroupExtension launchGroup) {
+ super();
+ fLaunchGroup = launchGroup;
+ }
+
+ /**
+ * Returns the launch group this view is displaying.
+ *
+ * @return the launch group this view is displaying
+ */
+ protected LaunchGroupExtension getLaunchGroup() {
+ return fLaunchGroup;
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite)
+ */
+ protected Viewer createViewer(Composite parent) {
+ TreeViewer treeViewer = new TreeViewer(parent);
+ treeViewer.setLabelProvider(DebugUITools.newDebugModelPresentation());
+ treeViewer.setSorter(new WorkbenchViewerSorter());
+ treeViewer.setContentProvider(new LaunchConfigurationTreeContentProvider(fLaunchGroup.getMode(), parent.getShell()));
+ treeViewer.addFilter(new LaunchGroupFilter(getLaunchGroup()));
+ treeViewer.setInput(ResourcesPlugin.getWorkspace().getRoot());
+ treeViewer.expandAll();
+ DebugPlugin.getDefault().getLaunchManager().addLaunchConfigurationListener(this);
+
+ IPropertyChangeListener titleUpdater= new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ String property= event.getProperty();
+ if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE.equals(property)) {
+ // TODO: tooltip
+ //updateTreeLabelTooltip();
+ }
+ }
+ };
+ setWorkingSetActionManager(new LaunchConfigurationWorkingSetActionManager(treeViewer, parent.getShell(), titleUpdater));
+
+ return treeViewer;
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractDebugView#createActions()
+ */
+ protected void createActions() {
+
+ fCreateAction = new CreateLaunchConfigurationAction(getViewer());
+ setAction(CreateLaunchConfigurationAction.ID_CREATE_ACTION, fCreateAction);
+
+ fDeleteAction = new DeleteLaunchConfigurationAction(getViewer());
+ setAction(DeleteLaunchConfigurationAction.ID_DELETE_ACTION, fDeleteAction);
+ setAction(IDebugView.REMOVE_ACTION, fDeleteAction);
+
+ fDuplicateAction = new DuplicateLaunchConfigurationAction(getViewer());
+ setAction(DuplicateLaunchConfigurationAction.ID_DUPLICATE_ACTION, fDuplicateAction);
+
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractDebugView#getHelpContextId()
+ */
+ protected String getHelpContextId() {
+ return IDebugHelpContextIds.LAUNCH_CONFIGURATION_VIEW;
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractDebugView#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ protected void fillContextMenu(IMenuManager menu) {
+ menu.add(fCreateAction);
+ menu.add(fDuplicateAction);
+ menu.add(fDeleteAction);
+ menu.add(new Separator());
+ getWorkingSetActionManager().contributeToMenu(menu);
+ }
+
+ /**
+ * @see org.eclipse.debug.ui.AbstractDebugView#configureToolBar(org.eclipse.jface.action.IToolBarManager)
+ */
+ protected void configureToolBar(IToolBarManager tbm) {
+ }
+
+ /**
+ * Returns this view's tree viewer
+ *
+ * @return this view's tree viewer
+ */
+ protected TreeViewer getTreeViewer() {
+ return (TreeViewer)getViewer();
+ }
+
+ /**
+ * @see org.eclipse.ui.IWorkbenchPart#dispose()
+ */
+ public void dispose() {
+ getWorkingSetActionManager().dispose();
+ fCreateAction.dispose();
+ fDeleteAction.dispose();
+ fDuplicateAction.dispose();
+ DebugPlugin.getDefault().getLaunchManager().removeLaunchConfigurationListener(this);
+ }
+
+ /**
+ * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationAdded(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ public void launchConfigurationAdded(ILaunchConfiguration configuration) {
+ try {
+ getTreeViewer().add(configuration.getType(), configuration);
+ } catch (CoreException e) {
+ }
+ getTreeViewer().setSelection(new StructuredSelection(configuration), true);
+ }
+
+ /**
+ * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationChanged(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ public void launchConfigurationChanged(ILaunchConfiguration configuration) {
+ }
+
+ /**
+ * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationRemoved(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ public void launchConfigurationRemoved(ILaunchConfiguration configuration) {
+ ILaunchConfigurationType type = null;
+ int typeIndex= -1; // The index of the deleted configuration's type
+ int configIndex= -1; // The index of the deleted configuration
+ // Initialize data used to set the selection after deletion
+ TreeItem[] items= getTreeViewer().getTree().getItems();
+ TreeItem typeItem;
+ for (int i= 0, numTypes= items.length; (i < numTypes && type == null); i++) {
+ typeItem= items[i];
+ typeIndex= i;
+ TreeItem[] configs= typeItem.getItems();
+ for (int j= 0, numConfigs= configs.length; j < numConfigs; j++) {
+ if (configuration.equals(configs[j].getData())) {
+ configIndex= j;
+ type = (ILaunchConfigurationType)typeItem.getData();
+ break;
+ }
+ }
+ }
+
+ getTreeViewer().remove(configuration);
+ if (getViewer().getSelection().isEmpty()) {
+ IStructuredSelection newSelection= null;
+ if (typeIndex != -1 && configIndex != -1) {
+ // Reset selection to the next config
+ TreeItem[] configItems= getTreeViewer().getTree().getItems()[typeIndex].getItems();
+ int numItems= configItems.length;
+ if (numItems > configIndex) { // Select the item at the same index as the deleted
+ newSelection= new StructuredSelection(configItems[configIndex].getData());
+ } else if (numItems > 0) { // Deleted the last item(s). Select the last item
+ newSelection= new StructuredSelection(configItems[numItems - 1].getData());
+ }
+ }
+ if (newSelection == null && type != null) {
+ // Reset selection to the config type of the first selected configuration
+ newSelection = new StructuredSelection(type);
+ }
+ getTreeViewer().setSelection(newSelection);
+ }
+ }
+
+ /**
+ * This is similar to IWorkbenchPart#createPartControl(Composite), but it is
+ * called by the launch dialog when creating the launch config tree view.
+ * Since this view is not contained in the workbench, we cannot do all the
+ * usual initialzation (toolbars, etc).
+ */
+ public void createLaunchDialogControl(Composite parent) {
+ fViewer = createViewer(parent);
+ createActions();
+ createContextMenu(getViewer().getControl());
+ WorkbenchHelp.setHelp(parent, getHelpContextId());
+ getViewer().getControl().addKeyListener(new KeyAdapter() {
+ public void keyPressed(KeyEvent e) {
+ handleKeyPressed(e);
+ }
+ });
+ if (getViewer() instanceof StructuredViewer) {
+ ((StructuredViewer)getViewer()).addDoubleClickListener(this);
+ }
+ }
+
+
+
+ /**
+ * @see org.eclipse.debug.ui.IDebugView#getViewer()
+ */
+ public Viewer getViewer() {
+ return fViewer;
+ }
+
+ private void setWorkingSetActionManager(LaunchConfigurationWorkingSetActionManager actionManager) {
+ fWorkingSetActionManager = actionManager;
+ }
+
+ protected LaunchConfigurationWorkingSetActionManager getWorkingSetActionManager() {
+ return fWorkingSetActionManager;
+ }
+
+
+
+}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationWorkingSetActionManager.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationWorkingSetActionManager.java
index d50bb0432..eafe1f79b 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationWorkingSetActionManager.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/launchConfigurations/LaunchConfigurationWorkingSetActionManager.java
@@ -276,7 +276,7 @@ public class LaunchConfigurationWorkingSetActionManager {
fTitleUpdater = titleUpdater;
}
- private IPropertyChangeListener getTitleUpdater() {
+ protected IPropertyChangeListener getTitleUpdater() {
return fTitleUpdater;
}
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
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/AbstractDebugView.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/AbstractDebugView.java
index a5231e4ae..070f35f54 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/AbstractDebugView.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/AbstractDebugView.java
@@ -345,7 +345,9 @@ public abstract class AbstractDebugView extends PageBookView implements IDebugVi
menuControl.setMenu(menu);
// register the context menu such that other plugins may contribute to it
- getSite().registerContextMenu(menuMgr, getViewer());
+ if (getSite() != null) {
+ getSite().registerContextMenu(menuMgr, getViewer());
+ }
addContextMenuManager(menuMgr);
}
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
index 22e515cb4..7bb757b0d 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/DebugUITools.java
@@ -31,20 +31,8 @@ import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.DefaultLabelProvider;
import org.eclipse.debug.internal.ui.DelegatingModelPresentation;
import org.eclipse.debug.internal.ui.LazyModelPresentation;
-import org
- .eclipse
- .debug
- .internal
- .ui
- .launchConfigurations
- .LaunchConfigurationDialog;
-import org
- .eclipse
- .debug
- .internal
- .ui
- .launchConfigurations
- .LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
+import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
@@ -52,6 +40,7 @@ import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
@@ -315,13 +304,14 @@ public class DebugUITools {
* @since 2.1
*/
public static int openLaunchConfigurationDialogOnGroup(Shell shell, IStructuredSelection selection, String groupIdentifier) {
- LaunchConfigurationDialog dialog = (LaunchConfigurationDialog) LaunchConfigurationDialog.getCurrentlyVisibleLaunchConfigurationDialog();
+ LaunchConfigurationsDialog dialog = (LaunchConfigurationsDialog) LaunchConfigurationsDialog.getCurrentlyVisibleLaunchConfigurationDialog();
if (dialog != null) {
- dialog.setTreeViewerSelection(selection);
- return LaunchConfigurationDialog.LAUNCH_CONFIGURATION_DIALOG_REUSE_OPEN;
+ dialog.setInitialSelection(selection);
+ dialog.doInitialTreeSelection();
+ return Window.OK;
} else {
- dialog = new LaunchConfigurationDialog(shell, null, LaunchConfigurationManager.getDefault().getLaunchGroup(groupIdentifier));
- dialog.setOpenMode(LaunchConfigurationDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION);
+ dialog = new LaunchConfigurationsDialog(shell, null, LaunchConfigurationManager.getDefault().getLaunchGroup(groupIdentifier));
+ dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION);
dialog.setInitialSelection(selection);
return dialog.open();
}

Back to the top