blob: ddec5089044d49633312830412eed2442759cb03 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2011 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
*******************************************************************************/
package org.eclipse.debug.ui;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.RefreshUtil;
import org.eclipse.debug.internal.ui.DebugPluginImages;
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.internal.ui.launchConfigurations.LaunchConfigurationsDialog;
import org.eclipse.debug.internal.ui.stringsubstitution.StringSubstitutionMessages;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.IWorkingSetEditWizard;
/**
* A launch configuration tab which allows the user to specify
* which resources should be refreshed when the launch
* terminates.
* <p>
* Clients may call {@link #setHelpContextId(String)} on this tab prior to control
* creation to alter the default context help associated with this tab.
* </p>
* <p>
* This class may be instantiate.
* </p>
* @since 3.0
* @noextend This class is not intended to be sub-classed by clients.
*/
public class RefreshTab extends AbstractLaunchConfigurationTab {
/**
* Boolean attribute indicating if a refresh scope is recursive. Default
* value is <code>true</code>.
*/
public static final String ATTR_REFRESH_RECURSIVE = RefreshUtil.ATTR_REFRESH_RECURSIVE;
/**
* String attribute identifying the scope of resources that should be
* refreshed after an external tool is run. The value is either a refresh
* variable or the default value, <code>null</code>, indicating no refresh.
*/
public static final String ATTR_REFRESH_SCOPE = RefreshUtil.ATTR_REFRESH_SCOPE;
// Check Buttons
private Button fRefreshButton;
private Button fRecursiveButton;
// Group box
private Group fGroup;
// Radio Buttons
private Button fContainerButton;
private Button fProjectButton;
private Button fResourceButton;
private Button fWorkingSetButton;
private Button fWorkspaceButton;
// Push Button
private Button fSelectButton;
// Working set
private IWorkingSet fWorkingSet;
/**
* Constructor
*/
public RefreshTab() {
setHelpContextId(IDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_REFRESH_TAB);
}
/**
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createControl(Composite parent) {
Composite mainComposite = new Composite(parent, SWT.NONE);
setControl(mainComposite);
PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), getHelpContextId());
GridLayout layout = new GridLayout();
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
mainComposite.setLayout(layout);
mainComposite.setLayoutData(gd);
mainComposite.setFont(parent.getFont());
fRefreshButton = createCheckButton(mainComposite, StringSubstitutionMessages.RefreshTab_31);
fRefreshButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateEnabledState();
updateLaunchConfigurationDialog();
}
});
fGroup = new Group(mainComposite, SWT.NONE);
fGroup.setFont(mainComposite.getFont());
layout = new GridLayout();
layout.numColumns = 2;
layout.makeColumnsEqualWidth = false;
fGroup.setLayout(layout);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fGroup.setLayoutData(gd);
SelectionAdapter adapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (((Button)e.getSource()).getSelection()) {
updateEnabledState();
updateLaunchConfigurationDialog();
}
}
};
fWorkspaceButton = createRadioButton(fGroup, StringSubstitutionMessages.RefreshTab_32);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fWorkspaceButton.setLayoutData(gd);
fWorkspaceButton.addSelectionListener(adapter);
fResourceButton = createRadioButton(fGroup, StringSubstitutionMessages.RefreshTab_33);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fResourceButton.setLayoutData(gd);
fResourceButton.addSelectionListener(adapter);
fProjectButton = createRadioButton(fGroup, StringSubstitutionMessages.RefreshTab_34);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fProjectButton.setLayoutData(gd);
fProjectButton.addSelectionListener(adapter);
fContainerButton = createRadioButton(fGroup, StringSubstitutionMessages.RefreshTab_35);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
fContainerButton.setLayoutData(gd);
fContainerButton.addSelectionListener(adapter);
fWorkingSetButton = createRadioButton(fGroup, StringSubstitutionMessages.RefreshTab_36);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 1;
fWorkingSetButton.setLayoutData(gd);
fWorkingSetButton.addSelectionListener(adapter);
fSelectButton = createPushButton(fGroup, StringSubstitutionMessages.RefreshTab_37, null);
gd = (GridData)fSelectButton.getLayoutData();
gd.horizontalAlignment = GridData.HORIZONTAL_ALIGN_END;
fSelectButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
selectResources();
}
});
createVerticalSpacer(fGroup, 2);
createRecursiveComponent(fGroup);
}
/**
* Prompts the user to select the resources to refresh.
*/
private void selectResources() {
IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
if (fWorkingSet == null){
fWorkingSet = workingSetManager.createWorkingSet(StringSubstitutionMessages.RefreshTab_40, new IAdaptable[0]);
}
IWorkingSetEditWizard wizard = workingSetManager.createWorkingSetEditWizard(fWorkingSet);
WizardDialog dialog = new WizardDialog(((LaunchConfigurationsDialog)LaunchConfigurationsDialog.getCurrentlyVisibleLaunchConfigurationDialog()).getShell(), wizard);
dialog.create();
if (dialog.open() == Window.CANCEL) {
return;
}
fWorkingSet = wizard.getSelection();
updateLaunchConfigurationDialog();
}
/**
* Creates the controls needed to edit the refresh recursive
* attribute of a launch configuration
*
* @param parent the composite to create the controls in
*/
private void createRecursiveComponent(Composite parent) {
fRecursiveButton = createCheckButton(parent, StringSubstitutionMessages.RefreshTab_0);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
data.horizontalSpan = 2;
fRecursiveButton.setLayoutData(data);
fRecursiveButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateLaunchConfigurationDialog();
}
});
}
/**
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
*/
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
}
/**
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
*/
@Override
public void initializeFrom(ILaunchConfiguration configuration) {
updateRefresh(configuration);
updateRecursive(configuration);
updateScope(configuration);
updateEnabledState();
}
/**
* Updates the tab to display the refresh scope specified by the launch config
* @param configuration the configuration to update scope information on
*/
private void updateScope(ILaunchConfiguration configuration) {
String scope = null;
try {
scope= configuration.getAttribute(ATTR_REFRESH_SCOPE, (String)null);
} catch (CoreException ce) {
DebugUIPlugin.log(DebugUIPlugin.newErrorStatus("Exception reading launch configuration", ce)); //$NON-NLS-1$
}
fWorkspaceButton.setSelection(false);
fResourceButton.setSelection(false);
fContainerButton.setSelection(false);
fProjectButton.setSelection(false);
fWorkingSetButton.setSelection(false);
if (scope == null) {
// select the workspace by default
fWorkspaceButton.setSelection(true);
} else {
if (scope.equals(RefreshUtil.MEMENTO_WORKSPACE)) {
fWorkspaceButton.setSelection(true);
} else if (scope.equals(RefreshUtil.MEMENTO_SELECTED_RESOURCE)) {
fResourceButton.setSelection(true);
} else if (scope.equals(RefreshUtil.MEMENTO_SELECTED_CONTAINER)) {
fContainerButton.setSelection(true);
} else if (scope.equals(RefreshUtil.MEMENTO_SELECTED_PROJECT)) {
fProjectButton.setSelection(true);
} else if (scope.startsWith("${resource:")) { //$NON-NLS-1$
fWorkingSetButton.setSelection(true);
try {
IResource[] resources = getRefreshResources(scope);
IWorkingSetManager workingSetManager= PlatformUI.getWorkbench().getWorkingSetManager();
fWorkingSet = workingSetManager.createWorkingSet(StringSubstitutionMessages.RefreshTab_40, resources);
} catch (CoreException e) {
fWorkingSet = null;
}
} else if (scope.startsWith("${working_set:")) { //$NON-NLS-1$
fWorkingSetButton.setSelection(true);
fWorkingSet = getWorkingSet(scope);
}
}
}
/**
* Method updateRecursive.
* @param configuration the launch configuration to update the refresh button from
*/
private void updateRecursive(ILaunchConfiguration configuration) {
boolean recursive= true;
try {
recursive= configuration.getAttribute(ATTR_REFRESH_RECURSIVE, true);
} catch (CoreException ce) {
DebugUIPlugin.log(DebugUIPlugin.newErrorStatus("Exception reading launch configuration", ce)); //$NON-NLS-1$
}
fRecursiveButton.setSelection(recursive);
}
/**
* Method updateRefresh.
* @param configuration the configuration to update the refresh scope button from
*/
private void updateRefresh(ILaunchConfiguration configuration) {
String scope= null;
try {
scope= configuration.getAttribute(ATTR_REFRESH_SCOPE, (String)null);
} catch (CoreException ce) {
DebugUIPlugin.log(DebugUIPlugin.newErrorStatus("Exception reading launch configuration", ce)); //$NON-NLS-1$
}
fRefreshButton.setSelection(scope != null);
}
/**
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
*/
@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
if (fRefreshButton.getSelection()) {
String scope = generateScopeMemento();
configuration.setAttribute(ATTR_REFRESH_SCOPE, scope);
setAttribute(ATTR_REFRESH_RECURSIVE, configuration, fRecursiveButton.getSelection(), true);
} else {
//clear the refresh attributes
configuration.setAttribute(ATTR_REFRESH_SCOPE, (String)null);
setAttribute(ATTR_REFRESH_RECURSIVE, configuration, true, true);
}
}
/**
* Generates a memento for the refresh scope. This is based on old refresh
* variables.
*
* @return a memento
*/
private String generateScopeMemento() {
if (fWorkspaceButton.getSelection()) {
return RefreshUtil.MEMENTO_WORKSPACE;
}
if (fResourceButton.getSelection()) {
return RefreshUtil.MEMENTO_SELECTED_RESOURCE;
}
if (fContainerButton.getSelection()) {
return RefreshUtil.MEMENTO_SELECTED_CONTAINER;
}
if (fProjectButton.getSelection()) {
return RefreshUtil.MEMENTO_SELECTED_PROJECT;
}
if (fWorkingSetButton.getSelection()) {
return getRefreshAttribute(fWorkingSet);
}
return null;
}
/**
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
*/
@Override
public String getName() {
return StringSubstitutionMessages.RefreshTab_6;
}
/**
* Updates the enablement state of the fields.
*/
private void updateEnabledState() {
boolean enabled= fRefreshButton.getSelection();
fRecursiveButton.setEnabled(enabled);
fGroup.setEnabled(enabled);
fWorkspaceButton.setEnabled(enabled);
fResourceButton.setEnabled(enabled);
fContainerButton.setEnabled(enabled);
fProjectButton.setEnabled(enabled);
fWorkingSetButton.setEnabled(enabled);
fSelectButton.setEnabled(enabled && fWorkingSetButton.getSelection());
if (!enabled) {
super.setErrorMessage(null);
}
}
/**
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
*/
@Override
public Image getImage() {
return DebugPluginImages.getImage(IInternalDebugUIConstants.IMG_OBJS_REFRESH_TAB);
}
@Override
public boolean isValid(ILaunchConfiguration launchConfig) {
setErrorMessage(null);
setMessage(null);
if (fRefreshButton.getSelection() && (fWorkingSetButton.getSelection() && (fWorkingSet == null || fWorkingSet.getElements().length == 0))) {
setErrorMessage(StringSubstitutionMessages.RefreshTab_42);
return false;
}
return true;
}
/**
* Refreshes the resources as specified by the given launch configuration.
*
* @param configuration launch configuration
* @param monitor progress monitor which may be <code>null</code>
* @throws CoreException if an exception occurs while refreshing resources
*/
public static void refreshResources(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
RefreshUtil.refreshResources(configuration, monitor);
}
/**
* Returns a collection of resources referred to by a refresh scope attribute.
*
* @param scope refresh scope attribute (<code>ATTR_REFRESH_SCOPE</code>)
* @return collection of resources referred to by the refresh scope attribute
* @throws CoreException if unable to resolve a set of resources
*/
public static IResource[] getRefreshResources(String scope) throws CoreException {
return RefreshUtil.toResources(scope);
}
/**
* Returns the refresh scope attribute specified by the given launch configuration
* or <code>null</code> if none.
*
* @param configuration launch configuration
* @return refresh scope attribute (<code>ATTR_REFRESH_SCOPE</code>)
* @throws CoreException if unable to access the associated attribute
*/
public static String getRefreshScope(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(ATTR_REFRESH_SCOPE, (String) null);
}
/**
* Returns whether the refresh scope specified by the given launch
* configuration is recursive.
*
* @param configuration the configuration to check for recursive refresh being set
* @return whether the refresh scope is recursive
* @throws CoreException if unable to access the associated attribute
*/
public static boolean isRefreshRecursive(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(ATTR_REFRESH_RECURSIVE, true);
}
/**
* Creates and returns a memento for the given working set, to be used as a
* refresh attribute.
*
* @param workingSet a working set, or <code>null</code>
* @return an equivalent refresh attribute
*/
public static String getRefreshAttribute(IWorkingSet workingSet) {
if (workingSet == null || workingSet.getElements().length == 0) {
return RefreshUtil.toMemento(new IResource[0]);
} else {
IAdaptable[] elements = workingSet.getElements();
IResource[] resources = new IResource[elements.length];
for (int i = 0; i < resources.length; i++) {
resources[i]= elements[i].getAdapter(IResource.class);
}
return RefreshUtil.toMemento(resources);
}
}
/**
* Creates and returns a working set from the given refresh attribute created by
* the method <code>getRefreshAttribute(IWorkingSet)</code>, or <code>null</code>
* if none.
*
* @param refreshAttribute a refresh attribute that represents a working set
* @return equivalent working set, or <code>null</code>
*/
public static IWorkingSet getWorkingSet(String refreshAttribute) {
if (refreshAttribute.startsWith("${working_set:")) { //$NON-NLS-1$
try {
IResource[] resources = RefreshUtil.toResources(refreshAttribute);
IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager();
IWorkingSet workingSet = workingSetManager.createWorkingSet(StringSubstitutionMessages.RefreshTab_1, resources);
return workingSet;
} catch (CoreException e) {
DebugUIPlugin.log(e);
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
*/
@Override
public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
// do nothing on activation
}
/* (non-Javadoc)
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#deactivated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
*/
@Override
public void deactivated(ILaunchConfigurationWorkingCopy workingCopy) {
// do nothing on deactivation
}
/**
* @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getId()
*
* @since 3.5
*/
@Override
public String getId() {
return "org.eclipse.debug.ui.refreshTab"; //$NON-NLS-1$
}
}