Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 167010 | Differences between
and this patch

Collapse All | Expand All

(-)META-INF/MANIFEST.MF (-1 / +2 lines)
Lines 53-59 Link Here
53
 org.eclipse.update.core;bundle-version="[3.1.100,4.0.0)",
53
 org.eclipse.update.core;bundle-version="[3.1.100,4.0.0)",
54
 org.eclipse.update.ui;bundle-version="[3.1.100,4.0.0)",
54
 org.eclipse.update.ui;bundle-version="[3.1.100,4.0.0)",
55
 org.eclipse.jface.text;bundle-version="[3.2.0,4.0.0)",
55
 org.eclipse.jface.text;bundle-version="[3.2.0,4.0.0)",
56
 org.eclipse.ui.forms
56
 org.eclipse.ui.forms,
57
 org.eclipse.core.databinding
57
Eclipse-LazyStart: true
58
Eclipse-LazyStart: true
58
Import-Package: com.ibm.icu.text
59
Import-Package: com.ibm.icu.text
59
Bundle-RequiredExecutionEnvironment: J2SE-1.4
60
Bundle-RequiredExecutionEnvironment: J2SE-1.4
(-)plugin.xml (+6 lines)
Lines 1019-1023 Link Here
1019
               value="0"/>
1019
               value="0"/>
1020
      </markerAttributeGrouping>
1020
      </markerAttributeGrouping>
1021
   </extension>
1021
   </extension>
1022
   <extension
1023
         point="org.eclipse.ui.internalQuickAccessProvider">
1024
      <provider
1025
            class="org.eclipse.ui.internal.ide.ResourceProvider">
1026
      </provider>
1027
   </extension>
1022
   
1028
   
1023
</plugin>
1029
</plugin>
(-)src/org/eclipse/ui/internal/ide/ResourceProvider.java (+163 lines)
Added Link Here
1
package org.eclipse.ui.internal.ide;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
6
import org.eclipse.core.resources.IFile;
7
import org.eclipse.core.resources.IResource;
8
import org.eclipse.core.resources.IResourceProxy;
9
import org.eclipse.core.resources.IResourceProxyVisitor;
10
import org.eclipse.core.resources.IWorkspace;
11
import org.eclipse.core.resources.ResourcesPlugin;
12
import org.eclipse.core.runtime.CoreException;
13
import org.eclipse.core.runtime.IPath;
14
import org.eclipse.core.runtime.IStatus;
15
import org.eclipse.core.runtime.Path;
16
import org.eclipse.jface.resource.ImageDescriptor;
17
import org.eclipse.ui.IWorkbenchPage;
18
import org.eclipse.ui.IWorkbenchWindow;
19
import org.eclipse.ui.PartInitException;
20
import org.eclipse.ui.PlatformUI;
21
import org.eclipse.ui.ide.IDE;
22
import org.eclipse.ui.internal.incubator.AbstractElement;
23
import org.eclipse.ui.internal.incubator.AbstractProvider;
24
import org.eclipse.ui.internal.incubator.QuickAccessElement;
25
import org.eclipse.ui.internal.incubator.IncrementalFilterSet.IStreamVisitor;
26
import org.eclipse.ui.statushandling.StatusManager;
27
28
/**
29
 * Provides the resources in the workspace
30
 * 
31
 * @since 3.3
32
 * 
33
 */
34
public class ResourceProvider extends AbstractProvider {
35
36
	static IWorkspace workspace;
37
38
	/**
39
	 * 
40
	 */
41
	public ResourceProvider() {
42
		workspace = ResourcesPlugin.getWorkspace();
43
	}
44
45
	public AbstractElement getElementForId(String id) {
46
		IResource resource = workspace.getRoot().findMember(
47
				Path.fromPortableString(id));
48
		return resource == null ? null : new ResourceElement(this, resource
49
				.getFullPath());
50
	}
51
52
	public AbstractElement[] getElements() {
53
		final List result = new ArrayList();
54
		try {
55
			workspace.getRoot().accept(new IResourceProxyVisitor() {
56
57
				public boolean visit(IResourceProxy proxy) {
58
					if (proxy.getType() == IResource.FILE && !proxy.isDerived()) {
59
						result.add(new ResourceElement(ResourceProvider.this,
60
								proxy.requestFullPath()));
61
					}
62
					return true;
63
				}
64
			}, 0);
65
		} catch (CoreException e) {
66
			StatusManager
67
					.getManager()
68
					.handle(
69
							StatusUtil
70
									.newStatus(
71
											IStatus.ERROR,
72
											"NON-NLSed: Error while retrieving workspace resources", e), //$NON-NLS-1$
73
							StatusManager.LOG);
74
		}
75
		return (AbstractElement[]) result.toArray(new AbstractElement[result
76
				.size()]);
77
	}
78
79
	public String getId() {
80
		return "org.eclipse.ui.ide.ResourceProvider"; //$NON-NLS-1$
81
	}
82
83
	public ImageDescriptor getImageDescriptor() {
84
		return null;
85
	}
86
87
	public String getName() {
88
		return "NON-NLSed: Resources"; //$NON-NLS-1$
89
	}
90
91
	private static class ResourceElement extends AbstractElement {
92
93
		private final IPath path;
94
95
		ResourceElement(ResourceProvider provider, IPath path) {
96
			super(provider);
97
			this.path = path;
98
		}
99
100
		public void execute() {
101
			IResource resource = workspace.getRoot().findMember(path);
102
			if (!resource.exists() || resource.getType() != IResource.FILE)
103
				return;
104
			IWorkbenchWindow window = PlatformUI.getWorkbench()
105
					.getActiveWorkbenchWindow();
106
			if (window == null)
107
				return;
108
			IWorkbenchPage activePage = window.getActivePage();
109
			if (activePage == null)
110
				return;
111
			try {
112
				IDE.openEditor(activePage, (IFile) resource);
113
			} catch (PartInitException e) {
114
				StatusManager.getManager().handle(
115
						StatusUtil.newStatus(IStatus.ERROR,
116
								"NON-NLSed: Error while opening editor", e), //$NON-NLS-1$
117
						StatusManager.SHOWANDLOG);
118
			}
119
		}
120
121
		public String getId() {
122
			return path.toPortableString();
123
		}
124
125
		public ImageDescriptor getImageDescriptor() {
126
			return null;
127
		}
128
129
		public String getLabel() {
130
			return path.lastSegment() + " - " + path.toString(); //$NON-NLS-1$
131
		}
132
133
	}
134
135
	public void accept(final IStreamVisitor visitor) {
136
		try {
137
			workspace.getRoot().accept(new IResourceProxyVisitor() {
138
139
				public boolean visit(IResourceProxy proxy) {
140
					if (proxy.getType() == IResource.FILE && !proxy.isDerived()) {
141
						final IResource resource = proxy.requestResource();
142
						return visitor.visit(new QuickAccessElement() {
143
							public String getLabel() {
144
								return resource.getName() + " -  " + resource.getParent().getFullPath().toString(); //$NON-NLS-1$
145
							}
146
						});
147
					}
148
					return true;
149
				}
150
			}, 0);
151
		} catch (CoreException e) {
152
			StatusManager
153
					.getManager()
154
					.handle(
155
							StatusUtil
156
									.newStatus(
157
											IStatus.ERROR,
158
											"NON-NLSed: Error while retrieving workspace resources", e), //$NON-NLS-1$
159
							StatusManager.LOG);
160
		}
161
	};
162
163
}
(-)Eclipse UI/org/eclipse/ui/internal/incubator/CtrlEAction.java (-11 / +47 lines)
Lines 3-14 Link Here
3
import java.util.ArrayList;
3
import java.util.ArrayList;
4
import java.util.HashMap;
4
import java.util.HashMap;
5
import java.util.LinkedList;
5
import java.util.LinkedList;
6
import java.util.List;
6
import java.util.Map;
7
import java.util.Map;
7
import java.util.StringTokenizer;
8
import java.util.StringTokenizer;
8
9
9
import org.eclipse.core.commands.AbstractHandler;
10
import org.eclipse.core.commands.AbstractHandler;
10
import org.eclipse.core.commands.ExecutionEvent;
11
import org.eclipse.core.commands.ExecutionEvent;
11
import org.eclipse.core.runtime.Assert;
12
import org.eclipse.core.runtime.Assert;
13
import org.eclipse.core.runtime.CoreException;
14
import org.eclipse.core.runtime.IConfigurationElement;
15
import org.eclipse.core.runtime.IStatus;
16
import org.eclipse.core.runtime.Platform;
12
import org.eclipse.jface.dialogs.IDialogSettings;
17
import org.eclipse.jface.dialogs.IDialogSettings;
13
import org.eclipse.jface.resource.DeviceResourceException;
18
import org.eclipse.jface.resource.DeviceResourceException;
14
import org.eclipse.jface.resource.ImageDescriptor;
19
import org.eclipse.jface.resource.ImageDescriptor;
Lines 35-41 Link Here
35
import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
40
import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
36
import org.eclipse.ui.internal.WorkbenchImages;
41
import org.eclipse.ui.internal.WorkbenchImages;
37
import org.eclipse.ui.internal.WorkbenchPlugin;
42
import org.eclipse.ui.internal.WorkbenchPlugin;
43
import org.eclipse.ui.internal.misc.StatusUtil;
38
import org.eclipse.ui.internal.progress.ProgressManagerUtil;
44
import org.eclipse.ui.internal.progress.ProgressManagerUtil;
45
import org.eclipse.ui.statushandling.StatusManager;
39
46
40
/**
47
/**
41
 * Experimental Action for search-based navigation to UI elements such as
48
 * Experimental Action for search-based navigation to UI elements such as
Lines 71-81 Link Here
71
		}
78
		}
72
79
73
		if (providers == null) {
80
		if (providers == null) {
74
			providers = new AbstractProvider[] { new PreviousPicksProvider(),
81
			List providerList = new ArrayList();
75
					new EditorProvider(), new ViewProvider(),
82
			providerList.add(new PreviousPicksProvider());
76
					new PerspectiveProvider(), new CommandProvider(),
83
			providerList.add(new EditorProvider());
77
					new ActionProvider(), new WizardProvider(),
84
			providerList.add(new ViewProvider());
78
					new PreferenceProvider() };
85
			providerList.add(new PerspectiveProvider());
86
			// add contributed providers
87
			IConfigurationElement[] elements = Platform.getExtensionRegistry()
88
					.getConfigurationElementsFor(
89
							"org.eclipse.ui.internalQuickAccessProvider"); //$NON-NLS-1$
90
			for (int i = 0; i < elements.length; i++) {
91
				AbstractProvider provider;
92
				try {
93
					provider = (AbstractProvider) elements[i]
94
							.createExecutableExtension("class"); //$NON-NLS-1$
95
					providerList.add(provider);
96
				} catch (CoreException e) {
97
					StatusManager
98
							.getManager()
99
							.handle(
100
									StatusUtil
101
											.newStatus(
102
													IStatus.ERROR,
103
													"NON-NLSed: Error with extension " + elements[i], e), //$NON-NLS-1$
104
									StatusManager.LOG);
105
				}
106
			}
107
108
			providerList.add(new CommandProvider());
109
			providerList.add(new ActionProvider());
110
			providerList.add(new WizardProvider());
111
			providerList.add(new PreferenceProvider());
112
			providers = (AbstractProvider[]) providerList
113
					.toArray(new AbstractProvider[providerList.size()]);
79
114
80
			providerMap = new HashMap();
115
			providerMap = new HashMap();
81
			for (int i = 0; i < providers.length; i++) {
116
			for (int i = 0; i < providers.length; i++) {
Lines 171-177 Link Here
171
		public String[] getMatchNames(Object element, Object parentElementOrNull) {
206
		public String[] getMatchNames(Object element, Object parentElementOrNull) {
172
			if (element instanceof AbstractProvider) {
207
			if (element instanceof AbstractProvider) {
173
				AbstractProvider provider = (AbstractProvider) element;
208
				AbstractProvider provider = (AbstractProvider) element;
174
				return (new String[]{provider.getName()});
209
				return (new String[] { provider.getName() });
175
			} else if (element instanceof AbstractElement) {
210
			} else if (element instanceof AbstractElement) {
176
				AbstractElement abstractElement = (AbstractElement) element;
211
				AbstractElement abstractElement = (AbstractElement) element;
177
				String sortLabel = abstractElement.getSortLabel();
212
				String sortLabel = abstractElement.getSortLabel();
Lines 181-201 Link Here
181
					String combinedLabel = abstractProvider.getName()
216
					String combinedLabel = abstractProvider.getName()
182
							+ " " + abstractElement.getLabel(); //$NON-NLS-1$
217
							+ " " + abstractElement.getLabel(); //$NON-NLS-1$
183
					String combinedCamelCase = getCamelCase(combinedLabel);
218
					String combinedCamelCase = getCamelCase(combinedLabel);
184
					return (new String[] { sortLabel, camelCase, combinedLabel, combinedCamelCase });
219
					return (new String[] { sortLabel, camelCase, combinedLabel,
220
							combinedCamelCase });
185
				}
221
				}
186
				return (new String[] { sortLabel, camelCase });
222
				return (new String[] { sortLabel, camelCase });
187
			}
223
			}
188
			return (new String[]{""}); //$NON-NLS-1$
224
			return (new String[] { "" }); //$NON-NLS-1$
189
		}
225
		}
190
		
226
191
		/**
227
		/**
192
		 * @return a string containing the first character of every word for
228
		 * @return a string containing the first character of every word for
193
		 * camel case checking.
229
		 *         camel case checking.
194
		 */
230
		 */
195
		private String getCamelCase(String label) {
231
		private String getCamelCase(String label) {
196
			StringTokenizer tokenizer = new StringTokenizer(label);
232
			StringTokenizer tokenizer = new StringTokenizer(label);
197
			StringBuffer camelCase = new StringBuffer();
233
			StringBuffer camelCase = new StringBuffer();
198
			while(tokenizer.hasMoreTokens()) {
234
			while (tokenizer.hasMoreTokens()) {
199
				String word = tokenizer.nextToken();
235
				String word = tokenizer.nextToken();
200
				camelCase.append(word.charAt(0));
236
				camelCase.append(word.charAt(0));
201
			}
237
			}
(-)Eclipse UI/org/eclipse/ui/internal/incubator/AbstractProvider.java (-1 / +11 lines)
Lines 12-23 Link Here
12
package org.eclipse.ui.internal.incubator;
12
package org.eclipse.ui.internal.incubator;
13
13
14
import org.eclipse.jface.resource.ImageDescriptor;
14
import org.eclipse.jface.resource.ImageDescriptor;
15
import org.eclipse.ui.internal.incubator.IncrementalFilterSet.IElementStream;
16
import org.eclipse.ui.internal.incubator.IncrementalFilterSet.IStreamVisitor;
15
17
16
/**
18
/**
17
 * @since 3.3
19
 * @since 3.3
18
 * 
20
 * 
19
 */
21
 */
20
public abstract class AbstractProvider {
22
public abstract class AbstractProvider implements IElementStream {
21
23
22
	/**
24
	/**
23
	 * Returns the unique ID of this provider.
25
	 * Returns the unique ID of this provider.
Lines 56-59 Link Here
56
	 * @return the element with the given ID, or null if not found.
58
	 * @return the element with the given ID, or null if not found.
57
	 */
59
	 */
58
	public abstract AbstractElement getElementForId(String id);
60
	public abstract AbstractElement getElementForId(String id);
61
62
	public void accept(IStreamVisitor visitor) {
63
		AbstractElement[] elements = getElements();
64
		for (int i = 0; i < elements.length; i++) {
65
			if (!visitor.visit(elements[i]))
66
				return;
67
		}
68
	}
59
}
69
}
(-)META-INF/MANIFEST.MF (-2 / +4 lines)
Lines 38-44 Link Here
38
 org.eclipse.ui.internal.expressions;x-internal:=true,
38
 org.eclipse.ui.internal.expressions;x-internal:=true,
39
 org.eclipse.ui.internal.handlers;x-internal:=true,
39
 org.eclipse.ui.internal.handlers;x-internal:=true,
40
 org.eclipse.ui.internal.help;x-internal:=true,
40
 org.eclipse.ui.internal.help;x-internal:=true,
41
 org.eclipse.ui.internal.incubator;x-friends:="org.eclipse.ui",
41
 org.eclipse.ui.internal.incubator;x-friends:="org.eclipse.ui,org.eclipse.ui.ide",
42
 org.eclipse.ui.internal.intro;x-internal:=true,
42
 org.eclipse.ui.internal.intro;x-internal:=true,
43
 org.eclipse.ui.internal.keys;x-internal:=true,
43
 org.eclipse.ui.internal.keys;x-internal:=true,
44
 org.eclipse.ui.internal.layout;x-friends:="org.eclipse.ui.presentations.r21,org.eclipse.ui.intro",
44
 org.eclipse.ui.internal.layout;x-friends:="org.eclipse.ui.presentations.r21,org.eclipse.ui.intro",
Lines 80-86 Link Here
80
 org.eclipse.help;bundle-version="[3.2.0,4.0.0)",
80
 org.eclipse.help;bundle-version="[3.2.0,4.0.0)",
81
 org.eclipse.jface;bundle-version="[3.3.0,4.0.0)",
81
 org.eclipse.jface;bundle-version="[3.3.0,4.0.0)",
82
 org.eclipse.swt;bundle-version="[3.3.0,4.0.0)",
82
 org.eclipse.swt;bundle-version="[3.3.0,4.0.0)",
83
 org.eclipse.core.expressions;bundle-version="[3.2.0,4.0.0)"
83
 org.eclipse.core.expressions;bundle-version="[3.2.0,4.0.0)",
84
 org.eclipse.core.databinding,
85
 org.eclipse.jface.databinding
84
Eclipse-LazyStart: true
86
Eclipse-LazyStart: true
85
Import-Package: com.ibm.icu.text,
87
Import-Package: com.ibm.icu.text,
86
 javax.xml.parsers,
88
 javax.xml.parsers,
(-)Eclipse (+71 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.incubator;
13
14
import java.util.ArrayList;
15
import java.util.List;
16
17
import org.eclipse.core.commands.AbstractHandler;
18
import org.eclipse.core.commands.ExecutionEvent;
19
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.IConfigurationElement;
21
import org.eclipse.core.runtime.IStatus;
22
import org.eclipse.core.runtime.Platform;
23
import org.eclipse.ui.IWorkbenchWindow;
24
import org.eclipse.ui.PlatformUI;
25
import org.eclipse.ui.internal.misc.StatusUtil;
26
import org.eclipse.ui.statushandling.StatusManager;
27
28
/**
29
 * @since 3.3
30
 * 
31
 */
32
public class QuickAccessHandler extends AbstractHandler {
33
34
	public Object execute(ExecutionEvent event) {
35
36
		IWorkbenchWindow window = PlatformUI.getWorkbench()
37
				.getActiveWorkbenchWindow();
38
		if (window == null) {
39
			return null;
40
		}
41
42
		List providerList = new ArrayList();
43
		// add contributed providers
44
		IConfigurationElement[] elements = Platform.getExtensionRegistry()
45
				.getConfigurationElementsFor(
46
						"org.eclipse.ui.internalQuickAccessProvider"); //$NON-NLS-1$
47
		for (int i = 0; i < elements.length; i++) {
48
			AbstractProvider provider;
49
			try {
50
				provider = (AbstractProvider) elements[i]
51
						.createExecutableExtension("class"); //$NON-NLS-1$
52
				providerList.add(provider);
53
			} catch (CoreException e) {
54
				StatusManager
55
						.getManager()
56
						.handle(
57
								StatusUtil
58
										.newStatus(
59
												IStatus.ERROR,
60
												"NON-NLSed: Error with extension " + elements[i], e), //$NON-NLS-1$
61
								StatusManager.LOG);
62
			}
63
		}
64
		AbstractProvider provider = (AbstractProvider) providerList.get(0);
65
66
		new QuickAccessPopup(window.getShell(), provider).open();
67
68
		return null;
69
	}
70
71
}
(-)Eclipse (+149 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.incubator;
13
14
import org.eclipse.core.databinding.BindSpec;
15
import org.eclipse.core.databinding.DataBindingContext;
16
import org.eclipse.core.databinding.observable.Realm;
17
import org.eclipse.core.databinding.observable.value.IObservableValue;
18
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
19
import org.eclipse.core.databinding.observable.value.ValueDiff;
20
import org.eclipse.core.databinding.observable.value.WritableValue;
21
import org.eclipse.core.databinding.util.IFilter;
22
import org.eclipse.jface.databinding.swt.SWTObservables;
23
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
24
import org.eclipse.jface.dialogs.PopupDialog;
25
import org.eclipse.jface.layout.GridLayoutFactory;
26
import org.eclipse.jface.viewers.LabelProvider;
27
import org.eclipse.jface.viewers.TableViewer;
28
import org.eclipse.jface.viewers.ViewerComparator;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.events.DisposeEvent;
31
import org.eclipse.swt.events.DisposeListener;
32
import org.eclipse.swt.layout.GridData;
33
import org.eclipse.swt.widgets.Composite;
34
import org.eclipse.swt.widgets.Control;
35
import org.eclipse.swt.widgets.Display;
36
import org.eclipse.swt.widgets.Shell;
37
import org.eclipse.swt.widgets.Text;
38
import org.eclipse.ui.internal.incubator.IncrementalFilterSet.IElementStream;
39
import org.eclipse.ui.internal.incubator.IncrementalFilterSet.IStreamVisitor;
40
41
import com.ibm.icu.text.DecimalFormat;
42
43
/**
44
 * @since 3.3
45
 * 
46
 */
47
public class QuickAccessPopup extends PopupDialog {
48
49
	static final int FILTER_WAIT = 0;
50
	static final int VISITOR_WAIT = 0;
51
52
	private Text text;
53
	private TableViewer tableViewer;
54
	private Composite composite;
55
	private IncrementalFilterSet filteredContents;
56
	protected String filterText = ""; //$NON-NLS-1$
57
	private final IElementStream elementStream;
58
59
	/**
60
	 * 
61
	 * @param parent
62
	 */
63
	public QuickAccessPopup(Shell parent, IElementStream elementStream) {
64
		super(parent, PopupDialog.INFOPOPUPRESIZE_SHELLSTYLE, true, true, true,
65
				true, null, null);
66
		this.elementStream = elementStream;
67
	}
68
69
	protected Control createDialogArea(Composite parent) {
70
		composite = new Composite(parent, SWT.NONE);
71
		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
72
		text = new Text(composite, SWT.NONE);
73
		tableViewer = new TableViewer(composite);
74
		bind();
75
		GridLayoutFactory.fillDefaults().generateLayout(composite);
76
		return composite;
77
	}
78
79
	/**
80
	 * 
81
	 */
82
	private void bind() {
83
		Realm swtRealm = SWTObservables.getRealm(getShell().getDisplay());
84
		final DataBindingContext dbc = new DataBindingContext(swtRealm);
85
		composite.addDisposeListener(new DisposeListener() {
86
			public void widgetDisposed(DisposeEvent e) {
87
				dbc.dispose();
88
			}
89
		});
90
		tableViewer.setContentProvider(new ObservableSetContentProvider());
91
		tableViewer.setComparator(new ViewerComparator());
92
		tableViewer.setLabelProvider(new LabelProvider() {
93
			public String getText(Object element) {
94
				return ((QuickAccessElement)element).getLabel();
95
			}
96
		});
97
		final WritableValue filterTextObservable = new WritableValue(swtRealm,
98
				String.class);
99
		dbc.bindValue(SWTObservables.observeText(text, SWT.Modify),
100
				filterTextObservable, new BindSpec().setUpdateTarget(false));
101
		filteredContents = new IncrementalFilterSet(getShell().getDisplay(),
102
				elementStream, new IFilter() {
103
					public boolean select(Object toTest) {
104
						return ((QuickAccessElement) toTest).getLabel()
105
								.indexOf(filterText) != -1;
106
					}
107
				});
108
		filterTextObservable.addValueChangeListener(new IValueChangeListener() {
109
			public void handleValueChange(IObservableValue source,
110
					ValueDiff diff) {
111
				String oldFilterText = filterText;
112
				filterText = (String) filterTextObservable.getValue();
113
				if (filterText.startsWith(oldFilterText)) {
114
					filteredContents.requestFilter();
115
				} else if (filterText.length() == 0) {
116
					filteredContents.requestClear();
117
				} else {
118
					filteredContents.requestRecalculation();
119
				}
120
			}
121
		});
122
		tableViewer.setInput(filteredContents);
123
	}
124
125
	public static void main(String[] args) {
126
		Display display = new Display();
127
		final DecimalFormat decimalFormat = new DecimalFormat("0000"); //$NON-NLS-1$
128
		QuickAccessPopup popup = new QuickAccessPopup(null,
129
				new IElementStream() {
130
					public void accept(IStreamVisitor visitor) {
131
						for (int i = 0; i < 10000; i++) {
132
							final Integer val = new Integer(i);
133
							visitor.visit(new QuickAccessElement() {
134
								public String getLabel() {
135
									return decimalFormat.format(val);
136
								}
137
							});
138
						}
139
					}
140
				});
141
		popup.setBlockOnOpen(true);
142
		popup.open();
143
		while (popup.getShell() != null && !popup.getShell().isDisposed()) {
144
			if (!display.readAndDispatch()) {
145
				display.sleep();
146
			}
147
		}
148
	}
149
}
(-)Eclipse (+34 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.incubator;
13
14
/**
15
 * @since 3.3
16
 *
17
 */
18
public abstract class QuickAccessElement {
19
20
	/**
21
	 * @return
22
	 */
23
	public abstract String getLabel();
24
25
	public boolean equals(Object o) {
26
		if (o.getClass()!=this.getClass())return false;
27
		return ((QuickAccessElement)o).getLabel().equals(getLabel());
28
	}
29
30
	public int hashCode() {
31
		return getLabel().hashCode();
32
	}
33
34
}
(-)Eclipse (+318 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 ******************************************************************************/
11
12
package org.eclipse.ui.internal.incubator;
13
14
import java.util.Collections;
15
import java.util.HashSet;
16
import java.util.LinkedList;
17
import java.util.Set;
18
19
import org.eclipse.core.databinding.observable.Diffs;
20
import org.eclipse.core.databinding.observable.set.ObservableSet;
21
import org.eclipse.core.databinding.util.IFilter;
22
import org.eclipse.core.runtime.IProgressMonitor;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.Status;
25
import org.eclipse.core.runtime.jobs.Job;
26
import org.eclipse.jface.databinding.swt.SWTObservables;
27
import org.eclipse.swt.widgets.Display;
28
29
/**
30
 * @since 3.3
31
 * 
32
 */
33
public class IncrementalFilterSet extends ObservableSet {
34
35
	/**
36
	 * 
37
	 */
38
	private static final int MAX_WORK = 100;
39
40
	public static interface IElementStream {
41
		public void accept(IStreamVisitor visitor);
42
	}
43
44
	public static interface IStreamVisitor {
45
		public boolean visit(Object element);
46
	}
47
48
	protected static final boolean DEBUG = true;
49
50
	private IFilter filter;
51
52
	private static Object CLEAR_ALL = new Object();
53
	private static Object MODE_ADD = new Object();
54
	private static Object MODE_REMOVE = new Object();
55
	/**
56
	 * CLEAR_ALL element in this list represents a clear all operation, MODE_ADD
57
	 * changes the mode so that from now on, other elements represent an add
58
	 * operation with that element, and MODE_REMOVE changes the mode so that
59
	 * from now on, other elements represent a remove operation of that element
60
	 */
61
	private LinkedList workQueue = new LinkedList();
62
	// the workQueue writer's current state
63
	boolean writerAdding = true;
64
	// the workQueue reader's current state
65
	boolean readerAdding = true;
66
67
	private static Object REQUEST_RECALCULATE = new Object();
68
	private static Object REQUEST_FILTER = new Object();
69
	private static Object REQUEST_CLEAR = new Object();
70
	private LinkedList requestQueue = new LinkedList();
71
	boolean consistent = false;
72
73
	private Job filterJob = new Job("Filtering") { //$NON-NLS-1$
74
		Object request;
75
76
		protected IStatus run(IProgressMonitor monitor) {
77
			try {
78
				request = dequeue(requestQueue);
79
				while (request != null) {
80
					if (request == REQUEST_CLEAR) {
81
						if (DEBUG) {
82
							System.out.println("clearing"); //$NON-NLS-1$
83
						}
84
						request = null;
85
						enqueueWorkQueueClearAll();
86
						consistent = false;
87
						scheduleWorker();
88
					} else if (consistent && request == REQUEST_FILTER) {
89
						if (DEBUG) {
90
							System.out
91
									.println("filtering, wrappedSet.size=" + wrappedSet.size()); //$NON-NLS-1$
92
						}
93
						int filtered = 0;
94
						request = null;
95
						boolean removing;
96
						synchronized (workQueue) {
97
							removing = workQueue.isEmpty();
98
						}
99
						if (!removing) {
100
							enqueueWorkQueueClearAll();
101
							scheduleWorker();
102
						}
103
						Object[] elements = wrappedSet
104
								.toArray(new Object[wrappedSet.size()]);
105
						for (int i = 0; request == null && i < elements.length; i++) {
106
							Object element = elements[i];
107
							if (!filter.select(element)) {
108
								if (removing) {
109
									if (writerAdding) {
110
										enqueue(workQueue, MODE_REMOVE);
111
										writerAdding = false;
112
									}
113
									enqueue(workQueue, element);
114
									scheduleWorker();
115
									filtered++;
116
								}
117
							} else {
118
								if (!removing) {
119
									if (!writerAdding) {
120
										enqueue(workQueue, MODE_ADD);
121
										writerAdding = true;
122
									}
123
									enqueue(workQueue, element);
124
									scheduleWorker();
125
									filtered++;
126
								}
127
							}
128
							request = dequeue(requestQueue);
129
						}
130
						if (DEBUG) {
131
							System.out
132
									.println("filtered: " + (removing ? "removed " : "added ") + filtered + " elements"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
133
						}
134
					} else if (request == REQUEST_RECALCULATE
135
							|| (request == REQUEST_FILTER && !consistent)) {
136
						if (DEBUG) {
137
							System.out.println("recalculating"); //$NON-NLS-1$
138
						}
139
						request = null;
140
						enqueueWorkQueueClearAll();
141
						consistent = false;
142
						scheduleWorker();
143
						stream.accept(new IStreamVisitor() {
144
							public boolean visit(Object element) {
145
								if (request == null) {
146
									if (filter.select(element)) {
147
										if (!writerAdding) {
148
											enqueue(workQueue, MODE_ADD);
149
											writerAdding = true;
150
										}
151
										enqueue(workQueue, element);
152
										scheduleWorker();
153
									}
154
									request = dequeue(requestQueue);
155
								}
156
								return request == null;
157
							}
158
						});
159
						if (request == null) {
160
							consistent = true;
161
						}
162
					} else {
163
						throw new RuntimeException("unhandled case"); //$NON-NLS-1$
164
					}
165
					if (request == null) {
166
						request = dequeue(requestQueue);
167
					}
168
				}
169
			} catch (Exception ex) {
170
				ex.printStackTrace();
171
			}
172
			return Status.OK_STATUS;
173
		}
174
	};
175
176
	private Runnable worker;
177
178
	private Display display;
179
180
	private final IElementStream stream;
181
182
	private void enqueue(LinkedList queue, Object element) {
183
		synchronized (queue) {
184
			queue.addLast(element);
185
		}
186
	}
187
188
	/**
189
	 * non-blocking - returns null if no element in queue
190
	 * 
191
	 * @param queue
192
	 *            TODO
193
	 */
194
	Object dequeue(LinkedList queue) {
195
		synchronized (queue) {
196
			return queue.isEmpty() ? null : queue.removeFirst();
197
		}
198
	}
199
200
	/**
201
	 */
202
	protected IncrementalFilterSet(Display display, IElementStream stream,
203
			IFilter filter) {
204
		super(SWTObservables.getRealm(display), new HashSet(), Object.class);
205
		this.display = display;
206
		this.stream = stream;
207
		this.filter = filter;
208
	}
209
210
	/**
211
	 * May be called from any thread. Non-blocking.
212
	 * 
213
	 * @param stream
214
	 * @throws InterruptedException
215
	 */
216
	public void requestFilter() {
217
		enqueue(requestQueue, REQUEST_FILTER);
218
		filterJob.schedule();
219
	}
220
221
	public void requestRecalculation() {
222
		enqueue(requestQueue, REQUEST_RECALCULATE);
223
		filterJob.schedule();
224
	}
225
226
	/**
227
	 * 
228
	 */
229
	protected void scheduleWorker() {
230
		if (worker == null) {
231
			worker = new Runnable() {
232
				public void run() {
233
					Object work;
234
					Set additions = new HashSet();
235
					Set removals = new HashSet();
236
					int worked = 0;
237
					while (++worked < MAX_WORK
238
							&& (work = dequeue(workQueue)) != null) {
239
						if (work == CLEAR_ALL) {
240
							fireSetChange(Diffs.createSetDiff(
241
									Collections.EMPTY_SET, wrappedSet));
242
							wrappedSet = new HashSet();
243
							additions=new HashSet();
244
							removals=new HashSet();
245
							worked = MAX_WORK;
246
						} else if (work == MODE_ADD) {
247
							readerAdding = true;
248
							if (removals.size() > 0) {
249
								processRemovals(removals);
250
								worked = MAX_WORK;
251
							}
252
						} else if (work == MODE_REMOVE) {
253
							readerAdding = false;
254
							if (additions.size() > 0) {
255
								processAdditions(additions);
256
								worked = MAX_WORK;
257
							}
258
						} else if (readerAdding) {
259
								additions.add(work);
260
						} else {
261
								removals.add(work);
262
						}
263
					}
264
					processRemovals(removals);
265
					processAdditions(additions);
266
					synchronized (workQueue) {
267
						if (!workQueue.isEmpty()) {
268
							scheduleWorker();
269
						}
270
					}
271
				}
272
273
				private void processAdditions(Set additions) {
274
					if (!additions.isEmpty()) {
275
						if (DEBUG) {
276
							System.out.println("processing " + additions.size() //$NON-NLS-1$
277
									+ " additions"); //$NON-NLS-1$
278
						}
279
						wrappedSet.addAll(additions);
280
						fireSetChange(Diffs.createSetDiff(additions,
281
								Collections.EMPTY_SET));
282
						additions = new HashSet();
283
					}
284
				}
285
286
				private void processRemovals(Set removals) {
287
					if (!removals.isEmpty()) {
288
						if (DEBUG) {
289
							System.out.println("processing " + removals.size() //$NON-NLS-1$
290
									+ " removals"); //$NON-NLS-1$
291
						}
292
						wrappedSet.removeAll(removals);
293
						fireSetChange(Diffs.createSetDiff(
294
								Collections.EMPTY_SET, removals));
295
						removals = new HashSet();
296
					}
297
				}
298
			};
299
		}
300
		display.asyncExec(worker);
301
	}
302
303
	/**
304
	 * 
305
	 */
306
	public void requestClear() {
307
		enqueue(requestQueue, REQUEST_CLEAR);
308
		filterJob.schedule();
309
	}
310
311
	private void enqueueWorkQueueClearAll() {
312
		// enqueue clear all operation
313
		synchronized (workQueue) {
314
			workQueue.clear();
315
			workQueue.addLast(CLEAR_ALL);
316
		}
317
	}
318
}

Return to bug 167010