Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMickael Istria2019-08-02 14:10:56 +0000
committerMickael Istria2019-08-07 06:01:52 +0000
commit105036967aeb19a190eee942c4a8ddc5ffd065bb (patch)
tree47b7a715984b1582f8a9a1ad09723ee31f602111
parent5dd4aecee96ad1f2d01f408b38bbe719fece5224 (diff)
downloadeclipse.platform.ui-105036967aeb19a190eee942c4a8ddc5ffd065bb.tar.gz
eclipse.platform.ui-105036967aeb19a190eee942c4a8ddc5ffd065bb.tar.xz
eclipse.platform.ui-105036967aeb19a190eee942c4a8ddc5ffd065bb.zip
Bug 548058 - API for incremental QuickAccess providers
Introduce a IQuickAccessComputerExtension to allow to query for QuickAccessElement when filter content changes. The API is ready for long running operations and cancellation. Only cancellation is implemented at the moment, long running operation are still blocking (but this can/will be improved in another commit). Change-Id: Ib2a880fa201255ea4276f66cc30fe4941458474b Signed-off-by: Mickael Istria <mistria@redhat.com>
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/PreviousPicksProvider.java3
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java18
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessExtensionManager.java17
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessProvider.java53
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputer.java11
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputerExtension.java54
-rw-r--r--bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.ui.workbench/pom.xml2
8 files changed, 141 insertions, 19 deletions
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/PreviousPicksProvider.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/PreviousPicksProvider.java
index 229a8b3f8ef..9f0fd9e22f4 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/PreviousPicksProvider.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/PreviousPicksProvider.java
@@ -17,6 +17,7 @@ package org.eclipse.ui.internal.quickaccess;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
import org.eclipse.ui.internal.WorkbenchImages;
@@ -43,7 +44,7 @@ class PreviousPicksProvider extends QuickAccessProvider {
}
@Override
- public QuickAccessElement[] getElementsSorted() {
+ public QuickAccessElement[] getElementsSorted(String filter, IProgressMonitor monitor) {
return getElements();
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java
index 5a0bccdbd72..181840aced4 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessContents.java
@@ -31,6 +31,8 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.core.runtime.Adapters;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
@@ -94,6 +96,7 @@ public abstract class QuickAccessContents {
private static final int MIN_SEARCH_LENGTH = 3;
protected Text filterText;
+ private IProgressMonitor monitor;
private QuickAccessProvider[] providers;
private Map<String, QuickAccessProvider> providerMap = new HashMap<>();
@@ -138,6 +141,10 @@ public abstract class QuickAccessContents {
*
*/
public void refresh(String filter) {
+ if (monitor != null) {
+ monitor.setCanceled(true);
+ monitor = null;
+ }
if (table != null) {
boolean filterTextEmpty = filter.length() == 0;
@@ -151,7 +158,8 @@ public abstract class QuickAccessContents {
// perfect match, to be selected in the table if not null
QuickAccessElement perfectMatch = getPerfectMatch(filter);
- List<QuickAccessEntry>[] entries = computeMatchingEntries(filter, perfectMatch, extraEntries);
+ monitor = new NullProgressMonitor();
+ List<QuickAccessEntry>[] entries = computeMatchingEntries(filter, perfectMatch, extraEntries, monitor);
int selectionIndex = refreshTable(perfectMatch, entries, extraEntries);
if (table.getItemCount() > 0) {
@@ -424,11 +432,12 @@ public abstract class QuickAccessContents {
* @param extraEntries extra entries that will be added to the tabular
* visualization after computing matching entries, i.e.
* Search in Help
+ * @param aMonitor
* @return the array of lists (one per provider) contains the quick access
* entries that should be added to the table, possibly empty
*/
private List<QuickAccessEntry>[] computeMatchingEntries(String filter, QuickAccessElement perfectMatch,
- List<QuickAccessEntry> extraEntries) {
+ List<QuickAccessEntry> extraEntries, IProgressMonitor aMonitor) {
// collect matches in an array of lists
@SuppressWarnings("unchecked")
List<QuickAccessEntry>[] entries = new List[providers.length];
@@ -458,6 +467,9 @@ public abstract class QuickAccessContents {
filter = category + " " + categoryMatcher.group(2); //$NON-NLS-1$
}
for (int i = 0; i < providers.length && (showAllMatches || countTotal < maxCount); i++) {
+ if (aMonitor.isCanceled()) {
+ break;
+ }
if (entries[i] == null) {
entries[i] = new ArrayList<>();
indexPerProvider[i] = 0;
@@ -471,7 +483,7 @@ public abstract class QuickAccessContents {
continue;
}
if (filter.length() > 0 || provider.isAlwaysPresent() || showAllMatches) {
- QuickAccessElement[] sortedElements = provider.getElementsSorted();
+ QuickAccessElement[] sortedElements = provider.getElementsSorted(filter, aMonitor);
if (!(provider instanceof PreviousPicksProvider)) {
for (QuickAccessElement element : sortedElements) {
elementsToProviders.put(element, provider);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessExtensionManager.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessExtensionManager.java
index 721a6401d7b..c47edb74904 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessExtensionManager.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessExtensionManager.java
@@ -18,6 +18,7 @@ import java.util.Collection;
import java.util.stream.Collectors;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.osgi.util.NLS;
@@ -25,6 +26,7 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.quickaccess.IQuickAccessComputer;
+import org.eclipse.ui.quickaccess.IQuickAccessComputerExtension;
import org.eclipse.ui.quickaccess.QuickAccessElement;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
@@ -123,12 +125,12 @@ public class QuickAccessExtensionManager {
}
@Override
- public QuickAccessElement[] getElementsSorted() {
+ public QuickAccessElement[] getElementsSorted(String filter, IProgressMonitor monitor) {
if (canDelegate()) {
if (computer.needsRefresh()) {
reset();
}
- return super.getElementsSorted();
+ return super.getElementsSorted(filter, monitor);
}
return activateElement;
}
@@ -142,6 +144,17 @@ public class QuickAccessExtensionManager {
}
@Override
+ public QuickAccessElement[] getElements(String filter, IProgressMonitor monitor) {
+ if (canDelegate()) {
+ if (computer instanceof IQuickAccessComputerExtension) {
+ return ((IQuickAccessComputerExtension) computer).computeElements(filter, monitor);
+ }
+ return null;
+ }
+ return activateElement;
+ }
+
+ @Override
protected void doReset() {
if (canDelegate()) {
computer.resetState();
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessProvider.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessProvider.java
index f2503a07d70..b61fcd0709f 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessProvider.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/QuickAccessProvider.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2015 IBM Corporation and others.
+4 * Copyright (c) 2006, 2015 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,6 +14,10 @@
package org.eclipse.ui.internal.quickaccess;
import java.util.Arrays;
+import java.util.Comparator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.quickaccess.QuickAccessElement;
@@ -24,7 +28,10 @@ import org.eclipse.ui.quickaccess.QuickAccessElement;
*/
public abstract class QuickAccessProvider {
- private QuickAccessElement[] sortedElements;
+ /*
+ * Cached elements that are always returned
+ */
+ private QuickAccessElement[] cacheSortedElements;
/**
* Returns the unique ID of this provider.
@@ -48,18 +55,42 @@ public abstract class QuickAccessProvider {
public abstract ImageDescriptor getImageDescriptor();
/**
- * Returns the elements provided by this provider.
+ * Returns the elements provided by this provider in all circumstances. Elements
+ * get filter downstream in the process, so this list can be greedy. The result
+ * may be cached and reused so this method may be invoked only once for a
+ * QuickAccess session.
*
* @return this provider's elements
*/
public abstract QuickAccessElement[] getElements();
- public QuickAccessElement[] getElementsSorted() {
- if (sortedElements == null) {
- sortedElements = getElements();
- Arrays.sort(sortedElements, (e1, e2) -> e1.getSortLabel().compareTo(e2.getSortLabel()));
+ /**
+ * Returns the elements provided by this provider in all circumstances. Elements
+ * get filter downstream in the process, so this list can be greedy. The result
+ * isn't cached and reused, so this method will be invoked whenever user change
+ * input.
+ *
+ * @param filter user input
+ * @param monitor
+ * @return this provider's elements
+ */
+ public QuickAccessElement[] getElements(String filter, IProgressMonitor monitor) {
+ return null;
+ }
+
+ public QuickAccessElement[] getElementsSorted(String filter, IProgressMonitor monitor) {
+ if (cacheSortedElements == null) {
+ cacheSortedElements = getElements();
+ Arrays.sort(cacheSortedElements, Comparator.comparing(QuickAccessElement::getSortLabel));
+ }
+ QuickAccessElement[] filterSpecificElements = getElements(filter, monitor);
+ if (filterSpecificElements == null || filterSpecificElements.length == 0) {
+ return cacheSortedElements;
}
- return sortedElements;
+ SortedSet<QuickAccessElement> res = new TreeSet<>(Comparator.comparing(QuickAccessElement::getSortLabel));
+ res.addAll(Arrays.asList(cacheSortedElements));
+ res.addAll(Arrays.asList(filterSpecificElements));
+ return res.toArray(new QuickAccessElement[res.size()]);
}
/**
@@ -73,8 +104,8 @@ public abstract class QuickAccessProvider {
if (id == null) {
return null;
}
- if (sortedElements != null) {
- for (QuickAccessElement element : sortedElements) {
+ if (cacheSortedElements != null) {
+ for (QuickAccessElement element : cacheSortedElements) {
if (id.equals(element.getId())) {
return element;
}
@@ -92,7 +123,7 @@ public abstract class QuickAccessProvider {
* method will retrigger computation of elements.
*/
public final void reset() {
- sortedElements = null;
+ cacheSortedElements = null;
doReset();
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputer.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputer.java
index a7da9a3a2ce..d06d08bd9e6 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputer.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputer.java
@@ -17,12 +17,23 @@ package org.eclipse.ui.quickaccess;
* Implementations of this interface are used to compute some extra content for
* the Quick Access features, using extension point
* <code>org.eclipse.ui.quickaccess</code>.
+ * <p>
+ * Use extension class {@link IQuickAccessComputerExtension} to run a new query
+ * and return new results whenever filter text change.
+ * </p>
*
* @since 3.115
*/
public interface IQuickAccessComputer {
/**
+ * Returns the elements to add to the Quick Access proposals, for any request or
+ * filter.
+ * <p>
+ * The returned elements are then filtered according to user input so only
+ * relevant ones are shown in the list of proposals.
+ * </p>
+ *
* @return the elements to add to the Quick Access proposals
*/
QuickAccessElement[] computeElements();
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputerExtension.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputerExtension.java
new file mode 100644
index 00000000000..a3de4955ff9
--- /dev/null
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/quickaccess/IQuickAccessComputerExtension.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Mickael Istria (Red Hat Inc.)
+ *******************************************************************************/
+package org.eclipse.ui.quickaccess;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Extension interface for {@link IQuickAccessComputer} that provides ability to
+ * compute a new extra set of proposals whenever filter change.
+ * <p>
+ * This interfaces is intended to cover cases for which computing all possible
+ * elements statically with {@link IQuickAccessComputer#computeElements()} is
+ * either impossible or too expensive or not relevant; in which case it can be
+ * preferred to compute those proposals according to user input.
+ * </p>
+ * <p>
+ * This interface is not intended to deal with filtering: the returned elements
+ * would still be filtered according to user input.
+ * </p>
+ *
+ * @since 3.116
+ */
+public interface IQuickAccessComputerExtension extends IQuickAccessComputer {
+
+ /**
+ * Returns elements that are relevant for the given query.
+ * <p>
+ * This method is not intended to deal with filtering: the returned elements
+ * will still be filtered according to user input.
+ * </p>
+ * <p>
+ * This method will be called for each change in the query. So, if possible,
+ * it's preferred to use {@link IQuickAccessComputer#computeElements()} which is
+ * called only once per session and whose result is reused, leading to better
+ * performance.
+ * </p>
+ *
+ * @param query query text
+ * @param monitor support for feedback and cancellation
+ * @return the elements that can be inferred from the query.
+ */
+ public QuickAccessElement[] computeElements(String query, IProgressMonitor monitor);
+}
diff --git a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF
index f9897d15f8f..c13693a74be 100644
--- a/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.ui.workbench/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ui.workbench; singleton:=true
-Bundle-Version: 3.115.100.qualifier
+Bundle-Version: 3.116.0.qualifier
Bundle-ClassPath: .
Bundle-Activator: org.eclipse.ui.internal.WorkbenchPlugin
Bundle-ActivationPolicy: lazy
diff --git a/bundles/org.eclipse.ui.workbench/pom.xml b/bundles/org.eclipse.ui.workbench/pom.xml
index cbee2561db2..204f193efb6 100644
--- a/bundles/org.eclipse.ui.workbench/pom.xml
+++ b/bundles/org.eclipse.ui.workbench/pom.xml
@@ -20,7 +20,7 @@
</parent>
<groupId>org.eclipse.ui</groupId>
<artifactId>org.eclipse.ui.workbench</artifactId>
- <version>3.115.100-SNAPSHOT</version>
+ <version>3.116.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>

Back to the top