blob: 7ef512afa2ec4b804b1ba6cf816076675cbf29a0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sebastian Davids - Bug 137923
* Mohamed Hussein (Mentor Graphics) - Added s/getWarningMessage (Bug 386673)
* Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes
*******************************************************************************/
package org.eclipse.debug.internal.ui.launchConfigurations;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
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.core.IStatusHandler;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.core.LaunchConfigurationWorkingCopy;
import org.eclipse.debug.internal.core.LaunchManager;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
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.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
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.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.ProgressMonitorPart;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.WorkbenchJob;
import com.ibm.icu.text.MessageFormat;
/**
* The dialog used to edit and launch launch configurations.
*/
public class LaunchConfigurationsDialog extends TitleAreaDialog implements ILaunchConfigurationDialog, IPropertyChangeListener {
/**
* Keep track of the currently visible dialog instance
*/
private static ILaunchConfigurationDialog fgCurrentlyVisibleLaunchConfigurationDialog;
/**
* 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;
/**
* The id for the 'No' button on the discard changes message box
* @since 3.3
*/
protected static final int ID_DISCARD_BUTTON = IDialogConstants.CLIENT_ID + 4;
/**
* 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.
*/
protected static final float MAX_DIALOG_WIDTH_PERCENT = 0.75f;
/**
* Constant specifying how tall this dialog is allowed to get (as a percentage of
* total available screen height) as a result of preferred tab size.
*/
protected static final float MAX_DIALOG_HEIGHT_PERCENT = 0.65f;
/**
* Size of this dialog if there is no preference specifying a size.
*/
protected static final Point DEFAULT_INITIAL_DIALOG_SIZE = new Point(800, 640);
/**
* defines some default sash weights when we have a new workspace
* @since 3.2
*/
private static final int[] DEFAULT_SASH_WEIGHTS = new int[] {190, 610};
/**
* 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;
/**
* defines the delimiter used in the persistence of the expanded state
* @since 3.2
*/
private static final String DELIMITER = ", "; //$NON-NLS-1$
/**
* 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_OPEN_ON_LAST_LAUNCHED;
private boolean fIsShift = false;
/**
* dialog settings
*/
private static final String DIALOG_SASH_WEIGHTS_1 = IDebugUIConstants.PLUGIN_ID + ".DIALOG_SASH_WEIGHTS_1"; //$NON-NLS-1$
private static final String DIALOG_SASH_WEIGHTS_2 = IDebugUIConstants.PLUGIN_ID + ".DIALOG_SASH_WEIGHTS_2"; //$NON-NLS-1$
private static final String DIALOG_EXPANDED_NODES = IDebugUIConstants.PLUGIN_ID + ".EXPANDED_NODES"; //$NON-NLS-1$
/**
* Returns the currently visible dialog
* @return the currently visible launch dialog
*/
public static ILaunchConfigurationDialog getCurrentlyVisibleLaunchConfigurationDialog() {
return fgCurrentlyVisibleLaunchConfigurationDialog;
}
/**
* Sets which launch dialog is currently the visible one
* @param dialog the dialog to set as the visible one
*/
public static void setCurrentlyVisibleLaunchConfigurationDialog(ILaunchConfigurationDialog dialog) {
fgCurrentlyVisibleLaunchConfigurationDialog = dialog;
}
/**
* widgets
*/
private Control fLastControl;
private Composite fButtonComp;
private SashForm fSashForm;
private LaunchConfigurationView fLaunchConfigurationView;
private LaunchConfigurationTabGroupViewer fTabViewer;
private ProgressMonitorPart fProgressMonitorPart;
private LaunchGroupExtension fGroup;
private Image fBannerImage;
/**
* 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;
/**
* The status to open the dialog on, or <code>null</code> if none.
*/
private IStatus fInitialStatus;
/**
* The number of 'long-running' operations currently taking place in this dialog
*/
private long fActiveRunningOperations = 0;
/**
* Double-click action
*/
private IAction fDoubleClickAction;
/**
* Filters for the LCD
* @since 3.2
*/
private ClosedProjectFilter fClosedProjectFilter;
private DeletedProjectFilter fDeletedProjectFilter;
private LaunchConfigurationTypeFilter fLCTFilter;
private WorkingSetsFilter fWorkingSetsFilter;
/**
* set of reserved names that should not be considered when generating a new name for a launch configuration
*/
protected Set<String> fReservedNames = null;
/**
* Whether to set default values when opened
* @since 3.6
*/
private boolean fSetDefaultOnOpen = false;
/**
* Whether in the process of setting the input to the tab viewer
*/
private boolean fSettingInput = false;
/**
* Constructs a new launch configuration dialog on the given
* parent shell.
*
* @param shell the parent shell
* @param group the group of launch configuration to display
*/
public LaunchConfigurationsDialog(Shell shell, LaunchGroupExtension group) {
super(shell);
setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
setLaunchGroup(group);
}
/**
* Adds content to the dialog area
*
* @param dialogComp
*/
protected void addContent(Composite dialogComp) {
GridData gd;
Composite topComp = new Composite(dialogComp, SWT.NONE);
gd = new GridData(GridData.FILL_BOTH);
topComp.setLayoutData(gd);
GridLayout topLayout = new GridLayout(2, false);
topLayout.marginHeight = 5;
topLayout.marginWidth = 5;
topComp.setLayout(topLayout);
// Set the things that TitleAreaDialog takes care of
setTitle(LaunchConfigurationsMessages.LaunchConfigurationDialog_Create__manage__and_run_launch_configurations_8);
setMessage(LaunchConfigurationsMessages.LaunchConfigurationDialog_Ready_to_launch_2);
setModeLabelState();
// Create the SashForm that contains the selection area on the left,
// and the edit area on the right
gd = new GridData(GridData.FILL_BOTH);
gd.horizontalSpan = 2;
SashForm sash = new SashForm(topComp, SWT.SMOOTH);
sash.setOrientation(SWT.HORIZONTAL);
sash.setLayoutData(gd);
sash.setFont(dialogComp.getFont());
sash.setVisible(true);
fSashForm = sash;
// Build the launch configuration selection area and put it into the composite.
Control launchConfigSelectionArea = createLaunchConfigurationSelectionArea(fSashForm);
gd = new GridData(GridData.FILL_VERTICAL);
launchConfigSelectionArea.setLayoutData(gd);
// Build the launch configuration edit area and put it into the composite.
Composite editAreaComp = createLaunchConfigurationEditArea(fSashForm);
gd = new GridData(GridData.FILL_BOTH);
editAreaComp.setLayoutData(gd);
dialogComp.layout(true);
applyDialogFont(dialogComp);
}
/**
* Handle the 'close' & 'launch' buttons here, all others are handled
* in <code>Dialog</code>
*
* @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
*/
@Override
protected void buttonPressed(int buttonId) {
if (buttonId == ID_LAUNCH_BUTTON) {
handleLaunchPressed();
}
else if (buttonId == ID_CLOSE_BUTTON) {
handleClosePressed();
}
else {
super.buttonPressed(buttonId);
}
}
/**
* Return whether the current configuration should be saved or discarded. This involves determining
* if it is dirty, and if it is, asking the user what to do.
*
* @return if we can discard the current config or not
*/
protected int shouldSaveCurrentConfig() {
if (fTabViewer.isDirty()) {
if (fTabViewer.canSave()) {
return showSaveChangesDialog();
}
return showUnsavedChangesDialog();
}
return IDialogConstants.NO_ID;
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#close()
*/
@Override
public boolean close() {
if (!isSafeToClose()) {
return false;
}
persistSashWeights();
persistExpansion();
setCurrentlyVisibleLaunchConfigurationDialog(null);
fTabViewer.dispose();
if (fLaunchConfigurationView != null) {
fLaunchConfigurationView.dispose();
}
DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
boolean result = super.close();
getBannerImage().dispose();
return result;
}
/**
* Sets the title for the dialog, and establishes the help context.
*
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell);
*/
@Override
protected void configureShell(Shell shell) {
super.configureShell(shell);
shell.setText(getShellTitle());
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#create()
*/
@Override
public void create() {
super.create();
if (fTabViewer.getInput() == null) {
fTabViewer.inputChanged(null);
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createButtonBar(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createButtonBar(Composite parent) {
Font font = parent.getFont();
Composite composite = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight= 0;
layout.marginWidth= 0;
layout.marginLeft = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
composite.setFont(font);
// create help control if needed
if (isHelpAvailable()) {
createHelpControl(composite);
}
Composite monitorComposite = new Composite(composite, SWT.NULL);
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 2;
monitorComposite.setLayout(layout);
monitorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
GridLayout pmLayout = new GridLayout();
fProgressMonitorPart= new ProgressMonitorPart(monitorComposite, pmLayout, true);
fProgressMonitorPart.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
fProgressMonitorPart.setFont(font);
monitorComposite.setVisible(false);
/*
* Create the rest of the button bar, but tell it not to
* create a help button (we've already created it).
*/
boolean helpAvailable = isHelpAvailable();
setHelpAvailable(false);
fButtonComp = (Composite) super.createButtonBar(composite);
setHelpAvailable(helpAvailable);
return composite;
}
/**
*
* @param buttonId
*/
protected void launchButtonPressed(int buttonId) {
if (buttonId == ID_LAUNCH_BUTTON) {
handleLaunchPressed();
} else if (buttonId == ID_CLOSE_BUTTON) {
handleClosePressed();
} else {
super.buttonPressed(buttonId);
}
}
/**
* 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(org.eclipse.swt.widgets.Composite)
*/
@Override
protected void createButtonsForButtonBar(Composite parent) {
Button button = createButton(parent, ID_LAUNCH_BUTTON, getLaunchButtonText(), true);
button.setEnabled(false);
Listener[] listeners = button.getListeners(SWT.Selection);
for (Listener listener : listeners) {
button.removeListener(SWT.Selection, listener);
}
listeners = button.getListeners(SWT.DefaultSelection);
for (Listener listener : listeners) {
button.removeListener(SWT.DefaultSelection, listener);
}
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
setShift(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
handleLaunchPressed();
}
});
createButton(parent, ID_CLOSE_BUTTON, LaunchConfigurationsMessages.LaunchConfigurationDialog_Close_1, false);
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createContents(Composite parent) {
Control contents = super.createContents(parent);
initializeContent();
PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), getHelpContextId());
return contents;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Control createDialogArea(Composite parent) {
Composite dialogComp = (Composite)super.createDialogArea(parent);
addContent(dialogComp);
if(fLaunchConfigurationView != null) {
fLaunchConfigurationView.updateFilterLabel();
}
return dialogComp;
}
/**
* 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
*/
protected Composite createLaunchConfigurationEditArea(Composite parent) {
setTabViewer(new LaunchConfigurationTabGroupViewer(parent, this));
return (Composite)fTabViewer.getControl();
}
/**
* Creates all of the actions for the toolbar
* @param toolbar
* @since 3.2
*/
protected void createToolbarActions(ToolBarManager tmanager) {
tmanager.add(getNewAction());
tmanager.add(getNewPrototypeAction());
tmanager.add(getExportAction());
tmanager.add(getDuplicateAction());
tmanager.add(getDeleteAction());
tmanager.add(new Separator());
tmanager.add(getCollapseAllAction());
tmanager.add(getFilterAction());
tmanager.update(true);
DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
}
protected void setShift(boolean isShift) {
fIsShift = isShift;
}
/**
* 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
*/
protected Control createLaunchConfigurationSelectionArea(Composite parent) {
Composite comp = new Composite(parent, SWT.FLAT);
GridLayout gridLayout = new GridLayout(1, false);
gridLayout.marginHeight = 0;
gridLayout.marginWidth = 0;
comp.setLayout(gridLayout);
comp.setLayoutData(new GridData(GridData.FILL_BOTH));
ViewForm viewForm = new ViewForm(comp, SWT.FLAT | SWT.BORDER);
ToolBarManager toolBarManager= new ToolBarManager(SWT.FLAT);
ToolBar toolBar = toolBarManager.createControl(viewForm);
toolBar.setBackground(parent.getBackground());
viewForm.setTopLeft(toolBar);
viewForm.setLayoutData(new GridData(GridData.FILL_BOTH));
Composite viewFormContents = new Composite(viewForm, SWT.FLAT);
gridLayout = new GridLayout();
gridLayout.marginHeight = 5;
gridLayout.marginWidth = 5;
viewFormContents.setLayout(gridLayout);
viewFormContents.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
fLaunchConfigurationView = new LaunchConfigurationView(getLaunchGroup(), createViewerFilters());
fLaunchConfigurationView.createLaunchDialogControl(viewFormContents);
Text filterText = fLaunchConfigurationView.getFilteringTextControl();
if (filterText != null){
filterText.setFocus();
}
//create toolbar actions, we reuse the actions from the view so we wait until after
//the view is created to add them to the toolbar
createToolbarActions(toolBarManager);
fDoubleClickAction = new Action() {
@Override
public void run() {
runInternal(false);
}
@Override
public void runWithEvent(Event event) {
runInternal(((event.stateMask & SWT.SHIFT) > 0) ? true : false);
}
void runInternal(boolean isShift) {
IStructuredSelection selection = (IStructuredSelection)fLaunchConfigurationView.getViewer().getSelection();
Object target = selection.getFirstElement();
if (target instanceof ILaunchConfiguration) {
if (fTabViewer.canLaunch() & fTabViewer.canLaunchWithModes() & !fTabViewer.hasDuplicateDelegates()) {
setShift(isShift);
handleLaunchPressed();
}
} else {
getNewAction().run();
}
}
};
fLaunchConfigurationView.setAction(IDebugView.DOUBLE_CLICK_ACTION, fDoubleClickAction);
Viewer viewer = fLaunchConfigurationView.getViewer();
Control control = viewer.getControl();
GridData gd = new GridData(GridData.FILL_BOTH);
control.setLayoutData(gd);
viewForm.setContent(viewFormContents);
AbstractLaunchConfigurationAction.IConfirmationRequestor requestor = new AbstractLaunchConfigurationAction.IConfirmationRequestor() {
@Override
public boolean getConfirmation() {
int status = shouldSaveCurrentConfig();
if(status == IDialogConstants.YES_ID) {
fTabViewer.handleApplyPressed();
return true;
}
else if(status == IDialogConstants.NO_ID) {
fTabViewer.handleRevertPressed();
return true;
}
return false;
}
};
getDuplicateAction().setConfirmationRequestor(requestor);
getExportAction().setConfirmationRequestor(requestor);
getNewAction().setConfirmationRequestor(requestor);
getNewPrototypeAction().setConfirmationRequestor(requestor);
getLinkPrototypeAction().setConfirmationRequestor(requestor);
getUnlinkPrototypeAction().setConfirmationRequestor(requestor);
getResetWithPrototypeValuesAction().setConfirmationRequestor(requestor);
((StructuredViewer) viewer).addPostSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
handleLaunchConfigurationSelectionChanged(event);
getNewAction().setEnabled(getNewAction().isEnabled());
getNewPrototypeAction().setEnabled(getNewPrototypeAction().isEnabled());
getDeleteAction().setEnabled(getDeleteAction().isEnabled());
getExportAction().setEnabled(getExportAction().isEnabled());
getDuplicateAction().setEnabled(getDuplicateAction().isEnabled());
getLinkPrototypeAction().setEnabled(getLinkPrototypeAction().isEnabled());
getUnlinkPrototypeAction().setEnabled(getUnlinkPrototypeAction().isEnabled());
getResetWithPrototypeValuesAction().setEnabled(getResetWithPrototypeValuesAction().isEnabled());
}
});
return comp;
}
/**
* Create the filters to be initially applied to the viewer.
* The initial filters are based on the persisted preferences
* @return the array of initial filters
* @since 3.2
*/
private ViewerFilter[] createViewerFilters() {
ArrayList<ViewerFilter> filters = new ArrayList<>();
fClosedProjectFilter = new ClosedProjectFilter();
if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_CLOSED)) {
filters.add(fClosedProjectFilter);
}
fDeletedProjectFilter = new DeletedProjectFilter();
if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_DELETED)) {
filters.add(fDeletedProjectFilter);
}
fLCTFilter = new LaunchConfigurationTypeFilter();
if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES)) {
filters.add(fLCTFilter);
}
fWorkingSetsFilter = new WorkingSetsFilter();
if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_WORKING_SETS)) {
filters.add(fWorkingSetsFilter);
}
return filters.toArray(new ViewerFilter[filters.size()]);
}
/**
* Set the initial selection in the tree.
*/
public void doInitialTreeSelection() {
fLaunchConfigurationView.getViewer().setSelection(fInitialSelection);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#generateName(java.lang.String)
*/
@Override
public String generateName(String name) {
if (name == null) {
return getLaunchManager().generateLaunchConfigurationName(IInternalDebugCoreConstants.EMPTY_STRING);
}
return getLaunchManager().generateLaunchConfigurationName(name);
}
/**
* Generates and returns a unique name using the specified name as a prefix in the event
* the specified name already exists or is contained in the set of reserved names.
* @param name the name to use as a prefix for generating a new name
* @param reservednames a listing of names that should be considered as 'taken' and cannot be generated
* by this method
* @return a new name based on the specified name.
*
* @since 3.3
*/
public String generateName(String name, Set<String> reservednames) {
if(name == null) {
return ((LaunchManager) getLaunchManager()).generateUniqueLaunchConfigurationNameFrom(IInternalDebugCoreConstants.EMPTY_STRING, reservednames);
}
return ((LaunchManager)getLaunchManager()).generateUniqueLaunchConfigurationNameFrom(name, reservednames);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#getActiveTab()
*/
@Override
public ILaunchConfigurationTab getActiveTab() {
return fTabViewer.getActiveTab();
}
/**
* 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;
}
/**
* Gets the delete menu action
*
* @return the delete menu action
*/
protected AbstractLaunchConfigurationAction getDeleteAction() {
return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(DeleteLaunchConfigurationAction.ID_DELETE_ACTION);
}
/**
* Gets the filter action
* @return the filter menu action
* @since 3.2
*/
protected IAction getFilterAction() {
return fLaunchConfigurationView.getAction(FilterLaunchConfigurationAction.ID_FILTER_ACTION);
}
/**
* Gets the collapse all action
* @return the collapse all action
* @since 3.2
*/
protected IAction getCollapseAllAction() {
return fLaunchConfigurationView.getAction(CollapseAllLaunchConfigurationAction.ID_COLLAPSEALL_ACTION);
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
* @since 3.2
*/
@Override
protected IDialogSettings getDialogBoundsSettings() {
return getDialogSettings();
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsStrategy()
*/
@Override
protected int getDialogBoundsStrategy() {
return DIALOG_PERSISTSIZE;
}
/**
* Returns the dialog settings for this dialog. Subclasses should override
* <code>getDialogSettingsSectionName()</code>.
*
* @return IDialogSettings
*/
protected IDialogSettings getDialogSettings() {
IDialogSettings settings = DebugUIPlugin.getDefault().getDialogSettings();
IDialogSettings section = settings.getSection(getDialogSettingsSectionName());
if (section == null) {
section = settings.addNewSection(getDialogSettingsSectionName());
}
return section;
}
/**
* Returns the name of the section that this dialog stores its settings in
*
* @return String
*/
protected String getDialogSettingsSectionName() {
return IDebugUIConstants.PLUGIN_ID + ".LAUNCH_CONFIGURATIONS_DIALOG_SECTION"; //$NON-NLS-1$
}
/**
* Gets the current display
*
* @return the display
*/
protected Display getDisplay() {
Shell shell = getShell();
if (shell != null) {
return shell.getDisplay();
}
return DebugUIPlugin.getStandardDisplay();
}
/**
* Gets the duplicate menu action
*
* @return the duplicate menu action
*/
protected AbstractLaunchConfigurationAction getDuplicateAction() {
return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(DuplicateLaunchConfigurationAction.ID_DUPLICATE_ACTION);
}
/**
* Gets the export menu action
*
* @return the export menu action
*/
protected AbstractLaunchConfigurationAction getExportAction() {
return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(ExportLaunchConfigurationAction.ID_EXPORT_ACTION);
}
/**
* Gets the help context id
*
* @return the help context id
*/
protected String getHelpContextId() {
return IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG;
}
/**
* Returns the status the dialog was opened on or <code>null</code> if none.
*
* @return IStatus
*/
protected IStatus getInitialStatus() {
return fInitialStatus;
}
/**
* Return the last launched configuration in the workspace.
*
* @return the last launched configuration
*/
protected ILaunchConfiguration getLastLaunchedWorkbenchConfiguration() {
return DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLastLaunch(getLaunchGroup().getIdentifier());
}
/**
* Returns the appropriate text for the launch button - run or debug.
*
* @return the launch button text
*/
protected String getLaunchButtonText() {
return DebugPlugin.getDefault().getLaunchManager().getLaunchMode(getMode()).getLabel();
}
/**
* Returns the launch group being displayed.
*
* @return launch group
*/
public LaunchGroupExtension getLaunchGroup() {
return fGroup;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#getMode()
*/
@Override
public String getMode() {
return getLaunchGroup().getMode();
}
/**
* Gets the new menu action
*
* @return the new menu action
*/
protected AbstractLaunchConfigurationAction getNewAction() {
return (AbstractLaunchConfigurationAction)fLaunchConfigurationView.getAction(CreateLaunchConfigurationAction.ID_CREATE_ACTION);
}
/**
* Gets the new prototype menu action
*
* @return the new prototype menu action
*
* @since 3.13
*/
protected AbstractLaunchConfigurationAction getNewPrototypeAction() {
return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(CreateLaunchConfigurationPrototypeAction.ID_CREATE_PROTOTYPE_ACTION);
}
/**
* Gets the link prototype menu action
*
* @return the link prototype menu action
*
* @since 3.13
*/
protected AbstractLaunchConfigurationAction getLinkPrototypeAction() {
return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(LinkPrototypeAction.ID_LINK_PROTOTYPE_ACTION);
}
/**
* Gets the unlink prototype menu action
*
* @return the unlink prototype menu action
*
* @since 3.13
*/
protected AbstractLaunchConfigurationAction getUnlinkPrototypeAction() {
return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(UnlinkPrototypeAction.ID_UNLINK_PROTOTYPE_ACTION);
}
/**
* Gets the reset with prototype values menu action
*
* @return the reset with prototype values menu action
*
* @since 3.13
*/
protected AbstractLaunchConfigurationAction getResetWithPrototypeValuesAction() {
return (AbstractLaunchConfigurationAction) fLaunchConfigurationView.getAction(ResetWithPrototypeValuesAction.ID_RESET_WITH_PROTOTYPE_VALUES_ACTION);
}
/**
* Returns the reserved name set (if there is one), <code>null</code> otherwise
* @return the reserved name set or <code>null</code>
* @since 3.3
*
*/
public Set<String> getReservedNameSet() {
return fReservedNames;
}
/**
* returns the open mode
*
* @return the open mode
*/
protected int getOpenMode() {
return fOpenMode;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IPageChangeProvider#getSelectedPage()
*/
public Object getSelectedPage() {
return getActiveTab();
}
/**
* Returns the title of the shell
* @return the shell title
*/
protected String getShellTitle() {
String title = null;
if(getLaunchGroup() != null) {
title = MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationsDialog_configurations, new Object[] { DebugUIPlugin.removeAccelerators(getLaunchGroup().getLabel()) });
}
if (title == null) {
title = LaunchConfigurationsMessages.LaunchConfigurationDialog_Launch_Configurations_18;
}
return title;
}
/**
* Returns the current tab group
*
* @return the current tab group, or <code>null</code> if none
*/
public ILaunchConfigurationTabGroup getTabGroup() {
if (fTabViewer != null) {
return fTabViewer.getTabGroup();
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#getTabs()
*/
@Override
public ILaunchConfigurationTab[] getTabs() {
if (getTabGroup() == null) {
return null;
}
return getTabGroup().getTabs();
}
/**
* Returns the viewer used to display the tabs for a launch configuration.
*
* @return LaunchConfigurationTabGroupViewer
*/
public LaunchConfigurationTabGroupViewer getTabViewer() {
return fTabViewer;
}
/**
* Notification the 'Close' button has been pressed.
*/
protected void handleClosePressed() {
if(fTabViewer.canSave()) {
int status = shouldSaveCurrentConfig();
if(status != IDialogConstants.CANCEL_ID) {
if(status != ID_DISCARD_BUTTON) {
if(status == IDialogConstants.YES_ID) {
fTabViewer.handleApplyPressed();
}
cancelPressed();
}
}
}
else {
cancelPressed();
}
}
/**
* 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;
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
if (selection.size() == 1) {
newInput = selection.getFirstElement();
}
if (!isEqual(input, newInput)) {
ILaunchConfiguration original = fTabViewer.getOriginal();
if (original != null && newInput == null && getLaunchManager().getMovedTo(original) != null) {
return;
}
boolean deleted = false;
if (original != null) {
deleted = !original.exists();
}
boolean renamed = false;
if (newInput instanceof ILaunchConfiguration) {
renamed = getLaunchManager().getMovedFrom((ILaunchConfiguration)newInput) != null;
}
try {
fSettingInput = true;
if (fTabViewer.canSave() && fTabViewer.isDirty() && !deleted && !renamed) {
if(fLaunchConfigurationView != null) {
fLaunchConfigurationView.setAutoSelect(false);
}
int ret = showUnsavedChangesDialog();
if(ret == IDialogConstants.YES_ID) {
fTabViewer.handleApplyPressed();
ILaunchConfigurationTab[] tabs = getTabs();
if (tabs != null) {
for (ILaunchConfigurationTab tab : tabs) {
tab.postApply();
}
}
fTabViewer.setInput(newInput);
}
else if(ret == IDialogConstants.NO_ID) {
fTabViewer.handleRevertPressed();
fTabViewer.setInput(newInput);
}
else {
fLaunchConfigurationView.getViewer().setSelection(new StructuredSelection(input));
}
fLaunchConfigurationView.setAutoSelect(true);
}
else {
fTabViewer.setInput(newInput);
if(fTabViewer.isDirty()) {
fTabViewer.handleApplyPressed();
}
}
} finally {
fSettingInput = false;
updateButtons();
updateMessage();
}
if(getShell() != null && getShell().isVisible()) {
resize();
}
}
}
/**
* Notification the 'launch' button has been pressed. Save and launch.
*
*/
protected void handleLaunchPressed() {
ILaunchConfiguration config = fTabViewer.getOriginal();
if (fTabViewer.isDirty() && fTabViewer.canSave()) {
config = fTabViewer.handleApplyPressed();
}
if(config != null) {
close();
DebugUITools.launch(config, getMode(), fIsShift);
}
setShift(false);
}
/**
* Consult a status handler for the given status, if any. The status handler
* is passed this launch config dialog as an argument.
*
* @param status the status to be handled
*/
public void handleStatus(IStatus status) {
IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(status);
if (handler != null) {
try {
handler.handleStatus(status, this);
return;
}
catch (CoreException e) {status = e.getStatus();}
}
// if no handler, or handler failed, display error/warning dialog
String title = null;
switch (status.getSeverity()) {
case IStatus.ERROR:
title = LaunchConfigurationsMessages.LaunchConfigurationsDialog_Error_1;
break;
case IStatus.WARNING:
title = LaunchConfigurationsMessages.LaunchConfigurationsDialog_Warning_2;
break;
default:
title = LaunchConfigurationsMessages.LaunchConfigurationsDialog_Information_3;
break;
}
ErrorDialog.openError(getShell(), title, null, status);
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#initializeBounds()
*/
@Override
protected void initializeBounds() {
IDialogSettings settings = getDialogSettings();
if (fSashForm != null) {
int w1, w2;
try {
w1 = settings.getInt(DIALOG_SASH_WEIGHTS_1);
if(w1 < 10) {
w1 = DEFAULT_SASH_WEIGHTS[0];
}
w2 = settings.getInt(DIALOG_SASH_WEIGHTS_2);
if(w2 < 10) {
w2 = DEFAULT_SASH_WEIGHTS[1];
}
}
catch(NumberFormatException nfe) {
w1 = DEFAULT_SASH_WEIGHTS[0];
w2 = DEFAULT_SASH_WEIGHTS[1];
}
fSashForm.setWeights(new int[] {w1, w2});
}
super.initializeBounds();
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.TitleAreaDialog#getInitialSize()
*/
@Override
protected Point getInitialSize() {
try {
getDialogSettings().getInt("DIALOG_HEIGHT"); //$NON-NLS-1$
return super.getInitialSize();
}
catch(NumberFormatException nfe) {
return DEFAULT_INITIAL_DIALOG_SIZE;
}
}
/**
* Sets the default values for the given {@link LaunchConfigurationWorkingCopy}
* @param wc
* @since 3.6
*/
protected void doSetDefaults(ILaunchConfigurationWorkingCopy wc) {
try {
ILaunchConfigurationTabGroup tabGroup = LaunchConfigurationPresentationManager.getDefault().getTabGroup(wc, getMode());
// 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++) {
tabs[i].setLaunchConfigurationDialog(dialog);
}
tabGroup.setDefaults(wc);
tabGroup.dispose();
} catch (CoreException e) {
DebugUIPlugin.log(e.getStatus());
}
}
/**
* Performs initialization of the content by setting the initial tree selection
*/
protected void initializeContent() {
if(fSetDefaultOnOpen) {
try {
Object o = fInitialSelection.getFirstElement();
if(o instanceof ILaunchConfigurationWorkingCopy) {
ILaunchConfigurationWorkingCopy wc = (ILaunchConfigurationWorkingCopy) o;
doSetDefaults(wc);
setInitialSelection(new StructuredSelection(wc.doSave()));
}
} catch (CoreException e) {
DebugUIPlugin.log(e);
}
}
doInitialTreeSelection();
IStatus status = getInitialStatus();
if (status != null) {
handleStatus(status);
}
restoreExpansion();
}
/**
* Compares two objects to determine their equality
*
* @param o1 the first object
* @param o2 the object to compare to object one
* @return true if they are equal, false if object 1 is null, the result of o1.equals(o2) otherwise
*/
protected boolean isEqual(Object o1, Object o2) {
if (o1 == o2) {
return true;
} else if (o1 == null) {
return false;
} else {
return o1.equals(o2);
}
}
/**
* Returns whether the dialog can be closed
*
* @return whether the dialog can be closed
*/
protected boolean isSafeToClose() {
return fActiveRunningOperations == 0;
}
/**
* Determine the initial configuration for this dialog.
* Open the dialog in the mode set using #setOpenMode(int) and return one of
* <code>Window. OK</code> or <code>Window.CANCEL</code>.
*
* @see org.eclipse.jface.window.Window#open()
* @return the int status of opening the dialog
*/
@Override
public int open() {
int mode = getOpenMode();
setCurrentlyVisibleLaunchConfigurationDialog(this);
if (mode == LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_LAST_LAUNCHED) {
ILaunchConfiguration lastLaunchedConfig = getLastLaunchedWorkbenchConfiguration();
if (lastLaunchedConfig != null) {
setInitialSelection(new StructuredSelection(lastLaunchedConfig));
}
}
return super.open();
}
/**
* saves which of the nodes are expanded at the time the dialog is closed
* @since 3.2
*/
protected void persistExpansion() {
if(fLaunchConfigurationView != null) {
IDialogSettings settings = getDialogSettings();
TreeItem[] items = fLaunchConfigurationView.getTreeViewer().getTree().getItems();
String value = settings.get(DIALOG_EXPANDED_NODES);
if(value == null) {
value = IInternalDebugCoreConstants.EMPTY_STRING;
}
ArrayList<String> list = new ArrayList<>();
String[] persisted = value.split(DELIMITER);
for(int i = 0; i < persisted.length; i++) {
list.add(persisted[i]);
}
String type = IInternalDebugCoreConstants.EMPTY_STRING;
//if the item is not in the list and is expanded add it, otherwise if it
//is not expanded do a remove...either way for the else we query the list
for(int i = 0; i < items.length; i++) {
type = ((ILaunchConfigurationType)items[i].getData()).getIdentifier();
if(!list.contains(type) & items[i].getExpanded()) {
list.add(type);
}
else if(!items[i].getExpanded()) {
list.remove(type);
}
}
value = IInternalDebugCoreConstants.EMPTY_STRING;
//build the preference string
for (Iterator<String> iter = list.iterator(); iter.hasNext();) {
value += iter.next() + DELIMITER;
}
settings.put(DIALOG_EXPANDED_NODES, value);
}
}
/**
* Restore the original expansion state of the nodes in the viewer
* @since 3.2
*/
protected void restoreExpansion() {
if(fLaunchConfigurationView != null) {
IDialogSettings settings = getDialogSettings();
String value = settings.get(DIALOG_EXPANDED_NODES);
if(value != null) {
String[] nodes = value.split(DELIMITER);
TreeItem[] items = fLaunchConfigurationView.getTreeViewer().getTree().getItems();
HashSet<Object> toexpand = new HashSet<>();
// if we have a selection make sure it is expanded
if(fInitialSelection != null && !fInitialSelection.isEmpty()) {
Object obj = fInitialSelection.getFirstElement();
if(obj instanceof ILaunchConfigurationType) {
toexpand.add(obj);
}
else if(obj instanceof ILaunchConfiguration) {
try {
toexpand.add(((ILaunchConfiguration) obj).getType());
}
catch (CoreException e) {DebugUIPlugin.log(e);}
}
}
for(int i = 0; i < nodes.length; i++) {
for(int k = 0; k < items.length; k++) {
ILaunchConfigurationType type = (ILaunchConfigurationType)items[k].getData();
if(type.getIdentifier().equals(nodes[i])) {
toexpand.add(type);
}
}
}
fLaunchConfigurationView.getTreeViewer().setExpandedElements(toexpand.toArray());
}
}
}
/**
* Save the current sash weights
*/
protected void persistSashWeights() {
IDialogSettings settings = getDialogSettings();
if (fSashForm != null) {
int[] sashWeights = fSashForm.getWeights();
settings.put(DIALOG_SASH_WEIGHTS_1, (sashWeights[0] < 10 ? DEFAULT_SASH_WEIGHTS[0] : sashWeights[0]));
settings.put(DIALOG_SASH_WEIGHTS_2, (sashWeights[1] < 10 ? DEFAULT_SASH_WEIGHTS[1] : sashWeights[1]));
}
}
/**
* Update buttons and message.
*/
protected void refreshStatus() {
updateMessage();
updateButtons();
}
/**
* Refresh the launch configurations' tree viewer
*
* @since 3.13
*/
public void refreshLaunchConfigurationView() {
fLaunchConfigurationView.getTreeViewer().refresh();
}
/**
* resize the dialog to show all relevant content
*/
protected void resize() {
if(getTabGroup() != null) {
Point shell = getShell().getSize();
int maxx = (int)(getDisplay().getBounds().width * MAX_DIALOG_WIDTH_PERCENT),
maxy = (int) (getDisplay().getBounds().height * MAX_DIALOG_HEIGHT_PERCENT);
maxx = (maxx < DEFAULT_INITIAL_DIALOG_SIZE.x ? DEFAULT_INITIAL_DIALOG_SIZE.x : maxx);
maxy = (maxy < DEFAULT_INITIAL_DIALOG_SIZE.y ? DEFAULT_INITIAL_DIALOG_SIZE.y : maxy);
Point psize = getShell().computeSize(SWT.DEFAULT, maxy);
if((psize.x > maxx ? maxx : psize.x) > shell.x || (psize.y > maxy ? maxy : psize.y) > shell.y) {
setShellSize(Math.min(psize.x, maxx), Math.min(psize.y, maxy));
constrainShellSize();
}
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.operation.IRunnableContext#run(boolean, boolean, org.eclipse.jface.operation.IRunnableWithProgress)
*/
@Override
public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
if (getShell() != null && getShell().isVisible()) {
// Save focus control
fLastControl = getShell().getDisplay().getFocusControl();
if (fLastControl != null && fLastControl.getShell() != getShell()) {
fLastControl = null;
}
// Attach the progress monitor part to the cancel button
fProgressMonitorPart.attachToCancelComponent(null);
fProgressMonitorPart.getParent().setVisible(true);
fActiveRunningOperations++;
//do work here collecting enabled states, otherwise to get these states we would need to
//perform the validation of the dialog again, which is expensive and would cause flashing of widgets.
Control[] children = ((Composite)fButtonComp.getChildren()[0]).getChildren();
boolean[] prev = new boolean[children.length+2];
prev[0] = fTabViewer.getApplyButton().isEnabled();
prev[1] = fTabViewer.getRevertButton().isEnabled();
for(int i = 0; i < children.length; i++) {
prev[i+2] = children[i].isEnabled();
}
try {
updateRunnnableControls(false, prev);
ModalContext.run(runnable, fork, fProgressMonitorPart, getShell().getDisplay());
}
finally {
fActiveRunningOperations--;
updateRunnnableControls(true, prev);
if (getShell() != null) {
fProgressMonitorPart.getParent().setVisible(false);
fProgressMonitorPart.removeFromCancelComponent(null);
if (fLastControl != null && !fLastControl.isDisposed()) {
fLastControl.setFocus();
}
}
}
}
else {
PlatformUI.getWorkbench().getProgressService().run(fork, cancelable, runnable);
}
}
/**
* Updates the enablement of the runnable controls to appear disabled as a job is running
* @param enabled the desired enable status of the dialog area, revert//apply buttons, and
* @param prev the previous settings for the apply and revert buttons to be reset to, only takes effect if enable is set to true
* any children of the button bar
* @since 3.3.0
*/
private void updateRunnnableControls(boolean enabled, boolean[] prev) {
fTabViewer.getApplyButton().setEnabled(enabled ? prev[0] : enabled);
fTabViewer.getRevertButton().setEnabled(enabled ? prev[1] : enabled);
//the arrangement never differs: button comp has one child that holds all the buttons
Control[] children = ((Composite)fButtonComp.getChildren()[0]).getChildren();
for(int i = 0; i < children.length; i++) {
children[i].setEnabled(enabled ? prev[i+2] : enabled);
}
getDialogArea().setEnabled(enabled);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#setActiveTab(org.eclipse.debug.ui.ILaunchConfigurationTab)
*/
@Override
public void setActiveTab(ILaunchConfigurationTab tab) {
fTabViewer.setActiveTab(tab);
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#setActiveTab(int)
*/
@Override
public void setActiveTab(int index) {
fTabViewer.setActiveTab(index);
}
/**
* 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;
}
/**
* Sets the status to open the dialog on.
*
* @param status the initial status for the dialog
*/
public void setInitialStatus(IStatus status) {
fInitialStatus = status;
}
/**
* Sets whether the tab group should set default values in the launch configuration
* when the dialog is opened. If this method is not called, default values are not
* set.
*
* @param setDefaults whether to set default values
* @since 3.6
*/
public void setDefaultsOnOpen(boolean setDefaults) {
fSetDefaultOnOpen = setDefaults;
}
/**
* Returns if the dialog is supposed to be setting the default values for
* the initial configuration when it opens
*
* @return <code>true</code> if the defaults should be set on open, <code>false</code> otherwise
* @since 3.6
*/
public boolean shouldSetDefaultsOnOpen() {
return fSetDefaultOnOpen;
}
/**
* Sets the launch group to display.
*
* @param group launch group
*/
protected void setLaunchGroup(LaunchGroupExtension group) {
fGroup = group;
}
/**
* Set the title area image based on the mode this dialog was initialized with
*/
protected void setModeLabelState() {
setTitleImage(getBannerImage());
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#setName(java.lang.String)
*/
@Override
public void setName(String name) {
fTabViewer.setName(name);
}
/**
* Returns the current launch manager
* @return the current launch manager
*/
protected ILaunchManager getLaunchManager() {
return DebugPlugin.getDefault().getLaunchManager();
}
/**
* 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;
}
/**
* 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.
*/
protected void setShellSize(int width, int height) {
Rectangle bounds = getShell().getMonitor().getBounds();
getShell().setSize(Math.min(width, bounds.width), Math.min(height, bounds.height));
}
/**
* Sets the viewer used to display the tabs for a launch configuration.
*
* @param viewer the new view to set
*/
protected void setTabViewer(LaunchConfigurationTabGroupViewer viewer) {
fTabViewer = viewer;
}
/**
* Create and return a dialog that asks the user whether they want to discard
* unsaved changes.
*
* @return the return code based on the button selected.
* The value will be one of <code>YES_ID</code> or <code>NO_ID</code> from
* <code>IDialogConstants</code>.
*/
private int showDiscardChangesDialog() {
StringBuffer buffer = new StringBuffer(MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationDialog_The_configuration___35, new Object[] { fTabViewer.getWorkingCopy().getName() }));
buffer.append(fTabViewer.getErrorMesssage());
buffer.append(LaunchConfigurationsMessages.LaunchConfigurationDialog_Do_you_wish_to_discard_changes_37);
MessageDialog dialog = new MessageDialog(getShell(),
LaunchConfigurationsMessages.LaunchConfigurationDialog_Discard_changes__38,
null,
buffer.toString(),
MessageDialog.QUESTION,
new String[] {
LaunchConfigurationsMessages.LaunchConfigurationDialog_Discard_Button,
LaunchConfigurationsMessages.LaunchConfigurationDialog_Dont_Discard_Button },
1);
int val = IDialogConstants.NO_ID;
if (dialog.open() == 0) {
if (fLaunchConfigurationView != null) {
fLaunchConfigurationView.setAutoSelect(false);
}
fTabViewer.handleRevertPressed();
val = IDialogConstants.YES_ID;
if (fLaunchConfigurationView != null) {
fLaunchConfigurationView.setAutoSelect(true);
}
}
if(val == IDialogConstants.NO_ID) {
val = ID_DISCARD_BUTTON;
}
return val;
}
/**
* Create and return a dialog that asks the user whether they want to save
* unsaved changes.
*
* @return the return code based on the button selected.
* The value will be one of <code>YES_ID</code>, <code>NO_ID</code>, or <code>CANCEL_ID</code>, from
* <code>IDialogConstants</code>.
*/
private int showSaveChangesDialog() {
String message = MessageFormat.format(LaunchConfigurationsMessages.LaunchConfigurationDialog_The_configuration___29, new Object[] { fTabViewer.getWorkingCopy().getName() });
MessageDialog dialog = new MessageDialog(getShell(),
LaunchConfigurationsMessages.LaunchConfigurationFilteredTree_save_changes,
null,
message,
MessageDialog.QUESTION,
new String[] {
LaunchConfigurationsMessages.LaunchConfigurationDialog_Save_Button,
LaunchConfigurationsMessages.LaunchConfigurationDialog_Dont_Save_Button,
LaunchConfigurationsMessages.LaunchConfigurationsDialog_c_ancel },
0);
int ret = dialog.open();
int val = IDialogConstants.CANCEL_ID;
if (ret == 0 || ret == 1) {
if (ret == 0) {
val = IDialogConstants.YES_ID;
}
else {
val = IDialogConstants.NO_ID;
}
}
return val;
}
/**
* 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.
*
* @return returns the <code>showSaveChangesDialog</code> return value
*/
private int showUnsavedChangesDialog() {
if (fTabViewer.canSave()) {
return showSaveChangesDialog();
}
return showDiscardChangesDialog();
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#updateButtons()
*/
@Override
public void updateButtons() {
if (!fSettingInput) {
// New, Delete, & Duplicate toolbar actions
getNewAction().setEnabled(getNewAction().isEnabled());
getExportAction().setEnabled(getExportAction().isEnabled());
getDeleteAction().setEnabled(getDeleteAction().isEnabled());
getDuplicateAction().setEnabled(getDuplicateAction().isEnabled());
getLinkPrototypeAction().setEnabled(getLinkPrototypeAction().isEnabled());
getUnlinkPrototypeAction().setEnabled(getUnlinkPrototypeAction().isEnabled());
getResetWithPrototypeValuesAction().setEnabled(getResetWithPrototypeValuesAction().isEnabled());
fTabViewer.refresh();
getButton(ID_LAUNCH_BUTTON).setEnabled(fTabViewer.canLaunch() & fTabViewer.canLaunchWithModes() & !fTabViewer.hasDuplicateDelegates());
} else {
fTabViewer.refresh();
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationDialog#updateMessage()
*/
@Override
public void updateMessage() {
if (!fSettingInput) {
setErrorMessage(fTabViewer.getErrorMesssage());
if (fTabViewer.getWarningMessage() != null) {
setMessage(fTabViewer.getWarningMessage(), IMessageProvider.WARNING);
} else {
setMessage(fTabViewer.getMessage());
}
}
}
/**
* Returns if there is a selection in the tree viewer or not
* @return true if something in the tree is selected, false otherwise
* @since 3.2
*/
public boolean isTreeSelectionEmpty() {
return fLaunchConfigurationView.getTreeViewer().getSelection().isEmpty();
}
/* (non-Javadoc)
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
@Override
public void propertyChange(final PropertyChangeEvent event) {
WorkbenchJob job = new WorkbenchJob(IInternalDebugCoreConstants.EMPTY_STRING) {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
TreeViewer viewer = fLaunchConfigurationView.getTreeViewer();
boolean newvalue = Boolean.valueOf(event.getNewValue().toString()).booleanValue();
if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_CLOSED)) {
updateFilter(newvalue, fClosedProjectFilter);
}
else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_DELETED)) {
updateFilter(newvalue, fDeletedProjectFilter);
}
else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES)) {
updateFilter(newvalue, fLCTFilter);
}
else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_WORKING_SETS)) {
updateFilter(newvalue, fWorkingSetsFilter);
}
else if(event.getProperty().equals(IInternalDebugUIConstants.PREF_FILTER_TYPE_LIST)) {
if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES)) {
viewer.refresh();
fLaunchConfigurationView.updateFilterLabel();
}
}
return Status.OK_STATUS;
}
};
job.runInUIThread(new NullProgressMonitor());
}
/**
* Updates the state of a filter based on the state variable
* @param state if the filter needs to be added or removed, true indicates add, false indicates remove
* @param filter the filter to update
*/
private void updateFilter(boolean state, ViewerFilter filter) {
TreeViewer viewer = (TreeViewer)fLaunchConfigurationView.getViewer();
if(state) {
viewer.addFilter(filter);
}
else {
viewer.removeFilter(filter);
}
fLaunchConfigurationView.updateFilterLabel();
}
}