Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 51185 Details for
Bug 123674
[Experimental] - various patches posted here for data xfer
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
org.eclipse.ide.patch
org.eclipse.ui.ide.patch (text/plain), 207.79 KB, created by
Susan McCourt
on 2006-09-29 14:00:17 EDT
(
hide
)
Description:
org.eclipse.ide.patch
Filename:
MIME Type:
Creator:
Susan McCourt
Created:
2006-09-29 14:00:17 EDT
Size:
207.79 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.ui.ide >Index: extensions/org/eclipse/ui/dialogs/WizardNewFileCreationPage.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/dialogs/WizardNewFileCreationPage.java,v >retrieving revision 1.18 >diff -u -r1.18 WizardNewFileCreationPage.java >--- extensions/org/eclipse/ui/dialogs/WizardNewFileCreationPage.java 15 Jun 2006 19:52:17 -0000 1.18 >+++ extensions/org/eclipse/ui/dialogs/WizardNewFileCreationPage.java 29 Sep 2006 18:00:39 -0000 >@@ -15,6 +15,7 @@ > import java.lang.reflect.InvocationTargetException; > import java.util.Iterator; > >+import org.eclipse.core.commands.ExecutionException; > import org.eclipse.core.resources.IFile; > import org.eclipse.core.resources.IFolder; > import org.eclipse.core.resources.IResource; >@@ -30,10 +31,9 @@ > import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.core.runtime.Path; > import org.eclipse.core.runtime.Preferences; >-import org.eclipse.core.runtime.SubProgressMonitor; > import org.eclipse.core.runtime.jobs.ISchedulingRule; >-import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.jface.operation.IRunnableWithProgress; > import org.eclipse.jface.viewers.IStructuredSelection; > import org.eclipse.jface.wizard.WizardPage; > import org.eclipse.osgi.util.NLS; >@@ -49,7 +49,7 @@ > import org.eclipse.swt.widgets.Listener; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.actions.WorkspaceModifyOperation; >+import org.eclipse.ui.ide.undo.CreateFileOperation; > import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; > import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; > import org.eclipse.ui.internal.ide.IIDEHelpContextIds; >@@ -218,6 +218,10 @@ > * @param monitor the progress monitor to show visual progress with > * @exception CoreException if the operation fails > * @exception OperationCanceledException if the operation is canceled >+ * >+ * @deprecated As of 3.3, use or override {@link #createNewFile()} which uses the >+ * undoable operation support. To supply customized file content for >+ * a subclass, use {@link #getInitialContents()}. > */ > protected void createFile(IFile fileHandle, InputStream contents, > IProgressMonitor monitor) throws CoreException { >@@ -321,45 +325,42 @@ > final InputStream initialContents = getInitialContents(); > > createLinkTarget(); >- WorkspaceModifyOperation op = new WorkspaceModifyOperation(createRule(newFileHandle)) { >- protected void execute(IProgressMonitor monitor) >- throws CoreException { >- try { >- monitor.beginTask(IDEWorkbenchMessages.WizardNewFileCreationPage_progress, 2000); >- ContainerGenerator generator = new ContainerGenerator( >- containerPath); >- generator.generateContainer(new SubProgressMonitor(monitor, >- 1000)); >- createFile(newFileHandle, initialContents, >- new SubProgressMonitor(monitor, 1000)); >- } finally { >- monitor.done(); >- } >- } >- }; >+ IRunnableWithProgress op = new IRunnableWithProgress() { >+ public void run(IProgressMonitor monitor) { >+ CreateFileOperation op = new CreateFileOperation( >+ newFileHandle, linkTargetPath, initialContents, >+ IDEWorkbenchMessages.WizardNewFileCreationPage_title); >+ try { >+ PlatformUI.getWorkbench().getOperationSupport() >+ .getOperationHistory().execute(op, monitor, >+ new IAdaptable() { >+ public Object getAdapter(Class clazz) { >+ if (clazz == Shell.class) { >+ return getContainer() >+ .getShell(); >+ } >+ return null; >+ } >+ }); >+ } catch (ExecutionException e) { >+ IDEWorkbenchPlugin.log(e.getMessage(), e); >+ } >+ } >+ }; > > try { > getContainer().run(true, true, op); > } catch (InterruptedException e) { > return null; > } catch (InvocationTargetException e) { >- if (e.getTargetException() instanceof CoreException) { >- ErrorDialog >- .openError( >- getContainer().getShell(), // Was Utilities.getFocusShell() >- IDEWorkbenchMessages.WizardNewFileCreationPage_errorTitle, >- null, // no special message >- ((CoreException) e.getTargetException()) >- .getStatus()); >- } else { >- // CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur. >- IDEWorkbenchPlugin.log(getClass(), >- "createNewFile()", e.getTargetException()); //$NON-NLS-1$ >- MessageDialog >- .openError( >- getContainer().getShell(), >- IDEWorkbenchMessages.WizardNewFileCreationPage_internalErrorTitle, NLS.bind(IDEWorkbenchMessages.WizardNewFileCreationPage_internalErrorMessage, e.getTargetException().getMessage())); >- } >+ // Execution Exceptions are handled above but we may still get unexpected runtime errors. >+ IDEWorkbenchPlugin.log(getClass(), >+ "createNewFile()", e.getTargetException()); //$NON-NLS-1$ >+ MessageDialog >+ .openError( >+ getContainer().getShell(), >+ IDEWorkbenchMessages.WizardNewFileCreationPage_internalErrorTitle, NLS.bind(IDEWorkbenchMessages.WizardNewFileCreationPage_internalErrorMessage, e.getTargetException().getMessage())); >+ > return null; > } > >Index: extensions/org/eclipse/ui/dialogs/WizardNewFolderMainPage.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/dialogs/WizardNewFolderMainPage.java,v >retrieving revision 1.19 >diff -u -r1.19 WizardNewFolderMainPage.java >--- extensions/org/eclipse/ui/dialogs/WizardNewFolderMainPage.java 14 Jun 2006 14:39:44 -0000 1.19 >+++ extensions/org/eclipse/ui/dialogs/WizardNewFolderMainPage.java 29 Sep 2006 18:00:41 -0000 >@@ -15,6 +15,7 @@ > import java.lang.reflect.InvocationTargetException; > import java.util.Iterator; > >+import org.eclipse.core.commands.ExecutionException; > import org.eclipse.core.resources.IFolder; > import org.eclipse.core.resources.IResource; > import org.eclipse.core.resources.IResourceStatus; >@@ -29,9 +30,8 @@ > import org.eclipse.core.runtime.Path; > import org.eclipse.core.runtime.Preferences; > import org.eclipse.core.runtime.SubProgressMonitor; >-import org.eclipse.core.runtime.jobs.ISchedulingRule; >-import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.jface.operation.IRunnableWithProgress; > import org.eclipse.jface.viewers.IStructuredSelection; > import org.eclipse.jface.wizard.WizardPage; > import org.eclipse.osgi.util.NLS; >@@ -47,7 +47,7 @@ > import org.eclipse.swt.widgets.Listener; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.actions.WorkspaceModifyOperation; >+import org.eclipse.ui.ide.undo.CreateFolderOperation; > import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; > import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; > import org.eclipse.ui.internal.ide.IIDEHelpContextIds; >@@ -62,448 +62,441 @@ > * <p> > * Subclasses may extend > * <ul> >- * <li><code>handleEvent</code></li> >+ * <li><code>handleEvent</code></li> > * </ul> > * </p> > */ > public class WizardNewFolderMainPage extends WizardPage implements Listener { >- private static final int SIZING_CONTAINER_GROUP_HEIGHT = 250; >+ private static final int SIZING_CONTAINER_GROUP_HEIGHT = 250; > >- private IStructuredSelection currentSelection; >+ private IStructuredSelection currentSelection; > >- private IFolder newFolder; >+ private IFolder newFolder; > >- // link target location >- private IPath linkTargetPath; >+ // link target location >+ private IPath linkTargetPath; > >- // widgets >- private ResourceAndContainerGroup resourceGroup; >- >- private Button advancedButton; >- >- private CreateLinkedResourceGroup linkedResourceGroup; >- >- private Composite linkedResourceParent; >- >- private Composite linkedResourceComposite; >- >- /** >- * Height of the "advanced" linked resource group. Set when the >- * advanced group is first made visible. >- */ >- private int linkedResourceGroupHeight = -1; >- >- /** >- * First time the advanced group is validated. >- */ >- private boolean firstLinkCheck = true; >- >- /** >- * Creates a new folder creation wizard page. If the initial resource selection >- * contains exactly one container resource then it will be used as the default >- * container resource. >- * >- * @param pageName the name of the page >- * @param selection the current resource selection >- */ >- public WizardNewFolderMainPage(String pageName, >- IStructuredSelection selection) { >- super("newFolderPage1");//$NON-NLS-1$ >- setTitle(pageName); >- setDescription(IDEWorkbenchMessages.WizardNewFolderMainPage_description); >- this.currentSelection = selection; >- } >- >- /** >- * Creates the widget for advanced options. >- * >- * @param parent the parent composite >- */ >- protected void createAdvancedControls(Composite parent) { >- Preferences preferences = ResourcesPlugin.getPlugin() >- .getPluginPreferences(); >- >- if (preferences.getBoolean(ResourcesPlugin.PREF_DISABLE_LINKING) == false) { >- linkedResourceParent = new Composite(parent, SWT.NONE); >- linkedResourceParent.setFont(parent.getFont()); >- linkedResourceParent.setLayoutData(new GridData( >- GridData.FILL_HORIZONTAL)); >- GridLayout layout = new GridLayout(); >- layout.marginHeight = 0; >- layout.marginWidth = 0; >- linkedResourceParent.setLayout(layout); >- >- advancedButton = new Button(linkedResourceParent, SWT.PUSH); >- advancedButton.setFont(linkedResourceParent.getFont()); >- advancedButton.setText(IDEWorkbenchMessages.showAdvanced); >- GridData data = setButtonLayoutData(advancedButton); >- data.horizontalAlignment = GridData.BEGINNING; >- advancedButton.setLayoutData(data); >- advancedButton.addSelectionListener(new SelectionAdapter() { >- public void widgetSelected(SelectionEvent e) { >- handleAdvancedButtonSelect(); >- } >- }); >- } >- linkedResourceGroup = new CreateLinkedResourceGroup(IResource.FOLDER, >- new Listener() { >- public void handleEvent(Event e) { >- setPageComplete(validatePage()); >- firstLinkCheck = false; >- } >- }, >- new CreateLinkedResourceGroup.IStringValue() { >- public String getValue() { >- return resourceGroup.getResource(); >- } >- public void setValue(String string) { >- resourceGroup.setResource(string); >- } >- }); >- } >- >- /** (non-Javadoc) >- * Method declared on IDialogPage. >- */ >- public void createControl(Composite parent) { >- initializeDialogUnits(parent); >- // top level group >- Composite composite = new Composite(parent, SWT.NONE); >- composite.setFont(parent.getFont()); >- composite.setLayout(new GridLayout()); >- composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL >- | GridData.HORIZONTAL_ALIGN_FILL)); >- >- PlatformUI.getWorkbench().getHelpSystem() >- .setHelp(composite, IIDEHelpContextIds.NEW_FOLDER_WIZARD_PAGE); >- >- resourceGroup = new ResourceAndContainerGroup( >- composite, >- this, >- IDEWorkbenchMessages.WizardNewFolderMainPage_folderName, IDEWorkbenchMessages.WizardNewFolderMainPage_folderLabel, false, SIZING_CONTAINER_GROUP_HEIGHT); >- resourceGroup.setAllowExistingResources(false); >- createAdvancedControls(composite); >- initializePage(); >- validatePage(); >- // Show description on opening >- setErrorMessage(null); >- setMessage(null); >- setControl(composite); >- } >- >- /** >- * Creates a folder resource given the folder handle. >- * >- * @param folderHandle the folder handle to create a folder resource for >- * @param monitor the progress monitor to show visual progress with >- * @exception CoreException if the operation fails >- * @exception OperationCanceledException if the operation is canceled >- */ >- protected void createFolder(IFolder folderHandle, IProgressMonitor monitor) >- throws CoreException { >- try { >- // Create the folder resource in the workspace >- // Update: Recursive to create any folders which do not exist already >- if (!folderHandle.exists()) { >- if (linkTargetPath != null) { >+ // widgets >+ private ResourceAndContainerGroup resourceGroup; >+ >+ private Button advancedButton; >+ >+ private CreateLinkedResourceGroup linkedResourceGroup; >+ >+ private Composite linkedResourceParent; >+ >+ private Composite linkedResourceComposite; >+ >+ /** >+ * Height of the "advanced" linked resource group. Set when the advanced >+ * group is first made visible. >+ */ >+ private int linkedResourceGroupHeight = -1; >+ >+ /** >+ * First time the advanced group is validated. >+ */ >+ private boolean firstLinkCheck = true; >+ >+ /** >+ * Creates a new folder creation wizard page. If the initial resource >+ * selection contains exactly one container resource then it will be used as >+ * the default container resource. >+ * >+ * @param pageName >+ * the name of the page >+ * @param selection >+ * the current resource selection >+ */ >+ public WizardNewFolderMainPage(String pageName, >+ IStructuredSelection selection) { >+ super("newFolderPage1");//$NON-NLS-1$ >+ setTitle(pageName); >+ setDescription(IDEWorkbenchMessages.WizardNewFolderMainPage_description); >+ this.currentSelection = selection; >+ } >+ >+ /** >+ * Creates the widget for advanced options. >+ * >+ * @param parent >+ * the parent composite >+ */ >+ protected void createAdvancedControls(Composite parent) { >+ Preferences preferences = ResourcesPlugin.getPlugin() >+ .getPluginPreferences(); >+ >+ if (preferences.getBoolean(ResourcesPlugin.PREF_DISABLE_LINKING) == false) { >+ linkedResourceParent = new Composite(parent, SWT.NONE); >+ linkedResourceParent.setFont(parent.getFont()); >+ linkedResourceParent.setLayoutData(new GridData( >+ GridData.FILL_HORIZONTAL)); >+ GridLayout layout = new GridLayout(); >+ layout.marginHeight = 0; >+ layout.marginWidth = 0; >+ linkedResourceParent.setLayout(layout); >+ >+ advancedButton = new Button(linkedResourceParent, SWT.PUSH); >+ advancedButton.setFont(linkedResourceParent.getFont()); >+ advancedButton.setText(IDEWorkbenchMessages.showAdvanced); >+ GridData data = setButtonLayoutData(advancedButton); >+ data.horizontalAlignment = GridData.BEGINNING; >+ advancedButton.setLayoutData(data); >+ advancedButton.addSelectionListener(new SelectionAdapter() { >+ public void widgetSelected(SelectionEvent e) { >+ handleAdvancedButtonSelect(); >+ } >+ }); >+ } >+ linkedResourceGroup = new CreateLinkedResourceGroup(IResource.FOLDER, >+ new Listener() { >+ public void handleEvent(Event e) { >+ setPageComplete(validatePage()); >+ firstLinkCheck = false; >+ } >+ }, new CreateLinkedResourceGroup.IStringValue() { >+ public String getValue() { >+ return resourceGroup.getResource(); >+ } >+ >+ public void setValue(String string) { >+ resourceGroup.setResource(string); >+ } >+ }); >+ } >+ >+ /** >+ * (non-Javadoc) Method declared on IDialogPage. >+ */ >+ public void createControl(Composite parent) { >+ initializeDialogUnits(parent); >+ // top level group >+ Composite composite = new Composite(parent, SWT.NONE); >+ composite.setFont(parent.getFont()); >+ composite.setLayout(new GridLayout()); >+ composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL >+ | GridData.HORIZONTAL_ALIGN_FILL)); >+ >+ PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, >+ IIDEHelpContextIds.NEW_FOLDER_WIZARD_PAGE); >+ >+ resourceGroup = new ResourceAndContainerGroup(composite, this, >+ IDEWorkbenchMessages.WizardNewFolderMainPage_folderName, >+ IDEWorkbenchMessages.WizardNewFolderMainPage_folderLabel, >+ false, SIZING_CONTAINER_GROUP_HEIGHT); >+ resourceGroup.setAllowExistingResources(false); >+ createAdvancedControls(composite); >+ initializePage(); >+ validatePage(); >+ // Show description on opening >+ setErrorMessage(null); >+ setMessage(null); >+ setControl(composite); >+ } >+ >+ /** >+ * Creates a folder resource given the folder handle. >+ * >+ * @param folderHandle >+ * the folder handle to create a folder resource for >+ * @param monitor >+ * the progress monitor to show visual progress with >+ * @exception CoreException >+ * if the operation fails >+ * @exception OperationCanceledException >+ * if the operation is canceled >+ * >+ * @deprecated As of 3.3, use {@link #createNewFolder()} which uses the >+ * undoable operation support. >+ */ >+ protected void createFolder(IFolder folderHandle, IProgressMonitor monitor) >+ throws CoreException { >+ try { >+ // Create the folder resource in the workspace >+ // Update: Recursive to create any folders which do not exist >+ // already >+ if (!folderHandle.exists()) { >+ if (linkTargetPath != null) { > folderHandle.createLink(linkTargetPath, >- IResource.ALLOW_MISSING_LOCAL, monitor); >+ IResource.ALLOW_MISSING_LOCAL, monitor); > } else { >- IPath path = folderHandle.getFullPath(); >- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); >- int numSegments= path.segmentCount(); >- if (numSegments > 2 && !root.getFolder(path.removeLastSegments(1)).exists()) { >- // If the direct parent of the path doesn't exist, try to create the >- // necessary directories. >- for (int i= numSegments - 2; i > 0; i--) { >- IFolder folder = root.getFolder(path.removeLastSegments(i)); >- if (!folder.exists()) { >- folder.create(false, true, monitor); >- } >- } >- } >- folderHandle.create(false, true, monitor); >- } >- } >- } catch (CoreException e) { >- // If the folder already existed locally, just refresh to get contents >- if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) { >+ IPath path = folderHandle.getFullPath(); >+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace() >+ .getRoot(); >+ int numSegments = path.segmentCount(); >+ if (numSegments > 2 >+ && !root.getFolder(path.removeLastSegments(1)) >+ .exists()) { >+ // If the direct parent of the path doesn't exist, try >+ // to create the >+ // necessary directories. >+ for (int i = numSegments - 2; i > 0; i--) { >+ IFolder folder = root.getFolder(path >+ .removeLastSegments(i)); >+ if (!folder.exists()) { >+ folder.create(false, true, monitor); >+ } >+ } >+ } >+ folderHandle.create(false, true, monitor); >+ } >+ } >+ } catch (CoreException e) { >+ // If the folder already existed locally, just refresh to get >+ // contents >+ if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) { > folderHandle.refreshLocal(IResource.DEPTH_INFINITE, >- new SubProgressMonitor(monitor, 500)); >+ new SubProgressMonitor(monitor, 500)); > } else { > throw e; > } >- } >+ } > >- if (monitor.isCanceled()) { >+ if (monitor.isCanceled()) { > throw new OperationCanceledException(); > } >- } >+ } > >- /** >- * Creates a folder resource handle for the folder with the given workspace path. >- * This method does not create the folder resource; this is the responsibility >- * of <code>createFolder</code>. >- * >- * @param folderPath the path of the folder resource to create a handle for >- * @return the new folder resource handle >- * @see #createFolder >- */ >- protected IFolder createFolderHandle(IPath folderPath) { >- return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder( >- folderPath); >- } >- >- /** >- * Creates the link target path if a link target has been specified. >- */ >- protected void createLinkTarget() { >- String linkTarget = linkedResourceGroup.getLinkTarget(); >- if (linkTarget != null) { >- linkTargetPath = new Path(linkTarget); >- } else { >- linkTargetPath = null; >- } >- } >- >- /** >- * Creates a new folder resource in the selected container and with the selected >- * name. Creates any missing resource containers along the path; does nothing if >- * the container resources already exist. >- * <p> >- * In normal usage, this method is invoked after the user has pressed Finish on >- * the wizard; the enablement of the Finish button implies that all controls on >- * this page currently contain valid values. >- * </p> >- * <p> >- * Note that this page caches the new folder once it has been successfully >- * created; subsequent invocations of this method will answer the same >- * folder resource without attempting to create it again. >- * </p> >- * <p> >- * This method should be called within a workspace modify operation since >- * it creates resources. >- * </p> >- * >- * @return the created folder resource, or <code>null</code> if the folder >- * was not created >- */ >- public IFolder createNewFolder() { >- if (newFolder != null) { >+ /** >+ * Creates a folder resource handle for the folder with the given workspace >+ * path. This method does not create the folder resource; this is the >+ * responsibility of <code>createFolder</code>. >+ * >+ * @param folderPath >+ * the path of the folder resource to create a handle for >+ * @return the new folder resource handle >+ * @see #createFolder >+ */ >+ protected IFolder createFolderHandle(IPath folderPath) { >+ return IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getFolder( >+ folderPath); >+ } >+ >+ /** >+ * Creates the link target path if a link target has been specified. >+ */ >+ protected void createLinkTarget() { >+ String linkTarget = linkedResourceGroup.getLinkTarget(); >+ if (linkTarget != null) { >+ linkTargetPath = new Path(linkTarget); >+ } else { >+ linkTargetPath = null; >+ } >+ } >+ >+ /** >+ * Creates a new folder resource in the selected container and with the >+ * selected name. Creates any missing resource containers along the path; >+ * does nothing if the container resources already exist. >+ * <p> >+ * In normal usage, this method is invoked after the user has pressed Finish >+ * on the wizard; the enablement of the Finish button implies that all >+ * controls on this page currently contain valid values. >+ * </p> >+ * <p> >+ * Note that this page caches the new folder once it has been successfully >+ * created; subsequent invocations of this method will answer the same >+ * folder resource without attempting to create it again. >+ * </p> >+ * <p> >+ * This method should be called within a workspace modify operation since it >+ * creates resources. >+ * </p> >+ * >+ * @return the created folder resource, or <code>null</code> if the folder >+ * was not created >+ */ >+ public IFolder createNewFolder() { >+ if (newFolder != null) { > return newFolder; > } > >- // create the new folder and cache it if successful >- final IPath containerPath = resourceGroup.getContainerFullPath(); >- IPath newFolderPath = containerPath.append(resourceGroup.getResource()); >- final IFolder newFolderHandle = createFolderHandle(newFolderPath); >- >- createLinkTarget(); >- WorkspaceModifyOperation op = new WorkspaceModifyOperation(createRule(newFolderHandle)) { >- public void execute(IProgressMonitor monitor) throws CoreException { >- try { >- monitor.beginTask(IDEWorkbenchMessages.WizardNewFolderCreationPage_progress, 2000); >- ContainerGenerator generator = new ContainerGenerator( >- containerPath); >- generator.generateContainer(new SubProgressMonitor(monitor, >- 1000)); >- createFolder(newFolderHandle, new SubProgressMonitor( >- monitor, 1000)); >- } finally { >- monitor.done(); >- } >- } >- }; >- >- try { >- getContainer().run(true, true, op); >- } catch (InterruptedException e) { >- return null; >- } catch (InvocationTargetException e) { >- if (e.getTargetException() instanceof CoreException) { >- ErrorDialog >- .openError( >- getContainer().getShell(), // Was Utilities.getFocusShell() >- IDEWorkbenchMessages.WizardNewFolderCreationPage_errorTitle, >- null, // no special message >- ((CoreException) e.getTargetException()) >- .getStatus()); >- } else { >- // CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur. >- >- IDEWorkbenchPlugin.log(getClass(), >- "createNewFolder()", e.getTargetException()); //$NON-NLS-1$ >- MessageDialog >- .openError( >- getContainer().getShell(), >- IDEWorkbenchMessages.WizardNewFolderCreationPage_internalErrorTitle, NLS.bind(IDEWorkbenchMessages.WizardNewFolder_internalError, e.getTargetException().getMessage())); >- } >- return null; // ie.- one of the steps resulted in a core exception >- } >- >- newFolder = newFolderHandle; >- >- return newFolder; >- } >- >- /** >- * Returns the scheduling rule to use when creating the resource at >- * the given container path. The rule should be the creation rule for >- * the top-most non-existing parent. >- * @param resource The resource being created >- * @return The scheduling rule for creating the given resource >- * @since 3.1 >- */ >- private ISchedulingRule createRule(IResource resource) { >- IResource parent = resource.getParent(); >- while (parent != null) { >- if (parent.exists()) { >- return resource.getWorkspace().getRuleFactory().createRule(resource); >+ // create the new folder and cache it if successful >+ final IPath containerPath = resourceGroup.getContainerFullPath(); >+ IPath newFolderPath = containerPath.append(resourceGroup.getResource()); >+ final IFolder newFolderHandle = createFolderHandle(newFolderPath); >+ >+ createLinkTarget(); >+ IRunnableWithProgress op = new IRunnableWithProgress() { >+ public void run(IProgressMonitor monitor) { >+ CreateFolderOperation op = new CreateFolderOperation( >+ newFolderHandle, linkTargetPath, >+ IDEWorkbenchMessages.WizardNewFolderCreationPage_title); >+ try { >+ PlatformUI.getWorkbench().getOperationSupport() >+ .getOperationHistory().execute(op, monitor, >+ new IAdaptable() { >+ public Object getAdapter(Class clazz) { >+ if (clazz == Shell.class) { >+ return getContainer() >+ .getShell(); >+ } >+ return null; >+ } >+ }); >+ } catch (ExecutionException e) { >+ IDEWorkbenchPlugin.log(e.getMessage(), e); >+ } >+ } >+ }; >+ >+ try { >+ getContainer().run(true, true, op); >+ } catch (InterruptedException e) { >+ return null; >+ } catch (InvocationTargetException e) { >+ // ExecutionExceptions are handled above, but unexpected runtime >+ // exceptions and errors may still occur. >+ IDEWorkbenchPlugin.log(getClass(), >+ "createNewFolder()", e.getTargetException()); //$NON-NLS-1$ >+ MessageDialog >+ .openError( >+ getContainer().getShell(), >+ IDEWorkbenchMessages.WizardNewFolderCreationPage_internalErrorTitle, NLS.bind(IDEWorkbenchMessages.WizardNewFolder_internalError, e.getTargetException().getMessage())); >+ return null; >+ } >+ >+ newFolder = newFolderHandle; >+ >+ return newFolder; >+ } >+ >+ /** >+ * Shows/hides the advanced option widgets. >+ */ >+ protected void handleAdvancedButtonSelect() { >+ Shell shell = getShell(); >+ Point shellSize = shell.getSize(); >+ Composite composite = (Composite) getControl(); >+ >+ if (linkedResourceComposite != null) { >+ linkedResourceComposite.dispose(); >+ linkedResourceComposite = null; >+ composite.layout(); >+ shell.setSize(shellSize.x, shellSize.y - linkedResourceGroupHeight); >+ advancedButton.setText(IDEWorkbenchMessages.showAdvanced); >+ } else { >+ linkedResourceComposite = linkedResourceGroup >+ .createContents(linkedResourceParent); >+ if (linkedResourceGroupHeight == -1) { >+ Point groupSize = linkedResourceComposite.computeSize( >+ SWT.DEFAULT, SWT.DEFAULT, true); >+ linkedResourceGroupHeight = groupSize.y; >+ } >+ shell.setSize(shellSize.x, shellSize.y + linkedResourceGroupHeight); >+ composite.layout(); >+ advancedButton.setText(IDEWorkbenchMessages.hideAdvanced); >+ } >+ } >+ >+ /** >+ * The <code>WizardNewFolderCreationPage</code> implementation of this >+ * <code>Listener</code> method handles all events and enablements for >+ * controls on this page. Subclasses may extend. >+ */ >+ public void handleEvent(Event ev) { >+ setPageComplete(validatePage()); >+ } >+ >+ /** >+ * Initializes this page's controls. >+ */ >+ protected void initializePage() { >+ Iterator it = currentSelection.iterator(); >+ if (it.hasNext()) { >+ Object next = it.next(); >+ IResource selectedResource = null; >+ if (next instanceof IResource) { >+ selectedResource = (IResource) next; >+ } else if (next instanceof IAdaptable) { >+ selectedResource = (IResource) ((IAdaptable) next) >+ .getAdapter(IResource.class); > } >- resource = parent; >- parent = parent.getParent(); >- } >- return resource.getWorkspace().getRoot(); >- } >- >- /** >- * Shows/hides the advanced option widgets. >- */ >- protected void handleAdvancedButtonSelect() { >- Shell shell = getShell(); >- Point shellSize = shell.getSize(); >- Composite composite = (Composite) getControl(); >- >- if (linkedResourceComposite != null) { >- linkedResourceComposite.dispose(); >- linkedResourceComposite = null; >- composite.layout(); >- shell.setSize(shellSize.x, shellSize.y - linkedResourceGroupHeight); >- advancedButton.setText(IDEWorkbenchMessages.showAdvanced); >- } else { >- linkedResourceComposite = linkedResourceGroup >- .createContents(linkedResourceParent); >- if (linkedResourceGroupHeight == -1) { >- Point groupSize = linkedResourceComposite.computeSize( >- SWT.DEFAULT, SWT.DEFAULT, true); >- linkedResourceGroupHeight = groupSize.y; >- } >- shell.setSize(shellSize.x, shellSize.y + linkedResourceGroupHeight); >- composite.layout(); >- advancedButton.setText(IDEWorkbenchMessages.hideAdvanced); >- } >- } >- >- /** >- * The <code>WizardNewFolderCreationPage</code> implementation of this >- * <code>Listener</code> method handles all events and enablements for controls >- * on this page. Subclasses may extend. >- */ >- public void handleEvent(Event ev) { >- setPageComplete(validatePage()); >- } >- >- /** >- * Initializes this page's controls. >- */ >- protected void initializePage() { >- Iterator it = currentSelection.iterator(); >- if (it.hasNext()) { >- Object next = it.next(); >- IResource selectedResource = null; >- if (next instanceof IResource) { >- selectedResource = (IResource) next; >- } else if (next instanceof IAdaptable) { >- selectedResource = (IResource) ((IAdaptable) next) >- .getAdapter(IResource.class); >- } >- if (selectedResource != null) { >- if (selectedResource.getType() == IResource.FILE) { >+ if (selectedResource != null) { >+ if (selectedResource.getType() == IResource.FILE) { > selectedResource = selectedResource.getParent(); > } >- if (selectedResource.isAccessible()) { >+ if (selectedResource.isAccessible()) { > resourceGroup.setContainerFullPath(selectedResource >- .getFullPath()); >+ .getFullPath()); > } >- } >- } >+ } >+ } > >- setPageComplete(false); >- } >+ setPageComplete(false); >+ } > >- /* >- * @see DialogPage.setVisible(boolean) >- */ >- public void setVisible(boolean visible) { >- super.setVisible(visible); >- if (visible) { >+ /* >+ * @see DialogPage.setVisible(boolean) >+ */ >+ public void setVisible(boolean visible) { >+ super.setVisible(visible); >+ if (visible) { > resourceGroup.setFocus(); > } >- } >+ } > >- /** >- * Checks whether the linked resource target is valid. >- * Sets the error message accordingly and returns the status. >- * >- * @return IStatus validation result from the CreateLinkedResourceGroup >- */ >- protected IStatus validateLinkedResource() { >- IPath containerPath = resourceGroup.getContainerFullPath(); >- IPath newFolderPath = containerPath.append(resourceGroup.getResource()); >- IFolder newFolderHandle = createFolderHandle(newFolderPath); >- IStatus status = linkedResourceGroup >- .validateLinkLocation(newFolderHandle); >+ /** >+ * Checks whether the linked resource target is valid. Sets the error >+ * message accordingly and returns the status. >+ * >+ * @return IStatus validation result from the CreateLinkedResourceGroup >+ */ >+ protected IStatus validateLinkedResource() { >+ IPath containerPath = resourceGroup.getContainerFullPath(); >+ IPath newFolderPath = containerPath.append(resourceGroup.getResource()); >+ IFolder newFolderHandle = createFolderHandle(newFolderPath); >+ IStatus status = linkedResourceGroup >+ .validateLinkLocation(newFolderHandle); > >- if (status.getSeverity() == IStatus.ERROR) { >- if (firstLinkCheck) { >+ if (status.getSeverity() == IStatus.ERROR) { >+ if (firstLinkCheck) { > setMessage(status.getMessage()); > } else { > setErrorMessage(status.getMessage()); > } >- } else if (status.getSeverity() == IStatus.WARNING) { >- setMessage(status.getMessage(), WARNING); >- setErrorMessage(null); >- } >- return status; >- } >- >- /** >- * Returns whether this page's controls currently all contain valid >- * values. >- * >- * @return <code>true</code> if all controls are valid, and >- * <code>false</code> if at least one is invalid >- */ >- protected boolean validatePage() { >- boolean valid = true; >- >- if (!resourceGroup.areAllValuesValid()) { >- // if blank name then fail silently >- if (resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_RESOURCE_EMPTY >- || resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_CONTAINER_EMPTY) { >- setMessage(resourceGroup.getProblemMessage()); >- setErrorMessage(null); >- } else { >- setErrorMessage(resourceGroup.getProblemMessage()); >- } >- valid = false; >- } >- >- IStatus linkedResourceStatus = null; >- if (valid) { >- linkedResourceStatus = validateLinkedResource(); >- if (linkedResourceStatus.getSeverity() == IStatus.ERROR) { >+ } else if (status.getSeverity() == IStatus.WARNING) { >+ setMessage(status.getMessage(), WARNING); >+ setErrorMessage(null); >+ } >+ return status; >+ } >+ >+ /** >+ * Returns whether this page's controls currently all contain valid values. >+ * >+ * @return <code>true</code> if all controls are valid, and >+ * <code>false</code> if at least one is invalid >+ */ >+ protected boolean validatePage() { >+ boolean valid = true; >+ >+ if (!resourceGroup.areAllValuesValid()) { >+ // if blank name then fail silently >+ if (resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_RESOURCE_EMPTY >+ || resourceGroup.getProblemType() == ResourceAndContainerGroup.PROBLEM_CONTAINER_EMPTY) { >+ setMessage(resourceGroup.getProblemMessage()); >+ setErrorMessage(null); >+ } else { >+ setErrorMessage(resourceGroup.getProblemMessage()); >+ } >+ valid = false; >+ } >+ >+ IStatus linkedResourceStatus = null; >+ if (valid) { >+ linkedResourceStatus = validateLinkedResource(); >+ if (linkedResourceStatus.getSeverity() == IStatus.ERROR) { > valid = false; > } >- } >- // validateLinkedResource sets messages itself >- if (valid >- && (linkedResourceStatus == null || linkedResourceStatus.isOK())) { >- setMessage(null); >- setErrorMessage(null); >- } >- return valid; >- } >+ } >+ // validateLinkedResource sets messages itself >+ if (valid >+ && (linkedResourceStatus == null || linkedResourceStatus.isOK())) { >+ setMessage(null); >+ setErrorMessage(null); >+ } >+ return valid; >+ } > > } >- >Index: src/org/eclipse/ui/internal/ide/undo/UndoMessages.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/UndoMessages.java,v >retrieving revision 1.4 >diff -u -r1.4 UndoMessages.java >--- src/org/eclipse/ui/internal/ide/undo/UndoMessages.java 13 Sep 2006 00:02:38 -0000 1.4 >+++ src/org/eclipse/ui/internal/ide/undo/UndoMessages.java 29 Sep 2006 18:00:50 -0000 >@@ -36,6 +36,29 @@ > public static String AbstractWorkspaceOperation_RedoSideEffectsWarningMessage; > public static String AbstractWorkspaceOperation_ErrorInvalidMessage; > public static String AbstractWorkspaceOperation_GenericWarningMessage; >+ >+ public static String AbstractResourcesOperation_ResourcesDoNotExist; >+ public static String AbstractResourcesOperation_NotEnoughInfo; >+ public static String AbstractResourcesOperation_InvalidRestoreInfo; >+ public static String AbstractResourcesOperation_DeleteResourcesProgress; >+ public static String AbstractResourcesOperation_CreateResourcesProgress; >+ public static String AbstractResourcesOperation_CopyingResourcesProgress; >+ public static String AbstractResourcesOperation_MovingResources; >+ public static String AbstractResourcesOperation_outOfSyncError; >+ public static String AbstractResourcesOperation_outOfSyncQuestion; >+ public static String AbstractResourcesOperation_deletionMessageTitle; >+ public static String AbstractResourcesOperation_deletionExceptionMessage; >+ >+ public static String DeleteResourcesOperation_DeletingProjectContentWarning; >+ public static String CreateProjectOperation_caseVariantExistsError; >+ >+ public static String ProjectDescription_NewProjectProgress; >+ public static String FileDescription_NewFileProgress; >+ public static String FileDescription_SavingUndoInfoProgress; >+ public static String FileDescription_ContentsCouldNotBeRestored; >+ public static String FolderDescription_NewFolderProgress; >+ public static String FolderDescription_SavingUndoInfoProgress; >+ > > public static String MarkerOperation_ResourceDoesNotExist; > public static String MarkerOperation_MarkerDoesNotExist; >Index: src/org/eclipse/ui/internal/ide/undo/messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/undo/messages.properties,v >retrieving revision 1.4 >diff -u -r1.4 messages.properties >--- src/org/eclipse/ui/internal/ide/undo/messages.properties 13 Sep 2006 00:02:38 -0000 1.4 >+++ src/org/eclipse/ui/internal/ide/undo/messages.properties 29 Sep 2006 18:00:50 -0000 >@@ -20,6 +20,29 @@ > AbstractWorkspaceOperation_UndoSideEffectsWarningMessage=Undoing "{0}" may have undesirable side effects. > AbstractWorkspaceOperation_RedoSideEffectsWarningMessage=Redoing "{0}" may have undesirable side effects. > >+AbstractResourcesOperation_ResourcesDoNotExist=Cannot complete operation because resources no longer exist. >+AbstractResourcesOperation_NotEnoughInfo=There is not enough information to complete the resource operation. >+AbstractResourcesOperation_InvalidRestoreInfo=There is no longer enough information to restore the resource. >+AbstractResourcesOperation_DeleteResourcesProgress=Deleting resources... >+AbstractResourcesOperation_CreateResourcesProgress=Creating resources... >+AbstractResourcesOperation_CopyingResourcesProgress=Copying resources... >+AbstractResourcesOperation_MovingResources=Moving resources... >+AbstractResourcesOperation_outOfSyncError = Resource is out of sync with the file system. Refresh and try again. >+AbstractResourcesOperation_outOfSyncQuestion = Resource ''{0}'' is out of sync with the file system. Do you want to delete it anyway? >+AbstractResourcesOperation_deleteMessageTitle = Problems deleting >+AbstractResourcesOperation_deletionExceptionMessage=Multiple problems occurred while deleting resources. >+ >+DeleteResourcesOperation_DeletingProjectContentWarning=Deleting a project's content will erase all of its file and folder history. Only the project itself can be restored by undoing this operation. >+ >+CreateProjectOperation_caseVariantExistsError = The underlying file system is case insensitive. There is an existing project which conflicts with ''{0}''. >+ >+ProjectDescription_NewProjectProgress=Creating new project... >+FileDescription_NewFileProgress=Creating new file... >+FileDescription_ContentsCouldNotBeRestored=Unexpected error. File contents could not be restored from local history during undo/redo. >+FileDescription_SavingUndoInfoProgress=Saving file info... >+FolderDescription_NewFolderProgress=Creating new folder... >+FolderDescription_SavingUndoInfoProgress=Saving folder info... >+ > MarkerOperation_ResourceDoesNotExist=Cannot complete operation because resource no longer exists. > MarkerOperation_MarkerDoesNotExist=Cannot complete operation because marker no longer exists. > MarkerOperation_NotEnoughInfo=There is not enough information to perform the marker operation. >Index: extensions/org/eclipse/ui/actions/DeleteResourceAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/DeleteResourceAction.java,v >retrieving revision 1.25 >diff -u -r1.25 DeleteResourceAction.java >--- extensions/org/eclipse/ui/actions/DeleteResourceAction.java 8 May 2006 20:54:12 -0000 1.25 >+++ extensions/org/eclipse/ui/actions/DeleteResourceAction.java 29 Sep 2006 18:00:33 -0000 >@@ -10,25 +10,17 @@ > *******************************************************************************/ > package org.eclipse.ui.actions; > >-import java.util.ArrayList; > import java.util.List; > >+import org.eclipse.core.commands.ExecutionException; > import org.eclipse.core.resources.IProject; > import org.eclipse.core.resources.IResource; > import org.eclipse.core.resources.IResourceRuleFactory; >-import org.eclipse.core.resources.IResourceStatus; >-import org.eclipse.core.resources.IWorkspace; >-import org.eclipse.core.resources.IWorkspaceRunnable; > import org.eclipse.core.resources.ResourcesPlugin; >-import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; >-import org.eclipse.core.resources.mapping.ResourceChangeValidator; >-import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.IStatus; >-import org.eclipse.core.runtime.MultiStatus; >-import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.core.runtime.Status; >-import org.eclipse.core.runtime.SubProgressMonitor; > import org.eclipse.core.runtime.jobs.ISchedulingRule; > import org.eclipse.core.runtime.jobs.Job; > import org.eclipse.core.runtime.jobs.MultiRule; >@@ -47,7 +39,7 @@ > import org.eclipse.swt.widgets.Control; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.ide.IDE; >+import org.eclipse.ui.ide.undo.DeleteResourcesOperation; > import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; > import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; > import org.eclipse.ui.internal.ide.IIDEHelpContextIds; >@@ -207,11 +199,6 @@ > private boolean deleteContent = false; > > /** >- * Whether or not to automatically delete out of sync resources >- */ >- private boolean forceOutOfSyncDelete = false; >- >- /** > * Flag that allows testing mode ... it won't pop up the project delete > * dialog, and will return "delete all content". > */ >@@ -317,44 +304,6 @@ > } > > /** >- * Creates and returns a result status appropriate for the given list of >- * exceptions. >- * >- * @param exceptions >- * The list of exceptions that occurred (may be empty) >- * @return The result status for the deletion >- */ >- private IStatus createResult(List exceptions) { >- if (exceptions.isEmpty()) { >- return Status.OK_STATUS; >- } >- final int exceptionCount = exceptions.size(); >- if (exceptionCount == 1) { >- return ((CoreException) exceptions.get(0)).getStatus(); >- } >- CoreException[] children = (CoreException[]) exceptions >- .toArray(new CoreException[exceptionCount]); >- boolean outOfSync = false; >- for (int i = 0; i < children.length; i++) { >- if (children[i].getStatus().getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) { >- outOfSync = true; >- break; >- } >- } >- String title = outOfSync ? IDEWorkbenchMessages.DeleteResourceAction_outOfSyncError >- : IDEWorkbenchMessages.DeleteResourceAction_deletionExceptionMessage; >- final MultiStatus multi = new MultiStatus( >- IDEWorkbenchPlugin.IDE_WORKBENCH, 0, title, null); >- for (int i = 0; i < exceptionCount; i++) { >- CoreException exception = children[i]; >- IStatus status = exception.getStatus(); >- multi.add(new Status(status.getSeverity(), status.getPlugin(), >- status.getCode(), status.getMessage(), exception)); >- } >- return multi; >- } >- >- /** > * Asks the user to confirm a delete operation. > * > * @param resources >@@ -363,13 +312,11 @@ > * <code>false</code> if the deletion should be abandoned > */ > private boolean confirmDelete(IResource[] resources) { >- if (validateDelete(resources)) { >- if (containsOnlyProjects(resources)) { >- return confirmDeleteProjects(resources); >- } >- return confirmDeleteNonProjects(resources); >+ if (containsOnlyProjects(resources)) { >+ return confirmDeleteProjects(resources); > } >- return false; >+ return confirmDeleteNonProjects(resources); >+ > } > > /** >@@ -430,82 +377,8 @@ > return code == 0; // YES > } > >- /** >- * Deletes the given resources. >- */ >- private void delete(IResource[] resourcesToDelete, IProgressMonitor monitor) >- throws CoreException { >- final List exceptions = new ArrayList(); >- forceOutOfSyncDelete = false; >- monitor.beginTask("", resourcesToDelete.length); //$NON-NLS-1$ >- try { >- for (int i = 0; i < resourcesToDelete.length; ++i) { >- if (monitor.isCanceled()) { >- throw new OperationCanceledException(); >- } >- try { >- delete(resourcesToDelete[i], new SubProgressMonitor( >- monitor, 1, >- SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); >- } catch (CoreException e) { >- exceptions.add(e); >- } >- } >- IStatus result = createResult(exceptions); >- if (!result.isOK()) { >- throw new CoreException(result); >- } >- } finally { >- monitor.done(); >- } >- } > >- /** >- * Deletes the given resource. >- */ >- private void delete(IResource resourceToDelete, IProgressMonitor monitor) >- throws CoreException { >- boolean force = false; // don't force deletion of out-of-sync resources >- try { >- if (resourceToDelete.getType() == IResource.PROJECT) { >- // if it's a project, ask whether content should be deleted too >- IProject project = (IProject) resourceToDelete; >- project.delete(deleteContent, force, monitor); >- } else { >- // if it's not a project, just delete it >- resourceToDelete.delete(IResource.KEEP_HISTORY, monitor); >- } >- } catch (CoreException exception) { >- if (resourceToDelete.getType() == IResource.FILE) { >- IStatus[] children = exception.getStatus().getChildren(); >- >- if (children.length == 1 >- && children[0].getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) { >- if (forceOutOfSyncDelete) { >- resourceToDelete.delete(IResource.KEEP_HISTORY >- | IResource.FORCE, monitor); >- } else { >- int result = queryDeleteOutOfSync(resourceToDelete); >- >- if (result == IDialogConstants.YES_ID) { >- resourceToDelete.delete(IResource.KEEP_HISTORY >- | IResource.FORCE, monitor); >- } else if (result == IDialogConstants.YES_TO_ALL_ID) { >- forceOutOfSyncDelete = true; >- resourceToDelete.delete(IResource.KEEP_HISTORY >- | IResource.FORCE, monitor); >- } else if (result == IDialogConstants.CANCEL_ID) { >- throw new OperationCanceledException(); >- } >- } >- } else { >- throw exception; >- } >- } else { >- throw exception; >- } >- } >- } >+ > > /** > * Return an array of the currently selected resources. >@@ -593,17 +466,22 @@ > IDEWorkbenchMessages.DeleteResourceAction_jobName) { > public IStatus run(IProgressMonitor monitor) { > try { >- ResourcesPlugin.getWorkspace().run( >- new IWorkspaceRunnable() { >- public void run(IProgressMonitor monitor) >- throws CoreException { >- delete(resourcesToDelete, monitor); >- } >- }, null, IWorkspace.AVOID_UPDATE, monitor); >- } catch (CoreException e) { >- return e.getStatus(); >+ DeleteResourcesOperation op = >+ new DeleteResourcesOperation(resourcesToDelete, getText(), deleteContent); >+ op.setModelProviderIds(getModelProviderIds()); >+ return PlatformUI.getWorkbench().getOperationSupport() >+ .getOperationHistory().execute(op, monitor, new IAdaptable() { >+ public Object getAdapter(Class clazz) { >+ if (clazz == Shell.class) { >+ return shell; >+ } >+ return null; >+ } >+ }); >+ } catch (ExecutionException e) { >+ IDEWorkbenchPlugin.log(e.getMessage(), e); >+ return new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, e.getMessage(),e); > } >- return Status.OK_STATUS; > } > > /* >@@ -678,71 +556,6 @@ > } > > /** >- * Ask the user whether the given resource should be deleted despite being >- * out of sync with the file system. >- * >- * @param resource >- * the out of sync resource >- * @return One of the IDialogConstants constants indicating which of the >- * Yes, Yes to All, No, Cancel options has been selected by the >- * user. >- */ >- private int queryDeleteOutOfSync(IResource resource) { >- final MessageDialog dialog = new MessageDialog( >- shell, >- IDEWorkbenchMessages.DeleteResourceAction_messageTitle, >- null, >- NLS >- .bind( >- IDEWorkbenchMessages.DeleteResourceAction_outOfSyncQuestion, >- resource.getName()), MessageDialog.QUESTION, >- new String[] { IDialogConstants.YES_LABEL, >- IDialogConstants.YES_TO_ALL_LABEL, >- IDialogConstants.NO_LABEL, >- IDialogConstants.CANCEL_LABEL }, 0); >- shell.getDisplay().syncExec(new Runnable() { >- public void run() { >- dialog.open(); >- } >- }); >- int result = dialog.getReturnCode(); >- if (result == 0) { >- return IDialogConstants.YES_ID; >- } >- if (result == 1) { >- return IDialogConstants.YES_TO_ALL_ID; >- } >- if (result == 2) { >- return IDialogConstants.NO_ID; >- } >- return IDialogConstants.CANCEL_ID; >- } >- >- /** >- * Validates the operation against the model providers. >- * >- * @param resources >- * the resources to be deleted >- * @return whether the operation should proceed >- */ >- private boolean validateDelete(IResource[] resources) { >- IResourceChangeDescriptionFactory factory = ResourceChangeValidator >- .getValidator().createDeltaFactory(); >- for (int i = 0; i < resources.length; i++) { >- IResource resource = resources[i]; >- factory.delete(resource); >- } >- return IDE.promptToConfirm(shell, >- IDEWorkbenchMessages.DeleteResourceAction_confirm, >- IDEWorkbenchMessages.DeleteResourceAction_warning, factory >- .getDelta(), getModelProviderIds(), false /* >- * no need >- * to >- * syncExec >- */); >- } >- >- /** > * Returns the model provider ids that are known to the client that > * instantiated this operation. > * >Index: extensions/org/eclipse/ui/actions/MoveProjectAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/MoveProjectAction.java,v >retrieving revision 1.15 >diff -u -r1.15 MoveProjectAction.java >--- extensions/org/eclipse/ui/actions/MoveProjectAction.java 8 May 2006 20:54:12 -0000 1.15 >+++ extensions/org/eclipse/ui/actions/MoveProjectAction.java 29 Sep 2006 18:00:37 -0000 >@@ -12,22 +12,19 @@ > > import java.lang.reflect.InvocationTargetException; > >+import org.eclipse.core.commands.ExecutionException; > import org.eclipse.core.resources.IProject; >-import org.eclipse.core.resources.IProjectDescription; > import org.eclipse.core.resources.IResource; >-import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; >-import org.eclipse.core.resources.mapping.ResourceChangeValidator; >-import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.IProgressMonitor; >-import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.core.runtime.Path; >-import org.eclipse.jface.dialogs.ErrorDialog; >+import org.eclipse.jface.operation.IRunnableWithProgress; > import org.eclipse.osgi.util.NLS; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.PlatformUI; > import org.eclipse.ui.dialogs.ProjectLocationMoveDialog; >-import org.eclipse.ui.ide.IDE; >+import org.eclipse.ui.ide.undo.MoveResourcesOperation; > import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; > import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; > import org.eclipse.ui.internal.ide.IIDEHelpContextIds; >@@ -44,8 +41,6 @@ > > private static String PROBLEMS_TITLE = IDEWorkbenchMessages.MoveProjectAction_dialogTitle; > >- private static String MOVE_PROGRESS_TITLE = IDEWorkbenchMessages.MoveProjectAction_progressMessage; >- > /** > * The id of this action. > */ >@@ -69,6 +64,9 @@ > * Return the title of the errors dialog. > * > * @return java.lang.String >+ * >+ * @deprecated As of 3.3, the error handling is performed by the undoable >+ * operation which handles the move. > */ > protected String getErrorsTitle() { > return PROBLEMS_TITLE; >@@ -88,35 +86,33 @@ > */ > boolean performMove(final IProject project, final String projectName, > final IPath newLocation) { >- WorkspaceModifyOperation op = new WorkspaceModifyOperation() { >- public void execute(IProgressMonitor monitor) { >- try { >- if (monitor.isCanceled()) { >- throw new OperationCanceledException(); >- } >- >- monitor.setTaskName(MOVE_PROGRESS_TITLE); >- //Get a copy of the current description and modify it >- IProjectDescription newDescription = createDescription( >- project, projectName, newLocation); >- >- project.move(newDescription, IResource.FORCE >- | IResource.SHALLOW, monitor); >- >- } catch (CoreException e) { >- recordError(e); // log error >- } finally { >- monitor.done(); >- } >- } >- }; >- >+ >+ IRunnableWithProgress op = new IRunnableWithProgress() { >+ public void run(IProgressMonitor monitor) { >+ MoveResourcesOperation op = new MoveResourcesOperation(new IResource[] {project}, newLocation, getText()); >+ op.setModelProviderIds(getModelProviderIds()); >+ try { >+ PlatformUI.getWorkbench().getOperationSupport() >+ .getOperationHistory().execute(op, monitor, new IAdaptable() { >+ public Object getAdapter(Class clazz) { >+ if (clazz == Shell.class) { >+ return shell; >+ } >+ return null; >+ } >+ }); >+ } catch (ExecutionException e) { >+ IDEWorkbenchPlugin.log(e.getMessage(), e); >+ } >+ } >+ }; >+ > try { > new ProgressMonitorJobsDialog(shell).run(true, true, op); > } catch (InterruptedException e) { > return false; > } catch (InvocationTargetException e) { >- // CoreExceptions are collected above, but unexpected runtime >+ // CoreExceptions are collected by the operation, but unexpected runtime > // exceptions and errors may still occur. > IDEWorkbenchPlugin.log(getClass(), > "performMove()", e.getTargetException()); //$NON-NLS-1$ >@@ -160,40 +156,7 @@ > > String projectName = (String) destinationPaths[0]; > IPath newLocation = new Path((String) destinationPaths[1]); >- >- if (!validateMove(project, projectName)) { >- return; >- } > >- boolean completed = performMove(project, projectName, newLocation); >- >- if (!completed) { >- return; // not appropriate to show errors >- } >- >- // If errors occurred, open an Error dialog >- if (errorStatus != null) { >- ErrorDialog >- .openError(this.shell, PROBLEMS_TITLE, null, errorStatus); >- errorStatus = null; >- } >- } >- >- /** >- * Validates the operation against the model providers. >- * >- * @param project the project to move >- * @param newName the new name >- * @return whether the operation should proceed >- * @since 3.2 >- */ >- private boolean validateMove(IProject project, String newName) { >- if (project.getName().equals(newName)) { >- // Only the location changed >- return true; >- } >- IResourceChangeDescriptionFactory factory = ResourceChangeValidator.getValidator().createDeltaFactory(); >- factory.move(project, new Path(newName)); >- return IDE.promptToConfirm(shell, IDEWorkbenchMessages.CopyProjectAction_confirm, NLS.bind(IDEWorkbenchMessages.CopyProjectAction_warning, project.getName()), factory.getDelta(), getModelProviderIds(), false /* no need to syncExec */); >+ performMove(project, projectName, newLocation); > } > } >Index: extensions/org/eclipse/ui/actions/CopyProjectAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectAction.java,v >retrieving revision 1.13 >diff -u -r1.13 CopyProjectAction.java >--- extensions/org/eclipse/ui/actions/CopyProjectAction.java 8 May 2006 20:54:12 -0000 1.13 >+++ extensions/org/eclipse/ui/actions/CopyProjectAction.java 29 Sep 2006 18:00:33 -0000 >@@ -23,7 +23,6 @@ > import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.core.runtime.Path; > import org.eclipse.core.runtime.Platform; >-import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.dialogs.MessageDialog; > import org.eclipse.jface.viewers.IStructuredSelection; > import org.eclipse.osgi.util.NLS; >@@ -135,6 +134,9 @@ > /** > * Return the title of the errors dialog. > * @return java.lang.String >+ * >+ * @deprecated As of 3.3, the undoable operation created by this action >+ * handles error dialogs. > */ > protected String getErrorsTitle() { > return PROBLEMS_TITLE; >@@ -243,18 +245,8 @@ > return; > } > >- boolean completed = performCopy(project, newName, newLocation); >- >- if (!completed) { >- return; // not appropriate to show errors >- } >+ performCopy(project, newName, newLocation); > >- // If errors occurred, open an Error dialog >- if (errorStatus != null) { >- ErrorDialog.openError(this.shell, getErrorsTitle(), null, >- errorStatus); >- errorStatus = null; >- } > } > > /** >Index: extensions/org/eclipse/ui/actions/WorkspaceAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceAction.java,v >retrieving revision 1.19 >diff -u -r1.19 WorkspaceAction.java >--- extensions/org/eclipse/ui/actions/WorkspaceAction.java 8 May 2006 20:54:12 -0000 1.19 >+++ extensions/org/eclipse/ui/actions/WorkspaceAction.java 29 Sep 2006 18:00:39 -0000 >@@ -28,6 +28,7 @@ > import org.eclipse.core.runtime.jobs.Job; > import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.jface.operation.IRunnableWithProgress; > import org.eclipse.jface.viewers.IStructuredSelection; > import org.eclipse.osgi.util.NLS; > import org.eclipse.swt.widgets.Shell; >@@ -37,377 +38,405 @@ > import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; > > /** >- * The abstract superclass for actions which invoke commands >- * implemented in org.eclipse.core.* on a set of selected resources. >+ * The abstract superclass for actions which invoke commands implemented in >+ * org.eclipse.core.* on a set of selected resources. > * >- * It iterates over all selected resources; errors are collected and >- * displayed to the user via a problems dialog at the end of the operation. >- * User requests to cancel the operation are passed along to the core. >+ * It iterates over all selected resources; errors are collected and displayed >+ * to the user via a problems dialog at the end of the operation. User requests >+ * to cancel the operation are passed along to the core. > * <p> > * Subclasses must implement the following methods: > * <ul> >- * <li><code>invokeOperation</code> - to perform the operation on one of the >- * selected resources</li> >- * <li><code>getOperationMessage</code> - to furnish a title for the progress >- * dialog</li> >+ * <li><code>invokeOperation</code> - to perform the operation on one of the >+ * selected resources</li> >+ * <li><code>getOperationMessage</code> - to furnish a title for the progress >+ * dialog</li> > * </ul> > * </p> > * <p> > * Subclasses may override the following methods: > * <ul> >- * <li><code>shouldPerformResourcePruning</code> - reimplement to turn off</li> >- * <li><code>updateSelection</code> - extend to refine enablement criteria</li> >- * <li><code>getProblemsTitle</code> - reimplement to furnish a title for the >- * problems dialog</li> >- * <li><code>getProblemsMessage</code> - reimplement to furnish a message for >- * the problems dialog</li> >- * <li><code>run</code> - extend to </li> >+ * <li><code>shouldPerformResourcePruning</code> - reimplement to turn off</li> >+ * <li><code>updateSelection</code> - extend to refine enablement criteria</li> >+ * <li><code>getProblemsTitle</code> - reimplement to furnish a title for the >+ * problems dialog</li> >+ * <li><code>getProblemsMessage</code> - reimplement to furnish a message for >+ * the problems dialog</li> >+ * <li><code>run</code> - extend to </li> > * </ul> > * </p> > */ > public abstract class WorkspaceAction extends SelectionListenerAction { >- /** >- * The shell in which to show the progress and problems dialog. >- */ >- private final Shell shell; >- >- /** >- * Creates a new action with the given text. >- * >- * @param shell the shell (for the modal progress dialog and error messages) >- * @param text the string used as the text for the action, >- * or <code>null</code> if there is no text >- */ >- protected WorkspaceAction(Shell shell, String text) { >- super(text); >- if (shell == null) { >- throw new IllegalArgumentException(); >- } >- this.shell = shell; >- } >- >- /** >- * Opens an error dialog to display the given message. >- * <p> >- * Note that this method must be called from UI thread. >- * </p> >- * >- * @param message the message >- */ >- void displayError(String message) { >- if (message == null) { >- message = IDEWorkbenchMessages.WorkbenchAction_internalError; >- } >- MessageDialog.openError(shell, getProblemsTitle(), message); >- } >- >- /** >- * Runs <code>invokeOperation</code> on each of the selected resources, reporting >- * progress and fielding cancel requests from the given progress monitor. >- * <p> >- * Note that if an action is running in the background, the same action instance >- * can be executed multiple times concurrently. This method must not access >- * or modify any mutable state on action class. >- * >- * @param monitor a progress monitor >- * @return The result of the execution >- */ >- final IStatus execute(List resources, IProgressMonitor monitor) { >- MultiStatus errors = null; >- //1FTIMQN: ITPCORE:WIN - clients required to do too much iteration work >- if (shouldPerformResourcePruning()) { >- resources = pruneResources(resources); >- } >- // 1FV0B3Y: ITPUI:ALL - sub progress monitors granularity issues >- monitor.beginTask("", resources.size() * 1000); //$NON-NLS-1$ >- // Fix for bug 31768 - Don't provide a task name in beginTask >- // as it will be appended to each subTask message. Need to >- // call setTaskName as its the only was to assure the task name is >- // set in the monitor (see bug 31824) >- monitor.setTaskName(getOperationMessage()); >- Iterator resourcesEnum = resources.iterator(); >- try { >- while (resourcesEnum.hasNext()) { >- IResource resource = (IResource) resourcesEnum.next(); >- try { >- // 1FV0B3Y: ITPUI:ALL - sub progress monitors granularity issues >- invokeOperation(resource, new SubProgressMonitor(monitor, >- 1000)); >- } catch (CoreException e) { >- errors = recordError(errors, e); >- } >- if (monitor.isCanceled()) { >+ /** >+ * The shell in which to show the progress and problems dialog. >+ */ >+ private final Shell shell; >+ >+ /** >+ * Creates a new action with the given text. >+ * >+ * @param shell >+ * the shell (for the modal progress dialog and error messages) >+ * @param text >+ * the string used as the text for the action, or >+ * <code>null</code> if there is no text >+ */ >+ protected WorkspaceAction(Shell shell, String text) { >+ super(text); >+ if (shell == null) { >+ throw new IllegalArgumentException(); >+ } >+ this.shell = shell; >+ } >+ >+ /** >+ * Opens an error dialog to display the given message. >+ * <p> >+ * Note that this method must be called from UI thread. >+ * </p> >+ * >+ * @param message >+ * the message >+ */ >+ void displayError(String message) { >+ if (message == null) { >+ message = IDEWorkbenchMessages.WorkbenchAction_internalError; >+ } >+ MessageDialog.openError(shell, getProblemsTitle(), message); >+ } >+ >+ /** >+ * Runs <code>invokeOperation</code> on each of the selected resources, >+ * reporting progress and fielding cancel requests from the given progress >+ * monitor. >+ * <p> >+ * Note that if an action is running in the background, the same action >+ * instance can be executed multiple times concurrently. This method must >+ * not access or modify any mutable state on action class. >+ * >+ * @param monitor >+ * a progress monitor >+ * @return The result of the execution >+ */ >+ final IStatus execute(List resources, IProgressMonitor monitor) { >+ MultiStatus errors = null; >+ // 1FTIMQN: ITPCORE:WIN - clients required to do too much iteration work >+ if (shouldPerformResourcePruning()) { >+ resources = pruneResources(resources); >+ } >+ // 1FV0B3Y: ITPUI:ALL - sub progress monitors granularity issues >+ monitor.beginTask("", resources.size() * 1000); //$NON-NLS-1$ >+ // Fix for bug 31768 - Don't provide a task name in beginTask >+ // as it will be appended to each subTask message. Need to >+ // call setTaskName as its the only was to assure the task name is >+ // set in the monitor (see bug 31824) >+ monitor.setTaskName(getOperationMessage()); >+ Iterator resourcesEnum = resources.iterator(); >+ try { >+ while (resourcesEnum.hasNext()) { >+ IResource resource = (IResource) resourcesEnum.next(); >+ try { >+ // 1FV0B3Y: ITPUI:ALL - sub progress monitors granularity >+ // issues >+ invokeOperation(resource, new SubProgressMonitor(monitor, >+ 1000)); >+ } catch (CoreException e) { >+ errors = recordError(errors, e); >+ } >+ if (monitor.isCanceled()) { > throw new OperationCanceledException(); > } >- } >- return errors == null ? Status.OK_STATUS : errors; >- } finally { >- monitor.done(); >- } >- } >- >- /** >- * Returns the string to display for this action's operation. >- * <p> >- * Note that this hook method is invoked in a non-UI thread. >- * </p> >- * <p> >- * Subclasses must implement this method. >- * </p> >- * >- * @return the message >- * >- * @since 3.1 >- */ >- protected abstract String getOperationMessage(); >- >- /** >- * Returns the string to display for this action's problems dialog. >- * <p> >- * The <code>WorkspaceAction</code> implementation of this method returns a >- * vague message (localized counterpart of something like "The following >- * problems occurred."). Subclasses may reimplement to provide something more >- * suited to the particular action. >- * </p> >- * >- * @return the problems message >- * >- * @since 3.1 >- */ >- protected String getProblemsMessage() { >- return IDEWorkbenchMessages.WorkbenchAction_problemsMessage; >- } >- >- /** >- * Returns the title for this action's problems dialog. >- * <p> >- * The <code>WorkspaceAction</code> implementation of this method returns a >- * generic title (localized counterpart of "Problems"). Subclasses may >- * reimplement to provide something more suited to the particular action. >- * </p> >- * >- * @return the problems dialog title >- * >- * @since 3.1 >- */ >- protected String getProblemsTitle() { >- return IDEWorkbenchMessages.WorkspaceAction_problemsTitle; >- } >- >- /** >- * Returns the shell for this action. This shell is used for the modal progress >- * and error dialogs. >- * >- * @return the shell >- */ >- Shell getShell() { >- return shell; >- } >- >- /** >- * Performs this action's operation on each of the selected resources, reporting >- * progress to, and fielding cancel requests from, the given progress monitor. >- * <p> >- * Note that this method is invoked in a non-UI thread. >- * </p> >- * <p> >- * Subclasses must implement this method. >- * </p> >- * >- * @param resource one of the selected resources >- * @param monitor a progress monitor >- * @exception CoreException if the operation fails >- * >- * @since 3.1 >- */ >- protected abstract void invokeOperation(IResource resource, IProgressMonitor monitor) >- throws CoreException; >- >- /** >- * Returns whether the given resource is a descendent of any of the resources >- * in the given list. >- * >- * @param resources the list of resources (element type: <code>IResource</code>) >- * @param child the resource to check >- * @return <code>true</code> if <code>child</code> is a descendent of any of the >- * elements of <code>resources</code> >- */ >- boolean isDescendent(List resources, IResource child) { >- IResource parent = child.getParent(); >- return parent != null >- && (resources.contains(parent) || isDescendent(resources, >- parent)); >- } >- >- /** >- * Performs pruning on the given list of resources, as described in >- * <code>shouldPerformResourcePruning</code>. >- * >- * @param resourceCollection the list of resources (element type: >- * <code>IResource</code>) >- * @return the list of resources (element type: <code>IResource</code>) >- * after pruning. >- * @see #shouldPerformResourcePruning >- */ >- List pruneResources(List resourceCollection) { >- List prunedList = new ArrayList(resourceCollection); >- Iterator elementsEnum = prunedList.iterator(); >- while (elementsEnum.hasNext()) { >- IResource currentResource = (IResource) elementsEnum.next(); >- if (isDescendent(prunedList, currentResource)) { >- elementsEnum.remove(); //Removes currentResource > } >- } >- return prunedList; >- } >- >- /** >- * Records the core exception to be displayed to the user >- * once the action is finished. >- * >- * @param error a <code>CoreException</code> >- */ >- MultiStatus recordError(MultiStatus errors, CoreException error) { >- if (errors == null) { >+ return errors == null ? Status.OK_STATUS : errors; >+ } finally { >+ monitor.done(); >+ } >+ } >+ >+ /** >+ * Returns the string to display for this action's operation. >+ * <p> >+ * Note that this hook method is invoked in a non-UI thread. >+ * </p> >+ * <p> >+ * Subclasses must implement this method. >+ * </p> >+ * >+ * @return the message >+ * >+ * @since 3.1 >+ */ >+ protected abstract String getOperationMessage(); >+ >+ /** >+ * Returns the string to display for this action's problems dialog. >+ * <p> >+ * The <code>WorkspaceAction</code> implementation of this method returns >+ * a vague message (localized counterpart of something like "The following >+ * problems occurred."). Subclasses may reimplement to provide something >+ * more suited to the particular action. >+ * </p> >+ * >+ * @return the problems message >+ * >+ * @since 3.1 >+ */ >+ protected String getProblemsMessage() { >+ return IDEWorkbenchMessages.WorkbenchAction_problemsMessage; >+ } >+ >+ /** >+ * Returns the title for this action's problems dialog. >+ * <p> >+ * The <code>WorkspaceAction</code> implementation of this method returns >+ * a generic title (localized counterpart of "Problems"). Subclasses may >+ * reimplement to provide something more suited to the particular action. >+ * </p> >+ * >+ * @return the problems dialog title >+ * >+ * @since 3.1 >+ */ >+ protected String getProblemsTitle() { >+ return IDEWorkbenchMessages.WorkspaceAction_problemsTitle; >+ } >+ >+ /** >+ * Returns the shell for this action. This shell is used for the modal >+ * progress and error dialogs. >+ * >+ * @return the shell >+ */ >+ Shell getShell() { >+ return shell; >+ } >+ >+ /** >+ * Performs this action's operation on each of the selected resources, >+ * reporting progress to, and fielding cancel requests from, the given >+ * progress monitor. >+ * <p> >+ * Note that this method is invoked in a non-UI thread. >+ * </p> >+ * <p> >+ * Subclasses must implement this method. >+ * <p> >+ * @deprecated Since 3.3, subclasses should instead implement the method >+ * {@link #createOperation(IStatus[])} and provide an empty implementation >+ * for this method. >+ * </p> >+ * >+ * @param resource >+ * one of the selected resources >+ * @param monitor >+ * a progress monitor >+ * @exception CoreException >+ * if the operation fails >+ * >+ * @since 3.1 >+ */ >+ protected abstract void invokeOperation(IResource resource, >+ IProgressMonitor monitor) throws CoreException; >+ >+ /** >+ * Returns whether the given resource is a descendent of any of the >+ * resources in the given list. >+ * >+ * @param resources >+ * the list of resources (element type: <code>IResource</code>) >+ * @param child >+ * the resource to check >+ * @return <code>true</code> if <code>child</code> is a descendent of >+ * any of the elements of <code>resources</code> >+ */ >+ boolean isDescendent(List resources, IResource child) { >+ IResource parent = child.getParent(); >+ return parent != null >+ && (resources.contains(parent) || isDescendent(resources, >+ parent)); >+ } >+ >+ /** >+ * Performs pruning on the given list of resources, as described in >+ * <code>shouldPerformResourcePruning</code>. >+ * >+ * @param resourceCollection >+ * the list of resources (element type: <code>IResource</code>) >+ * @return the list of resources (element type: <code>IResource</code>) >+ * after pruning. >+ * @see #shouldPerformResourcePruning >+ */ >+ List pruneResources(List resourceCollection) { >+ List prunedList = new ArrayList(resourceCollection); >+ Iterator elementsEnum = prunedList.iterator(); >+ while (elementsEnum.hasNext()) { >+ IResource currentResource = (IResource) elementsEnum.next(); >+ if (isDescendent(prunedList, currentResource)) { >+ elementsEnum.remove(); // Removes currentResource >+ } >+ } >+ return prunedList; >+ } >+ >+ /** >+ * Records the core exception to be displayed to the user once the action is >+ * finished. >+ * >+ * @param error >+ * a <code>CoreException</code> >+ */ >+ MultiStatus recordError(MultiStatus errors, CoreException error) { >+ if (errors == null) { > errors = new MultiStatus(IDEWorkbenchPlugin.IDE_WORKBENCH, >- IStatus.ERROR, getProblemsMessage(), null); >+ IStatus.ERROR, getProblemsMessage(), null); >+ } >+ errors.merge(error.getStatus()); >+ return errors; >+ } >+ >+ /** >+ * The <code>CoreWrapperAction</code> implementation of this >+ * <code>IAction</code> method uses a <code>ProgressMonitorDialog</code> >+ * to run the operation. The operation calls <code>execute</code> (which, >+ * in turn, calls <code>invokeOperation</code>). Afterwards, any >+ * <code>CoreException</code>s encountered while running the operation >+ * are reported to the user via a problems dialog. >+ * <p> >+ * Subclasses may extend this method. >+ * </p> >+ */ >+ public void run() { >+ IStatus[] errorStatus = new IStatus[1]; >+ try { >+ new ProgressMonitorJobsDialog(shell).run(true, true, >+ createOperation(errorStatus)); >+ } catch (InterruptedException e) { >+ return; >+ } catch (InvocationTargetException e) { >+ // we catch CoreException in execute(), but unexpected runtime >+ // exceptions or errors may still occur >+ String msg = NLS.bind( >+ IDEWorkbenchMessages.WorkspaceAction_logTitle, getClass() >+ .getName(), e.getTargetException()); >+ IDEWorkbenchPlugin.log(msg, StatusUtil.newStatus(IStatus.ERROR, >+ msg, e.getTargetException())); >+ displayError(e.getTargetException().getMessage()); >+ } >+ // If errors occurred, open an Error dialog & build a multi status error >+ // for it >+ if (errorStatus[0] != null && !errorStatus[0].isOK()) { >+ ErrorDialog.openError(shell, getProblemsTitle(), null, // no >+ // special >+ // message >+ errorStatus[0]); > } >- errors.merge(error.getStatus()); >- return errors; >- } >- >- /** >- * The <code>CoreWrapperAction</code> implementation of this <code>IAction</code> >- * method uses a <code>ProgressMonitorDialog</code> to run the operation. The >- * operation calls <code>execute</code> (which, in turn, calls >- * <code>invokeOperation</code>). Afterwards, any <code>CoreException</code>s >- * encountered while running the operation are reported to the user via a >- * problems dialog. >- * <p> >- * Subclasses may extend this method. >- * </p> >- */ >- public void run() { >- final IStatus[] errorStatus = new IStatus[1]; >- try { >- WorkspaceModifyOperation op = new WorkspaceModifyOperation() { >- public void execute(IProgressMonitor monitor) { >- errorStatus[0] = WorkspaceAction.this.execute(getActionResources(), monitor); >- } >- }; >- new ProgressMonitorJobsDialog(shell).run(true, true, op); >- } catch (InterruptedException e) { >- return; >- } catch (InvocationTargetException e) { >- // we catch CoreException in execute(), but unexpected runtime exceptions or errors may still occur >- String msg = NLS.bind(IDEWorkbenchMessages.WorkspaceAction_logTitle, getClass().getName(), e.getTargetException()); >- IDEWorkbenchPlugin.log(msg, StatusUtil.newStatus(IStatus.ERROR, >- msg, e.getTargetException())); >- displayError(e.getTargetException().getMessage()); >- } >- // If errors occurred, open an Error dialog & build a multi status error for it >- if (errorStatus[0] != null && !errorStatus[0].isOK()) { >- ErrorDialog.openError(shell, getProblemsTitle(), null, // no special message >- errorStatus[0]); >- } >- } >- >- /** >- * Returns whether this action should attempt to optimize the resources being >- * operated on. This kind of pruning makes sense when the operation has depth >- * infinity semantics (when the operation is applied explicitly to a resource >- * then it is also applied implicitly to all the resource's descendents). >- * <p> >- * The <code>WorkspaceAction</code> implementation of this method returns >- * <code>true</code>. Subclasses should reimplement to return <code>false</code> >- * if pruning is not required. >- * </p> >- * >- * @return <code>true</code> if pruning should be performed, >- * and <code>false</code> if pruning is not desired >- * >- * @since 3.1 >- */ >- protected boolean shouldPerformResourcePruning() { >- return true; >- } >- >- /** >- * The <code>WorkspaceAction</code> implementation of this >- * <code>SelectionListenerAction</code> method ensures that this action is >- * disabled if any of the selected resources are inaccessible. Subclasses may >- * extend to react to selection changes; however, if the super method returns >- * <code>false</code>, the overriding method should also return <code>false</code>. >- */ >- protected boolean updateSelection(IStructuredSelection selection) { >- if (!super.updateSelection(selection) || selection.isEmpty()) { >- return false; >- } >- for (Iterator i = getSelectedResources().iterator(); i.hasNext();) { >- IResource r = (IResource) i.next(); >- if (!r.isAccessible()) { >- return false; >- } >- } >- return true; >- } >- >- /** >- * Returns the elements that the action is to be performed on. >- * By default return the selected resources. >- * <p> >- * Subclasses may override this method. >- * >- * @return list of resource elements (element type: <code>IResource</code>) >- */ >- protected List getActionResources() { >- return getSelectedResources(); >- } >- >- /** >- * Run the action in the background rather than with the >- * progress dialog. >- * @param rule The rule to apply to the background job or >- * <code>null</code> if there isn't one. >- */ >- public void runInBackground(ISchedulingRule rule) { >- runInBackground(rule, (Object []) null); >- } >- >- /** >- * Run the action in the background rather than with the >- * progress dialog. >- * @param rule The rule to apply to the background job or >- * <code>null</code> if there isn't one. >- * @param jobFamily a single family that the job should >- * belong to or <code>null</code> if none. >- * >- * @since 3.1 >- */ >- public void runInBackground(ISchedulingRule rule, Object jobFamily) { >- if (jobFamily == null) { >- runInBackground(rule, (Object []) null); >+ } >+ >+ /** >+ * Returns whether this action should attempt to optimize the resources >+ * being operated on. This kind of pruning makes sense when the operation >+ * has depth infinity semantics (when the operation is applied explicitly to >+ * a resource then it is also applied implicitly to all the resource's >+ * descendents). >+ * <p> >+ * The <code>WorkspaceAction</code> implementation of this method returns >+ * <code>true</code>. Subclasses should reimplement to return >+ * <code>false</code> if pruning is not required. >+ * </p> >+ * >+ * @return <code>true</code> if pruning should be performed, and >+ * <code>false</code> if pruning is not desired >+ * >+ * @since 3.1 >+ */ >+ protected boolean shouldPerformResourcePruning() { >+ return true; >+ } >+ >+ /** >+ * The <code>WorkspaceAction</code> implementation of this >+ * <code>SelectionListenerAction</code> method ensures that this action is >+ * disabled if any of the selected resources are inaccessible. Subclasses >+ * may extend to react to selection changes; however, if the super method >+ * returns <code>false</code>, the overriding method should also return >+ * <code>false</code>. >+ */ >+ protected boolean updateSelection(IStructuredSelection selection) { >+ if (!super.updateSelection(selection) || selection.isEmpty()) { >+ return false; >+ } >+ for (Iterator i = getSelectedResources().iterator(); i.hasNext();) { >+ IResource r = (IResource) i.next(); >+ if (!r.isAccessible()) { >+ return false; >+ } >+ } >+ return true; >+ } >+ >+ /** >+ * Returns the elements that the action is to be performed on. By default >+ * return the selected resources. >+ * <p> >+ * Subclasses may override this method. >+ * >+ * @return list of resource elements (element type: <code>IResource</code>) >+ */ >+ protected List getActionResources() { >+ return getSelectedResources(); >+ } >+ >+ /** >+ * Run the action in the background rather than with the progress dialog. >+ * >+ * @param rule >+ * The rule to apply to the background job or <code>null</code> >+ * if there isn't one. >+ */ >+ public void runInBackground(ISchedulingRule rule) { >+ runInBackground(rule, (Object[]) null); >+ } >+ >+ /** >+ * Run the action in the background rather than with the progress dialog. >+ * >+ * @param rule >+ * The rule to apply to the background job or <code>null</code> >+ * if there isn't one. >+ * @param jobFamily >+ * a single family that the job should belong to or >+ * <code>null</code> if none. >+ * >+ * @since 3.1 >+ */ >+ public void runInBackground(ISchedulingRule rule, Object jobFamily) { >+ if (jobFamily == null) { >+ runInBackground(rule, (Object[]) null); > } else { >- runInBackground(rule, new Object[] {jobFamily}); >+ runInBackground(rule, new Object[] { jobFamily }); > } >- } >- >- /** >- * Run the action in the background rather than with the >- * progress dialog. >- * @param rule The rule to apply to the background job or >- * <code>null</code> if there isn't one. >- * @param jobFamilies the families the job should belong >- * to or <code>null</code> if none. >- * >- * @since 3.1 >- */ >- public void runInBackground(ISchedulingRule rule, final Object [] jobFamilies) { >- //obtain a copy of the selected resources before the job is forked >- final List resources = new ArrayList(getActionResources()); >- Job job = new WorkspaceJob(removeMnemonics(getText())) { >- >- /* (non-Javadoc) >+ } >+ >+ /** >+ * Run the action in the background rather than with the progress dialog. >+ * >+ * @param rule >+ * The rule to apply to the background job or <code>null</code> >+ * if there isn't one. >+ * @param jobFamilies >+ * the families the job should belong to or <code>null</code> >+ * if none. >+ * >+ * @since 3.1 >+ */ >+ public void runInBackground(ISchedulingRule rule, final Object[] jobFamilies) { >+ // obtain a copy of the selected resources before the job is forked >+ final List resources = new ArrayList(getActionResources()); >+ Job job = new WorkspaceJob(removeMnemonics(getText())) { >+ >+ /* >+ * (non-Javadoc) >+ * > * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object) > */ > public boolean belongsTo(Object family) { >@@ -421,18 +450,48 @@ > } > return false; > } >- >- /* (non-Javadoc) >- * @see org.eclipse.core.resources.WorkspaceJob#runInWorkspace(org.eclipse.core.runtime.IProgressMonitor) >- */ >- public IStatus runInWorkspace(IProgressMonitor monitor) { >- return WorkspaceAction.this.execute(resources, monitor); >- } >- }; >- if (rule != null) { >+ >+ /* >+ * (non-Javadoc) >+ * >+ * @see org.eclipse.core.resources.WorkspaceJob#runInWorkspace(org.eclipse.core.runtime.IProgressMonitor) >+ */ >+ public IStatus runInWorkspace(IProgressMonitor monitor) { >+ return WorkspaceAction.this.execute(resources, monitor); >+ } >+ }; >+ if (rule != null) { > job.setRule(rule); > } >- job.setUser(true); >- job.schedule(); >- } >+ job.setUser(true); >+ job.schedule(); >+ } >+ >+ /** >+ * Returns the operation to perform when this action runs. The returned >+ * operation must be an {@link IRunnableWithProgress} that will perform the >+ * action's work. The default implementation returns an operation that will >+ * iterate over the selected resources and call >+ * {@link #invokeOperation(IResource, IProgressMonitor)} for each resource. >+ * Subclasses must either implement >+ * {@link #invokeOperation(IResource, IProgressMonitor)} or override this >+ * method to provide a different operation. Subclasses typically override >+ * this method when an undoable operation is to be provided. >+ * >+ * @param errorStatus >+ * an array of error status objects to which the result of >+ * running the operation should be added. >+ * >+ * @return the operation to perform when this action runs. >+ * @since 3.3 >+ */ >+ protected IRunnableWithProgress createOperation(final IStatus[] errorStatus) { >+ return new WorkspaceModifyOperation() { >+ public void execute(IProgressMonitor monitor) { >+ errorStatus[0] = WorkspaceAction.this.execute( >+ getActionResources(), monitor); >+ } >+ }; >+ } >+ > } >Index: extensions/org/eclipse/ui/actions/RenameResourceAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/RenameResourceAction.java,v >retrieving revision 1.20 >diff -u -r1.20 RenameResourceAction.java >--- extensions/org/eclipse/ui/actions/RenameResourceAction.java 2 Aug 2006 14:52:03 -0000 1.20 >+++ extensions/org/eclipse/ui/actions/RenameResourceAction.java 29 Sep 2006 18:00:37 -0000 >@@ -10,31 +10,23 @@ > *******************************************************************************/ > package org.eclipse.ui.actions; > >-import com.ibm.icu.text.MessageFormat; > import java.util.ArrayList; > import java.util.List; > >-import org.eclipse.core.resources.IFile; >-import org.eclipse.core.resources.IProject; >-import org.eclipse.core.resources.IProjectDescription; >+import org.eclipse.core.commands.ExecutionException; > import org.eclipse.core.resources.IResource; > import org.eclipse.core.resources.IWorkspace; >-import org.eclipse.core.resources.IWorkspaceRoot; > import org.eclipse.core.resources.ResourceAttributes; >-import org.eclipse.core.resources.ResourcesPlugin; >-import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; >-import org.eclipse.core.resources.mapping.ResourceChangeValidator; >-import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; > import org.eclipse.core.runtime.IPath; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.IStatus; >-import org.eclipse.core.runtime.SubProgressMonitor; > import org.eclipse.jface.dialogs.IInputValidator; > import org.eclipse.jface.dialogs.InputDialog; > import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.jface.operation.IRunnableWithProgress; > import org.eclipse.jface.viewers.IStructuredSelection; > import org.eclipse.jface.window.Window; >-import org.eclipse.osgi.util.NLS; > import org.eclipse.swt.SWT; > import org.eclipse.swt.custom.TreeEditor; > import org.eclipse.swt.events.FocusAdapter; >@@ -49,11 +41,13 @@ > import org.eclipse.swt.widgets.Tree; > import org.eclipse.swt.widgets.TreeItem; > import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.ide.IDE; >+import org.eclipse.ui.ide.undo.MoveResourcesOperation; > import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; > import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; > import org.eclipse.ui.internal.ide.IIDEHelpContextIds; > >+import com.ibm.icu.text.MessageFormat; >+ > /** > * Standard action for renaming the selected resources. > * <p> >@@ -97,12 +91,6 @@ > > private static final String CHECK_RENAME_MESSAGE = IDEWorkbenchMessages.RenameResourceAction_readOnlyCheck; > >- private static String RESOURCE_EXISTS_TITLE = IDEWorkbenchMessages.RenameResourceAction_resourceExists; >- >- private static String RESOURCE_EXISTS_MESSAGE = IDEWorkbenchMessages.RenameResourceAction_overwriteQuestion; >- >- private static String RENAMING_MESSAGE = IDEWorkbenchMessages.RenameResourceAction_progressMessage; >- > /** > * Creates a new action. Using this constructor directly will rename using a > * dialog rather than the inline editor of a ResourceNavigator. >@@ -129,37 +117,7 @@ > this.treeEditor = new TreeEditor(tree); > } > >- /** >- * Check if the user wishes to overwrite the supplied resource >- * @returns true if there is no collision or delete was successful >- * @param shell the shell to create the dialog in >- * @param destination - the resource to be overwritten >- */ >- private boolean checkOverwrite(final Shell shell, >- final IResource destination) { >- >- final boolean[] result = new boolean[1]; >- >- //Run it inside of a runnable to make sure we get to parent off of the shell as we are not >- //in the UI thread. >- >- Runnable query = new Runnable() { >- public void run() { >- String pathName = destination.getFullPath().makeRelative() >- .toString(); >- result[0] = MessageDialog.openQuestion(shell, >- RESOURCE_EXISTS_TITLE, MessageFormat.format( >- RESOURCE_EXISTS_MESSAGE, >- new Object[] { pathName })); >- } >- >- }; >- >- shell.getDisplay().syncExec(query); >- return result[0]; >- } >- >- /** >+ /** > * Check if the supplied resource is read only or null. If it is then ask the user if they want > * to continue. Return true if the resource is not read only or if the user has given > * permission. >@@ -181,7 +139,6 @@ > > return true; > } >- > Composite createParent() { > Tree tree = getTree(); > Composite result = new Composite(tree, SWT.NONE); >@@ -341,67 +298,14 @@ > > /* (non-Javadoc) > * Method declared on WorkspaceAction. >+ * Since 3.3, this method is not used, but an implementation is still >+ * provided for compatibility. All work is now done in the operation >+ * created in createOperation(IStatus[]). > */ >- protected void invokeOperation(IResource resource, IProgressMonitor monitor) >- throws CoreException { >- >- if (!validateMove(resource, newPath)) { >- return; >- } >- monitor.beginTask(RENAMING_MESSAGE, 100); >- IWorkspaceRoot workspaceRoot = resource.getWorkspace().getRoot(); >- >- IResource newResource = workspaceRoot.findMember(newPath); >- if (newResource != null) { >- if (checkOverwrite(getShell(), newResource)) { >- if (resource.getType() == IResource.FILE >- && newResource.getType() == IResource.FILE) { >- IFile file = (IFile) resource; >- IFile newFile = (IFile) newResource; >- if (validateEdit(file, newFile, getShell())) { >- IProgressMonitor subMonitor = new SubProgressMonitor( >- monitor, 50); >- newFile.setContents(file.getContents(), >- IResource.KEEP_HISTORY, subMonitor); >- file.delete(IResource.KEEP_HISTORY, subMonitor); >- } >- monitor.worked(100); >- return; >- } >- newResource.delete(IResource.KEEP_HISTORY, >- new SubProgressMonitor(monitor, 50)); >- } else { >- monitor.worked(100); >- return; >- } >- } >- if (resource.getType() == IResource.PROJECT) { >- IProject project = (IProject) resource; >- IProjectDescription description = project.getDescription(); >- description.setName(newPath.segment(0)); >- project.move(description, IResource.FORCE | IResource.SHALLOW, >- monitor); >- } else { >- resource.move(newPath, IResource.KEEP_HISTORY | IResource.SHALLOW, >- new SubProgressMonitor(monitor, 50)); >- } >+ protected void invokeOperation(IResource resource, IProgressMonitor monitor) { > } > > /** >- * Validates the operation against the model providers. >- * >- * @param resource the resource to move >- * @param path the new path >- * @return whether the operation should proceed >- * @since 3.2 >- */ >- private boolean validateMove(IResource resource, IPath path) { >- IResourceChangeDescriptionFactory factory = ResourceChangeValidator.getValidator().createDeltaFactory(); >- factory.move(resource, path); >- return IDE.promptToConfirm(getShell(), IDEWorkbenchMessages.RenameResourceAction_confirm, NLS.bind(IDEWorkbenchMessages.RenameResourceAction_warning, resource.getName()), factory.getDelta(), modelProviderIds, true /* syncExec */); >- } >- >- /** > * Return the new name to be given to the target resource. > * > * @return java.lang.String >@@ -475,7 +379,7 @@ > if (currentResource == null || !currentResource.exists()) { > return; > } >- //Do a quick read only and null check >+ //Do a quick read only and null check > if (!checkReadOnlyAndNull(currentResource)) { > return; > } >@@ -500,9 +404,7 @@ > if (!checkReadOnlyAndNull(currentResource)) { > return; > } >- > queryNewResourceNameInline(currentResource); >- > } > > /** >@@ -612,33 +514,7 @@ > textActionHandler = actionHandler; > } > >- /** >- * Validates the destination file if it is read-only and additionally >- * the source file if both are read-only. >- * Returns true if both files could be made writeable. >- * >- * @param source source file >- * @param destination destination file >- * @param shell ui context for the validation >- * @return boolean <code>true</code> both files could be made writeable. >- * <code>false</code> either one or both files were not made writeable >- */ >- boolean validateEdit(IFile source, IFile destination, Shell shell) { >- if (destination.isReadOnly()) { >- IWorkspace workspace = ResourcesPlugin.getWorkspace(); >- IStatus status; >- if (source.isReadOnly()) { >- status = workspace.validateEdit(new IFile[] { source, >- destination }, shell); >- } else { >- status = workspace.validateEdit(new IFile[] { destination }, >- shell); >- } >- return status.isOK(); >- } >- return true; >- } >- >+ > /** > * Returns the model provider ids that are known to the client > * that instantiated this operation. >@@ -663,5 +539,35 @@ > public void setModelProviderIds(String[] modelProviderIds) { > this.modelProviderIds = modelProviderIds; > } >- >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.ui.actions.WorkspaceAction#createOperation(org.eclipse.core.runtime.IStatus[]) >+ * >+ * Overridden to create and execute an undoable operation that >+ * performs the rename. >+ * @since 3.3 >+ */ >+ protected IRunnableWithProgress createOperation(final IStatus [] errorStatus) { >+ return new IRunnableWithProgress() { >+ public void run(IProgressMonitor monitor) { >+ IResource [] resources = (IResource [])getSelectedResources().toArray(new IResource [getSelectedResources().size()]); >+ MoveResourcesOperation op = new MoveResourcesOperation(resources, newPath, getText()); >+ op.setModelProviderIds(getModelProviderIds()); >+ try { >+ errorStatus[0] = PlatformUI.getWorkbench().getOperationSupport() >+ .getOperationHistory().execute(op, monitor, new IAdaptable() { >+ public Object getAdapter(Class clazz) { >+ if (clazz == Shell.class) { >+ return getShell(); >+ } >+ return null; >+ } >+ }); >+ } catch (ExecutionException e) { >+ IDEWorkbenchPlugin.log(e.getMessage(), e); >+ } >+ } >+ }; >+ } > } >Index: src/org/eclipse/ui/ide/undo/MarkerDescription.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/MarkerDescription.java >diff -N src/org/eclipse/ui/ide/undo/MarkerDescription.java >--- src/org/eclipse/ui/ide/undo/MarkerDescription.java 22 Aug 2006 22:28:21 -0000 1.1 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,75 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2006 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.ui.ide.undo; >- >-import java.util.Map; >- >-import org.eclipse.core.resources.IMarker; >-import org.eclipse.core.resources.IResource; >-import org.eclipse.core.runtime.CoreException; >- >-/** >- * MarkerDescription is a lightweight description of a marker that can be used >- * to describe a marker to be created or updated. >- * >- * This class is not intended to be instantiated or used by clients. >- * >- * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >- * of a work in progress. This API may change at any given time. Please do not >- * use this API without consulting with the Platform/UI team. >- * >- * @since 3.3 >- * >- */ >-class MarkerDescription { >- String type; >- >- Map attributes; >- >- IResource resource; >- >- /* >- * Create a marker description from the specified marker. >- */ >- MarkerDescription(IMarker marker) throws CoreException { >- this.type = marker.getType(); >- this.attributes = marker.getAttributes(); >- this.resource = marker.getResource(); >- >- } >- >- /* >- * Create a marker description from the specified marker type, attributes, >- * and resource. >- */ >- MarkerDescription(String type, Map attributes, IResource resource) { >- this.type = type; >- this.attributes = attributes; >- this.resource = resource; >- } >- >- /* >- * Create a marker from the marker description. >- */ >- protected IMarker createMarker() throws CoreException { >- IMarker marker = resource.createMarker(type); >- marker.setAttributes(attributes); >- return marker; >- } >- >- /* >- * Update an existing marker using the attributes in the marker description. >- */ >- protected void updateMarker(IMarker marker) throws CoreException { >- marker.setAttributes(attributes); >- } >-} >\ No newline at end of file >Index: src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java,v >retrieving revision 1.3 >diff -u -r1.3 AbstractMarkersOperation.java >--- src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java 22 Sep 2006 22:55:18 -0000 1.3 >+++ src/org/eclipse/ui/ide/undo/AbstractMarkersOperation.java 29 Sep 2006 18:00:41 -0000 >@@ -21,6 +21,7 @@ > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.IStatus; > import org.eclipse.core.runtime.Status; >+import org.eclipse.ui.internal.ide.undo.MarkerDescription; > import org.eclipse.ui.internal.ide.undo.UndoMessages; > > /** >@@ -183,7 +184,7 @@ > if (markerDescriptions != null) { > resources = new IResource[markerDescriptions.length]; > for (int i = 0; i < markerDescriptions.length; i++) { >- resources[i] = markerDescriptions[i].resource; >+ resources[i] = markerDescriptions[i].getResource(); > } > } > } else { >@@ -212,7 +213,7 @@ > if (markerDescriptions != null) { > types = new String[markerDescriptions.length]; > for (int i = 0; i < markerDescriptions.length; i++) { >- types[i] = markerDescriptions[i].type; >+ types[i] = markerDescriptions[i].getType(); > } > } > } else { >Index: src/org/eclipse/ui/ide/undo/AbstractWorkspaceOperation.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/AbstractWorkspaceOperation.java,v >retrieving revision 1.2 >diff -u -r1.2 AbstractWorkspaceOperation.java >--- src/org/eclipse/ui/ide/undo/AbstractWorkspaceOperation.java 13 Sep 2006 00:02:38 -0000 1.2 >+++ src/org/eclipse/ui/ide/undo/AbstractWorkspaceOperation.java 29 Sep 2006 18:00:43 -0000 >@@ -59,11 +59,11 @@ > > private static String ELLIPSIS = "..."; //$NON-NLS-1$ > >- private static int EXECUTE = 1; >+ protected static int EXECUTE = 1; > >- private static int UNDO = 2; >+ protected static int UNDO = 2; > >- private static int REDO = 3; >+ protected static int REDO = 3; > > protected IResource[] resources; > >@@ -137,7 +137,7 @@ > public boolean canExecute() { > return isValid(); > } >- >+ > /* > * (non-Javadoc) > * >@@ -173,25 +173,29 @@ > public void run(IProgressMonitor monitor) throws CoreException { > doExecute(monitor, info); > } >- }, null); >+ }, null, IWorkspace.AVOID_UPDATE, null); > } catch (final CoreException e) { >+ final boolean[] propagateException = new boolean[1]; > getShell(info).getDisplay().syncExec(new Runnable() { > public void run() { >- ErrorDialog >- .openError( >- getShell(info), >- NLS >- .bind( >- UndoMessages.AbstractWorkspaceOperation_ExecuteErrorTitle, >- getLabel()), null, e >- .getStatus()); >+ propagateException[0] = handleCoreException( >+ e, >+ getShell(info), >+ NLS >+ .bind( >+ UndoMessages.AbstractWorkspaceOperation_ExecuteErrorTitle, >+ getLabel())); > > } > > }); >- throw new ExecutionException(NLS.bind( >- UndoMessages.AbstractWorkspaceOperation_ExecuteErrorTitle, >- getLabel()), e); >+ if (propagateException[0]) { >+ throw new ExecutionException( >+ NLS >+ .bind( >+ UndoMessages.AbstractWorkspaceOperation_ExecuteErrorTitle, >+ getLabel()), e); >+ } > } > isValid = true; > return Status.OK_STATUS; >@@ -215,23 +219,24 @@ > } > }, null); > } catch (final CoreException e) { >+ final boolean[] propagateException = new boolean[1]; > getShell(info).getDisplay().syncExec(new Runnable() { > public void run() { >- ErrorDialog >- .openError( >- getShell(info), >- NLS >- .bind( >- UndoMessages.AbstractWorkspaceOperation_RedoErrorTitle, >- getLabel()), null, e >- .getStatus()); >- >+ propagateException[0] = handleCoreException( >+ e, >+ getShell(info), >+ NLS >+ .bind( >+ UndoMessages.AbstractWorkspaceOperation_RedoErrorTitle, >+ getLabel())); > } > > }); >- throw new ExecutionException(NLS.bind( >- UndoMessages.AbstractWorkspaceOperation_RedoErrorTitle, >- getLabel()), e); >+ if (propagateException[0]) { >+ throw new ExecutionException(NLS.bind( >+ UndoMessages.AbstractWorkspaceOperation_RedoErrorTitle, >+ getLabel()), e); >+ } > } > isValid = true; > return Status.OK_STATUS; >@@ -255,23 +260,25 @@ > } > }, null); > } catch (final CoreException e) { >+ final boolean[] propagateException = new boolean[1]; > getShell(info).getDisplay().syncExec(new Runnable() { > public void run() { >- ErrorDialog >- .openError( >- getShell(info), >- NLS >- .bind( >- UndoMessages.AbstractWorkspaceOperation_UndoErrorTitle, >- getLabel()), null, e >- .getStatus()); >+ propagateException[0] = handleCoreException( >+ e, >+ getShell(info), >+ NLS >+ .bind( >+ UndoMessages.AbstractWorkspaceOperation_UndoErrorTitle, >+ getLabel())); > > } > > }); >- throw new ExecutionException(NLS.bind( >- UndoMessages.AbstractWorkspaceOperation_UndoErrorTitle, >- getLabel()), e); >+ if (propagateException[0]) { >+ throw new ExecutionException(NLS.bind( >+ UndoMessages.AbstractWorkspaceOperation_UndoErrorTitle, >+ getLabel()), e); >+ } > } > isValid = true; > return Status.OK_STATUS; >@@ -306,8 +313,7 @@ > /** > * Return whether the proposed operation is valid. The default > * implementation simply checks to see if the flag has been marked as >- * invalid, relying on subclasses to mark the flag invalid when >- * appropriate. >+ * invalid, relying on subclasses to mark the flag invalid when appropriate. > * > */ > protected boolean isValid() { >@@ -331,18 +337,30 @@ > public Object[] getAffectedObjects() { > return resources; > } >- >+ > /* >- * Return a status indicating the projected outcome of executing the receiver. >- * >- * This method computes the validity of execution by computing the resource >- * delta that would be generated on execution, and checking whether any >- * registered model providers are affected by the operation. This method is >- * not called by the operation history, but instead is used by clients (such >- * as implementers of {@link IOperationApprover2}) who wish to perform >- * advanced validation of an operation before attempting to execute it. If the >- * execute is not valid, then the validity flag on the operation should be >- * marked invalid. >+ * Return a status indicating the projected outcome of executing the >+ * receiver. This method is not called by the operation history, but instead >+ * is used by clients (such as implementers of {@link IOperationApprover2}) >+ * who wish to perform advanced validation of an operation before attempting >+ * to execute it. >+ * >+ * If an ERROR status is returned, the operation will not proceed and the >+ * user notified if deemed necessary by the caller. The validity flag on the >+ * operation should be marked as invalid. If an OK status is returned, the >+ * operation will proceed. The caller must interpret any other returned >+ * status severity, and may choose to prompt the user as to how to proceed. >+ * >+ * If there are multiple conditions that result in an ambiguous status >+ * severity, it is best for the implementor of this method to consult the >+ * user as to how to proceed for each one, and return an OK or ERROR status >+ * that accurately reflects the user's wishes, or to return a multi-status >+ * that accurately describes all of the issues at hand, so that the caller >+ * may potentially consult the user. >+ * >+ * This implementation computes the validity of execution by computing the >+ * resource delta that would be generated on execution, and checking whether >+ * any registered model providers are affected by the operation. > * > * @see org.eclipse.core.commands.operations.IAdvancedUndoableOperation#computeUndoableStatus(org.eclipse.core.runtime.IProgressMonitor) > */ >@@ -371,15 +389,27 @@ > > /* > * Return a status indicating the projected outcome of undoing the receiver. >- * >- * This method computes the validity of an undo by computing the resource >- * delta that would be generated on undo, and checking whether any >- * registered model providers are affected by the operation. This method is >- * not called by the operation history, but instead is used by clients (such >- * as implementers of {@link IOperationApprover}) who wish to perform >- * advanced validation of an operation before attempting to undo it. If the >- * undo is not valid, then the validity flag on the operation should be >- * marked invalid. >+ * This method is not called by the operation history, but instead is used >+ * by clients (such as implementers of {@link IOperationApprover2}) who >+ * wish to perform advanced validation of an operation before attempting to >+ * undo it. >+ * >+ * If an ERROR status is returned, the undo will not proceed and the user >+ * notified if deemed necessary by the caller. The validity flag on the >+ * operation should be marked as invalid. If an OK status is returned, the >+ * undo will proceed. The caller must interpret any other returned status >+ * severity, and may choose to prompt the user as to how to proceed. >+ * >+ * If there are multiple conditions that result in an ambiguous status >+ * severity, it is best for the implementor of this method to consult the >+ * user as to how to proceed for each one, and return an OK or ERROR status >+ * that accurately reflects the user's wishes, or to return a multi-status >+ * that accurately describes all of the issues at hand, so that the caller >+ * may potentially consult the user. >+ * >+ * This implementation computes the validity of undo by computing the >+ * resource delta that would be generated on undo, and checking whether any >+ * registered model providers are affected by the operation. * > * > * @see org.eclipse.core.commands.operations.IAdvancedUndoableOperation#computeUndoableStatus(org.eclipse.core.runtime.IProgressMonitor) > */ >@@ -408,15 +438,27 @@ > > /* > * Return a status indicating the projected outcome of redoing the receiver. >- * >- * This method computes the validity of a redo by computing the resource >- * delta that would be generated on redo, and checking whether any >- * registered model providers are affected by the operation. This method is >- * not called by the operation history, but instead is used by clients (such >- * as implementers of {@link IOperationApprover}) who wish to perform >- * advanced validation of an operation before attempting to redo it. If the >- * redo is not valid, then the validity flag on the operation should be >- * marked invalid. >+ * This method is not called by the operation history, but instead is used >+ * by clients (such as implementers of {@link IOperationApprover2}) who >+ * wish to perform advanced validation of an operation before attempting to >+ * redo it. >+ * >+ * If an ERROR status is returned, the redo will not proceed and the user >+ * notified if deemed necessary by the caller. The validity flag on the >+ * operation should be marked as invalid. If an OK status is returned, the >+ * redo will proceed. The caller must interpret any other returned status >+ * severity, and may choose to prompt the user as to how to proceed. >+ * >+ * If there are multiple conditions that result in an ambiguous status >+ * severity, it is best for the implementor of this method to consult the >+ * user as to how to proceed for each one, and return an OK or ERROR status >+ * that accurately reflects the user's wishes, or to return a multi-status >+ * that accurately describes all of the issues at hand, so that the caller >+ * may potentially consult the user. >+ * >+ * This implementation computes the validity of redo by computing the >+ * resource delta that would be generated on redo, and checking whether any >+ * registered model providers are affected by the operation. > * > * @see org.eclipse.core.commands.operations.IAdvancedUndoableOperation#computeUndoableStatus(org.eclipse.core.runtime.IProgressMonitor) > */ >@@ -512,4 +554,33 @@ > } > return true; > } >+ >+ /** >+ * Handle the core exception that occurred while trying to execute, undo, or >+ * redo the operation, returning a boolean to indicate whether this >+ * exception should cuase a {@link ExecutionException} to be thrown. >+ * >+ * It is safe to access UI in this method. The default implementation is to >+ * show an error dialog, but callers may choose to swallow certain >+ * exceptions or show them differently. >+ * >+ * If the only difference in handling the exception is to show a different >+ * error message, callers should override >+ * {@link #getErrorMessage(CoreException)} instead. >+ */ >+ protected boolean handleCoreException(CoreException e, Shell shell, >+ String errorTitle) { >+ ErrorDialog.openError(shell, errorTitle, getErrorMessage(e), e >+ .getStatus()); >+ return true; >+ } >+ >+ /** >+ * Return the specific error message to use when the specified core >+ * exception occurs, or <code>null</code> to indicate that the the >+ * exception's message should be used. >+ */ >+ protected String getErrorMessage(CoreException e) { >+ return null; >+ } > } >Index: src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java,v >retrieving revision 1.2 >diff -u -r1.2 CreateMarkersOperation.java >--- src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java 13 Sep 2006 00:02:38 -0000 1.2 >+++ src/org/eclipse/ui/ide/undo/CreateMarkersOperation.java 29 Sep 2006 18:00:43 -0000 >@@ -19,6 +19,7 @@ > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.IStatus; > import org.eclipse.core.runtime.NullProgressMonitor; >+import org.eclipse.ui.internal.ide.undo.MarkerDescription; > > /** > * A CreateMarkersOperation represents an undoable operation for creating one or >Index: src/org/eclipse/ui/internal/wizards/newresource/ResourceMessages.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/newresource/ResourceMessages.java,v >retrieving revision 1.3 >diff -u -r1.3 ResourceMessages.java >--- src/org/eclipse/ui/internal/wizards/newresource/ResourceMessages.java 8 May 2006 20:54:13 -0000 1.3 >+++ src/org/eclipse/ui/internal/wizards/newresource/ResourceMessages.java 29 Sep 2006 18:00:50 -0000 >@@ -34,7 +34,6 @@ > public static String NewProject_errorOpeningWindow; > public static String NewProject_errorMessage; > public static String NewProject_internalError; >- public static String NewProject_caseVariantExistsError; > public static String NewProject_perspSwitchTitle; > /** > * Combines a perspective name and text for introducing a perspective switch >Index: src/org/eclipse/ui/internal/wizards/newresource/messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/newresource/messages.properties,v >retrieving revision 1.6 >diff -u -r1.6 messages.properties >--- src/org/eclipse/ui/internal/wizards/newresource/messages.properties 8 May 2006 20:54:13 -0000 1.6 >+++ src/org/eclipse/ui/internal/wizards/newresource/messages.properties 29 Sep 2006 18:00:50 -0000 >@@ -31,7 +31,6 @@ > NewProject_errorOpeningWindow = Problems Opening Window > NewProject_errorMessage = Creation Problems > NewProject_internalError = Internal error: {0} >-NewProject_caseVariantExistsError = The underlying file system is case insensitive. There is an existing project which conflicts with ''{0}''. > NewProject_perspSwitchTitle = Open Associated Perspective? > NewProject_perspSwitchMessage = This kind of project is associated with the {0} perspective. Do you want to open this perspective now? > NewProject_perspSwitchMessageWithDesc = This kind of project is associated with the {0} perspective.\n\n{1}\n\nDo you want to open this perspective now? >Index: src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java,v >retrieving revision 1.38 >diff -u -r1.38 IDEWorkbenchMessages.java >--- src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java 6 Sep 2006 14:21:49 -0000 1.38 >+++ src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java 29 Sep 2006 18:00:46 -0000 >@@ -160,7 +160,6 @@ > public static String MoveProjectAction_text; > public static String MoveProjectAction_toolTip; > public static String MoveProjectAction_moveTitle; >- public static String MoveProjectAction_progressMessage; > public static String MoveProjectAction_dialogTitle; > public static String MoveProjectAction_internalError; > >@@ -177,10 +176,7 @@ > public static String RenameResourceAction_inputDialogMessage; > public static String RenameResourceAction_checkTitle; > public static String RenameResourceAction_readOnlyCheck; >- public static String RenameResourceAction_resourceExists; > public static String RenameResourceAction_nameExists; >- public static String RenameResourceAction_overwriteQuestion; >- public static String RenameResourceAction_progressMessage; > public static String RenameResourceAction_problemTitle; > public static String RenameResourceAction_progress; > public static String RenameResourceAction_nameMustBeDifferent; >@@ -202,10 +198,6 @@ > public static String DeleteResourceAction_confirmLinkedResource1; > public static String DeleteResourceAction_confirmLinkedResourceN; > public static String DeleteResourceAction_readOnlyQuestion; >- public static String DeleteResourceAction_messageTitle; >- public static String DeleteResourceAction_outOfSyncError; >- public static String DeleteResourceAction_outOfSyncQuestion; >- public static String DeleteResourceAction_deletionExceptionMessage; > public static String DeleteResourceAction_jobName; > public static String DeleteResourceAction_checkJobName; > >@@ -366,6 +358,7 @@ > public static String WizardNewFolderCreationPage_progress; > public static String WizardNewFolderCreationPage_errorTitle; > public static String WizardNewFolderCreationPage_internalErrorTitle; >+ public static String WizardNewFolderCreationPage_title; > public static String WizardNewFolder_internalError; > > // --- New File --- >@@ -375,6 +368,8 @@ > public static String WizardNewFileCreationPage_file; > public static String WizardNewFileCreationPage_internalErrorTitle; > public static String WizardNewFileCreationPage_internalErrorMessage; >+ public static String WizardNewFileCreationPage_title; >+ > > // --- Linked Resource --- > public static String WizardNewLinkPage_linkFileButton; >Index: src/org/eclipse/ui/internal/ide/messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties,v >retrieving revision 1.129 >diff -u -r1.129 messages.properties >--- src/org/eclipse/ui/internal/ide/messages.properties 25 Sep 2006 15:51:12 -0000 1.129 >+++ src/org/eclipse/ui/internal/ide/messages.properties 29 Sep 2006 18:00:48 -0000 >@@ -160,7 +160,6 @@ > MoveProjectAction_text = Mo&ve... > MoveProjectAction_toolTip = Move Project > MoveProjectAction_moveTitle = Move Project >-MoveProjectAction_progressMessage = Moving > MoveProjectAction_dialogTitle = Move Problems > MoveProjectAction_internalError = Internal error: {0} > >@@ -179,10 +178,7 @@ > RenameResourceAction_inputDialogMessage = Enter the new resource name: > RenameResourceAction_checkTitle = Check Rename > RenameResourceAction_readOnlyCheck = ''{0}'' is read only. Do you still wish to rename it? >-RenameResourceAction_resourceExists = Resource Exists > RenameResourceAction_nameExists = A resource with that name already exists >-RenameResourceAction_overwriteQuestion = ''{0}'' exists. Do you wish to overwrite? >-RenameResourceAction_progressMessage = Renaming... > RenameResourceAction_problemTitle = Rename Problems > RenameResourceAction_progress = Renaming: > RenameResourceAction_nameMustBeDifferent = You must use a different name >@@ -206,10 +202,6 @@ > DeleteResourceAction_confirmLinkedResource1 = Are you sure you want to delete linked resource ''{0}''?\nOnly the workspace link will be deleted. Link target will remain unchanged. > DeleteResourceAction_confirmLinkedResourceN = Are you sure you want to delete these {0} resources?\n\nSelection contains linked resources.\nOnly the workspace links will be deleted. Link targets will remain unchanged. > DeleteResourceAction_readOnlyQuestion = ''{0}'' is read only. Do you still wish to delete it? >-DeleteResourceAction_messageTitle = Problems deleting >-DeleteResourceAction_outOfSyncError = Resource is out of sync with the file system. Refresh and try again. >-DeleteResourceAction_outOfSyncQuestion = Resource ''{0}'' is out of sync with the file system. Do you want to delete it anyway? >-DeleteResourceAction_deletionExceptionMessage=Multiple problems occurred while deleting resources. > DeleteResourceAction_checkJobName = Checking resources > DeleteResourceAction_jobName = Deleting resources > >@@ -386,6 +378,7 @@ > WizardNewFolderCreationPage_progress = Creating > WizardNewFolderCreationPage_errorTitle = Creation Problems > WizardNewFolderCreationPage_internalErrorTitle = Creation problems >+WizardNewFolderCreationPage_title = New Folder > WizardNewFolder_internalError = Internal error: {0} > > # --- New File --- >@@ -395,6 +388,7 @@ > WizardNewFileCreationPage_file = file > WizardNewFileCreationPage_internalErrorTitle = Creation problems > WizardNewFileCreationPage_internalErrorMessage = Internal error: {0} >+WizardNewFileCreationPage_title = New File > > # --- Linked Resource --- > WizardNewLinkPage_linkFileButton = &Link to file on the file system >Index: src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java,v >retrieving revision 1.40 >diff -u -r1.40 BasicNewProjectResourceWizard.java >--- src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java 8 May 2006 20:54:13 -0000 1.40 >+++ src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java 29 Sep 2006 18:00:50 -0000 >@@ -19,29 +19,28 @@ > import java.util.Set; > import java.util.StringTokenizer; > >+import org.eclipse.core.commands.ExecutionException; > import org.eclipse.core.resources.IProject; > import org.eclipse.core.resources.IProjectDescription; >-import org.eclipse.core.resources.IResource; >-import org.eclipse.core.resources.IResourceStatus; > import org.eclipse.core.resources.IWorkspace; > import org.eclipse.core.resources.ResourcesPlugin; >-import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; > import org.eclipse.core.runtime.IConfigurationElement; > import org.eclipse.core.runtime.IExecutableExtension; > import org.eclipse.core.runtime.IProgressMonitor; > import org.eclipse.core.runtime.IStatus; >-import org.eclipse.core.runtime.OperationCanceledException; > import org.eclipse.core.runtime.Status; >-import org.eclipse.core.runtime.SubProgressMonitor; > import org.eclipse.jface.dialogs.ErrorDialog; > import org.eclipse.jface.dialogs.IDialogConstants; > import org.eclipse.jface.dialogs.IDialogSettings; > import org.eclipse.jface.dialogs.MessageDialog; > import org.eclipse.jface.dialogs.MessageDialogWithToggle; >+import org.eclipse.jface.operation.IRunnableWithProgress; > import org.eclipse.jface.preference.IPreferenceStore; > import org.eclipse.jface.resource.ImageDescriptor; > import org.eclipse.jface.viewers.IStructuredSelection; > import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.IPerspectiveDescriptor; > import org.eclipse.ui.IPerspectiveRegistry; > import org.eclipse.ui.IPluginContribution; >@@ -51,7 +50,6 @@ > import org.eclipse.ui.IWorkbenchWindow; > import org.eclipse.ui.PlatformUI; > import org.eclipse.ui.WorkbenchException; >-import org.eclipse.ui.actions.WorkspaceModifyOperation; > import org.eclipse.ui.activities.IActivityManager; > import org.eclipse.ui.activities.IIdentifier; > import org.eclipse.ui.activities.IWorkbenchActivitySupport; >@@ -59,6 +57,7 @@ > import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; > import org.eclipse.ui.dialogs.WizardNewProjectReferencePage; > import org.eclipse.ui.ide.IDE; >+import org.eclipse.ui.ide.undo.CreateProjectOperation; > import org.eclipse.ui.internal.IPreferenceConstants; > import org.eclipse.ui.internal.WorkbenchPlugin; > import org.eclipse.ui.internal.ide.IDEInternalPreferences; >@@ -196,12 +195,27 @@ > } > > // create the new project operation >- WorkspaceModifyOperation op = new WorkspaceModifyOperation() { >- protected void execute(IProgressMonitor monitor) >- throws CoreException { >- createProject(description, newProjectHandle, monitor); >- } >+ IRunnableWithProgress op = new IRunnableWithProgress() { >+ public void run(IProgressMonitor monitor) { >+ CreateProjectOperation op = new CreateProjectOperation( >+ description, ResourceMessages.NewProject_windowTitle); >+ try { >+ PlatformUI.getWorkbench().getOperationSupport() >+ .getOperationHistory().execute(op, monitor, new IAdaptable() { >+ public Object getAdapter(Class clazz) { >+ if (clazz == Shell.class) { >+ return getShell(); >+ } >+ return null; >+ } >+ }); >+ } catch (ExecutionException e) { >+ IDEWorkbenchPlugin.log(e.getMessage(), e); >+ } >+ } >+ > }; >+ > > // run the new project creation operation > try { >@@ -209,34 +223,18 @@ > } catch (InterruptedException e) { > return null; > } catch (InvocationTargetException e) { >- // ie.- one of the steps resulted in a core exception >- Throwable t = e.getTargetException(); >- if (t instanceof CoreException) { >- if (((CoreException) t).getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { >- MessageDialog >- .openError( >- getShell(), >- ResourceMessages.NewProject_errorMessage, >- NLS.bind(ResourceMessages.NewProject_caseVariantExistsError, newProjectHandle.getName()) >- ); >- } else { >- ErrorDialog.openError(getShell(), ResourceMessages.NewProject_errorMessage, >- null, // no special message >- ((CoreException) t).getStatus()); >- } >- } else { >- // CoreExceptions are handled above, but unexpected runtime >- // exceptions and errors may still occur. >- IDEWorkbenchPlugin.getDefault().getLog().log( >- new Status(IStatus.ERROR, >- IDEWorkbenchPlugin.IDE_WORKBENCH, 0, t >- .toString(), t)); >- MessageDialog >- .openError( >- getShell(), >- ResourceMessages.NewProject_errorMessage, >- NLS.bind(ResourceMessages.NewProject_internalError, t.getMessage())); >- } >+ Throwable t = e.getTargetException(); >+ // Exceptions are handled in the operation, but unexpected runtime >+ // exceptions and errors may still occur. >+ IDEWorkbenchPlugin.getDefault().getLog().log( >+ new Status(IStatus.ERROR, >+ IDEWorkbenchPlugin.IDE_WORKBENCH, 0, t >+ .toString(), t)); >+ MessageDialog.openError( >+ getShell(), >+ ResourceMessages.NewProject_errorMessage, >+ NLS.bind(ResourceMessages.NewProject_internalError, t.getMessage())); >+ > return null; > } > >@@ -246,41 +244,6 @@ > } > > /** >- * Creates a project resource given the project handle and description. >- * >- * @param description >- * the project description to create a project resource for >- * @param projectHandle >- * the project handle to create a project resource for >- * @param monitor >- * the progress monitor to show visual progress with >- * >- * @exception CoreException >- * if the operation fails >- * @exception OperationCanceledException >- * if the operation is canceled >- */ >- void createProject(IProjectDescription description, IProject projectHandle, >- IProgressMonitor monitor) throws CoreException, >- OperationCanceledException { >- try { >- monitor.beginTask("", 2000);//$NON-NLS-1$ >- >- projectHandle.create(description, new SubProgressMonitor(monitor, >- 1000)); >- >- if (monitor.isCanceled()) { >- throw new OperationCanceledException(); >- } >- >- projectHandle.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1000)); >- >- } finally { >- monitor.done(); >- } >- } >- >- /** > * Returns the newly created project. > * > * @return the created project, or <code>null</code> if project not >Index: src/org/eclipse/ui/internal/ide/undo/FileDescription.java >=================================================================== >RCS file: src/org/eclipse/ui/internal/ide/undo/FileDescription.java >diff -N src/org/eclipse/ui/internal/ide/undo/FileDescription.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/internal/ide/undo/FileDescription.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,137 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.internal.ide.undo; >+ >+import java.io.InputStream; >+import java.io.StringBufferInputStream; >+ >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.resources.IFileState; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IWorkspaceRoot; >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.OperationCanceledException; >+import org.eclipse.core.runtime.SubProgressMonitor; >+ >+/** >+ * FileDescription is a lightweight description that describes a file to be >+ * created. >+ * >+ * This class is not intended to be instantiated or used by clients. >+ * >+ * @since 3.3 >+ * >+ */ >+public class FileDescription extends ResourceDescription { >+ >+ String name; >+ >+ IPath location; >+ >+ private IFileState fileState; >+ >+ public FileDescription(IFile file) { >+ super(file); >+ this.name = file.getName(); >+ if (file.isLinked()) { >+ location = file.getLocation(); >+ } >+ >+ } >+ >+ /* >+ * Create a file description from the specified file handle. The handle does >+ * not exist, so no information should be derived from it. If a location >+ * path is specified, this folder should represent a link to another >+ * location. The IFileState describes any state that should be used when the >+ * file resource is created. >+ */ >+ public FileDescription(IFile file, IPath linkLocation, IFileState fileState) { >+ super(file); >+ this.name = file.getName(); >+ this.location = linkLocation; >+ this.fileState = fileState; >+ } >+ >+ public void recordLastHistory(IResource resource, >+ IProgressMonitor monitor) throws CoreException { >+ Assert.isLegal(resource.getType() != IResource.FILE); >+ >+ if (location != null) { >+ // file is linked, no need to record any history >+ return; >+ } >+ IFileState[] states = ((IFile) resource).getHistory(monitor); >+ if (states.length > 0) { >+ this.fileState = states[0]; >+ } >+ } >+ >+ /* >+ * (non-Javadoc) >+ * @see org.eclipse.ui.internal.ide.undo.ResourceDescription#createResourceHandle() >+ */ >+ public IResource createResourceHandle() { >+ IWorkspaceRoot workspaceRoot = parent.getWorkspace().getRoot(); >+ IPath filePath = parent.getFullPath().append(name); >+ return workspaceRoot.getFile(filePath); >+ } >+ >+ protected void createExistentResourceFromHandle(IResource resource, >+ IProgressMonitor monitor) throws CoreException { >+ >+ Assert.isLegal(resource instanceof IFile); >+ IFile fileHandle = (IFile) resource; >+ monitor.beginTask(UndoMessages.FileDescription_NewFileProgress, 200); >+ try { >+ if (monitor.isCanceled()) { >+ throw new OperationCanceledException(); >+ } >+ if (location != null) { >+ fileHandle.createLink(location, IResource.ALLOW_MISSING_LOCAL, >+ new SubProgressMonitor(monitor, 200)); >+ } else { >+ InputStream contents = new StringBufferInputStream( >+ UndoMessages.FileDescription_ContentsCouldNotBeRestored); >+ String charset = null; >+ // Retrieve the contents and charset from the file state. >+ // Other file state attributes, such as timestamps, have >+ // already been retrieved from the original IResource object >+ // and are restored in the superclass. >+ if (fileState != null && fileState.exists()) { >+ contents = fileState.getContents(); >+ charset = fileState.getCharset(); >+ } >+ fileHandle.create(contents, false, new SubProgressMonitor( >+ monitor, 100)); >+ fileHandle.setCharset(charset, new SubProgressMonitor(monitor, >+ 100)); >+ } >+ if (monitor.isCanceled()) { >+ throw new OperationCanceledException(); >+ } >+ } finally { >+ monitor.done(); >+ } >+ } >+ >+ public boolean isValid() { >+ return super.isValid() && fileState != null && fileState.exists(); >+ } >+ >+ public String getName() { >+ return name; >+ } >+} >Index: src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java >diff -N src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/ide/undo/DeleteResourcesOperation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,117 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.ide.undo; >+ >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.ui.internal.ide.undo.UndoMessages; >+ >+/** >+ * A DeleteResourcesOperation represents an undoable operation for deleting one >+ * or more resources in the workspace. >+ * >+ * This class is intended to be instantiated and used by clients. It is not >+ * intended to be subclassed by clients. >+ * >+ * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >+ * of a work in progress. This API may change at any given time. Please do not >+ * use this API without consulting with the Platform/UI team. >+ * >+ * @since 3.3 >+ * >+ */ >+public class DeleteResourcesOperation extends AbstractResourcesOperation { >+ >+ private boolean deleteContent = false; >+ >+ /** >+ * Create a DeleteResourcesOperation >+ * >+ * @param resources >+ * the resources to be deleted >+ * @param label >+ * the label of the operation >+ * @param deleteContent >+ * whether or not we are deleting content for projects >+ */ >+ public DeleteResourcesOperation(IResource[] resources, String label, >+ boolean deleteContent) { >+ super(resources, label); >+ this.deleteContent = deleteContent; >+ } >+ >+ protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ delete(monitor, uiInfo, deleteContent); >+ } >+ >+ protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ recreate(monitor, uiInfo); >+ } >+ >+ protected boolean updateResourceChangeDescriptionFactory( >+ IResourceChangeDescriptionFactory factory, int operation) { >+ boolean modified = false; >+ if (operation == UNDO) { >+ for (int i = 0; i < resourceDescriptions.length; i++) { >+ IResource resource = resourceDescriptions[i].createResourceHandle(); >+ factory.create(resource); >+ modified = true; >+ } >+ } else { >+ for (int i = 0; i < resources.length; i++) { >+ IResource resource = resources[i]; >+ factory.delete(resource); >+ modified = true; >+ } >+ } >+ return modified; >+ } >+ >+ public IStatus computeExecutionStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeExecutionStatus(monitor); >+ if (status.isOK()) { >+ status = computeDeleteStatus(); >+ } >+ if (status.isOK()) { >+ // If the resources to be deleted include projects whose content >+ // is to be deleted, warn the user that the data will be lost. >+ if (deleteContent) { >+ status = getWarningStatus( >+ UndoMessages.DeleteResourcesOperation_DeletingProjectContentWarning, >+ 0); >+ } >+ } >+ return status; >+ } >+ >+ public IStatus computeUndoableStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeUndoableStatus(monitor); >+ if (status.isOK()) { >+ status = computeCreateStatus(); >+ } >+ return status; >+ } >+ >+ public IStatus computeRedoableStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeRedoableStatus(monitor); >+ if (status.isOK()) { >+ status = computeDeleteStatus(); >+ } >+ return status; >+ } >+} >Index: src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java >=================================================================== >RCS file: src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java >diff -N src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/internal/ide/undo/MarkerDescription.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,85 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.internal.ide.undo; >+ >+import java.util.Map; >+ >+import org.eclipse.core.resources.IMarker; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.runtime.CoreException; >+ >+/** >+ * MarkerDescription is a lightweight description of a marker that can be used >+ * to describe a marker to be created or updated. >+ * >+ * This class is not intended to be instantiated or used by clients. >+ * >+ * @since 3.3 >+ * >+ */ >+public class MarkerDescription { >+ String type; >+ >+ Map attributes; >+ >+ IResource resource; >+ >+ /* >+ * Create a marker description from the specified marker. >+ */ >+ public MarkerDescription(IMarker marker) throws CoreException { >+ this.type = marker.getType(); >+ this.attributes = marker.getAttributes(); >+ this.resource = marker.getResource(); >+ >+ } >+ >+ /* >+ * Create a marker description from the specified marker type, attributes, >+ * and resource. >+ */ >+ public MarkerDescription(String type, Map attributes, IResource resource) { >+ this.type = type; >+ this.attributes = attributes; >+ this.resource = resource; >+ } >+ >+ /* >+ * Create a marker from the marker description. >+ */ >+ public IMarker createMarker() throws CoreException { >+ IMarker marker = resource.createMarker(type); >+ marker.setAttributes(attributes); >+ return marker; >+ } >+ >+ /* >+ * Update an existing marker using the attributes in the marker description. >+ */ >+ public void updateMarker(IMarker marker) throws CoreException { >+ marker.setAttributes(attributes); >+ } >+ >+ /* >+ * Return the resource associated with this marker. >+ */ >+ public IResource getResource() { >+ return resource; >+ } >+ >+ /* >+ * Return the marker type associated with this marker. >+ */ >+ public String getType() { >+ return type; >+ } >+} >Index: src/org/eclipse/ui/ide/undo/CreateFileOperation.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/CreateFileOperation.java >diff -N src/org/eclipse/ui/ide/undo/CreateFileOperation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/ide/undo/CreateFileOperation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,127 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.ide.undo; >+ >+import java.io.InputStream; >+import java.io.StringBufferInputStream; >+ >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.resources.IFileState; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.ui.internal.ide.undo.ContainerDescription; >+import org.eclipse.ui.internal.ide.undo.FileDescription; >+import org.eclipse.ui.internal.ide.undo.ResourceDescription; >+ >+/** >+ * A CreateFileOperation represents an undoable operation for creating a file in >+ * the workspace. If a link location is specified, the folder is considered to >+ * be linked to the file at the specified location. If a link location is not >+ * specified, the file will be created in the location specified by the handle, >+ * and the entire containment path of the file will be created if it does not >+ * exist. >+ * >+ * This class is intended to be instantiated and used by clients. It is not >+ * intended to be subclassed by clients. >+ * >+ * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >+ * of a work in progress. This API may change at any given time. Please do not >+ * use this API without consulting with the Platform/UI team. >+ * >+ * @since 3.3 >+ * >+ */ >+public class CreateFileOperation extends AbstractCreateResourcesOperation { >+ >+ /** >+ * Create a CreateFileOperation >+ * >+ * @param fileHandle >+ * the file to be created >+ * @param linkLocation >+ * the location of the file if it is to be linked >+ * @param contents >+ * the initial contents of the file, or null if there is to be no >+ * contents >+ * @param label >+ * the label of the operation >+ */ >+ public CreateFileOperation(IFile fileHandle, IPath linkLocation, InputStream contents, String label) { >+ super(null, label); >+ ResourceDescription resourceDescription; >+ if (linkLocation == null) { >+ if (fileHandle.getParent().exists()) { >+ resourceDescription = new FileDescription(fileHandle, null, createFileState(fileHandle, contents)); >+ } else { >+ // must first ensure descriptions for the parent folders are >+ // created >+ ContainerDescription containerDescription = ContainerDescription.fromContainer(fileHandle.getParent()); >+ containerDescription.getFirstLeafFolder().addMember(new FileDescription(fileHandle, null, createFileState(fileHandle, contents))); >+ resourceDescription = containerDescription; >+ } >+ } else { >+ // create a linked file description >+ resourceDescription = new FileDescription(fileHandle, linkLocation, createFileState(fileHandle, contents)); >+ } >+ resourceDescriptions = new ResourceDescription[ ] { resourceDescription }; >+ >+ } >+ >+ /* >+ * Create a file state that represents the desired contents and attributes >+ * of the file to be created. Used to mimic file history when a resource is >+ * first created. >+ */ >+ private IFileState createFileState(final IFile file, >+ final InputStream contents) { >+ return new IFileState() { >+ public InputStream getContents() { >+ if (contents != null) { >+ return contents; >+ } >+ return new StringBufferInputStream(""); //$NON-NLS-1$ >+ } >+ >+ public Object getAdapter(Class clazz) { >+ return null; >+ } >+ >+ public String getCharset() { >+ try { >+ return file.getCharset(); >+ } catch (CoreException e) { >+ return null; >+ } >+ } >+ >+ public IPath getFullPath() { >+ return file.getFullPath(); >+ } >+ >+ public String getName() { >+ return file.getName(); >+ } >+ >+ public boolean exists() { >+ return true; >+ } >+ >+ public boolean isReadOnly() { >+ return true; >+ } >+ >+ public long getModificationTime() { >+ return file.getLocalTimeStamp(); >+ } >+ }; >+ } >+} >Index: src/org/eclipse/ui/internal/ide/undo/FolderDescription.java >=================================================================== >RCS file: src/org/eclipse/ui/internal/ide/undo/FolderDescription.java >diff -N src/org/eclipse/ui/internal/ide/undo/FolderDescription.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/internal/ide/undo/FolderDescription.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,89 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.internal.ide.undo; >+ >+import org.eclipse.core.resources.IFolder; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IWorkspaceRoot; >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.OperationCanceledException; >+import org.eclipse.core.runtime.SubProgressMonitor; >+ >+/** >+ * FolderDescription is a lightweight description that describes a folder to be >+ * created. >+ * >+ * This class is not intended to be instantiated or used by clients. >+ * >+ * @since 3.3 >+ * >+ */ >+public class FolderDescription extends ContainerDescription { >+ >+ /* >+ * Create a FolderDescription from the specified folder handle. Typically >+ * used when the folder handle represents a resource that actually exists, >+ * although it will not fail if the resource is non-existent. >+ */ >+ public FolderDescription(IFolder folder) { >+ super(folder); >+ } >+ >+ /* >+ * Create a FolderDescription from the specified folder handle. >+ * If the folder to be created should be linked to a different location, >+ * specify the location. >+ */ >+ public FolderDescription(IFolder folder, IPath linkLocation) { >+ super(folder); >+ this.name = folder.getName(); >+ this.location = linkLocation; >+ } >+ >+ public IResource createResourceHandle() { >+ IWorkspaceRoot workspaceRoot = getWorkspaceRoot(); >+ IPath folderPath = parent.getFullPath().append(name); >+ return workspaceRoot.getFolder(folderPath); >+ } >+ >+ protected void createExistentResourceFromHandle(IResource resource, >+ IProgressMonitor monitor) throws CoreException { >+ >+ Assert.isLegal(resource instanceof IFolder); >+ IFolder folderHandle = (IFolder) resource; >+ try { >+ monitor.beginTask(UndoMessages.FolderDescription_NewFolderProgress, >+ 200); >+ if (monitor.isCanceled()) { >+ throw new OperationCanceledException(); >+ } >+ if (location != null) { >+ folderHandle.createLink(location, >+ IResource.ALLOW_MISSING_LOCAL, new SubProgressMonitor( >+ monitor, 100)); >+ } else { >+ folderHandle.create(false, true, new SubProgressMonitor( >+ monitor, 100)); >+ } >+ if (monitor.isCanceled()) { >+ throw new OperationCanceledException(); >+ } >+ createChildResources(folderHandle, monitor, 100); >+ >+ } finally { >+ monitor.done(); >+ } >+ } >+} >Index: src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java >diff -N src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/ide/undo/MoveResourcesOperation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,160 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.ide.undo; >+ >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.ui.internal.ide.undo.UndoMessages; >+ >+/** >+ * A MoveResourcesOperation represents an undoable operation for moving one or >+ * more resources in the workspace. >+ * >+ * This class is intended to be instantiated and used by clients. It is not >+ * intended to be subclassed by clients. >+ * >+ * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >+ * of a work in progress. This API may change at any given time. Please do not >+ * use this API without consulting with the Platform/UI team. >+ * >+ * @since 3.3 >+ * >+ */ >+public class MoveResourcesOperation extends AbstractResourcesOperation { >+ >+ IPath proposedPath; >+ >+ /** >+ * Create a MoveResourcesOperation >+ * >+ * @param resources >+ * the resources to be renamed >+ * @param newPath >+ * the new path for the resource. >+ * @param label >+ * the label of the operation >+ */ >+ public MoveResourcesOperation(IResource[] resources, IPath newPath, >+ String label) { >+ super(resources, label); >+ proposedPath = newPath; >+ } >+ >+ protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ swapLocation(monitor, uiInfo); >+ } >+ >+ protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ swapLocation(monitor, uiInfo); >+ } >+ >+ private IPath getProposedPath() { >+ return proposedPath; >+ } >+ >+ private void swapLocation(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ IResource resource = getResource(); >+ IPath currentPath = resource.getFullPath(); >+ move(resource, getProposedPath(), monitor, uiInfo); >+ proposedPath = currentPath; >+ } >+ >+ protected boolean updateResourceChangeDescriptionFactory( >+ IResourceChangeDescriptionFactory factory, int operation) { >+ IResource resource = getResource(); >+ IPath newPath = getProposedPath(); >+ factory.move(resource, newPath); >+ return true; >+ } >+ >+ public IStatus computeExecutionStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeExecutionStatus(monitor); >+ if (status.isOK()) { >+ status = computeMoveStatus(); >+ } >+ return status; >+ } >+ >+ public IStatus computeUndoableStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeUndoableStatus(monitor); >+ if (status.isOK()) { >+ status = computeMoveStatus(); >+ } >+ return status; >+ } >+ >+ public IStatus computeRedoableStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeRedoableStatus(monitor); >+ if (status.isOK()) { >+ status = computeMoveStatus(); >+ } >+ return status; >+ } >+ >+ /* >+ * Compute the status for moving the resources. >+ * >+ * Note this method may be called on initial moving of a resource, or when a >+ * move is undone or redone. Therefore, this method should check conditions >+ * that can change over the life of the operation, such as whether moving >+ * the file will cause an overwrite. One-time static checks should typically >+ * be done by the caller (such as the action that creates the operation) so >+ * that the user is not continually prompted or warned about conditions that >+ * were acceptable at the time of original execution. >+ * >+ * TODO: Note that this currently only operates on the first resource. >+ */ >+ private IStatus computeMoveStatus() { >+ IResource resource = getResource(); >+ // Does the resource still exist? >+ if (!resource.exists()) { >+ markInvalid(); >+ return getErrorStatus(UndoMessages.RenameResourceOperation_ResourceDoesNotExist); >+ } >+ // Are we really trying to rename it a different name? >+ IPath proposedPath = getProposedPath(); >+ if (resource.getFullPath().equals(proposedPath)) { >+ markInvalid(); >+ return getErrorStatus(UndoMessages.RenameResourceOperation_SameName); >+ } >+ // Is the proposed name valid? >+ IStatus status = getWorkspace().validateName( >+ proposedPath.lastSegment(), resource.getType()); >+ if (status.getSeverity() == IStatus.ERROR) { >+ markInvalid(); >+ } >+ if (!status.isOK()) { >+ return status; >+ } >+ >+ // Does the newly named resource already exist. If so, we could >+ // overwrite >+ IResource newResource = getWorkspace().getRoot().findMember( >+ proposedPath); >+ if (newResource != null) { >+ return getWarningStatus(NLS.bind( >+ UndoMessages.RenameResourceOperation_ResourceAlreadyExists, >+ proposedPath.toString()), 0); >+ } >+ return Status.OK_STATUS; >+ } >+} >Index: src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java >diff -N src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/ide/undo/AbstractCreateResourcesOperation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,105 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.ide.undo; >+ >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.ui.internal.ide.undo.ResourceDescription; >+ >+/** >+ * A CreateResourcesOperation represents an undoable operation for creating >+ * resources in the workspace. >+ * >+ * This class is not intended to be subclassed by clients. >+ * >+ * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >+ * of a work in progress. This API may change at any given time. Please do not >+ * use this API without consulting with the Platform/UI team. >+ * >+ * @since 3.3 >+ * >+ */ >+public abstract class AbstractCreateResourcesOperation extends >+ AbstractResourcesOperation { >+ >+ /** >+ * Create a create resources operation >+ * >+ * @param resourceDescriptions >+ * the resourceDescriptions describing resources to be created >+ * @param label >+ * the label of the operation >+ */ >+ AbstractCreateResourcesOperation(ResourceDescription[] resourceDescriptions, >+ String label) { >+ super(resourceDescriptions, label); >+ } >+ >+ protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ recreate(monitor, uiInfo); >+ } >+ >+ protected void doUndo(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ delete(monitor, uiInfo, false); // never delete content on undo of >+ // create project >+ } >+ >+ protected boolean updateResourceChangeDescriptionFactory( >+ IResourceChangeDescriptionFactory factory, int operation) { >+ boolean modified = false; >+ if (operation == UNDO) { >+ for (int i = 0; i < resources.length; i++) { >+ IResource resource = resources[i]; >+ factory.delete(resource); >+ modified = true; >+ } >+ } else { >+ for (int i = 0; i < resourceDescriptions.length; i++) { >+ IResource resource = resourceDescriptions[i] >+ .createResourceHandle(); >+ factory.create(resource); >+ modified = true; >+ } >+ } >+ return modified; >+ } >+ >+ public IStatus computeExecutionStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeExecutionStatus(monitor); >+ if (status.isOK()) { >+ status = computeCreateStatus(); >+ } >+ return status; >+ } >+ >+ public IStatus computeUndoableStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeUndoableStatus(monitor); >+ if (status.isOK()) { >+ status = computeDeleteStatus(); >+ } >+ return status; >+ } >+ >+ public IStatus computeRedoableStatus(IProgressMonitor monitor) { >+ IStatus status = super.computeRedoableStatus(monitor); >+ if (status.isOK()) { >+ status = computeCreateStatus(); >+ } >+ return status; >+ } >+} >Index: src/org/eclipse/ui/internal/ide/undo/ResourceDescription.java >=================================================================== >RCS file: src/org/eclipse/ui/internal/ide/undo/ResourceDescription.java >diff -N src/org/eclipse/ui/internal/ide/undo/ResourceDescription.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/internal/ide/undo/ResourceDescription.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,157 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.internal.ide.undo; >+ >+import org.eclipse.core.resources.IContainer; >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.resources.IFolder; >+import org.eclipse.core.resources.IMarker; >+import org.eclipse.core.resources.IProject; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IWorkspaceRoot; >+import org.eclipse.core.resources.ResourceAttributes; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; >+ >+/** >+ * ResourceDescription is a lightweight description that describes the common >+ * attributes of a resource to be created. >+ * >+ * This class is not intended to be instantiated or used by clients. >+ * >+ * @since 3.3 >+ * >+ */ >+public abstract class ResourceDescription { >+ IContainer parent; >+ >+ long modificationStamp = IResource.NULL_STAMP; >+ >+ long localTimeStamp = IResource.NULL_STAMP; >+ >+ ResourceAttributes resourceAttributes; >+ >+ MarkerDescription[] markerDescriptions; >+ >+ /** >+ * @param resource >+ * @return the resource description >+ */ >+ public static ResourceDescription fromResource(IResource resource) { >+ if (resource.getType() == IResource.PROJECT) { >+ return new ProjectDescription((IProject) resource); >+ } else if (resource.getType() == IResource.FOLDER) { >+ return new FolderDescription((IFolder) resource); >+ } else if (resource.getType() == IResource.FILE) { >+ return new FileDescription((IFile) resource); >+ } else { >+ throw new IllegalArgumentException(); >+ } >+ } >+ >+ protected static IWorkspaceRoot getWorkspaceRoot() { >+ return IDEWorkbenchPlugin.getPluginWorkspace().getRoot(); >+ >+ } >+ >+ >+ /* >+ * Create a resource description with no initial attributes >+ */ >+ protected ResourceDescription() { >+ super(); >+ } >+ >+ /* >+ * Create a resource description from the specified resource. >+ */ >+ protected ResourceDescription(IResource resource) { >+ super(); >+ parent = resource.getParent(); >+ if (resource.exists()) { >+ modificationStamp = resource.getModificationStamp(); >+ localTimeStamp = resource.getLocalTimeStamp(); >+ resourceAttributes = resource.getResourceAttributes(); >+ try { >+ IMarker[] markers = resource.findMarkers(null, true, >+ IResource.DEPTH_INFINITE); >+ markerDescriptions = new MarkerDescription[markers.length]; >+ for (int i = 0; i < markers.length; i++) { >+ markerDescriptions[i] = new MarkerDescription(markers[i]); >+ } >+ } catch (CoreException e) { >+ // Eat this exception because it only occurs when the resource >+ // does not exist and we have already checked this. >+ // We do not want to throw exceptions on the simple constructor, >+ // as >+ // no one has actually tried to do anything yet. >+ } >+ } >+ } >+ >+ /* >+ * Create a resource handle that can be used to create a resource from this >+ * resource description. This handle can be used to create the actual >+ * resource, or to describe the creation to a resource delta factory. >+ */ >+ public abstract IResource createResourceHandle(); >+ >+ /* >+ * Get the name of this resource. >+ */ >+ public abstract String getName(); >+ >+ /* >+ * Create an existent resource from this resource description. >+ */ >+ public IResource createResource(IProgressMonitor monitor) >+ throws CoreException { >+ IResource resource = createResourceHandle(); >+ createExistentResourceFromHandle(resource, monitor); >+ if (modificationStamp != IResource.NULL_STAMP) { >+ resource.revertModificationStamp(modificationStamp); >+ } >+ if (localTimeStamp != IResource.NULL_STAMP) { >+ resource.setLocalTimeStamp(localTimeStamp); >+ } >+ if (resourceAttributes != null) { >+ resource.setResourceAttributes(resourceAttributes); >+ } >+ if (markerDescriptions != null) { >+ for (int i = 0; i < markerDescriptions.length; i++) { >+ markerDescriptions[i].resource = resource; >+ markerDescriptions[i].createMarker(); >+ } >+ } >+ return resource; >+ } >+ >+ /* >+ * Given a resource handle, create the actual existent resource represented >+ * by that handle. >+ */ >+ protected abstract void createExistentResourceFromHandle( >+ IResource resource, IProgressMonitor monitor) throws CoreException; >+ >+ public boolean isValid() { >+ return parent == null || parent.exists(); >+ } >+ >+ public void recordLastHistory(IResource resource, IProgressMonitor monitor) >+ throws CoreException { >+ // Nothing to do by default >+ monitor.beginTask("", 100); //$NON-NLS-1$ >+ monitor.done(); >+ } >+ >+} >Index: src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java >diff -N src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/ide/undo/AbstractResourcesOperation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,528 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.ide.undo; >+ >+import java.util.ArrayList; >+import java.util.List; >+ >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.resources.IProject; >+import org.eclipse.core.resources.IProjectDescription; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IResourceStatus; >+import org.eclipse.core.resources.IWorkspace; >+import org.eclipse.core.resources.IWorkspaceRoot; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IAdaptable; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.IStatus; >+import org.eclipse.core.runtime.MultiStatus; >+import org.eclipse.core.runtime.OperationCanceledException; >+import org.eclipse.core.runtime.Status; >+import org.eclipse.core.runtime.SubProgressMonitor; >+import org.eclipse.jface.dialogs.IDialogConstants; >+import org.eclipse.jface.dialogs.MessageDialog; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; >+import org.eclipse.ui.internal.ide.undo.FileDescription; >+import org.eclipse.ui.internal.ide.undo.ResourceDescription; >+import org.eclipse.ui.internal.ide.undo.UndoMessages; >+ >+/** >+ * An AbstractResourcesOperation represents an undoable operation that >+ * manipulates resources. It provides implementations for resource rename, >+ * delete, creation, and modification. It also assigns the workspace undo >+ * context as the undo context for operations of this type. >+ * >+ * This class is not intended to be subclassed by clients. >+ * >+ * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >+ * of a work in progress. This API may change at any given time. Please do not >+ * use this API without consulting with the Platform/UI team. >+ * >+ * @since 3.3 >+ * >+ */ >+public abstract class AbstractResourcesOperation extends >+ AbstractWorkspaceOperation { >+ >+ /* >+ * Delete all of the specified resources, returning resource descriptions >+ * that can be used to restore them. >+ * >+ * This method is static to ensure "statelessness." Calling instance methods >+ * are responsible for maintaining the current state of resources and >+ * resource descriptions for the operation. >+ */ >+ protected static ResourceDescription[] delete( >+ IResource[] resourcesToDelete, IProgressMonitor monitor, >+ IAdaptable uiInfo, boolean deleteContent) throws CoreException { >+ final List exceptions = new ArrayList(); >+ ResourceDescription[] returnedResourceDescriptions = new ResourceDescription[resourcesToDelete.length]; >+ monitor >+ .beginTask( >+ UndoMessages.AbstractResourcesOperation_DeleteResourcesProgress, >+ 100 * resourcesToDelete.length); >+ try { >+ for (int i = 0; i < resourcesToDelete.length; ++i) { >+ if (monitor.isCanceled()) { >+ throw new OperationCanceledException(); >+ } >+ try { >+ IResource resource = resourcesToDelete[i]; >+ returnedResourceDescriptions[i] = delete(resource, >+ new SubProgressMonitor(monitor, 100), uiInfo, >+ false, deleteContent); >+ } catch (CoreException e) { >+ exceptions.add(e); >+ } >+ } >+ IStatus result = createResult(exceptions); >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ } finally { >+ monitor.done(); >+ } >+ return returnedResourceDescriptions; >+ } >+ >+ /* >+ * Recreate the resources from the specified resource descriptions. >+ * >+ * This method is static to ensure "statelessness." Calling instance methods >+ * are responsible for maintaining the current state of resources and >+ * resource descriptions for the operation. >+ */ >+ protected static IResource[] recreate( >+ ResourceDescription[] resourcesToRecreate, >+ IProgressMonitor monitor, IAdaptable uiInfo) throws CoreException { >+ final List exceptions = new ArrayList(); >+ IResource[] resourcesToReturn = new IResource[resourcesToRecreate.length]; >+ monitor.beginTask("", resourcesToRecreate.length); //$NON-NLS-1$ >+ try { >+ for (int i = 0; i < resourcesToRecreate.length; ++i) { >+ if (monitor.isCanceled()) { >+ throw new OperationCanceledException(); >+ } >+ try { >+ resourcesToReturn[i] = resourcesToRecreate[i] >+ .createResource(new SubProgressMonitor( >+ monitor, >+ 1, >+ SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); >+ } catch (CoreException e) { >+ exceptions.add(e); >+ } >+ } >+ IStatus result = createResult(exceptions); >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ } finally { >+ monitor.done(); >+ } >+ return resourcesToReturn; >+ } >+ >+ /* >+ * Delete the specified resource, recording enough information about it that >+ * it can be restored later. Return a ResourceDescription capable of >+ * restoring the resource. >+ * >+ * This method is static to ensure "statelessness." Calling instance methods >+ * are responsible for maintaining the current state of resources and >+ * resource descriptions for the operation. >+ */ >+ protected static ResourceDescription delete(IResource resourceToDelete, >+ IProgressMonitor monitor, IAdaptable uiInfo, >+ boolean forceOutOfSyncDelete, boolean deleteContent) >+ throws CoreException { >+ ResourceDescription resourceDescription = ResourceDescription >+ .fromResource(resourceToDelete); >+ try { >+ if (resourceToDelete.getType() == IResource.PROJECT) { >+ IProject project = (IProject) resourceToDelete; >+ project.delete(deleteContent, forceOutOfSyncDelete, monitor); >+ } else { >+ // if it's not a project, just delete it >+ monitor >+ .beginTask( >+ UndoMessages.AbstractResourcesOperation_DeleteResourcesProgress, >+ 100); >+ resourceToDelete.delete(IResource.KEEP_HISTORY, >+ new SubProgressMonitor(monitor, 50)); >+ resourceDescription.recordLastHistory(resourceToDelete, >+ new SubProgressMonitor(monitor, 50)); >+ monitor.done(); >+ } >+ } catch (CoreException exception) { >+ if (resourceToDelete.getType() == IResource.FILE) { >+ IStatus[] children = exception.getStatus().getChildren(); >+ >+ if (children.length == 1 >+ && children[0].getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) { >+ if (forceOutOfSyncDelete) { >+ resourceToDelete.delete(IResource.KEEP_HISTORY >+ | IResource.FORCE, new SubProgressMonitor( >+ monitor, 1)); >+ resourceDescription.recordLastHistory(resourceToDelete, >+ new SubProgressMonitor(monitor, 1)); >+ } else { >+ int result = queryDeleteOutOfSync(resourceToDelete, >+ uiInfo); >+ >+ if (result == IDialogConstants.YES_ID) { >+ resourceToDelete.delete(IResource.KEEP_HISTORY >+ | IResource.FORCE, new SubProgressMonitor( >+ monitor, 1)); >+ resourceDescription.recordLastHistory( >+ resourceToDelete, new SubProgressMonitor( >+ monitor, 1)); >+ } else if (result == IDialogConstants.YES_TO_ALL_ID) { >+ forceOutOfSyncDelete = true; >+ resourceToDelete.delete(IResource.KEEP_HISTORY >+ | IResource.FORCE, new SubProgressMonitor( >+ monitor, 1)); >+ resourceDescription.recordLastHistory( >+ resourceToDelete, new SubProgressMonitor( >+ monitor, 1)); >+ >+ } else if (result == IDialogConstants.CANCEL_ID) { >+ throw new OperationCanceledException(); >+ } >+ } >+ } else { >+ throw exception; >+ } >+ } else { >+ throw exception; >+ } >+ } >+ return resourceDescription; >+ } >+ >+ /** >+ * Ask the user whether the given resource should be deleted despite being >+ * out of sync with the file system. >+ * >+ * @param resource >+ * the out of sync resource >+ * @param uiInfo >+ * an adaptable describing the ui info for this operation >+ * @return One of the IDialogConstants constants indicating which of the >+ * Yes, Yes to All, No, Cancel options has been selected by the >+ * user. >+ */ >+ private static int queryDeleteOutOfSync(IResource resource, >+ IAdaptable uiInfo) { >+ Shell shell = null; >+ if (uiInfo != null) { >+ shell = (Shell) uiInfo.getAdapter(Shell.class); >+ } >+ if (shell == null) { >+ shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() >+ .getShell(); >+ } >+ final MessageDialog dialog = new MessageDialog( >+ shell, >+ UndoMessages.AbstractResourcesOperation_deletionMessageTitle, >+ null, >+ NLS >+ .bind( >+ UndoMessages.AbstractResourcesOperation_outOfSyncQuestion, >+ resource.getName()), MessageDialog.QUESTION, >+ new String[] { IDialogConstants.YES_LABEL, >+ IDialogConstants.YES_TO_ALL_LABEL, >+ IDialogConstants.NO_LABEL, >+ IDialogConstants.CANCEL_LABEL }, 0); >+ shell.getDisplay().syncExec(new Runnable() { >+ public void run() { >+ dialog.open(); >+ } >+ }); >+ int result = dialog.getReturnCode(); >+ if (result == 0) { >+ return IDialogConstants.YES_ID; >+ } >+ if (result == 1) { >+ return IDialogConstants.YES_TO_ALL_ID; >+ } >+ if (result == 2) { >+ return IDialogConstants.NO_ID; >+ } >+ return IDialogConstants.CANCEL_ID; >+ } >+ >+ /** >+ * Creates and returns a result status appropriate for the given list of >+ * exceptions. >+ * >+ * @param exceptions >+ * The list of exceptions that occurred (may be empty) >+ * @return The result status for the deletion >+ */ >+ private static IStatus createResult(List exceptions) { >+ if (exceptions.isEmpty()) { >+ return Status.OK_STATUS; >+ } >+ final int exceptionCount = exceptions.size(); >+ if (exceptionCount == 1) { >+ return ((CoreException) exceptions.get(0)).getStatus(); >+ } >+ CoreException[] children = (CoreException[]) exceptions >+ .toArray(new CoreException[exceptionCount]); >+ boolean outOfSync = false; >+ for (int i = 0; i < children.length; i++) { >+ if (children[i].getStatus().getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) { >+ outOfSync = true; >+ break; >+ } >+ } >+ String title = outOfSync ? UndoMessages.AbstractResourcesOperation_outOfSyncError >+ : UndoMessages.AbstractResourcesOperation_deletionExceptionMessage; >+ final MultiStatus multi = new MultiStatus( >+ IDEWorkbenchPlugin.IDE_WORKBENCH, 0, title, null); >+ for (int i = 0; i < exceptionCount; i++) { >+ CoreException exception = children[i]; >+ IStatus status = exception.getStatus(); >+ multi.add(new Status(status.getSeverity(), status.getPlugin(), >+ status.getCode(), status.getMessage(), exception)); >+ } >+ return multi; >+ } >+ >+ ResourceDescription[] resourceDescriptions; >+ >+ /** >+ * Create an Abstract Resources Operation >+ * >+ * @param resources >+ * the resources to be modified >+ * @param label >+ * the label of the operation >+ */ >+ AbstractResourcesOperation(IResource[] resources, String label) { >+ super(label); >+ this.addContext(WorkspaceUndoSupport.getWorkspaceUndoContext()); >+ >+ setTargetResources(resources); >+ } >+ >+ /** >+ * Create an Abstract Resources Operation >+ * >+ * @param resourceDescriptions >+ * the resourceDescriptions describing resources to be created >+ * @param label >+ * the label of the operation >+ */ >+ AbstractResourcesOperation(ResourceDescription[] resourceDescriptions, >+ String label) { >+ super(label); >+ this.addContext(WorkspaceUndoSupport.getWorkspaceUndoContext()); >+ this.resourceDescriptions = resourceDescriptions; >+ } >+ >+ /* >+ * Return the first resource in the list of resources. Used by subclasses >+ * that only operate on a single resource. >+ */ >+ protected IResource getResource() { >+ if (resources == null || resources.length == 0) { >+ return null; >+ } >+ return resources[0]; >+ } >+ >+ protected void delete(IProgressMonitor monitor, IAdaptable uiInfo, >+ boolean deleteContent) throws CoreException { >+ resourceDescriptions = AbstractResourcesOperation.delete(resources, >+ monitor, uiInfo, deleteContent); >+ resources = new IResource[0]; >+ } >+ >+ protected void recreate(IProgressMonitor monitor, IAdaptable uiInfo) >+ throws CoreException { >+ resources = AbstractResourcesOperation.recreate(resourceDescriptions, >+ monitor, uiInfo); >+ resourceDescriptions = new ResourceDescription[0]; >+ } >+ >+ protected void move(IResource resource, IPath newPath, >+ IProgressMonitor monitor, IAdaptable uiInfo) throws CoreException { >+ monitor.beginTask( >+ UndoMessages.AbstractResourcesOperation_MovingResources, 400); >+ IWorkspaceRoot workspaceRoot = resource.getWorkspace().getRoot(); >+ // Are there any files to be restored after the move? >+ ResourceDescription[] resourcesToRestore = null; >+ if (resourceDescriptions != null) { >+ resourcesToRestore = new ResourceDescription[resourceDescriptions.length]; >+ System.arraycopy(resourceDescriptions, 0, resourcesToRestore, 0, >+ resourceDescriptions.length); >+ } >+ // Now we consider resourceDescriptions to describe the resources >+ // to be restored later if this move is reversed. >+ resourceDescriptions = null; >+ // Some moves are optimized and recorded as complete in this flag >+ boolean moved = false; >+ >+ IResource newResource = workspaceRoot.findMember(newPath); >+ // If it already exists, we must overwrite it. >+ if (newResource != null) { >+ if (resource.getType() == IResource.FILE >+ && newResource.getType() == IResource.FILE) { >+ // File on file overwrite is optimized as a reset of the >+ // target file's contents >+ IFile file = (IFile) resource; >+ IFile existingFile = (IFile) newResource; >+ if (validateEdit(file, existingFile, getShell(uiInfo))) { >+ // Remember the state of the existing file so it can be >+ // restored. >+ FileDescription fileDescription = new FileDescription( >+ existingFile); >+ resourceDescriptions = new ResourceDescription[1]; >+ resourceDescriptions[0] = fileDescription; >+ // Reset the contents to that of the file being moved >+ existingFile.setContents(file.getContents(), >+ IResource.KEEP_HISTORY, new SubProgressMonitor( >+ monitor, 100)); >+ fileDescription.recordLastHistory(existingFile, >+ new SubProgressMonitor(monitor, 100)); >+ // Now delete the file that was renamed >+ file.delete(IResource.KEEP_HISTORY, new SubProgressMonitor( >+ monitor, 100)); >+ } >+ moved = true; >+ } else { >+ // Any other overwrite is simply a delete followed by the move >+ resourceDescriptions = delete(new IResource[] { newResource }, >+ new SubProgressMonitor(monitor, 100), uiInfo, true); >+ } >+ } else { >+ monitor.worked(100); >+ } >+ // Overwrites have been handled. If there is still a move to do, do so >+ // now. >+ if (!moved) { >+ if (resource.getType() == IResource.PROJECT) { >+ IProject project = (IProject) resource; >+ IProjectDescription description = project.getDescription(); >+ description.setName(newPath.segment(0)); >+ project.move(description, IResource.FORCE | IResource.SHALLOW, >+ new SubProgressMonitor(monitor, 200)); >+ } else { >+ resource.move(newPath, IResource.KEEP_HISTORY >+ | IResource.SHALLOW, new SubProgressMonitor(monitor, >+ 200)); >+ >+ } >+ } >+ >+ // Are there any previously overwritten resources to restore? >+ if (resourcesToRestore != null) { >+ for (int i = 0; i < resourcesToRestore.length; i++) { >+ resourcesToRestore[i].createResource(new SubProgressMonitor( >+ monitor, 100 / resourcesToRestore.length)); >+ } >+ } >+ setTargetResources(new IResource[] { getWorkspace().getRoot() >+ .findMember(newPath) }); >+ >+ monitor.done(); >+ } >+ >+ /** >+ * Validates the destination file if it is read-only and additionally the >+ * source file if both are read-only. Returns true if both files could be >+ * made writeable. >+ * >+ * @param source >+ * source file >+ * @param destination >+ * destination file >+ * @param shell >+ * ui context for the validation >+ * @return boolean <code>true</code> both files could be made writeable. >+ * <code>false</code> either one or both files were not made >+ * writeable >+ */ >+ protected boolean validateEdit(IFile source, IFile destination, Shell shell) { >+ if (destination.isReadOnly()) { >+ IWorkspace workspace = getWorkspace(); >+ IStatus status; >+ if (source.isReadOnly()) { >+ status = workspace.validateEdit(new IFile[] { source, >+ destination }, shell); >+ } else { >+ status = workspace.validateEdit(new IFile[] { destination }, >+ shell); >+ } >+ return status.isOK(); >+ } >+ return true; >+ } >+ >+ /* >+ * Compute the status for creating resources from the descriptions. >+ * >+ * Note this method may be called on initial creation of a resource, or when >+ * a create or delete operation is being undone or redone. Therefore, this >+ * method should check conditions that can change over the life of the >+ * operation, such as the existence of the information needed to carry out >+ * the operation. One-time static checks should typically be done by the >+ * caller (such as the action that creates the operation) so that the user >+ * is not continually prompted or warned about conditions that were >+ * acceptable at the time of original execution. >+ */ >+ protected IStatus computeCreateStatus() { >+ if (resourceDescriptions == null || resourceDescriptions.length == 0) { >+ markInvalid(); >+ return getErrorStatus(UndoMessages.AbstractResourcesOperation_NotEnoughInfo); >+ } >+ for (int i = 0; i < resourceDescriptions.length; i++) { >+ if (!resourceDescriptions[i].isValid()) { >+ markInvalid(); >+ return getErrorStatus(UndoMessages.AbstractResourcesOperation_InvalidRestoreInfo); >+ } >+ } >+ return Status.OK_STATUS; >+ } >+ >+ /* >+ * Compute the status for deleting resources. >+ * >+ * Note this method may be called on initial deletion of a resource, or when >+ * a create or delete operation is being undone or redone. Therefore, this >+ * method should check conditions that can change over the life of the >+ * operation, such as the existence of the resources to be deleted. One-time >+ * static checks should typically be done by the caller (such as the action >+ * that creates the operation) so that the user is not continually prompted >+ * or warned about conditions that were acceptable at the time of original >+ * execution. >+ */ >+ >+ protected IStatus computeDeleteStatus() { >+ if (resources == null || resources.length == 0) { >+ markInvalid(); >+ return getErrorStatus(UndoMessages.AbstractResourcesOperation_NotEnoughInfo); >+ } >+ if (!resourcesExist()) { >+ markInvalid(); >+ return getErrorStatus(UndoMessages.AbstractResourcesOperation_ResourcesDoNotExist); >+ } >+ return Status.OK_STATUS; >+ } >+} >Index: src/org/eclipse/ui/ide/undo/CreateFolderOperation.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/CreateFolderOperation.java >diff -N src/org/eclipse/ui/ide/undo/CreateFolderOperation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/ide/undo/CreateFolderOperation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,61 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.ide.undo; >+ >+import org.eclipse.core.resources.IFolder; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.ui.internal.ide.undo.ContainerDescription; >+import org.eclipse.ui.internal.ide.undo.FolderDescription; >+import org.eclipse.ui.internal.ide.undo.ResourceDescription; >+ >+/** >+ * A CreateFolderOperation represents an undoable operation for creating a >+ * folder in the workspace. If a link location is specified, the folder is >+ * considered to be linked to the specified location. If a link location is not >+ * specified, the folder will be created in the location specified by the >+ * handle, and the entire containment path of the folder will be created if it >+ * does not exist. >+ * >+ * This class is intended to be instantiated and used by clients. It is not >+ * intended to be subclassed by clients. >+ * >+ * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >+ * of a work in progress. This API may change at any given time. Please do not >+ * use this API without consulting with the Platform/UI team. >+ * >+ * @since 3.3 >+ * >+ */ >+public class CreateFolderOperation extends AbstractCreateResourcesOperation { >+ >+ /** >+ * Create a CreateFolderOperation >+ * >+ * @param folderHandle >+ * the folder to be created >+ * @param linkLocation >+ * the location of the folder if it is to be linked >+ * @param label >+ * the label of the operation >+ */ >+ public CreateFolderOperation(IFolder folderHandle, IPath linkLocation, String label) { >+ super(null, label); >+ ContainerDescription containerDescription; >+ if (linkLocation == null) { >+ containerDescription = ContainerDescription.fromContainer(folderHandle); >+ } else { >+ // create a linked folder description >+ containerDescription = new FolderDescription(folderHandle, linkLocation); >+ } >+ resourceDescriptions = new ResourceDescription[ ] {containerDescription}; >+ } >+} >Index: src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java >=================================================================== >RCS file: src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java >diff -N src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/internal/ide/undo/ContainerDescription.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,208 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.internal.ide.undo; >+ >+import org.eclipse.core.resources.IContainer; >+import org.eclipse.core.resources.IFile; >+import org.eclipse.core.resources.IFolder; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.IWorkspaceRoot; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IPath; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.Path; >+import org.eclipse.core.runtime.SubProgressMonitor; >+ >+/** >+ * ContainerDescription is a lightweight description that describes a container >+ * to be created. >+ * >+ * This class is not intended to be instantiated or used by clients. >+ * >+ * @since 3.3 >+ * >+ */ >+public abstract class ContainerDescription extends ResourceDescription { >+ >+ String name; >+ >+ IPath location; >+ >+ private ResourceDescription[] members; >+ >+ /* >+ * Create a container description from the specified container handle that >+ * can be used to create the container. The returned ContainerDescription >+ * should represent any non-existing parents in addition to the specified >+ * container. >+ */ >+ >+ public static ContainerDescription fromContainer(IContainer container) { >+ IPath fullPath = container.getFullPath(); >+ ContainerDescription firstCreatedParent = null; >+ ContainerDescription currentContainerDescription = null; >+ >+ // Does the container exist already? If so, then the parent exists and >+ // we use the normal creation constructor. >+ IWorkspaceRoot root = getWorkspaceRoot(); >+ IContainer currentContainer = (IContainer) root.findMember(fullPath); >+ if (container != null) { >+ return (ContainerDescription)ResourceDescription.fromResource(container); >+ } >+ >+ // Create container descriptions for any uncreated parents in the given >+ // path. >+ currentContainer = root; >+ for (int i = 0; i < fullPath.segmentCount(); i++) { >+ String currentSegment = fullPath.segment(i); >+ IResource resource = currentContainer.findMember(currentSegment); >+ if (resource != null) { >+ // parent already exists, no need to create a description for it >+ currentContainer = (IContainer)resource; >+ } else { >+ if (i == 0) { >+ // parent does not exist and it is a project >+ firstCreatedParent = new ProjectDescription(root.getProject(currentSegment)); >+ currentContainerDescription = firstCreatedParent; >+ } else { >+ IFolder folderHandle = currentContainer.getFolder(new Path(currentSegment)); >+ ContainerDescription currentFolder = new FolderDescription(folderHandle); >+ currentContainer = folderHandle; >+ if (currentContainerDescription != null) { >+ currentContainerDescription.addMember(currentFolder); >+ } >+ currentContainerDescription = currentFolder; >+ if (firstCreatedParent == null) { >+ firstCreatedParent = currentFolder; >+ } >+ } >+ } >+ } >+ return firstCreatedParent; >+ } >+ >+ /* >+ * Create a ContainerDescription with no state. >+ */ >+ public ContainerDescription() { >+ >+ } >+ >+ /* >+ * Create a ContainerDescription from the specified container handle. >+ * Typically used when the container handle represents a resource that >+ * actually exists, although it will not fail if the resource is >+ * non-existent. >+ */ >+ public ContainerDescription(IContainer container) { >+ super(container); >+ this.name = container.getName(); >+ if (container.isLinked()) { >+ this.location = container.getLocation(); >+ } >+ try { >+ if (container.exists()) { >+ IResource[] resourceMembers = container.members(); >+ members = new ResourceDescription[resourceMembers.length]; >+ for (int i = 0; i < resourceMembers.length; i++) { >+ members[i] = ResourceDescription >+ .fromResource(resourceMembers[i]); >+ } >+ } >+ } catch (CoreException e) { >+ // Eat this exception because it only occurs when the resource >+ // does not exist and we have already checked this. >+ // We do not want to throw exceptions on the simple constructor, as >+ // no one has actually tried to do anything yet. >+ } >+ } >+ >+ public IResource createResourceHandle() { >+ IWorkspaceRoot workspaceRoot = parent.getWorkspace().getRoot(); >+ IPath folderPath = parent.getFullPath().append(name); >+ return workspaceRoot.getFolder(folderPath); >+ } >+ >+ protected void createChildResources(IContainer parentHandle, >+ IProgressMonitor monitor, int ticks) throws CoreException { >+ >+ // restore any children >+ if (members != null && members.length > 0) { >+ for (int i = 0; i < members.length; i++) { >+ members[i].parent = parentHandle; >+ members[i].createResource(new SubProgressMonitor(monitor, ticks >+ / members.length)); >+ } >+ } >+ } >+ >+ public void recordLastHistory(IResource resource, IProgressMonitor monitor) >+ throws CoreException { >+ monitor.beginTask( >+ UndoMessages.FolderDescription_SavingUndoInfoProgress, 100); >+ for (int i = 0; i < members.length; i++) { >+ if (members[i] instanceof FileDescription) { >+ IPath path = resource.getFullPath().append( >+ ((FileDescription) members[i]).name); >+ IFile fileHandle = resource.getWorkspace().getRoot().getFile( >+ path); >+ members[i].recordLastHistory(fileHandle, >+ new SubProgressMonitor(monitor, 100 / members.length)); >+ } else if (members[i] instanceof FolderDescription) { >+ IPath path = resource.getFullPath().append( >+ ((FolderDescription) members[i]).name); >+ IFolder folderHandle = resource.getWorkspace().getRoot() >+ .getFolder(path); >+ members[i].recordLastHistory(folderHandle, >+ new SubProgressMonitor(monitor, 100 / members.length)); >+ } >+ } >+ monitor.done(); >+ } >+ >+ public String getName() { >+ return name; >+ } >+ >+ /* >+ * Return the first folder found that has no child folders. >+ */ >+ public ContainerDescription getFirstLeafFolder() { >+ // If there are no members, this is a leaf >+ if (members == null || members.length == 0) { >+ return this; >+ } >+ // Traverse the members and find the first potential leaf >+ for (int i = 0; i < members.length; i++) { >+ if (members[i] instanceof ContainerDescription) { >+ return ((ContainerDescription) members[i]).getFirstLeafFolder(); >+ } >+ } >+ // No child folders were found, this is a leaf >+ return this; >+ } >+ >+ /* >+ * Add the specified resource description as a member of this resource >+ * description >+ */ >+ public void addMember(ResourceDescription member) { >+ if (members == null) { >+ members = new ResourceDescription[] { member }; >+ } else { >+ ResourceDescription[] expandedMembers = new ResourceDescription[members.length + 1]; >+ System.arraycopy(members, 0, expandedMembers, 0, members.length); >+ expandedMembers[members.length] = member; >+ members = expandedMembers; >+ } >+ } >+} >Index: src/org/eclipse/ui/ide/undo/CreateProjectOperation.java >=================================================================== >RCS file: src/org/eclipse/ui/ide/undo/CreateProjectOperation.java >diff -N src/org/eclipse/ui/ide/undo/CreateProjectOperation.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/ide/undo/CreateProjectOperation.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,65 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.ide.undo; >+ >+import org.eclipse.core.resources.IProjectDescription; >+import org.eclipse.core.resources.IResourceStatus; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.osgi.util.NLS; >+import org.eclipse.ui.internal.ide.undo.ProjectDescription; >+import org.eclipse.ui.internal.ide.undo.UndoMessages; >+ >+/** >+ * A CreateProjectOperation represents an undoable operation for creating a >+ * project in the workspace. >+ * >+ * This class is intended to be instantiated and used by clients. It is not >+ * intended to be subclassed by clients. >+ * >+ * <strong>EXPERIMENTAL</strong> This class or interface has been added as part >+ * of a work in progress. This API may change at any given time. Please do not >+ * use this API without consulting with the Platform/UI team. >+ * >+ * @since 3.3 >+ * >+ */ >+public class CreateProjectOperation extends AbstractCreateResourcesOperation { >+ >+ /** >+ * Create a CreateProjectOperation >+ * >+ * @param projectDescription >+ * the project to be created >+ * @param label >+ * the label of the operation >+ */ >+ public CreateProjectOperation(IProjectDescription projectDescription, >+ String label) { >+ super(new ProjectDescription[] { new ProjectDescription( >+ projectDescription) }, label); >+ } >+ >+ /** >+ * Return the specific error message to use when the specified core >+ * exception occurs, or <code>null</code> to indicate that the the >+ * exception's message should be used. >+ */ >+ protected String getErrorMessage(CoreException e) { >+ if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { >+ if (resourceDescriptions != null && resourceDescriptions.length==1) { >+ ProjectDescription project = (ProjectDescription)resourceDescriptions[0]; >+ return NLS.bind(UndoMessages.CreateProjectOperation_caseVariantExistsError, project.getName()); >+ } >+ } >+ return super.getErrorMessage(e); >+ } >+} >Index: src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java >=================================================================== >RCS file: src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java >diff -N src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/internal/ide/undo/ProjectDescription.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,91 @@ >+/******************************************************************************* >+ * Copyright (c) 2006 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.ui.internal.ide.undo; >+ >+import org.eclipse.core.resources.IProject; >+import org.eclipse.core.resources.IProjectDescription; >+import org.eclipse.core.resources.IResource; >+import org.eclipse.core.resources.ResourcesPlugin; >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.core.runtime.CoreException; >+import org.eclipse.core.runtime.IProgressMonitor; >+import org.eclipse.core.runtime.OperationCanceledException; >+import org.eclipse.core.runtime.SubProgressMonitor; >+ >+/** >+ * ProjectDescription is a lightweight description that describes a project to >+ * be created. >+ * >+ * This class is not intended to be instantiated or used by clients. >+ * >+ * @since 3.3 >+ * >+ */ >+public class ProjectDescription extends ContainerDescription { >+ >+ private IProjectDescription projectDescription; >+ >+ /* >+ * Create a project description from a specified project. Used only when the >+ * project exists and is open. >+ */ >+ public ProjectDescription(IProject project) { >+ super(project); >+ Assert.isLegal(project.exists() && project.isOpen()); >+ try { >+ this.projectDescription = project.getDescription(); >+ } catch (CoreException e) { >+ // Eat this exception because it only occurs when the project >+ // does not exist or is not open, and we have already checked this. >+ // We do not want to throw exceptions on the simple constructor, as >+ // no one has actually tried to do anything yet. >+ } >+ } >+ >+ /* >+ * Create a project description from a specified IProjectDescription. Used >+ * when the project does not yet exist. >+ */ >+ public ProjectDescription(IProjectDescription projectDescription) { >+ super(); >+ this.projectDescription = projectDescription; >+ } >+ >+ public IResource createResourceHandle() { >+ return ResourcesPlugin.getWorkspace().getRoot().getProject(getName()); >+ } >+ >+ protected void createExistentResourceFromHandle(IResource resource, >+ IProgressMonitor monitor) throws CoreException { >+ Assert.isLegal(resource instanceof IProject); >+ IProject projectHandle = (IProject) resource; >+ monitor.beginTask(UndoMessages.ProjectDescription_NewProjectProgress, >+ 200); >+ if (projectDescription == null) { >+ projectHandle.create(new SubProgressMonitor(monitor, 100)); >+ } else { >+ projectHandle.create(projectDescription, new SubProgressMonitor( >+ monitor, 100)); >+ } >+ >+ if (monitor.isCanceled()) { >+ throw new OperationCanceledException(); >+ } >+ projectHandle.open(IResource.BACKGROUND_REFRESH, >+ new SubProgressMonitor(monitor, 100)); >+ monitor.done(); >+ } >+ >+ public String getName() { >+ return projectDescription.getName(); >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 123674
:
33180
|
33183
|
50409
|
51185
|
51440