Bug 487400 - [patch] Enable filtering for classpath tab entries
Change-Id: Ie5fab6e51a8e5dc88c1fe07f5c4ed0edfd03632f
Signed-off-by: Christian Buck <c.buck@gmx.de>
diff --git a/org.eclipse.jdt.debug.ui/.settings/.api_filters b/org.eclipse.jdt.debug.ui/.settings/.api_filters
index f23a01b..2a6baac 100644
--- a/org.eclipse.jdt.debug.ui/.settings/.api_filters
+++ b/org.eclipse.jdt.debug.ui/.settings/.api_filters
@@ -1,43 +1,35 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jdt.debug.ui" version="2">
- <resource path="ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java" type="org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab">
- <filter comment="Known illegal extension" id="576720909">
- <message_arguments>
- <message_argument value="AbstractJavaClasspathTab"/>
- <message_argument value="JavaClasspathTab"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="ui/org/eclipse/jdt/internal/debug/ui/classpath/ClasspathEntry.java" type="org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry">
- <filter comment="Known illegal implementation" id="574619656">
- <message_arguments>
- <message_argument value="IRuntimeClasspathEntry"/>
- <message_argument value="ClasspathEntry"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java" type="org.eclipse.jdt.internal.debug.ui.classpath.RuntimeClasspathViewer">
- <filter comment="Known illegal extension" id="571473929">
- <message_arguments>
- <message_argument value="TreeViewer"/>
- <message_argument value="RuntimeClasspathViewer"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="ui/org/eclipse/jdt/internal/debug/ui/display/DisplayViewerConfiguration.java" type="org.eclipse.jdt.internal.debug.ui.display.DisplayViewerConfiguration">
- <filter id="571473929">
- <message_arguments>
- <message_argument value="JavaSourceViewerConfiguration"/>
- <message_argument value="DisplayViewerConfiguration"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletSelectionDialog.java" type="org.eclipse.jdt.internal.debug.ui.launcher.AppletSelectionDialog$PackageRenderer">
- <filter comment="known API usage" id="571473929">
- <message_arguments>
- <message_argument value="JavaElementLabelProvider"/>
- <message_argument value="PackageRenderer"/>
- </message_arguments>
- </filter>
- </resource>
-</component>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jdt.debug.ui" version="2">
+ <resource path="ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java" type="org.eclipse.jdt.debug.ui.launchConfigurations.JavaClasspathTab">
+ <filter comment="Known illegal extension" id="576720909">
+ <message_arguments>
+ <message_argument value="AbstractJavaClasspathTab"/>
+ <message_argument value="JavaClasspathTab"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="ui/org/eclipse/jdt/internal/debug/ui/classpath/ClasspathEntry.java" type="org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry">
+ <filter comment="Known illegal implementation" id="574619656">
+ <message_arguments>
+ <message_argument value="IRuntimeClasspathEntry"/>
+ <message_argument value="ClasspathEntry"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="ui/org/eclipse/jdt/internal/debug/ui/display/DisplayViewerConfiguration.java" type="org.eclipse.jdt.internal.debug.ui.display.DisplayViewerConfiguration">
+ <filter id="571473929">
+ <message_arguments>
+ <message_argument value="JavaSourceViewerConfiguration"/>
+ <message_argument value="DisplayViewerConfiguration"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="ui/org/eclipse/jdt/internal/debug/ui/launcher/AppletSelectionDialog.java" type="org.eclipse.jdt.internal.debug.ui.launcher.AppletSelectionDialog$PackageRenderer">
+ <filter comment="known API usage" id="571473929">
+ <message_arguments>
+ <message_argument value="JavaElementLabelProvider"/>
+ <message_argument value="PackageRenderer"/>
+ </message_arguments>
+ </filter>
+ </resource>
+</component>
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java
index 13afaae..19087d3 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 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
@@ -121,13 +121,13 @@
fClasspathViewer = new RuntimeClasspathViewer(comp);
fClasspathViewer.addEntriesChangedListener(this);
- fClasspathViewer.getControl().setFont(font);
- fClasspathViewer.setLabelProvider(new ClasspathLabelProvider());
- fClasspathViewer.setContentProvider(new ClasspathContentProvider(this));
+ fClasspathViewer.getTreeViewer().getControl().setFont(font);
+ fClasspathViewer.getTreeViewer().setLabelProvider(new ClasspathLabelProvider());
+ fClasspathViewer.getTreeViewer().setContentProvider(new ClasspathContentProvider(this));
if (!isShowBootpath()) {
- fClasspathViewer.addFilter(new BootpathFilter());
+ fClasspathViewer.getTreeViewer().addFilter(new BootpathFilter());
}
-
+
Composite pathButtonComp = new Composite(comp, SWT.NONE);
GridLayout pathButtonLayout = new GridLayout();
pathButtonLayout.marginHeight = 0;
@@ -208,7 +208,7 @@
@Override
public void initializeFrom(ILaunchConfiguration configuration) {
refresh(configuration);
- fClasspathViewer.expandToLevel(2);
+ fClasspathViewer.getTreeViewer().expandToLevel(2);
}
/* (non-Javadoc)
@@ -224,7 +224,7 @@
return;
}
}
- fClasspathViewer.refresh();
+ fClasspathViewer.getTreeViewer().refresh();
} catch (CoreException e) {
}
}
@@ -235,23 +235,8 @@
* @param configuration the configuration
*/
private void refresh(ILaunchConfiguration configuration) {
- boolean useDefault = true;
setErrorMessage(null);
- try {
- useDefault = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
- } catch (CoreException e) {
- JDIDebugUIPlugin.log(e);
- }
-
- if (configuration == getLaunchConfiguration()) {
- // no need to update if an explicit path is being used and this setting
- // has not changed (and viewing the same config as last time)
- if (!useDefault) {
- setDirty(false);
- return;
- }
- }
-
+
setLaunchConfiguration(configuration);
try {
createClasspathModel(configuration);
@@ -260,7 +245,7 @@
}
fClasspathViewer.setLaunchConfiguration(configuration);
- fClasspathViewer.setInput(fModel);
+ fClasspathViewer.getTreeViewer().setInput(fModel);
setDirty(false);
}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java
index 3299fb8..a50fa2d 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 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
@@ -15,6 +15,8 @@
import java.util.Iterator;
import java.util.List;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
@@ -27,8 +29,8 @@
import org.eclipse.jdt.internal.debug.ui.launcher.IEntriesChangedListener;
import org.eclipse.jdt.internal.launching.LaunchingPlugin;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
-import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
@@ -37,14 +39,16 @@
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
+import org.eclipse.ui.progress.WorkbenchJob;
/**
* A viewer that displays and manipulates runtime classpath entries.
*/
-public class RuntimeClasspathViewer extends TreeViewer implements IClasspathViewer {
+public class RuntimeClasspathViewer implements IClasspathViewer {
/**
* Entry changed listeners
@@ -70,31 +74,86 @@
}
};
+
+ private static class RuntimeClasspathFilteredTree extends FilteredTree {
+
+ private boolean isFiltering;
+
+ private RuntimeClasspathFilteredTree(Composite parent, PatternFilter filter) {
+ super(parent, 0, filter, true);
+ }
+
+ private boolean hasFilterTextEntered() {
+ return isFiltering;
+ }
+
+ /**
+ * Called by modify listener -> implicit change listener.
+ */
+ @Override
+ protected void textChanged() {
+
+ super.textChanged();
+
+ final String filterString = getFilterString();
+ if (null != filterString) {
+ // REVIEW: There are several different ways used to check for empty filter texts:
+ // comparing with "", comparing with IInternalDebugCoreConstants.EMPTY_STRING and checking size of trimmed value.
+ isFiltering = !filterString.trim().isEmpty();
+ } else {
+ isFiltering = false;
+ }
+ }
+
+ @Override
+ protected WorkbenchJob doCreateRefreshJob() {
+ final WorkbenchJob job = super.doCreateRefreshJob();
+
+ return new WorkbenchJob("Classpath filter refresh") { //$NON-NLS-1$
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ final IStatus status = job.runInUIThread(monitor);
+
+ if (!isFiltering) {
+ getViewer().expandToLevel(2);
+ }
+
+ return status;
+ }
+ };
+ }
+ }
+
+ private final RuntimeClasspathFilteredTree fTree;
+ public TreeViewer getTreeViewer() {
+ return fTree.getViewer();
+ }
+
/**
* Creates a runtime classpath viewer with the given parent.
*
* @param parent the parent control
*/
public RuntimeClasspathViewer(Composite parent) {
- super(parent);
- GridData data = new GridData(GridData.FILL_BOTH);
- data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
- data.heightHint = getTree().getItemHeight();
- getTree().setLayoutData(data);
+ final PatternFilter filter = new PatternFilter();
+ filter.setIncludeLeadingWildcard(true);
+ fTree = new RuntimeClasspathFilteredTree(parent, filter);
- getTree().addKeyListener(new KeyAdapter() {
+ getTreeViewer().getTree().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent event) {
- if (updateSelection(RuntimeClasspathAction.REMOVE, (IStructuredSelection)getSelection()) && event.character == SWT.DEL && event.stateMask == 0) {
- List<?> selection= getSelectionFromWidget();
- getClasspathContentProvider().removeAll(selection);
+ if (updateSelection(RuntimeClasspathAction.REMOVE, (IStructuredSelection) getSelection()) && event.character == SWT.DEL
+ && event.stateMask == 0) {
+ getClasspathContentProvider().removeAll(((IStructuredSelection) getSelectedEntries()).toList());
notifyChanged();
}
}
});
- getTree().addDisposeListener(new DisposeListener() {
+
+ fTree.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(LaunchingPlugin.ID_PLUGIN);
@@ -190,8 +249,8 @@
* @param configuration the backing {@link ILaunchConfiguration}
*/
public void setLaunchConfiguration(ILaunchConfiguration configuration) {
- if (getLabelProvider() != null) {
- ((ClasspathLabelProvider)getLabelProvider()).setLaunchConfiguration(configuration);
+ if (getTreeViewer().getLabelProvider() != null) {
+ ((ClasspathLabelProvider) getTreeViewer().getLabelProvider()).setLaunchConfiguration(configuration);
}
}
@@ -242,11 +301,11 @@
*/
@Override
public Shell getShell() {
- return getControl().getShell();
+ return getTreeViewer().getControl().getShell();
}
private ClasspathContentProvider getClasspathContentProvider() {
- return (ClasspathContentProvider)super.getContentProvider();
+ return (ClasspathContentProvider) getTreeViewer().getContentProvider();
}
/* (non-Javadoc)
@@ -268,8 +327,11 @@
}
}
return selection.size() > 0;
+ case RuntimeClasspathAction.MOVE:
+ if (fTree.hasFilterTextEntered()) {
+ return false;
+ }
case RuntimeClasspathAction.REMOVE :
- case RuntimeClasspathAction.MOVE :
selected= selection.iterator();
while (selected.hasNext()) {
IClasspathEntry entry = selected.next();
@@ -303,4 +365,30 @@
return new StructuredSelection(entries);
}
+
+ @Override
+ public void addSelectionChangedListener(ISelectionChangedListener listener) {
+ getTreeViewer().addSelectionChangedListener(listener);
+ }
+
+ @Override
+ public ISelection getSelection() {
+ return getTreeViewer().getSelection();
+ }
+
+ @Override
+ public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+ getTreeViewer().removeSelectionChangedListener(listener);
+ }
+
+ @Override
+ public void setSelection(ISelection selection) {
+ getTreeViewer().setSelection(selection);
+ }
+
+ @Override
+ public void refresh(Object entry) {
+ getTreeViewer().refresh();
+ }
+
}