/******************************************************************************* * Copyright (c) 2000, 2011 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 *******************************************************************************/ 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. *

* Clients may call {@link #setHelpContextId(String)} on this tab prior to control * creation to alter the default context help associated with this tab. *

*

* This class may be instantiate. *

* @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 true. */ 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, null, 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 null * @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 (ATTR_REFRESH_SCOPE) * @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 null if none. * * @param configuration launch configuration * @return refresh scope attribute (ATTR_REFRESH_SCOPE) * @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 null * @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 getRefreshAttribute(IWorkingSet), or null * if none. * * @param refreshAttribute a refresh attribute that represents a working set * @return equivalent working set, or null */ 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$ } }