View | Details | Raw Unified | Return to bug 86973 | Differences between
and this patch

Collapse All | Expand All

(-)extensions/org/eclipse/ui/dialogs/FilteredResourcesSelectionDialog.java (-21 / +157 lines)
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
9
 *     IBM Corporation - initial API and implementation
10
 *     James Blackburn (Broadcom Corp.) Bug 86973 Allow path pattern matching
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.ui.dialogs;
12
package org.eclipse.ui.dialogs;
12
13
Lines 25-34 Link Here
25
import org.eclipse.core.resources.IWorkspace;
26
import org.eclipse.core.resources.IWorkspace;
26
import org.eclipse.core.resources.ResourcesPlugin;
27
import org.eclipse.core.resources.ResourcesPlugin;
27
import org.eclipse.core.runtime.CoreException;
28
import org.eclipse.core.runtime.CoreException;
29
import org.eclipse.core.runtime.IAdaptable;
28
import org.eclipse.core.runtime.IPath;
30
import org.eclipse.core.runtime.IPath;
29
import org.eclipse.core.runtime.IProgressMonitor;
31
import org.eclipse.core.runtime.IProgressMonitor;
30
import org.eclipse.core.runtime.IStatus;
32
import org.eclipse.core.runtime.IStatus;
31
import org.eclipse.core.runtime.ListenerList;
33
import org.eclipse.core.runtime.ListenerList;
34
import org.eclipse.core.runtime.Path;
32
import org.eclipse.core.runtime.Status;
35
import org.eclipse.core.runtime.Status;
33
import org.eclipse.jface.action.Action;
36
import org.eclipse.jface.action.Action;
34
import org.eclipse.jface.action.IAction;
37
import org.eclipse.jface.action.IAction;
Lines 40-45 Link Here
40
import org.eclipse.jface.util.PropertyChangeEvent;
43
import org.eclipse.jface.util.PropertyChangeEvent;
41
import org.eclipse.jface.viewers.ILabelProviderListener;
44
import org.eclipse.jface.viewers.ILabelProviderListener;
42
import org.eclipse.jface.viewers.ISelection;
45
import org.eclipse.jface.viewers.ISelection;
46
import org.eclipse.jface.viewers.IStructuredSelection;
43
import org.eclipse.jface.viewers.LabelProvider;
47
import org.eclipse.jface.viewers.LabelProvider;
44
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
48
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
45
import org.eclipse.jface.viewers.StyledString;
49
import org.eclipse.jface.viewers.StyledString;
Lines 97-104 Link Here
97
101
98
	private String title;
102
	private String title;
99
103
104
	/** @since 3.6 */
105
	protected ResourceFilter filter;
106
107
	/** The base outer-container which will be used to search for resources */ 
100
	private IContainer container;
108
	private IContainer container;
101
109
110
	/** The Container to use for relative search */
111
	private IContainer searchContainer;
112
102
	private int typeMask;
113
	private int typeMask;
103
114
104
	private boolean isDerived;
115
	private boolean isDerived;
Lines 111-117 Link Here
111
	 * @param multi
122
	 * @param multi
112
	 *            the multi selection flag
123
	 *            the multi selection flag
113
	 * @param container
124
	 * @param container
114
	 *            the container
125
	 *            the container to select resources from e.g. Workspace Root
115
	 * @param typesMask
126
	 * @param typesMask
116
	 *            the types mask
127
	 *            the types mask
117
	 */
128
	 */
Lines 125-130 Link Here
125
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
136
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
126
				IIDEHelpContextIds.OPEN_RESOURCE_DIALOG);
137
				IIDEHelpContextIds.OPEN_RESOURCE_DIALOG);
127
138
139
		/*
140
		 * Allow location of paths relative to "searchContainer"
141
		 *  - searchContainer is the container of the currently active editor
142
		 *  - or the first container found as a result of querying the selection service
143
		 */
144
		IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
145
		if (ww != null) {
146
			Object[] selection = new Object[0];
147
			ISelection isel = ww.getSelectionService().getSelection();
148
			// Search for an Active Editor
149
			if (ww.getActivePage() != null)
150
				if (ww.getActivePage().getActiveEditor() != null)
151
					selection = new Object[] {ww.getActivePage().getActiveEditor().getEditorInput()};
152
			// Else get active selection if IStructuredSelection
153
			if (selection.length == 0 && isel instanceof IStructuredSelection)
154
				selection = ((IStructuredSelection)isel).toArray();
155
156
			// Iterate over the Objects trying to adapt them to IResource
157
			for (int i = 0 ; i < selection.length ; ++i) {
158
				if (selection[i] instanceof IAdaptable) {
159
					IResource res = (IResource)((IAdaptable)selection[i]).getAdapter(IResource.class);
160
					if (res != null) {
161
						if (res instanceof IContainer) 
162
							searchContainer = (IContainer)res;
163
						else
164
							searchContainer = res.getParent();
165
						break;
166
					}
167
				}
168
			}
169
		}
170
		if (searchContainer == null)
171
			searchContainer = container;
172
128
		this.container = container;
173
		this.container = container;
129
		this.typeMask = typesMask;
174
		this.typeMask = typesMask;
130
175
Lines 377-383 Link Here
377
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter()
422
	 * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter()
378
	 */
423
	 */
379
	protected ItemsFilter createFilter() {
424
	protected ItemsFilter createFilter() {
380
		return new ResourceFilter(container, isDerived, typeMask);
425
		filter = new ResourceFilter(container, searchContainer, isDerived, typeMask);
426
		return filter;
381
	}
427
	}
382
428
383
	/* (non-Javadoc)
429
	/* (non-Javadoc)
Lines 407-426 Link Here
407
				IResource resource2 = (IResource) o2;
453
				IResource resource2 = (IResource) o2;
408
				String s1 = resource1.getName();
454
				String s1 = resource1.getName();
409
				String s2 = resource2.getName();
455
				String s2 = resource2.getName();
456
				// Compare their names
410
				int comparability = collator.compare(s1, s2);
457
				int comparability = collator.compare(s1, s2);
411
				if (comparability == 0) {
458
				if (comparability != 0)
412
					IPath p1 = resource1.getFullPath();
459
					return comparability;
413
					IPath p2 = resource2.getFullPath();
460
414
					int c1 = p1.segmentCount();
461
				// Search for resource relative paths
415
					int c2 = p2.segmentCount();
462
				if (filter != null) {
416
					for (int i= 0; i < c1 && i < c2; i++) {
463
					// Sort resource relative first
417
						comparability = collator.compare(p1.segment(i), p2.segment(i));
464
					if ((filter.matchesResourceRelativeFilter(resource1) && 
418
						if (comparability != 0)
465
							!filter.matchesResourceRelativeFilter(resource2)) ||
419
							return comparability;
466
						(filter.matchesResourceRelativeFilter(resource2) && 
467
							!filter.matchesResourceRelativeFilter(resource1))) {
468
						if (filter.matchesResourceRelativeFilter(resource1))
469
							return -1;
470
						return 1;
420
					}
471
					}
421
					comparability = c2 - c1;
472
473
					// Return paths 'closer' in the searchContainer first
474
					IContainer c1 = resource1 instanceof IContainer ? (IContainer) resource1 : resource1.getParent();
475
					IContainer c2 = resource2 instanceof IContainer ? (IContainer) resource2 : resource2.getParent();
476
					comparability = filter.pathDistance(c1) - filter.pathDistance(c2);
477
					if (comparability != 0)
478
						return comparability;
422
				}
479
				}
423
480
481
				// Finally compare fullpath segments; shorter paths sorted first
482
				IPath p1 = resource1.getFullPath();
483
				IPath p2 = resource2.getFullPath();
484
				int c1 = p1.segmentCount();
485
				int c2 = p2.segmentCount();
486
				for (int i= 0; i < c1 && i < c2; i++) {
487
					comparability = collator.compare(p1.segment(i), p2.segment(i));
488
					if (comparability != 0)
489
						return comparability;
490
				}
491
				comparability = c2 - c1;
492
424
				return comparability;
493
				return comparability;
425
			}
494
			}
426
		};
495
		};
Lines 752-757 Link Here
752
821
753
		private IContainer filterContainer;
822
		private IContainer filterContainer;
754
823
824
		/** Search pattern for resource relative lookups *
825
		 * @since 3.6 */
826
		protected SearchPattern resourceRelativePattern = new SearchPattern();
827
755
		private int filterTypeMask;
828
		private int filterTypeMask;
756
829
757
		/**
830
		/**
Lines 772-783 Link Here
772
845
773
		/**
846
		/**
774
		 * Creates new ResourceFilter instance
847
		 * Creates new ResourceFilter instance
848
		 * 
849
		 * @param container
850
		 * @param searchContainer 
851
		 *            IContainer to use for performing relative search
852
		 * @param showDerived
853
		 *            flag which determine showing derived elements
854
		 * @param typeMask
855
		 * @since 3.6
856
		 */
857
		public ResourceFilter(IContainer container, IContainer searchContainer, boolean showDerived, int typeMask) {
858
			this(container, showDerived, typeMask);
859
860
			String stringPattern = getPattern();
861
862
			// If pattern looks relative then add path
863
			stringPattern = searchContainer.getFullPath().append(stringPattern).toOSString();
864
			resourceRelativePattern.setPattern(stringPattern);
865
		}
866
867
		/**
868
		 * Creates new ResourceFilter instance
775
		 */
869
		 */
776
		public ResourceFilter() {
870
		public ResourceFilter() {
777
			super();
871
			this(container, searchContainer, isDerived, typeMask);
778
			this.filterContainer = container;
779
			this.showDerived = isDerived;
780
			this.filterTypeMask = typeMask;
781
		}
872
		}
782
873
783
		/**
874
		/**
Lines 791-797 Link Here
791
				return false;
882
				return false;
792
			}
883
			}
793
			IResource resource = (IResource) item;
884
			IResource resource = (IResource) item;
794
			if (this.filterContainer.findMember(resource.getFullPath()) != null)
885
			if (this.filterContainer.getFullPath().isPrefixOf(resource.getFullPath()))
795
				return true;
886
				return true;
796
			return false;
887
			return false;
797
		}
888
		}
Lines 810-816 Link Here
810
			if ((!this.showDerived && resource.isDerived())
901
			if ((!this.showDerived && resource.isDerived())
811
					|| ((this.filterTypeMask & resource.getType()) == 0))
902
					|| ((this.filterTypeMask & resource.getType()) == 0))
812
				return false;
903
				return false;
813
			return matches(resource.getName());
904
905
			if (matches(resource.getName()) || 
906
					// Allow matching of full path
907
					matches (resource.getFullPath().toOSString()) ||
908
					// Allow matching of path relative to current selection
909
					matchesResourceRelativeFilter(resource))
910
				return true;
911
			
912
			return false;			
913
		}
914
915
		/**
916
		 * Return true if the passed in item matches the resource relative filter
917
		 * @param item
918
		 * @return boolean indicating match
919
		 * @since 3.6
920
		 */
921
		public boolean matchesResourceRelativeFilter(IResource item) {
922
			return resourceRelativePattern.matches(item.getFullPath().toOSString());
923
		}
924
925
		/**
926
		 * Return the distance of the item from the root of the relative search container.
927
		 * Distances can be compared (smaller numbers are better).
928
		 * 
929
		 * Distance is how many directories you would have to traverse, changing one directory
930
		 * at a time, to get from item to the search container
931
		 * 
932
		 * @param item IContainer parent of the resource being examined
933
		 * @return the distance of the passed in IResource from the search container
934
		 * @since 3.6
935
		 */
936
		public int pathDistance(IContainer item) {
937
			// Container search path: e.g. /a/b/c
938
			IPath containerPath = searchContainer.getFullPath();
939
			// /a/b/c/d/e     ==> distance 2
940
			// /a/b           ==> distance 1
941
			// /a/b/e/f       ==> distance 3
942
			// /g/h           ==> distance 5
943
			IPath itemPath = item.getFullPath();
944
			int distance = containerPath.matchingFirstSegments(itemPath);
945
			return (itemPath.segmentCount() - distance) + (containerPath.segmentCount() - distance);
814
		}
946
		}
815
947
816
		/*
948
		/*
Lines 821-829 Link Here
821
		public boolean isSubFilter(ItemsFilter filter) {
953
		public boolean isSubFilter(ItemsFilter filter) {
822
			if (!super.isSubFilter(filter))
954
			if (!super.isSubFilter(filter))
823
				return false;
955
				return false;
824
			if (filter instanceof ResourceFilter)
956
			if (filter instanceof ResourceFilter && 
825
				if (this.showDerived == ((ResourceFilter) filter).showDerived)
957
					this.showDerived == ((ResourceFilter) filter).showDerived) {
826
					return true;
958
				// super.isSubFilter checks whether this pattern is more general than 'filter' pattern
959
				// Also check that the resource relative filter. For relative paths ../../ etc.
960
				IPath otherPath = new Path(((ResourceFilter)filter).resourceRelativePattern.getPattern());
961
				return (otherPath.segmentCount() >= new Path(resourceRelativePattern.getPattern()).segmentCount());
962
			}
827
			return false;
963
			return false;
828
		}
964
		}
829
965

Return to bug 86973