/******************************************************************************* * Copyright (c) 2000, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Martin Oberhuber (Wind River) - [325557] Perspective "none" is not persisted *******************************************************************************/ package org.eclipse.debug.internal.ui.launchConfigurations; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.eclipse.core.commands.contexts.Context; import org.eclipse.core.resources.ISaveContext; import org.eclipse.core.resources.ISaveParticipant; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchDelegate; import org.eclipse.debug.core.ILaunchListener; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.internal.core.IConfigurationElementConstants; import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; import org.eclipse.debug.internal.core.LaunchManager; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.internal.ui.viewers.AsynchronousSchedulingRuleFactory; import org.eclipse.debug.internal.ui.views.ViewContextManager; import org.eclipse.debug.internal.ui.views.ViewContextService; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.contexts.ISuspendTrigger; import org.eclipse.debug.ui.contexts.ISuspendTriggerListener; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.ibm.icu.text.MessageFormat; /** * The perspective manager manages the 'perspective' settings * defined by launch configurations. Specifically it: *
ISaveParticipant
, allowing it to participate in
* workspace persistence life-cycles.
*
* @see IDebugUIContants.ATTR_RUN_PERSPECTIVE
* @see IDebugUIContants.ATTR_DEBUG_PERSPECTIVE
* @see ISaveParticipant
* @see ISuspendTriggerListener
* @see ILaunchListener
* @see org.eclipse.debug.internal.ui.preferences.LaunchPerspectivePreferencePage
* @see DebugUIPlugin
*/
public class PerspectiveManager implements ILaunchListener, ISuspendTriggerListener, ISaveParticipant {
/**
* Describes exactly one perspective context, which is composed of an ILaunchCOnfigurationType
, and set of modes
* and an ILaunchDelegate
. Perspective ids are then cached for a context based on mode set.
*
* @since 3.3
*/
class PerspectiveContext {
private ILaunchConfigurationType fType = null;
private ILaunchDelegate fDelegate = null;
private Mapnull
, if there isn't one
*/
public String getPerspective(SetPerspectiveContext
s
*
* @since 3.3
*/
private Setnull
if none.
*
* @param shell shell to check
* @return a modal dialog currently open on the given shell or null
if none
*/
private Shell getModalDialogOpen(Shell shell) {
Shell[] shells = shell.getShells();
for (int i = 0; i < shells.length; i++) {
Shell dialog = shells[i];
if ((dialog.getStyle() & (SWT.APPLICATION_MODAL | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL)) > 0) {
return dialog;
}
}
return null;
}
/**
* Returns the workbench window in which the given perspective
* should be shown. First, check the current window to see if it
* is already showing the perspective. Then check any other windows.
*
* @param perspectiveId the perspective identifier
* @return which window the given perspective should be shown in
* or null
if there are no windows available
*/
private IWorkbenchWindow getWindowForPerspective(String perspectiveId) {
IWorkbenchWindow window = DebugUIPlugin.getActiveWorkbenchWindow();
if (isWindowShowingPerspective(window, perspectiveId)) {
return window;
}
IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
for (int i = 0; i < windows.length; i++) {
window = windows[i];
if (isWindowShowingPerspective(window, perspectiveId)) {
return window;
}
}
window = DebugUIPlugin.getActiveWorkbenchWindow();
if (window != null) {
return window;
}
if (windows.length > 0) {
return windows[0];
}
return null;
}
/**
* Returns if the specified window is showing the perspective denoted by the specified id
* @param window the window to query
* @param perspectiveId the perspective to ask about
* @return true if the specified window is showing the perspective, false otherwise
*/
private boolean isWindowShowingPerspective(IWorkbenchWindow window, String perspectiveId) {
if (window != null) {
IWorkbenchPage page = window.getActivePage();
if (page != null) {
IPerspectiveDescriptor perspectiveDescriptor = page.getPerspective();
if (perspectiveDescriptor != null && perspectiveDescriptor.getId().equals(perspectiveId)) {
return true;
}
}
}
return false;
}
/**
* Returns whether or not the user wishes to switch to the specified
* perspective when a launch occurs.
*
* @param perspectiveName the name of the perspective that will be presented
* to the user for confirmation if they've asked to be prompted about
* perspective switching
* @param message a message to be presented to the user. This message is expected to
* contain a slot for the perspective name to be inserted ("{0}").
* @param preferenceKey the preference key of the perspective switching preference
* @return whether or not the user wishes to switch to the specified perspective
* automatically
*/
private boolean shouldSwitchPerspective(IWorkbenchWindow window, String perspectiveId, String preferenceKey) {
if (isCurrentPerspective(window, perspectiveId)) {
return false;
}
String perspectiveName = getPerspectiveLabel(perspectiveId);
if (perspectiveName == null) {
return false;
}
String perspectiveDesc = getPerspectiveDescription(perspectiveId);
Object[] args;
if (perspectiveDesc != null) {
args = new String[] { perspectiveName , perspectiveDesc };
}
else {
args = new String[] { perspectiveName };
}
String switchPerspective = DebugUIPlugin.getDefault().getPreferenceStore().getString(preferenceKey);
if (MessageDialogWithToggle.ALWAYS.equals(switchPerspective)) {
return true;
} else if (MessageDialogWithToggle.NEVER.equals(switchPerspective)) {
return false;
}
Shell shell= window.getShell();
if (shell == null || fPrompting) {
return false;
}
fPrompting= true;
// Activate the shell if necessary so the prompt is visible
Shell modal = getModalDialogOpen(shell);
if (shell.getMinimized()) {
shell.setMinimized(false);
if (modal != null) {
modal.setFocus();
}
}
if (DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_ACTIVATE_WORKBENCH)) {
if (modal == null) {
shell.forceActive();
}
}
String message = IInternalDebugCoreConstants.EMPTY_STRING;
if(IInternalDebugUIConstants.PREF_SWITCH_PERSPECTIVE_ON_SUSPEND.equals(preferenceKey)) {
if (getPerspectiveDescription(perspectiveId) != null) {
message = LaunchConfigurationsMessages.PerspectiveManager_suspend_description;
}
else {
message = LaunchConfigurationsMessages.PerspectiveManager_13;
}
}
else if(IInternalDebugUIConstants.PREF_SWITCH_TO_PERSPECTIVE.equals(preferenceKey)) {
if (getPerspectiveDescription(perspectiveId) != null) {
message = LaunchConfigurationsMessages.PerspectiveManager_launch_description;
}
else {
message = LaunchConfigurationsMessages.PerspectiveManager_15;
}
}
LinkedHashMapnull
if no such perspective exists.
*
* @param perspectiveId the identifier
* @return the label of the perspective with the given identifier or
* null
if no such perspective exists
*/
protected String getPerspectiveLabel(String perspectiveId) {
IPerspectiveDescriptor newPerspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId);
if (newPerspective == null) {
return null;
}
return newPerspective.getLabel();
}
/**
* Returns the label of the perspective with the given identifier or
* null
if no such perspective exists.
*
* @param perspectiveId the identifier
* @return the label of the perspective with the given identifier or
* null
if no such perspective exists
*/
protected String getPerspectiveDescription(String perspectiveId) {
IPerspectiveDescriptor newPerspective = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId);
if (newPerspective == null) {
return null;
}
return newPerspective.getDescription();
}
/**
* Returns the perspective associated with the
* given launch, or null
if none.
*
* @param launch a launch
* @return the perspective associated with the launch,
* or null
* @exception CoreException if unable to retrieve a required
* launch configuration attribute
*/
protected String getPerspectiveId(ILaunch launch) throws CoreException {
if (launch == null) {
return null;
}
ILaunchConfiguration config = launch.getLaunchConfiguration();
if (config == null) {
return null;
}
Setnull
for
* the launch delegate results in the default perspective id being returned (if there is one).
* @param type the type we are launching
* @param modes the set of modes the type was launched with
* @param delegate the delegate performing the launch for this type and modeset
* @return the id of the perspective for the given launch configuration type, modeset and launch delegate
*
* @since 3.3
*/
public String getLaunchPerspective(ILaunchConfigurationType type, Setnull
if no switch should take
* place.
*
* This method is equivalent to calling getLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate)
,
* with the 'mode' parameter comprising a single element set and passing null
as the launch delegate.
*
null
* @since 3.0
*/
public String getLaunchPerspective(ILaunchConfigurationType type, String mode) {
HashSetPERSPECTIVE_NONE
indicates no
* perspective switch should take place. PERSPECTIVE_DEFAULT
indicates
* a default perspective switch should take place, as defined by the associated
* launch tab group extension.
*
* Calling this method is equivalent to calling setLaunchPerspective(ILaunchConfigurationType type, Set modes, ILaunchDelegate delegate, String perspectiveid)
,
* with the parameter 'mode' used in the set modes, and null passed as the delegate
*
PERSPECTIVE_NONE
, or
* PERSPECTIVE_DEFAULT
* @since 3.0
*/
public void setLaunchPerspective(ILaunchConfigurationType type, String mode, String perspective) {
HashSet
* Passing null
as a launch delegate will set the default perspective switch for that type and modeset, where
* PERSPECTIVE_NONE
indicates no perspective switch should take place.
*
null
if the default perspective should be used
*
* @since 3.3
*/
public void setLaunchPerspective(ILaunchConfigurationType type, SetPerspectiveContext
or null
if none
*
* @since 3.3
*/
private PerspectiveContext findContext(PerspectiveContext context) {
for (PerspectiveContext c : fPerspectiveContexts) {
if (context.equals(c)) {
return c;
}
}
return null;
}
/**
* Generates XML for the user specified perspective settings.
*
* @return XML
* @exception IOException if unable to generate the XML
* @exception TransformerException if unable to generate the XML
* @exception ParserConfigurationException if unable to generate the XML
*/
private String generatePerspectiveXML() throws ParserConfigurationException, CoreException {
Document doc = DebugUIPlugin.getDocument();
Element root = doc.createElement(IConfigurationElementConstants.LAUNCH_PERSPECTIVES);
doc.appendChild(root);
Mapnull
if none
* @param type the type
* @param delegate the associated delegate, or null
to specify that the default perspective id for that given type and mode set should be returned
* @param modes the set of modes this applies to
* @return the default perspective id for the given type, delegate and mode set combination, or null
if none
*
* @since 3.3
*/
public String getDefaultLaunchPerspective(ILaunchConfigurationType type, ILaunchDelegate delegate, SetILaunchDelegate
from the given ILaunch
* @param launch the launch
* @return
* @throws CoreException
*/
private ILaunchDelegate resolveLaunchDelegate(ILaunch launch) throws CoreException {
Set