| /******************************************************************************* |
| * Copyright (c) 2000, 2013 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 |
| * Sascha Radike - bug 56642 |
| * Martin Oberhuber (Wind River) - [327446] Avoid unnecessary wait-for-build dialog. |
| * Mohamed Hussein - bug 381175 |
| *******************************************************************************/ |
| package org.eclipse.debug.internal.ui; |
| |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.Set; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.eclipse.core.expressions.EvaluationContext; |
| import org.eclipse.core.expressions.IEvaluationContext; |
| import org.eclipse.core.resources.ISaveContext; |
| import org.eclipse.core.resources.ISaveParticipant; |
| import org.eclipse.core.resources.IncrementalProjectBuilder; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.FileLocator; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.core.runtime.jobs.IJobChangeEvent; |
| import org.eclipse.core.runtime.jobs.IJobChangeListener; |
| import org.eclipse.core.runtime.jobs.IJobManager; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.eclipse.debug.core.DebugException; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; |
| import org.eclipse.debug.core.ILaunchListener; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.core.IStatusHandler; |
| import org.eclipse.debug.core.Launch; |
| import org.eclipse.debug.core.model.IDebugElement; |
| import org.eclipse.debug.core.model.IProcess; |
| import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; |
| import org.eclipse.debug.internal.ui.contextlaunching.LaunchingResourceManager; |
| import org.eclipse.debug.internal.ui.launchConfigurations.ClosedProjectFilter; |
| import org.eclipse.debug.internal.ui.launchConfigurations.DeletedProjectFilter; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationEditDialog; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationPropertiesDialog; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationTypeFilter; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchGroupExtension; |
| import org.eclipse.debug.internal.ui.launchConfigurations.PerspectiveManager; |
| import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupFacility; |
| import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupManager; |
| import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager; |
| import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; |
| import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointOrganizerManager; |
| import org.eclipse.debug.internal.ui.views.console.ProcessConsoleManager; |
| import org.eclipse.debug.internal.ui.views.launch.DebugElementHelper; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.debug.ui.IDebugModelPresentation; |
| import org.eclipse.debug.ui.IDebugUIConstants; |
| import org.eclipse.debug.ui.ILaunchGroup; |
| import org.eclipse.jface.bindings.keys.KeyStroke; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialogWithToggle; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.preference.PreferenceConverter; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.resource.ImageRegistry; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.osgi.service.debug.DebugOptions; |
| import org.eclipse.osgi.service.debug.DebugOptionsListener; |
| import org.eclipse.osgi.service.debug.DebugTrace; |
| import org.eclipse.swt.custom.BusyIndicator; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.plugin.AbstractUIPlugin; |
| import org.eclipse.ui.progress.IProgressConstants2; |
| import org.eclipse.ui.progress.IProgressService; |
| import org.eclipse.ui.services.IEvaluationService; |
| import org.eclipse.ui.themes.IThemeManager; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.service.prefs.BackingStoreException; |
| import org.w3c.dom.Document; |
| |
| import com.ibm.icu.text.MessageFormat; |
| |
| /** |
| * The Debug UI Plug-in. |
| * |
| * Since 3.3 this plug-in registers an <code>ISaveParticipant</code>, allowing this plug-in to participate |
| * in workspace persistence life-cycles |
| * |
| * @see ISaveParticipant |
| * @see ILaunchListener |
| * @see LaunchConfigurationManager |
| * @see PerspectiveManager |
| */ |
| public class DebugUIPlugin extends AbstractUIPlugin implements ILaunchListener, DebugOptionsListener { |
| |
| public static boolean DEBUG = false; |
| public static boolean DEBUG_BREAKPOINT_DELTAS = false; |
| public static boolean DEBUG_MODEL = false; |
| public static boolean DEBUG_VIEWER = false; |
| public static boolean DEBUG_BREADCRUMB = false; |
| public static boolean DEBUG_TREE_VIEWER_DROPDOWN = false; |
| public static boolean DEBUG_CONTENT_PROVIDER = false; |
| public static boolean DEBUG_UPDATE_SEQUENCE = false; |
| public static boolean DEBUG_DELTAS = false; |
| public static boolean DEBUG_STATE_SAVE_RESTORE = false; |
| public static String DEBUG_PRESENTATION_ID = null; |
| public static boolean DEBUG_DYNAMIC_LOADING = false; |
| |
| static final String DEBUG_FLAG = "org.eclipse.debug.ui/debug"; //$NON-NLS-1$ |
| static final String DEBUG_BREAKPOINT_DELTAS_FLAG = "org.eclipse.debug.ui/debug/viewers/breakpointDeltas"; //$NON-NLS-1$ |
| static final String DEBUG_MODEL_FLAG = "org.eclipse.debug.ui/debug/viewers/model"; //$NON-NLS-1$ |
| static final String DEBUG_VIEWER_FLAG = "org.eclipse.debug.ui/debug/viewers/viewer"; //$NON-NLS-1$ |
| static final String DEBUG_BREADCRUMB_FLAG = "org.eclipse.debug.ui/debug/breadcrumb"; //$NON-NLS-1$ |
| static final String DEBUG_TREE_VIEWER_DROPDOWN_FLAG = "org.eclipse.debug.ui/debug/breadcrumb"; //$NON-NLS-1$ |
| static final String DEBUG_CONTENT_PROVIDER_FLAG ="org.eclipse.debug.ui/debug/viewers/contentProvider"; //$NON-NLS-1$ |
| static final String DEBUG_UPDATE_SEQUENCE_FLAG = "org.eclipse.debug.ui/debug/viewers/updateSequence"; //$NON-NLS-1$ |
| static final String DEBUG_DELTAS_FLAG ="org.eclipse.debug.ui/debug/viewers/deltas"; //$NON-NLS-1$ |
| static final String DEBUG_STATE_SAVE_RESTORE_FLAG = "org.eclipse.debug.ui/debug/viewers/stateSaveRestore"; //$NON-NLS-1$ |
| static final String DEBUG_PRESENTATION_ID_FLAG ="org.eclipse.debug.ui/debug/viewers/presentationId"; //$NON-NLS-1$ |
| static final String DEBUG_DYNAMIC_LOADING_FLAG = "org.eclipse.debug.ui/debug/memory/dynamicLoading"; //$NON-NLS-1$ |
| /** |
| * The {@link DebugTrace} object to print to OSGi tracing |
| * @since 3.8 |
| */ |
| private static DebugTrace fgDebugTrace; |
| |
| /** |
| * The singleton debug plug-in instance |
| */ |
| private static DebugUIPlugin fgDebugUIPlugin = null; |
| |
| /** |
| * A utility presentation used to obtain labels |
| */ |
| protected static IDebugModelPresentation fgPresentation = null; |
| |
| /** |
| * Default label provider |
| */ |
| private static DefaultLabelProvider fgDefaultLabelProvider; |
| |
| /** |
| * Launch configuration attribute - used by the stand-in launch |
| * config working copies that are created while a launch is waiting |
| * for a build to finish. This attribute allows the EditLaunchConfigurationAction |
| * to access the original config if the user asks to edit it. |
| */ |
| public static String ATTR_LAUNCHING_CONFIG_HANDLE= getUniqueIdentifier() + "launching_config_handle"; //$NON-NLS-1$ |
| |
| /** |
| * Singleton console document manager |
| */ |
| private ProcessConsoleManager fProcessConsoleManager = null; |
| |
| /** |
| * Perspective manager |
| */ |
| private PerspectiveManager fPerspectiveManager = null; |
| |
| /** |
| * Launch configuration manager |
| */ |
| private LaunchConfigurationManager fLaunchConfigurationManager = null; |
| |
| /** |
| * Context launching manager |
| */ |
| private LaunchingResourceManager fContextLaunchingManager = null; |
| |
| /** |
| * Image descriptor registry used for images with common overlays. |
| * |
| * @since 3.1 |
| */ |
| private ImageDescriptorRegistry fImageDescriptorRegistry; |
| |
| /** |
| * A set of <code>ISaveParticipant</code>s that want to contribute to saving via this plugin |
| * |
| * @since 3.3 |
| */ |
| private Set<ISaveParticipant> fSaveParticipants = new HashSet<ISaveParticipant>(); |
| |
| /** |
| * Theme listener. |
| * |
| * @since 3.4 |
| */ |
| private IPropertyChangeListener fThemeListener; |
| |
| /** |
| * Dummy launch node representing a launch that is waiting |
| * for a build to finish before proceeding. This node exists |
| * to provide immediate feedback to the user in the Debug view and |
| * allows termination, which equates to cancellation of the launch. |
| */ |
| public static class PendingLaunch extends Launch { |
| private Job fJob; |
| public PendingLaunch(ILaunchConfiguration launchConfiguration, String mode, Job job) { |
| super(launchConfiguration, mode, null); |
| fJob= job; |
| } |
| |
| // Allow the user to terminate the dummy launch as a means to |
| // cancel the launch while waiting for a build to finish. |
| @Override |
| public boolean canTerminate() { |
| return true; |
| } |
| |
| @Override |
| public void terminate() throws DebugException { |
| fJob.cancel(); |
| } |
| } |
| |
| /** |
| * Constructs the debug UI plug-in |
| */ |
| public DebugUIPlugin() { |
| super(); |
| fgDebugUIPlugin= this; |
| } |
| |
| /** |
| * Prints the given message to System.out and to the OSGi tracing (if started) |
| * @param option the option or <code>null</code> |
| * @param message the message to print or <code>null</code> |
| * @param throwable the {@link Throwable} or <code>null</code> |
| * @since 3.8 |
| */ |
| public static void trace(String option, String message, Throwable throwable) { |
| System.out.println(message); |
| if(fgDebugTrace != null) { |
| fgDebugTrace.trace(option, message, throwable); |
| } |
| } |
| |
| /** |
| * Prints the given message to System.out and to the OSGi tracing (if enabled) |
| * |
| * @param message the message or <code>null</code> |
| * @since 3.8 |
| */ |
| public static void trace(String message) { |
| trace(null, message, null); |
| } |
| |
| /** |
| * Returns the singleton instance of the debug plug-in. |
| * @return the singleton {@link DebugUIPlugin} |
| */ |
| public static DebugUIPlugin getDefault() { |
| if(fgDebugUIPlugin == null) { |
| fgDebugUIPlugin = new DebugUIPlugin(); |
| } |
| return fgDebugUIPlugin; |
| } |
| |
| /** |
| * Convenience method which returns the unique identifier of this plug-in. |
| * @return the identifier of the plug-in |
| */ |
| public static String getUniqueIdentifier() { |
| return IDebugUIConstants.PLUGIN_ID; |
| } |
| |
| /** |
| * Returns the default delegating model presentation |
| * @return the default delegating model presentation |
| */ |
| public static IDebugModelPresentation getModelPresentation() { |
| if (fgPresentation == null) { |
| fgPresentation = new DelegatingModelPresentation(); |
| } |
| return fgPresentation; |
| } |
| |
| /** |
| * Returns the launch configuration manager |
| * @return the launch configuration manager |
| */ |
| public LaunchConfigurationManager getLaunchConfigurationManager() { |
| if (fLaunchConfigurationManager == null) { |
| fLaunchConfigurationManager = new LaunchConfigurationManager(); |
| } |
| return fLaunchConfigurationManager; |
| } |
| |
| /** |
| * Returns the context launching resource manager. If one has not been created prior to this |
| * method call, a new manager is created and initialized, by calling its startup() method. |
| * @return the context launching resource manager |
| * |
| * @since 3.3 |
| */ |
| public LaunchingResourceManager getLaunchingResourceManager() { |
| if(fContextLaunchingManager == null) { |
| fContextLaunchingManager = new LaunchingResourceManager(); |
| fContextLaunchingManager.startup(); |
| } |
| return fContextLaunchingManager; |
| } |
| |
| /** |
| * Returns the currently active workbench window or <code>null</code> |
| * if none. |
| * |
| * @return the currently active workbench window or <code>null</code> |
| */ |
| public static IWorkbenchWindow getActiveWorkbenchWindow() { |
| return getDefault().getWorkbench().getActiveWorkbenchWindow(); |
| } |
| |
| /** |
| * Returns the currently active workbench window shell or <code>null</code> |
| * if none. |
| * |
| * @return the currently active workbench window shell or <code>null</code> |
| */ |
| public static Shell getShell() { |
| IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); |
| if (window == null) { |
| IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); |
| if (windows.length > 0) { |
| return windows[0].getShell(); |
| } |
| } |
| else { |
| return window.getShell(); |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the default label provider for the debug UI. |
| * @return the singleton {@link DefaultLabelProvider} |
| */ |
| public static ILabelProvider getDefaultLabelProvider() { |
| if (fgDefaultLabelProvider == null) { |
| fgDefaultLabelProvider = new DefaultLabelProvider(); |
| } |
| return fgDefaultLabelProvider; |
| } |
| |
| /** |
| * Creates an extension. If the extension plug-in has not |
| * been loaded a busy cursor will be activated during the duration of |
| * the load. |
| * |
| * @param element the config element defining the extension |
| * @param classAttribute the name of the attribute carrying the class |
| * @return the extension object |
| * @throws CoreException if an exception occurs |
| */ |
| public static Object createExtension(final IConfigurationElement element, final String classAttribute) throws CoreException { |
| // If plug-n has been loaded create extension. |
| // Otherwise, show busy cursor then create extension. |
| Bundle bundle = Platform.getBundle(element.getContributor().getName()); |
| if (bundle.getState() == Bundle.ACTIVE) { |
| return element.createExecutableExtension(classAttribute); |
| } |
| final Object [] ret = new Object[1]; |
| final CoreException [] exc = new CoreException[1]; |
| BusyIndicator.showWhile(null, new Runnable() { |
| @Override |
| public void run() { |
| try { |
| ret[0] = element.createExecutableExtension(classAttribute); |
| } catch (CoreException e) { |
| exc[0] = e; |
| } |
| } |
| }); |
| if (exc[0] != null) { |
| throw exc[0]; |
| } |
| return ret[0]; |
| } |
| |
| /** |
| * @see org.eclipse.ui.plugin.AbstractUIPlugin#createImageRegistry() |
| */ |
| @Override |
| protected ImageRegistry createImageRegistry() { |
| return DebugPluginImages.initializeImageRegistry(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) |
| */ |
| @Override |
| public void stop(BundleContext context) throws Exception { |
| try { |
| if (fProcessConsoleManager != null) { |
| fProcessConsoleManager.shutdown(); |
| } |
| |
| BreakpointOrganizerManager.getDefault().shutdown(); |
| |
| if (fPerspectiveManager != null) { |
| fPerspectiveManager.shutdown(); |
| } |
| if (fLaunchConfigurationManager != null) { |
| fLaunchConfigurationManager.shutdown(); |
| } |
| if(fContextLaunchingManager != null) { |
| fContextLaunchingManager.shutdown(); |
| } |
| |
| ColorManager.getDefault().dispose(); |
| |
| if (fgPresentation != null) { |
| fgPresentation.dispose(); |
| } |
| |
| if (fImageDescriptorRegistry != null) { |
| fImageDescriptorRegistry.dispose(); |
| } |
| |
| if (fgDefaultLabelProvider != null) { |
| fgDefaultLabelProvider.dispose(); |
| } |
| |
| SourceLookupFacility.shutdown(); |
| |
| DebugElementHelper.dispose(); |
| |
| fSaveParticipants.clear(); |
| |
| ResourcesPlugin.getWorkspace().removeSaveParticipant(getUniqueIdentifier()); |
| |
| if (fThemeListener != null) { |
| if (PlatformUI.isWorkbenchRunning()) { |
| PlatformUI.getWorkbench().getThemeManager().removePropertyChangeListener(fThemeListener); |
| } |
| fThemeListener= null; |
| } |
| |
| } finally { |
| super.stop(context); |
| } |
| } |
| |
| /** |
| * Add the specified <code>ISaveParticipant</code> to the current listing of |
| * registered participants |
| * @param participant the save participant to add |
| * @return true if this current listing did not already contain the specified participant |
| * @since 3.3 |
| */ |
| public boolean addSaveParticipant(ISaveParticipant participant) { |
| return fSaveParticipants.add(participant); |
| } |
| |
| /** |
| * Removes the specified <code>ISaveParticipant</code> from the current listing of registered |
| * participants |
| * @param participant the save participant to remove |
| * @return true if the set contained the specified element |
| * |
| * @since 3.3 |
| */ |
| public boolean removeSaveParticipant(ISaveParticipant participant) { |
| return fSaveParticipants.remove(participant); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) |
| */ |
| @Override |
| public void start(BundleContext context) throws Exception { |
| super.start(context); |
| Hashtable<String, String> props = new Hashtable<String, String>(2); |
| props.put(org.eclipse.osgi.service.debug.DebugOptions.LISTENER_SYMBOLICNAME, getUniqueIdentifier()); |
| context.registerService(DebugOptionsListener.class.getName(), this, props); |
| ResourcesPlugin.getWorkspace().addSaveParticipant(getUniqueIdentifier(), |
| new ISaveParticipant() { |
| @Override |
| public void saving(ISaveContext saveContext) throws CoreException { |
| IEclipsePreferences node = InstanceScope.INSTANCE.getNode(getUniqueIdentifier()); |
| if(node != null) { |
| try { |
| node.flush(); |
| } catch (BackingStoreException e) { |
| log(e); |
| } |
| } |
| for (ISaveParticipant sp : fSaveParticipants) { |
| sp.saving(saveContext); |
| } |
| } |
| @Override |
| public void rollback(ISaveContext saveContext) { |
| for (ISaveParticipant sp : fSaveParticipants) { |
| sp.rollback(saveContext); |
| } |
| } |
| @Override |
| public void prepareToSave(ISaveContext saveContext) throws CoreException { |
| for (ISaveParticipant sp : fSaveParticipants) { |
| sp.prepareToSave(saveContext); |
| } |
| } |
| @Override |
| public void doneSaving(ISaveContext saveContext) { |
| for (ISaveParticipant sp : fSaveParticipants) { |
| sp.doneSaving(saveContext); |
| } |
| } |
| }); |
| |
| // make sure the perspective manager is created |
| // and be the first debug event listener |
| fPerspectiveManager = new PerspectiveManager(); |
| fPerspectiveManager.startup(); |
| |
| getLaunchingResourceManager(); |
| |
| // Listen to launches to lazily create "launch processors" |
| ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); |
| ILaunch[] launches = launchManager.getLaunches(); |
| if (launches.length > 0) { |
| // if already launches, initialize processors |
| initializeLaunchListeners(); |
| } else { |
| // if no launches, wait for first launch to initialize processors |
| launchManager.addLaunchListener(this); |
| } |
| |
| // start the breakpoint organizer manager |
| BreakpointOrganizerManager.getDefault(); |
| |
| getLaunchConfigurationManager().startup(); |
| |
| if (PlatformUI.isWorkbenchRunning()) { |
| fThemeListener= new IPropertyChangeListener() { |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| if (IThemeManager.CHANGE_CURRENT_THEME.equals(event.getProperty())) { |
| DebugUIPreferenceInitializer.setThemeBasedPreferences(getPreferenceStore(), true); |
| } |
| } |
| }; |
| PlatformUI.getWorkbench().getThemeManager().addPropertyChangeListener(fThemeListener); |
| } |
| |
| // do the asynchronous exec last - see bug 209920 |
| getStandardDisplay().asyncExec( |
| new Runnable() { |
| @Override |
| public void run() { |
| //initialize the selected resource ` |
| SelectedResourceManager.getDefault(); |
| // forces launch shortcuts to be initialized so their key-bindings work |
| getLaunchConfigurationManager().getLaunchShortcuts(); |
| } |
| }); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osgi.service.debug.DebugOptionsListener#optionsChanged(org.eclipse.osgi.service.debug.DebugOptions) |
| */ |
| @Override |
| public void optionsChanged(DebugOptions options) { |
| fgDebugTrace = options.newDebugTrace(getUniqueIdentifier()); |
| DEBUG = options.getBooleanOption(DEBUG_FLAG, false); |
| DEBUG_BREAKPOINT_DELTAS = DEBUG && options.getBooleanOption(DEBUG_BREAKPOINT_DELTAS_FLAG, false); |
| DEBUG_MODEL = DEBUG && options.getBooleanOption(DEBUG_MODEL_FLAG, false); |
| DEBUG_VIEWER = DEBUG && options.getBooleanOption(DEBUG_VIEWER_FLAG, false); |
| DEBUG_BREADCRUMB = DEBUG && options.getBooleanOption(DEBUG_BREADCRUMB_FLAG, false); |
| DEBUG_TREE_VIEWER_DROPDOWN = DEBUG && options.getBooleanOption(DEBUG_TREE_VIEWER_DROPDOWN_FLAG, false); |
| DEBUG_CONTENT_PROVIDER = DEBUG && options.getBooleanOption(DEBUG_CONTENT_PROVIDER_FLAG, false); |
| DEBUG_UPDATE_SEQUENCE = DEBUG && options.getBooleanOption(DEBUG_UPDATE_SEQUENCE_FLAG, false); |
| DEBUG_DELTAS = DEBUG && options.getBooleanOption(DEBUG_DELTAS_FLAG, false); |
| DEBUG_STATE_SAVE_RESTORE = DEBUG && options.getBooleanOption(DEBUG_STATE_SAVE_RESTORE_FLAG, false); |
| DEBUG_DYNAMIC_LOADING = DEBUG && options.getBooleanOption(DEBUG_DYNAMIC_LOADING_FLAG, false); |
| if(DEBUG) { |
| DEBUG_PRESENTATION_ID = options.getOption(DEBUG_PRESENTATION_ID_FLAG, IInternalDebugCoreConstants.EMPTY_STRING); |
| if(IInternalDebugCoreConstants.EMPTY_STRING.equals(DEBUG_PRESENTATION_ID)) { |
| DEBUG_PRESENTATION_ID = null; |
| } |
| } |
| } |
| |
| /** |
| * Utility method with conventions |
| * @param shell the shell to open the dialog on |
| * @param title the title of the dialog |
| * @param message the message to display in the dialog |
| * @param s the underlying {@link IStatus} to display |
| */ |
| public static void errorDialog(Shell shell, String title, String message, IStatus s) { |
| // if the 'message' resource string and the IStatus' message are the same, |
| // don't show both in the dialog |
| if (s != null && message.equals(s.getMessage())) { |
| message= null; |
| } |
| ErrorDialog.openError(shell, title, message, s); |
| } |
| |
| /** |
| * Utility method with conventions |
| * @param shell the shell to open the dialog on |
| * @param title the title for the dialog |
| * @param message the message to display in the dialog |
| * @param t the underlying exception for the dialog |
| */ |
| public static void errorDialog(Shell shell, String title, String message, Throwable t) { |
| IStatus status; |
| if (t instanceof CoreException) { |
| status= ((CoreException)t).getStatus(); |
| // if the 'message' resource string and the IStatus' message are the same, |
| // don't show both in the dialog |
| if (status != null && message.equals(status.getMessage())) { |
| message= null; |
| } |
| } else { |
| status= new Status(IStatus.ERROR, getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "Error within Debug UI: ", t); //$NON-NLS-1$ |
| log(status); |
| } |
| ErrorDialog.openError(shell, title, message, status); |
| } |
| |
| /** |
| * Logs the specified status with this plug-in's log. |
| * |
| * @param status status to log |
| */ |
| public static void log(IStatus status) { |
| getDefault().getLog().log(status); |
| } |
| |
| /** |
| * Logs the specified throwable with this plug-in's log. |
| * |
| * @param t throwable to log |
| */ |
| public static void log(Throwable t) { |
| log(newErrorStatus("Error logged from Debug UI: ", t)); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Logs an internal error with the specified message. |
| * |
| * @param message the error message to log |
| */ |
| public static void logErrorMessage(String message) { |
| // this message is intentionally not internationalized, as an exception may |
| // be due to the resource bundle itself |
| log(newErrorStatus("Internal message logged from Debug UI: " + message, null)); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns a new error status for this plug-in with the given message |
| * @param message the message to be included in the status |
| * @param exception the exception to be included in the status or <code>null</code> if none |
| * @return a new error status |
| */ |
| public static IStatus newErrorStatus(String message, Throwable exception) { |
| return new Status(IStatus.ERROR, getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, message, exception); |
| } |
| |
| /** |
| * Open the launch configuration dialog on the specified launch |
| * configuration. The dialog displays the tabs for a single configuration |
| * only (a tree of launch configuration is not displayed) |
| * <p> |
| * If a status is specified, a status handler is consulted to handle the |
| * status. The status handler is passed the instance of the launch |
| * configuration dialog that is opened. This gives the status handler an |
| * opportunity to perform error handling/initialization as required. |
| * </p> |
| * @param shell the parent shell for the launch configuration dialog |
| * @param configuration the configuration to display |
| * @param groupIdentifier group identifier of the launch group the launch configuration |
| * belongs to |
| * @param status the status to display, or <code>null</code> if none |
| * @param showCancel if the cancel button should be shown in the particular instance of the dialog |
| * @return the return code from opening the launch configuration dialog - |
| * one of <code>Window.OK</code> or <code>Window.CANCEL</code> |
| * |
| * @since 3.3 |
| * |
| */ |
| public static int openLaunchConfigurationEditDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier, IStatus status, boolean showCancel) { |
| LaunchGroupExtension group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier); |
| if (group != null) { |
| LaunchConfigurationEditDialog dialog = new LaunchConfigurationEditDialog(shell, configuration, group, showCancel); |
| dialog.setInitialStatus(status); |
| return dialog.open(); |
| } |
| return Window.CANCEL; |
| } |
| |
| /** |
| * Open the launch configuration dialog on the specified launch |
| * configuration. The dialog displays the tabs for a single configuration |
| * only (a tree of launch configuration is not displayed) |
| * <p> |
| * If a status is specified, a status handler is consulted to handle the |
| * status. The status handler is passed the instance of the launch |
| * configuration dialog that is opened. This gives the status handler an |
| * opportunity to perform error handling/initialization as required. |
| * </p> |
| * @param shell the parent shell for the launch configuration dialog |
| * @param configuration the configuration to display |
| * @param groupIdentifier group identifier of the launch group the launch configuration |
| * belongs to |
| * @param reservednames a set of launch configuration names that cannot be used when creating or renaming |
| * the specified launch configuration |
| * @param status the status to display, or <code>null</code> if none |
| * @param setDefaults whether to set default values in the configuration |
| * @return the return code from opening the launch configuration dialog - |
| * one of <code>Window.OK</code> or <code>Window.CANCEL</code> |
| * |
| * @since 3.3 |
| * |
| */ |
| public static int openLaunchConfigurationPropertiesDialog(Shell shell, ILaunchConfiguration configuration, String groupIdentifier, Set<String> reservednames, IStatus status, boolean setDefaults) { |
| LaunchGroupExtension group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier); |
| if (group != null) { |
| LaunchConfigurationPropertiesDialog dialog = new LaunchConfigurationPropertiesDialog(shell, configuration, group, reservednames); |
| dialog.setInitialStatus(status); |
| dialog.setDefaultsOnOpen(setDefaults); |
| return dialog.open(); |
| } |
| return Window.CANCEL; |
| } |
| |
| /** |
| * Opens the {@link LaunchConfigurationsDialog} on the given selection for the given group. A status |
| * can be provided or <code>null</code> and the dialog can initialize the given {@link ILaunchConfiguration} |
| * to its defaults when opening as well - as long as the specified configuration is an {@link ILaunchConfigurationWorkingCopy}. |
| * @param shell the shell to open the dialog on |
| * @param selection the non-null selection to show when the dialog opens |
| * @param groupIdentifier the identifier of the launch group to open the dialog on |
| * @param setDefaults if the default values should be set on the opened configuration - if there is one |
| * @return the return code from the dialog.open() call |
| * @since 3.6 |
| */ |
| public static int openLaunchConfigurationsDialog(Shell shell, IStructuredSelection selection, String groupIdentifier, boolean setDefaults) { |
| LaunchGroupExtension group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(groupIdentifier); |
| if (group != null) { |
| LaunchConfigurationsDialog dialog = new LaunchConfigurationsDialog(shell, group); |
| dialog.setOpenMode(LaunchConfigurationsDialog.LAUNCH_CONFIGURATION_DIALOG_OPEN_ON_SELECTION); |
| dialog.setInitialSelection(selection); |
| dialog.setDefaultsOnOpen(setDefaults); |
| return dialog.open(); |
| } |
| return Window.CANCEL; |
| } |
| |
| /** |
| * Save all dirty editors in the workbench. |
| * Returns whether the operation succeeded. |
| * @param confirm if the user should be asked before saving |
| * |
| * @return whether all saving was completed |
| * @deprecated Saving has been moved to the launch delegate <code>LaunchConfigurationDelegate</code> to allow for scoped saving |
| * of resources that are only involved in the current launch, no longer the entire workspace |
| */ |
| @Deprecated |
| protected static boolean saveAllEditors(boolean confirm) { |
| if (getActiveWorkbenchWindow() == null) { |
| return false; |
| } |
| return PlatformUI.getWorkbench().saveAllEditors(confirm); |
| } |
| |
| /** |
| * Save & build the workspace according to the user-specified preferences. Return <code>false</code> if |
| * any problems were encountered, <code>true</code> otherwise. |
| * @return <code>false</code> if any problems were encountered, <code>true</code> otherwise. |
| * |
| * @deprecated this method is no longer to be used. It is an artifact from 2.0, and all saving is now done with the |
| * launch delegate <code>LaunchConfigurationDelegate</code> |
| */ |
| @Deprecated |
| public static boolean saveAndBuild() { |
| boolean status = true; |
| String saveDirty = getDefault().getPreferenceStore().getString(IInternalDebugUIConstants.PREF_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH); |
| boolean buildBeforeLaunch = getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_BUILD_BEFORE_LAUNCH); |
| |
| // If we're ignoring dirty editors, check if we need to build |
| if (saveDirty.equals(MessageDialogWithToggle.NEVER)) { |
| if (buildBeforeLaunch) { |
| return doBuild(); |
| } |
| } else { |
| status = saveAllEditors(saveDirty.equals(MessageDialogWithToggle.PROMPT)); |
| if (status && buildBeforeLaunch) { |
| status = doBuild(); |
| } |
| } |
| |
| return status; |
| } |
| |
| private static boolean doBuild() { |
| try { |
| PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException { |
| try { |
| ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| }); |
| } catch (InterruptedException e) { |
| // canceled by user |
| return false; |
| } catch (InvocationTargetException e) { |
| String title= DebugUIMessages.DebugUIPlugin_Run_Debug_1; |
| String message= DebugUIMessages.DebugUIPlugin_Build_error__Check_log_for_details__2; |
| Throwable t = e.getTargetException(); |
| errorDialog(getShell(), title, message, t); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Returns the workbench's display. |
| * @return the standard display |
| */ |
| public static Display getStandardDisplay() { |
| return PlatformUI.getWorkbench().getDisplay(); |
| } |
| |
| /** |
| * Returns the a color based on the type of output. |
| * Valid types: |
| * <li>CONSOLE_SYS_OUT_RGB</li> |
| * <li>CONSOLE_SYS_ERR_RGB</li> |
| * <li>CONSOLE_SYS_IN_RGB</li> |
| * <li>CHANGED_VARIABLE_RGB</li> |
| * @param type the name of the type to ask for |
| * @return the {@link Color} |
| */ |
| public static Color getPreferenceColor(String type) { |
| return ColorManager.getDefault().getColor(PreferenceConverter.getColor(getDefault().getPreferenceStore(), type)); |
| } |
| |
| /** |
| * Returns the process console manager. The manager will be created lazily on |
| * the first access. |
| * |
| * @return ProcessConsoleManager |
| */ |
| public ProcessConsoleManager getProcessConsoleManager() { |
| if (fProcessConsoleManager == null) { |
| fProcessConsoleManager = new ProcessConsoleManager(); |
| } |
| return fProcessConsoleManager; |
| } |
| |
| /** |
| * Returns a Document that can be used to build a DOM tree |
| * @return the Document |
| * @throws ParserConfigurationException if an exception occurs creating the document builder |
| * @since 3.0 |
| */ |
| public static Document getDocument() throws ParserConfigurationException { |
| DocumentBuilderFactory dfactory= DocumentBuilderFactory.newInstance(); |
| |
| DocumentBuilder docBuilder= dfactory.newDocumentBuilder(); |
| Document doc= docBuilder.newDocument(); |
| return doc; |
| } |
| |
| /** |
| * When the first launch is added, instantiate launch processors, |
| * and stop listening to launch notifications. |
| * |
| * @see org.eclipse.debug.core.ILaunchListener#launchAdded(org.eclipse.debug.core.ILaunch) |
| */ |
| @Override |
| public void launchAdded(ILaunch launch) { |
| DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); |
| initializeLaunchListeners(); |
| } |
| |
| /** |
| * Creates/starts launch listeners after a launch has been added. |
| * <p> |
| * Launch processors are: |
| * <ul> |
| * <li>console document manager</li> |
| * <li>perspective manager</li> |
| * </ul> |
| * </p> |
| */ |
| private void initializeLaunchListeners() { |
| getProcessConsoleManager().startup(); |
| SourceLookupManager.getDefault(); |
| } |
| |
| /** |
| * Returns the perspective manager. |
| * |
| * @return the singleton {@link PerspectiveManager} |
| */ |
| public PerspectiveManager getPerspectiveManager() { |
| return fPerspectiveManager; |
| } |
| |
| /** |
| * @see org.eclipse.debug.core.ILaunchListener#launchChanged(org.eclipse.debug.core.ILaunch) |
| */ |
| @Override |
| public void launchChanged(ILaunch launch) {} |
| |
| /** |
| * @see org.eclipse.debug.core.ILaunchListener#launchRemoved(org.eclipse.debug.core.ILaunch) |
| */ |
| @Override |
| public void launchRemoved(ILaunch launch) {} |
| |
| /** |
| * Formats the given key stroke or click name and the modifier keys |
| * to a key binding string that can be used in action texts. |
| * |
| * @param modifierKeys the modifier keys |
| * @param keyOrClick a key stroke or click, e.g. "Double Click" |
| * @return the formatted keyboard shortcut string, e.g. "Shift+Double Click" |
| * |
| * @since 3.8 |
| */ |
| public static final String formatKeyBindingString(int modifierKeys, String keyOrClick) { |
| // this should actually all be delegated to KeyStroke class |
| return KeyStroke.getInstance(modifierKeys, KeyStroke.NO_KEY).format() + keyOrClick; |
| } |
| |
| public static boolean DEBUG_TEST_PRESENTATION_ID(IPresentationContext context) { |
| if (context == null) { |
| return true; |
| } |
| return DEBUG_PRESENTATION_ID == null || DEBUG_PRESENTATION_ID.equals(context.getId()); |
| } |
| |
| /** |
| * Return the ILaunch associated with a model element, or null if there is |
| * no such association. |
| * |
| * @param element the model element |
| * @return the ILaunch associated with the element, or null. |
| * @since 3.6 |
| */ |
| public static ILaunch getLaunch(Object element) { |
| // support for custom models |
| ILaunch launch= (ILaunch)DebugPlugin.getAdapter(element, ILaunch.class); |
| if (launch == null) { |
| // support for standard debug model |
| if (element instanceof IDebugElement) { |
| launch= ((IDebugElement)element).getLaunch(); |
| } else if (element instanceof ILaunch) { |
| launch= ((ILaunch)element); |
| } else if (element instanceof IProcess) { |
| launch= ((IProcess)element).getLaunch(); |
| } |
| } |
| return launch; |
| } |
| |
| |
| /** |
| * Save dirty editors before launching, according to preferences. |
| * |
| * @return whether to proceed with launch |
| * @deprecated Saving has been moved to the launch delegate <code>LaunchConfigurationDelegate</code> to allow for scoped saving |
| * of resources that are only involved in the current launch, no longer the entire workspace |
| */ |
| @Deprecated |
| public static boolean preLaunchSave() { |
| String saveDirty = getDefault().getPreferenceStore().getString(IInternalDebugUIConstants.PREF_SAVE_DIRTY_EDITORS_BEFORE_LAUNCH); |
| if (saveDirty.equals(MessageDialogWithToggle.NEVER)) { |
| return true; |
| } |
| return saveAllEditors(saveDirty.equals(MessageDialogWithToggle.PROMPT)); |
| } |
| |
| /** |
| * Builds the workspace (according to preferences) and launches the given launch |
| * configuration in the specified mode. May return null if auto build is in process and |
| * user cancels the launch. |
| * |
| * @param configuration the configuration to launch |
| * @param mode launch mode - run or debug |
| * @param monitor progress monitor |
| * @exception CoreException if an exception occurs while building or launching |
| * @return resulting launch or <code>null</code> if user cancels |
| */ |
| public static ILaunch buildAndLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { |
| boolean buildBeforeLaunch = getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_BUILD_BEFORE_LAUNCH); |
| |
| monitor.beginTask(IInternalDebugCoreConstants.EMPTY_STRING, 1); |
| try |
| { |
| return configuration.launch( |
| mode, |
| new SubProgressMonitor(monitor, 1), |
| buildBeforeLaunch); |
| } |
| finally |
| { |
| monitor.done(); |
| } |
| } |
| |
| /** |
| * Saves and builds the workspace according to current preference settings and |
| * launches the given launch configuration in the specified mode in the |
| * foreground with a progress dialog. Reports any exceptions that occur |
| * in an error dialog. |
| * |
| * @param configuration the configuration to launch |
| * @param mode launch mode |
| * @since 3.0 |
| */ |
| public static void launchInForeground(final ILaunchConfiguration configuration, final String mode) { |
| final IJobManager jobManager = Job.getJobManager(); |
| IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore(); |
| boolean wait = false; |
| |
| if (jobManager.find(ResourcesPlugin.FAMILY_AUTO_BUILD).length > 0 || jobManager.find(ResourcesPlugin.FAMILY_MANUAL_BUILD).length >0) { |
| String waitForBuild = store.getString(IInternalDebugUIConstants.PREF_WAIT_FOR_BUILD); |
| |
| if (waitForBuild.equals(MessageDialogWithToggle.PROMPT)) { |
| MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoCancelQuestion(getShell(), DebugUIMessages.DebugUIPlugin_23, DebugUIMessages.DebugUIPlugin_24, null, false, store, IInternalDebugUIConstants.PREF_WAIT_FOR_BUILD); // |
| |
| switch (dialog.getReturnCode()) { |
| case IDialogConstants.CANCEL_ID: |
| return; |
| case IDialogConstants.YES_ID: |
| wait = false; |
| break; |
| case IDialogConstants.NO_ID: |
| wait = true; |
| break; |
| default: |
| break; |
| } |
| } else if (waitForBuild.equals(MessageDialogWithToggle.ALWAYS)) { |
| wait = true; |
| } |
| } |
| |
| if (wait) { |
| IWorkbench workbench = DebugUIPlugin.getDefault().getWorkbench(); |
| IProgressService progressService = workbench.getProgressService(); |
| final IRunnableWithProgress runnable = new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException { |
| /* Setup progress monitor |
| * - Waiting for jobs to finish (2) |
| * - Build & launch (98) */ |
| monitor.beginTask(MessageFormat.format(DebugUIMessages.DebugUIPlugin_25, new Object[] {configuration.getName()}), 100); |
| |
| try { |
| jobManager.join(ResourcesPlugin.FAMILY_MANUAL_BUILD, new SubProgressMonitor(monitor, 1)); |
| jobManager.join(ResourcesPlugin.FAMILY_AUTO_BUILD, new SubProgressMonitor(monitor, 1)); |
| } |
| catch (InterruptedException e) {/* continue*/} |
| if (!monitor.isCanceled()) { |
| try { |
| buildAndLaunch(configuration, mode, new SubProgressMonitor(monitor, 98)); |
| } |
| catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| } |
| }; |
| try { |
| progressService.busyCursorWhile(runnable); |
| } |
| catch (InterruptedException e) {} |
| catch (InvocationTargetException e2) { |
| handleInvocationTargetException(e2, configuration, mode); |
| } |
| } else { |
| IRunnableWithProgress runnable = new IRunnableWithProgress() { |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException { |
| /* Setup progress monitor |
| * - Build & launch (1) */ |
| monitor.beginTask(MessageFormat.format(DebugUIMessages.DebugUIPlugin_25, new Object[] {configuration.getName()}), 1); |
| try { |
| buildAndLaunch(configuration, mode, new SubProgressMonitor(monitor, 1)); |
| } |
| catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| }; |
| try { |
| PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnable); |
| } |
| catch (InvocationTargetException e) { |
| handleInvocationTargetException(e, configuration, mode); |
| } |
| catch (InterruptedException e) {} |
| |
| } |
| } |
| |
| private static void handleInvocationTargetException(InvocationTargetException e, ILaunchConfiguration configuration, String mode) { |
| Throwable targetException = e.getTargetException(); |
| Throwable t = e; |
| if (targetException instanceof CoreException) { |
| t = targetException; |
| } |
| if (t instanceof CoreException) { |
| CoreException ce = (CoreException)t; |
| IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(ce.getStatus()); |
| if (handler != null) { |
| ILaunchGroup group = DebugUITools.getLaunchGroup(configuration, mode); |
| if (group != null) { |
| DebugUITools.openLaunchConfigurationDialogOnGroup(DebugUIPlugin.getShell(), new StructuredSelection(configuration), group.getIdentifier(), ce.getStatus()); |
| return; |
| } |
| } |
| if ((ce.getStatus().getSeverity() & (IStatus.ERROR | IStatus.WARNING)) == 0) { |
| // If the exception is a CoreException with a status other |
| // than ERROR or WARNING, don't open an error dialog. |
| return; |
| } |
| } |
| DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), DebugUIMessages.DebugUITools_Error_1, DebugUIMessages.DebugUITools_Exception_occurred_during_launch_2, t); // |
| } |
| |
| /** |
| * Saves and builds the workspace according to current preference settings and |
| * launches the given launch configuration in the specified mode in a background |
| * Job with progress reported via the Job. Exceptions are reported in the Progress |
| * view. |
| * |
| * @param configuration the configuration to launch |
| * @param mode launch mode |
| * @since 3.0 |
| */ |
| public static void launchInBackground(final ILaunchConfiguration configuration, final String mode) { |
| final IJobManager jobManager = Job.getJobManager(); |
| IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore(); |
| boolean wait = (jobManager.find(ResourcesPlugin.FAMILY_AUTO_BUILD).length > 0 && ResourcesPlugin.getWorkspace().isAutoBuilding()) |
| || (jobManager.find(ResourcesPlugin.FAMILY_MANUAL_BUILD).length > 0); |
| String waitPref = store.getString(IInternalDebugUIConstants.PREF_WAIT_FOR_BUILD); |
| if (wait) { // if there are build jobs running, do we wait or not?? |
| if (waitPref.equals(MessageDialogWithToggle.PROMPT)) { |
| MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoCancelQuestion(getShell(), DebugUIMessages.DebugUIPlugin_23, DebugUIMessages.DebugUIPlugin_24, null, false, store, IInternalDebugUIConstants.PREF_WAIT_FOR_BUILD); // |
| switch (dialog.getReturnCode()) { |
| case IDialogConstants.CANCEL_ID: |
| return; |
| case IDialogConstants.YES_ID: |
| wait = true; |
| break; |
| case IDialogConstants.NO_ID: |
| wait = false; |
| break; |
| default: |
| break; |
| } |
| } |
| else { |
| wait = waitPref.equals(MessageDialogWithToggle.ALWAYS); |
| } |
| } |
| final boolean waitInJob = wait; |
| Job job = new Job(MessageFormat.format(DebugUIMessages.DebugUIPlugin_25, new Object[] {configuration.getName()})) { |
| @Override |
| public IStatus run(final IProgressMonitor monitor) { |
| /* Setup progress monitor |
| * - Waiting for jobs to finish (2) |
| * - Build & launch (98) */ |
| monitor.beginTask(DebugUIMessages.DebugUITools_3, 100); |
| try { |
| if(waitInJob) { |
| StringBuffer buffer = new StringBuffer(configuration.getName()); |
| buffer.append(DebugUIMessages.DebugUIPlugin_0); |
| ILaunchConfigurationWorkingCopy workingCopy = configuration.copy(buffer.toString()); |
| workingCopy.setAttribute(ATTR_LAUNCHING_CONFIG_HANDLE, configuration.getMemento()); |
| final ILaunch pendingLaunch = new PendingLaunch(workingCopy, mode, this); |
| DebugPlugin.getDefault().getLaunchManager().addLaunch(pendingLaunch); |
| IJobChangeListener listener= new IJobChangeListener() { |
| @Override |
| public void sleeping(IJobChangeEvent event) {} |
| @Override |
| public void scheduled(IJobChangeEvent event) {} |
| @Override |
| public void running(IJobChangeEvent event) {} |
| @Override |
| public void awake(IJobChangeEvent event) {} |
| @Override |
| public void aboutToRun(IJobChangeEvent event) {} |
| @Override |
| public void done(IJobChangeEvent event) { |
| DebugPlugin dp = DebugPlugin.getDefault(); |
| if (dp != null) { |
| dp.getLaunchManager().removeLaunch(pendingLaunch); |
| } |
| removeJobChangeListener(this); |
| } |
| }; |
| addJobChangeListener(listener); |
| try { |
| jobManager.join(ResourcesPlugin.FAMILY_MANUAL_BUILD, new SubProgressMonitor(monitor, 1)); |
| jobManager.join(ResourcesPlugin.FAMILY_AUTO_BUILD, new SubProgressMonitor(monitor, 1)); |
| } |
| catch (InterruptedException e) {/*just continue.*/} |
| DebugPlugin.getDefault().getLaunchManager().removeLaunch(pendingLaunch); |
| } |
| else { |
| monitor.worked(2); /* don't wait for jobs to finish */ |
| } |
| if (!monitor.isCanceled()) { |
| buildAndLaunch(configuration, mode, new SubProgressMonitor(monitor, 98)); |
| } |
| } catch (CoreException e) { |
| final IStatus status = e.getStatus(); |
| IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(status); |
| if (handler == null) { |
| return status; |
| } |
| final ILaunchGroup group = DebugUITools.getLaunchGroup(configuration, mode); |
| if (group == null) { |
| return status; |
| } |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| DebugUITools.openLaunchConfigurationDialogOnGroup(DebugUIPlugin.getShell(), new StructuredSelection(configuration), group.getIdentifier(), status); |
| } |
| }; |
| DebugUIPlugin.getStandardDisplay().asyncExec(r); |
| } |
| finally { |
| monitor.done(); |
| } |
| |
| return Status.OK_STATUS; |
| } |
| }; |
| |
| IWorkbench workbench = DebugUIPlugin.getDefault().getWorkbench(); |
| IProgressService progressService = workbench.getProgressService(); |
| |
| job.setPriority(Job.INTERACTIVE); |
| job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE); |
| job.setName(MessageFormat.format(DebugUIMessages.DebugUIPlugin_25, new Object[] {configuration.getName()})); |
| |
| if (wait) { |
| progressService.showInDialog(workbench.getActiveWorkbenchWindow().getShell(), job); |
| } |
| job.schedule(); |
| } |
| |
| /** |
| * Returns the label with any accelerators removed. |
| * @param label the label to remove accelerators from |
| * |
| * @return label without accelerators |
| */ |
| public static String removeAccelerators(String label) { |
| String title = label; |
| if (title != null) { |
| // strip out any '&' (accelerators) |
| int index = title.indexOf('&'); |
| if (index == 0) { |
| title = title.substring(1); |
| } else if (index > 0) { |
| //DBCS languages use "(&X)" format |
| if (title.charAt(index - 1) == '(' && title.length() >= index + 3 && title.charAt(index + 2) == ')') { |
| String first = title.substring(0, index - 1); |
| String last = title.substring(index + 3); |
| title = first + last; |
| } else if (index < (title.length() - 1)) { |
| String first = title.substring(0, index); |
| String last = title.substring(index + 1); |
| title = first + last; |
| } |
| } |
| } |
| return title; |
| } |
| |
| /** |
| * Returns the label with any DBCS accelerator moved to the end of the string. |
| * See bug 186921. |
| * @param label the label to be adjusted |
| * |
| * @return label with moved accelerator |
| */ |
| public static String adjustDBCSAccelerator(String label) { |
| String title = label; |
| if (title != null) { |
| // strip out any '&' (accelerators) |
| int index = title.indexOf('&'); |
| if (index > 0) { |
| //DBCS languages use "(&X)" format |
| if (title.charAt(index - 1) == '(' && title.length() >= index + 3 && title.charAt(index + 2) == ')') { |
| String first = title.substring(0, index - 1); |
| String accel = title.substring(index - 1, index + 3); |
| String last = title.substring(index + 3); |
| title = first + last; |
| if (title.endsWith("...")) { //$NON-NLS-1$ |
| title = title.substring(0, title.length() - 3); |
| title = title + accel + "..."; //$NON-NLS-1$ |
| } else { |
| title = title + accel; |
| } |
| } |
| } |
| } |
| return title; |
| } |
| |
| /** |
| * Returns the image descriptor registry used for this plug-in. |
| * @return the singleton {@link ImageDescriptorRegistry} |
| * |
| * @since 3.1 |
| */ |
| public static ImageDescriptorRegistry getImageDescriptorRegistry() { |
| if (getDefault().fImageDescriptorRegistry == null) { |
| getDefault().fImageDescriptorRegistry = new ImageDescriptorRegistry(); |
| } |
| return getDefault().fImageDescriptorRegistry; |
| } |
| |
| /** |
| * Returns an image descriptor for the icon referenced by the given attribute |
| * and configuration element, or <code>null</code> if none. |
| * |
| * @param element the configuration element |
| * @param attr the name of the attribute |
| * @return image descriptor or <code>null</code> |
| */ |
| public static ImageDescriptor getImageDescriptor(IConfigurationElement element, String attr) { |
| Bundle bundle = Platform.getBundle(element.getContributor().getName()); |
| String iconPath = element.getAttribute(attr); |
| if (iconPath != null) { |
| URL iconURL = FileLocator.find(bundle , new Path(iconPath), null); |
| if (iconURL != null) { |
| return ImageDescriptor.createFromURL(iconURL); |
| } else { // try to search as a URL in case it is absolute path |
| try { |
| iconURL = FileLocator.find(new URL(iconPath)); |
| if (iconURL != null) { |
| return ImageDescriptor.createFromURL(iconURL); |
| } |
| } catch (MalformedURLException e) { |
| // return null |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns an image descriptor for the icon referenced by the given path |
| * and contributor name, or <code>null</code> if none. |
| * |
| * @param name the name of the contributor |
| * @param path the path of the icon (from the configuration element) |
| * @return image descriptor or <code>null</code> |
| * @since 3.3 |
| */ |
| public static ImageDescriptor getImageDescriptor(String name, String path) { |
| Bundle bundle = Platform.getBundle(name); |
| if (path != null) { |
| URL iconURL = FileLocator.find(bundle , new Path(path), null); |
| if (iconURL != null) { |
| return ImageDescriptor.createFromURL(iconURL); |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Performs extra filtering for launch configurations based on the preferences set on the |
| * Launch Configurations page |
| * @param config the config to filter |
| * @return true if it should pass the filter, false otherwise |
| * @since 3.2 |
| */ |
| public static boolean doLaunchConfigurationFiltering(ILaunchConfiguration config) { |
| boolean ret = true; |
| if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_CLOSED)) { |
| ret &= new ClosedProjectFilter().select(null, null, config); |
| } |
| if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_DELETED)) { |
| ret &= new DeletedProjectFilter().select(null, null, config); |
| } |
| if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_FILTER_LAUNCH_TYPES)) { |
| try { |
| ret &= new LaunchConfigurationTypeFilter().select(null, null, config.getType()); |
| } |
| catch(CoreException e) { |
| DebugUIPlugin.log(e); |
| } |
| } |
| return ret; |
| } |
| |
| /** |
| * Creates a new {@link IEvaluationContext} initialized with the current platform state if the |
| * {@link IEvaluationService} can be acquired, otherwise the new context is created with no |
| * parent context |
| * |
| * @param defaultvar the default variable for the new context |
| * @return a new {@link IEvaluationContext} |
| * @since 3.7 |
| */ |
| public static IEvaluationContext createEvaluationContext(Object defaultvar) { |
| IEvaluationContext parent = null; |
| IEvaluationService esrvc = PlatformUI.getWorkbench().getService(IEvaluationService.class); |
| if (esrvc != null) { |
| parent = esrvc.getCurrentState(); |
| } |
| return new EvaluationContext(parent, defaultvar); |
| } |
| } |
| |