### Eclipse Workspace Patch 1.0 #P org.eclipse.ui.ide Index: extensions/org/eclipse/ui/dialogs/FilteredResourcesSelectionDialog.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.ui.ide/extensions/org/eclipse/ui/dialogs/FilteredResourcesSelectionDialog.java,v retrieving revision 1.18 diff -u -r1.18 FilteredResourcesSelectionDialog.java --- extensions/org/eclipse/ui/dialogs/FilteredResourcesSelectionDialog.java 24 Mar 2008 19:13:35 -0000 1.18 +++ extensions/org/eclipse/ui/dialogs/FilteredResourcesSelectionDialog.java 19 May 2008 13:08:43 -0000 @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.ui.dialogs; -import com.ibm.icu.text.Collator; - import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; @@ -20,25 +18,20 @@ import java.util.Comparator; import java.util.List; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.ListenerList; -import org.eclipse.core.runtime.Status; - import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; - -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; - +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.ListenerList; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; @@ -50,11 +43,15 @@ import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; - +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IMemento; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; @@ -73,6 +70,8 @@ import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.statushandlers.StatusManager; +import com.ibm.icu.text.Collator; + /** * Shows a list of resources to the user with a text entry field for a string * pattern used to filter the list of resources. @@ -100,8 +99,13 @@ private String title; + protected ResourceFilter filter; + private IContainer container; + /** The Container to use for searching for relative resources */ + private IContainer searchContainer; + private int typeMask; private boolean isDerived; @@ -128,6 +132,41 @@ PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IIDEHelpContextIds.OPEN_RESOURCE_DIALOG); + + /* + * Allow location of paths relative to "searchContainer" + * - searchContainer is the container of the currently active editor + * - or the first container found as a result of querying the selection service + */ + IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (ww != null) { + Object[] selection = new Object[0]; + ISelection isel = ww.getSelectionService().getSelection(); + // Search for an Active Editor + if (ww.getActivePage() != null) + if (ww.getActivePage().getActiveEditor() != null) + selection = new Object[] {ww.getActivePage().getActiveEditor().getEditorInput()}; + // Else get active selection if IStructuredSelection + if (selection.length == 0 && isel instanceof IStructuredSelection) + selection = ((IStructuredSelection)isel).toArray(); + + // Iterate over the Objects trying to adapt them to IResource + for (int i = 0 ; i < selection.length ; ++i) { + if (selection[i] instanceof IAdaptable) { + IResource res = (IResource)((IAdaptable)selection[i]).getAdapter(IResource.class); + if (res != null) { + if (res instanceof IContainer) + searchContainer = (IContainer)res; + else + searchContainer = res.getParent(); + break; + } + } + } + } + if (searchContainer == null) + searchContainer = container; + this.container = container; this.typeMask = typesMask; @@ -380,7 +419,8 @@ * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter() */ protected ItemsFilter createFilter() { - return new ResourceFilter(container, isDerived, typeMask); + filter = new ResourceFilter(container, searchContainer, isDerived, typeMask); + return filter; } /* (non-Javadoc) @@ -410,8 +450,21 @@ IResource resource2 = (IResource) o2; String s1 = resource1.getName(); String s2 = resource2.getName(); + // Compare their names int comparability = collator.compare(s1, s2); if (comparability == 0) { + + // Sort resource relative first + if ((filter.matchesResourceRelativeFilter(resource1) && + !filter.matchesResourceRelativeFilter(resource2)) || + (filter.matchesResourceRelativeFilter(resource2) && + !filter.matchesResourceRelativeFilter(resource1))) { + if (filter.matchesResourceRelativeFilter(resource1)) + return -1; + return 1; + } + + // Finall compare fullpaths; shorter paths sorted first IPath p1 = resource1.getFullPath(); IPath p2 = resource2.getFullPath(); int c1 = p1.segmentCount(); @@ -756,6 +809,9 @@ private IContainer filterContainer; + /** Search pattern for resource relative lookups */ + protected SearchPattern resourceRelativePattern = new SearchPattern(); + private int filterTypeMask; /** @@ -766,22 +822,26 @@ * flag which determine showing derived elements * @param typeMask */ - public ResourceFilter(IContainer container, boolean showDerived, - int typeMask) { + public ResourceFilter(IContainer container, IContainer searchContainer, + boolean showDerived, int typeMask) { super(); this.filterContainer = container; this.showDerived = showDerived; this.filterTypeMask = typeMask; + + String stringPattern = getPattern(); + + // If pattern looks relative then add path + stringPattern = searchContainer.getFullPath() + .append(stringPattern).toOSString(); + resourceRelativePattern.setPattern(stringPattern); } /** * Creates new ResourceFilter instance */ public ResourceFilter() { - super(); - this.filterContainer = container; - this.showDerived = isDerived; - this.filterTypeMask = typeMask; + this(container, searchContainer, isDerived, typeMask); } /** @@ -795,7 +855,7 @@ return false; } IResource resource = (IResource) item; - if (this.filterContainer.findMember(resource.getFullPath()) != null) + if (this.filterContainer.getFullPath().isPrefixOf(resource.getFullPath())) return true; return false; } @@ -814,7 +874,24 @@ if ((!this.showDerived && resource.isDerived()) || ((this.filterTypeMask & resource.getType()) == 0)) return false; - return matches(resource.getName()); + + if (matches(resource.getName()) || + // Allow matching of full path + matches (resource.getFullPath().toOSString()) || + // Allow matching of path relative to current selection + matchesResourceRelativeFilter(resource)) + return true; + + return false; + } + + /** + * Return true if the passed in item matches the resource relative filter + * @param item + * @return + */ + public boolean matchesResourceRelativeFilter(IResource item) { + return resourceRelativePattern.matches(item.getFullPath().toOSString()); } /* @@ -825,9 +902,13 @@ public boolean isSubFilter(ItemsFilter filter) { if (!super.isSubFilter(filter)) return false; - if (filter instanceof ResourceFilter) - if (this.showDerived == ((ResourceFilter) filter).showDerived) - return true; + if (filter instanceof ResourceFilter && + this.showDerived == ((ResourceFilter) filter).showDerived) { + // super.isSubFilter checks whether this pattern is more general than 'filter' pattern + // Also check that the resource relative filter. For relative paths ../../ etc. + IPath otherPath = new Path(((ResourceFilter)filter).resourceRelativePattern.getPattern()); + return (otherPath.segmentCount() >= new Path(resourceRelativePattern.getPattern()).segmentCount()); + } return false; }