diff options
8 files changed, 185 insertions, 60 deletions
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddAction.java index 6885bac2e..cabb2f2a6 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/AddAction.java @@ -17,7 +17,6 @@ import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.team.internal.ccvs.core.CVSException; import org.eclipse.team.internal.ccvs.core.ICVSResource; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.ui.CVSUIMessages; import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; import org.eclipse.team.internal.ccvs.ui.operations.AddOperation; @@ -47,7 +46,7 @@ public class AddAction extends WorkspaceTraversalAction { IResource[] resources = getSelectedResourcesWithOverlap(); boolean prompt = false; for (int i = 0; i < resources.length; i++) { - ICVSResource resource = CVSWorkspaceRoot.getCVSResourceFor(resources[i]); + ICVSResource resource = getCVSResourceFor(resources[i]); try { if (resource.isIgnored()) { prompt = true; diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java index 7f870004d..bffdcdffa 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSAction.java @@ -579,7 +579,11 @@ abstract public class CVSAction extends TeamAction implements IEditorActionDeleg * @see org.eclipse.team.internal.ui.actions.TeamAction#getSelectedResources() */ protected IResource[] getSelectedResources() { - return Utils.getResources(selection.toArray()); + CVSActionSelectionProperties props = CVSActionSelectionProperties.getProperties(getSelection()); + if (props == null) { + return Utils.getResources(selection.toArray()); + } + return props.getSelectedResources(); } /* (non-Javadoc) @@ -661,4 +665,12 @@ abstract public class CVSAction extends TeamAction implements IEditorActionDeleg } public void addHandlerListener(IHandlerListener handlerListener) { } + + protected final ICVSResource getCVSResourceFor(IResource resource) { + CVSActionSelectionProperties props = CVSActionSelectionProperties.getProperties(getSelection()); + if (props == null) { + return CVSWorkspaceRoot.getCVSResourceFor(resource); + } + return props.getCVSResourceFor(resource); + } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSActionSelectionProperties.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSActionSelectionProperties.java new file mode 100644 index 000000000..0b311d43e --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/CVSActionSelectionProperties.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 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.team.internal.ccvs.ui.actions; + +import java.util.*; + +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.team.internal.ccvs.core.ICVSResource; +import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.eclipse.team.internal.ui.Utils; + +/** + * This class represents a selection for a set of CVS actions. + */ +public class CVSActionSelectionProperties { + + // Use a weak hash map so that the properties ae collected when the selection is no longer referenced + private static Map selectionProperties = new WeakHashMap(); + + private IStructuredSelection selection; + private Map properties = new HashMap(); + + private static final String SELECTED_RESOURCES = "selectedResources"; //$NON-NLS-1$ + private static final String NONOVERLAPPING_SELECTED_RESOURCES = "nonoverlappingSelectedResources"; //$NON-NLS-1$ + private static final String CVS_RESOURCE_MAP = "cvsResourceMap"; //$NON-NLS-1$ + + public static CVSActionSelectionProperties getProperties(IStructuredSelection selection) { + if (selection == null) return null; + CVSActionSelectionProperties props = (CVSActionSelectionProperties)selectionProperties.get(selection); + if (props == null) { + props = new CVSActionSelectionProperties(selection); + selectionProperties.put(props.getSelection(), props); + } + return props; + } + + public CVSActionSelectionProperties(IStructuredSelection selection) { + this.selection = selection; + } + + public IStructuredSelection getSelection() { + return selection; + } + + public void put(String key, Object value) { + properties.put(key, value); + } + + public Object get(String key) { + return properties.get(key); + } + + public IResource[] getSelectedResources() { + IResource[] resources = (IResource[])get(SELECTED_RESOURCES); + if (resources == null) { + resources = Utils.getResources(selection.toArray()); + put(SELECTED_RESOURCES, resources); + } + return resources; + } + + public IResource[] getNonoverlappingSelectedResources() { + IResource[] resources = (IResource[])get(NONOVERLAPPING_SELECTED_RESOURCES); + if (resources == null) { + resources = getNonOverlapping(getSelectedResources()); + put (NONOVERLAPPING_SELECTED_RESOURCES, resources); + } + return resources; + } + + public ICVSResource getCVSResourceFor(IResource resource) { + Map map = (Map)get(CVS_RESOURCE_MAP); + if (map == null) { + map = new HashMap(); + put(CVS_RESOURCE_MAP, map); + } + ICVSResource cvsResource = (ICVSResource)map.get(resource); + if (cvsResource == null) { + cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); + map.put(resource, cvsResource); + } + return cvsResource; + } + + /** + * Method getNonOverlapping ensures that a resource is not covered more than once. + * @param resources + * @return IResource[] + */ + public static IResource[] getNonOverlapping(IResource[] resources) { + // Sort the resources so the shortest paths are first + List sorted = new ArrayList(); + sorted.addAll(Arrays.asList(resources)); + Collections.sort(sorted, new Comparator() { + public int compare(Object arg0, Object arg1) { + IResource resource0 = (IResource) arg0; + IResource resource1 = (IResource) arg1; + return resource0.getFullPath().segmentCount() - resource1.getFullPath().segmentCount(); + } + public boolean equals(Object arg0) { + return false; + } + }); + // Collect all non-overlapping resources + List coveredPaths = new ArrayList(); + for (Iterator iter = sorted.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + IPath resourceFullPath = resource.getFullPath(); + boolean covered = false; + for (Iterator it = coveredPaths.iterator(); it.hasNext();) { + IPath path = (IPath) it.next(); + if(path.isPrefixOf(resourceFullPath)) { + covered = true; + } + } + if (covered) { + // if the resource is covered by a parent, remove it + iter.remove(); + } else { + // if the resource is a non-covered folder, add it to the covered paths + if (resource.getType() == IResource.FOLDER) { + coveredPaths.add(resource.getFullPath()); + } + } + } + return (IResource[]) sorted.toArray(new IResource[sorted.size()]); + } + +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/IgnoreAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/IgnoreAction.java index ebea13f0e..343af1b9f 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/IgnoreAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/IgnoreAction.java @@ -21,9 +21,7 @@ import org.eclipse.osgi.util.NLS; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.internal.ccvs.core.*; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.ui.*; -import org.eclipse.team.internal.ccvs.ui.IgnoreResourcesDialog; import org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation; import org.eclipse.ui.IWorkbenchPart; @@ -59,7 +57,7 @@ public class IgnoreAction extends WorkspaceTraversalAction { for (int i = 0; i < resources.length; i++) { IResource resource = resources[i]; String pattern = dialog.getIgnorePatternFor(resource); - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); + ICVSResource cvsResource = getCVSResourceFor(resource); cvsResource.setIgnoredAs(pattern); monitor.worked(1); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java index a65467283..eccc81c3f 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/ShowAnnotationAction.java @@ -19,7 +19,6 @@ import org.eclipse.osgi.util.NLS; import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.listeners.LogEntry; -import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.ui.CVSUIMessages; import org.eclipse.team.internal.ccvs.ui.ICVSUIConstants; @@ -104,7 +103,7 @@ public class ShowAnnotationAction extends WorkspaceAction { // Selected from a Resource Navigator final IResource[] resources = getSelectedResources(); if (resources.length == 1) { - return CVSWorkspaceRoot.getCVSResourceFor(resources[0]); + return getCVSResourceFor(resources[0]); } return null; } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java index d9b34ffa2..95b7d7ff1 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceAction.java @@ -31,6 +31,7 @@ import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; import org.eclipse.team.internal.ccvs.core.util.Util; import org.eclipse.team.internal.ccvs.ui.CVSUIMessages; import org.eclipse.team.internal.ccvs.ui.Policy; +import org.eclipse.team.internal.ui.actions.TeamAction; import org.eclipse.team.internal.ui.dialogs.IPromptCondition; import org.eclipse.team.internal.ui.dialogs.PromptingDialog; @@ -322,7 +323,7 @@ public abstract class WorkspaceAction extends CVSAction { } // ensure that resource management state matches what the action requires - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); + ICVSResource cvsResource = getCVSResourceFor(resource); if (!isEnabledForCVSResource(cvsResource)) { return false; } @@ -342,8 +343,8 @@ public abstract class WorkspaceAction extends CVSAction { } return true; } - - /** + + /** * Return all the selected resources even if some overlap with others. * @return all the selected resources even if some overlap with others. */ @@ -426,57 +427,17 @@ public abstract class WorkspaceAction extends CVSAction { } /** - * Method getNonOverlapping ensures that a resource is not covered more than once. - * @param resources - * @return IResource[] - */ - public static IResource[] getNonOverlapping(IResource[] resources) { - // Sort the resources so the shortest paths are first - List sorted = new ArrayList(); - sorted.addAll(Arrays.asList(resources)); - Collections.sort(sorted, new Comparator() { - public int compare(Object arg0, Object arg1) { - IResource resource0 = (IResource) arg0; - IResource resource1 = (IResource) arg1; - return resource0.getFullPath().segmentCount() - resource1.getFullPath().segmentCount(); - } - public boolean equals(Object arg0) { - return false; - } - }); - // Collect all non-overlapping resources - List coveredPaths = new ArrayList(); - for (Iterator iter = sorted.iterator(); iter.hasNext();) { - IResource resource = (IResource) iter.next(); - IPath resourceFullPath = resource.getFullPath(); - boolean covered = false; - for (Iterator it = coveredPaths.iterator(); it.hasNext();) { - IPath path = (IPath) it.next(); - if(path.isPrefixOf(resourceFullPath)) { - covered = true; - } - } - if (covered) { - // if the resource is covered by a parent, remove it - iter.remove(); - } else { - // if the resource is a non-covered folder, add it to the covered paths - if (resource.getType() == IResource.FOLDER) { - coveredPaths.add(resource.getFullPath()); - } - } - } - return (IResource[]) sorted.toArray(new IResource[sorted.size()]); - } - - /** * Override to ensure that the selected resources so not overlap. * This method assumes that all actions are deep. * * @see org.eclipse.team.internal.ui.actions.TeamAction#getSelectedResources() */ protected final IResource[] getSelectedResources() { - return getNonOverlapping(getSelectedResourcesWithOverlap()); + CVSActionSelectionProperties props = CVSActionSelectionProperties.getProperties(getSelection()); + if (props == null) { + return CVSActionSelectionProperties.getNonOverlapping(getSelectedResourcesWithOverlap()); + } + return props.getNonoverlappingSelectedResources(); } protected void executeProviderAction(IProviderAction action, IResource[] resources, IProgressMonitor monitor) throws InvocationTargetException { @@ -516,7 +477,7 @@ public abstract class WorkspaceAction extends CVSAction { boolean multipleSameNames = true; for (int i = 0; i < resources.length; i++) { - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resources[i]); + ICVSResource cvsResource = getCVSResourceFor(resources[i]); CVSTag tag = null; if(cvsResource.isFolder()) { FolderSyncInfo info = ((ICVSFolder)cvsResource).getFolderSyncInfo(); @@ -585,7 +546,7 @@ public abstract class WorkspaceAction extends CVSAction { monitor.setTaskName(CVSUIMessages.ReplaceWithAction_calculatingDirtyResources); //$NON-NLS-1$ for (int i = 0; i < selectedResources.length; i++) { IResource resource = selectedResources[i]; - ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); + ICVSResource cvsResource = getCVSResourceFor(resource); if(cvsResource.isModified(Policy.subMonitorFor(monitor, 100))) { dirtyResources.add(resource); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceTraversalAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceTraversalAction.java index 482d134a9..3fa9c3afb 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceTraversalAction.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/actions/WorkspaceTraversalAction.java @@ -34,6 +34,8 @@ import org.eclipse.ui.PlatformUI; */ public abstract class WorkspaceTraversalAction extends WorkspaceAction { + private static final String SELECTED_RESOURCES_WITH_OVERLAP = "selectedResourcesWithOverlap"; //$NON-NLS-1$ + /** * Override to use the roots of the traversals as the selected resources. * On it's own, this would be enough to make the actions work but all the operations @@ -42,11 +44,21 @@ public abstract class WorkspaceTraversalAction extends WorkspaceAction { * @see org.eclipse.team.internal.ccvs.ui.actions.WorkspaceAction#getSelectedResources() */ protected IResource[] getSelectedResourcesWithOverlap() { + // First, look in the cache for the selection + CVSActionSelectionProperties props = CVSActionSelectionProperties.getProperties(getSelection()); + if (props != null) { + IResource[] resources = (IResource[])props.get(SELECTED_RESOURCES_WITH_OVERLAP); + if (resources != null) + return resources; + } try { // Get all the traversals since enablement may be based on entire selection ResourceTraversal[] traversals = getSelectedTraversals(ResourceMappingContext.LOCAL_CONTEXT, null); if (traversals.length == 0 && selection != null) { - return Utils.getResources(selection.toArray()); + if (props == null) { + return Utils.getResources(selection.toArray()); + } + return props.getSelectedResources(); } Set resources = new HashSet(); for (int i = 0; i < traversals.length; i++) { @@ -60,7 +72,11 @@ public abstract class WorkspaceTraversalAction extends WorkspaceAction { } } } - return (IResource[]) resources.toArray(new IResource[resources.size()]); + IResource[] result = (IResource[]) resources.toArray(new IResource[resources.size()]); + if (props != null) { + props.put(SELECTED_RESOURCES_WITH_OVERLAP, result); + } + return result; } catch (TeamException e) { CVSUIPlugin.log(e); return new IResource[0]; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java index a05bd444e..555b6a313 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java @@ -424,5 +424,6 @@ public abstract class TeamAction extends ActionDelegate implements IObjectAction if(window != null) { window.getSelectionService().removePostSelectionListener(selectionListener); } + selection = null; } } |