/******************************************************************************* * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * 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.Collections; 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 * setInitialSelection() 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 LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION * mode, this specifies the selection that is initially shown in the dialog. */ private IStructuredSelection fInitialSelection; /** * The status to open the dialog on, or null 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 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 Dialog * * @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; } @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()); } @Override public void create() { super.create(); if (fTabViewer.getInput() == null) { fTabViewer.inputChanged(null); } } @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); } @Override protected Control createContents(Composite parent) { Control contents = super.createContents(parent); initializeContent(); PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), getHelpContextId()); return contents; } @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 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); } @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 reservednames) { if(name == null) { return ((LaunchManager) getLaunchManager()).generateUniqueLaunchConfigurationNameFrom(IInternalDebugCoreConstants.EMPTY_STRING, reservednames); } return ((LaunchManager)getLaunchManager()).generateUniqueLaunchConfigurationNameFrom(name, reservednames); } @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); } /* * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings() * * @since 3.2 */ @Override protected IDialogSettings getDialogBoundsSettings() { return getDialogSettings(); } @Override protected int getDialogBoundsStrategy() { return DIALOG_PERSISTSIZE; } /** * Returns the dialog settings for this dialog. Subclasses should override * getDialogSettingsSectionName(). * * @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 null 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; } @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), null otherwise * @return the reserved name set or null * @since 3.3 * */ public Set getReservedNameSet() { return fReservedNames; } /** * returns the open mode * * @return the open mode */ protected int getOpenMode() { return fOpenMode; } 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 null if none */ public ILaunchConfigurationTabGroup getTabGroup() { if (fTabViewer != null) { return fTabViewer.getTabGroup(); } return null; } @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. *

* If the currently displayed configuration is not saved, * prompt for saving before moving on to the new selection. *

* * @param event selection changed event */ protected void handleLaunchConfigurationSelectionChanged(SelectionChangedEvent event) { Object input = fTabViewer.getInput(); Object newInput = null; IStructuredSelection selection = event.getStructuredSelection(); 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); } @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(); } @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 * Window. OK or Window.CANCEL. * * @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 list = new ArrayList<>(); String[] persisted = value.split(DELIMITER); Collections.addAll(list, persisted); 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 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 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(); } } } @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); } @Override public void setActiveTab(ILaunchConfigurationTab tab) { fTabViewer.setActiveTab(tab); } @Override public void setActiveTab(int index) { fTabViewer.setActiveTab(index); } /** * Sets the initial selection for the dialog when opened in * LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION 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 true if the defaults should be set on open, false 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()); } @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 open() 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 Shell 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 YES_ID or NO_ID from * IDialogConstants. */ private int showDiscardChangesDialog() { StringBuilder buffer = new StringBuilder(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 YES_ID, NO_ID, or CANCEL_ID, from * IDialogConstants. */ 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 true if the user indicated that they wish to replace * the current config, either by saving changes or by discarding the, return false * otherwise. * * @return returns the showSaveChangesDialog return value */ private int showUnsavedChangesDialog() { if (fTabViewer.canSave()) { return showSaveChangesDialog(); } return showDiscardChangesDialog(); } @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(); } } @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(); } @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(); } }