diff --git a/core/org.eclipse.cdt.ui.tests/plugin.xml b/core/org.eclipse.cdt.ui.tests/plugin.xml
index 5d346cd499e..6e420b224ba 100644
--- a/core/org.eclipse.cdt.ui.tests/plugin.xml
+++ b/core/org.eclipse.cdt.ui.tests/plugin.xml
@@ -121,5 +121,12 @@
id="org.eclipse.cdt.ui.tests.DOMAST.DOMAST.IncludeStatementFilter">
+
+
+
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/ProposalFilterPreferencesTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/ProposalFilterPreferencesTest.java
new file mode 100644
index 00000000000..55d83482672
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/ProposalFilterPreferencesTest.java
@@ -0,0 +1,50 @@
+package org.eclipse.cdt.ui.tests.text.contentassist;
+
+import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
+import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil.ComboState;
+import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import junit.framework.TestCase;
+
+/**
+ * This test covers the convenience methods
+ * in org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil
+ */
+public class ProposalFilterPreferencesTest extends TestCase {
+
+ public void testPreferences() {
+ // Check that the test filter is among the filternames
+ String[] filterNames = ProposalFilterPreferencesUtil.getProposalFilterNames();
+ int index = -1 ;
+ for (int i = 0; i < filterNames.length; i++) {
+ String name = filterNames[i];
+ if (name.equals("Testing Completion Filter")) {
+ index = i ;
+ break ;
+ }
+ }
+ assertTrue("Did not find expected filter!", index>=0);
+
+ // Set the preference to the tested filter
+ IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore();
+ String filterComboStateString = store.getString(ContentAssistPreference.PROPOSALS_FILTER);
+ ProposalFilterPreferencesUtil.ComboState state = ProposalFilterPreferencesUtil.getComboState(filterComboStateString);
+ StringBuffer newStateText = new StringBuffer();
+ newStateText.append(index+1); // First entry is always the , index+1 must be selected
+ for (int i = 0; i < state.items.length; i++) {
+ String item = state.items[i];
+ newStateText.append(";");
+ newStateText.append(item);
+ }
+ store.setValue(ContentAssistPreference.PROPOSALS_FILTER, newStateText.toString());
+
+ // Now we can test preferred filter retrieval:
+ IConfigurationElement preferredElement = ProposalFilterPreferencesUtil.getPreferredFilterElement();
+ String extensionId = preferredElement.getAttribute("id");
+ assertNotNull("Configuration element was not found!", extensionId);
+ assertEquals("Unexpected element id", "org.eclipse.cdt.ui.tests.TestProposalFilter", extensionId);
+ }
+}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/TestProposalFilter.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/TestProposalFilter.java
new file mode 100644
index 00000000000..e7b65212f7e
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist/TestProposalFilter.java
@@ -0,0 +1,19 @@
+package org.eclipse.cdt.ui.tests.text.contentassist;
+
+import org.eclipse.cdt.ui.text.ICCompletionProposal;
+import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
+
+/**
+ * Dummy filter implementation for testing purposes
+ */
+public class TestProposalFilter implements IProposalFilter {
+
+ /**
+ * This dummy filter method will return the original proposals unmodified.
+ */
+ public ICCompletionProposal[] filterProposals(
+ ICCompletionProposal[] proposals) {
+ return proposals ;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml
index d41ba1f5c0f..da6bf1930f4 100644
--- a/core/org.eclipse.cdt.ui/plugin.xml
+++ b/core/org.eclipse.cdt.ui/plugin.xml
@@ -17,6 +17,7 @@
+
diff --git a/core/org.eclipse.cdt.ui/schema/ProposalFilter.exsd b/core/org.eclipse.cdt.ui/schema/ProposalFilter.exsd
new file mode 100644
index 00000000000..6b898119bca
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/schema/ProposalFilter.exsd
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+ This extension point allows contributors to make their implementation of ICompletionFilter known to the platform.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CDT 3.1
+
+
+
+
+
+
+
+
+ [Enter extension point usage example here.]
+
+
+
+
+
+
+
+
+ [Enter API information here.]
+
+
+
+
+
+
+
+
+ [Enter information about supplied implementation of this extension point.]
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/AbstractPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/AbstractPreferencePage.java
index a3c130c0b93..949ed5989c3 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/AbstractPreferencePage.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/AbstractPreferencePage.java
@@ -33,6 +33,7 @@ import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
@@ -63,6 +64,16 @@ public abstract class AbstractPreferencePage extends PreferencePage implements I
fOverlayStore.setValue((String) fTextFields.get(text), text.getText());
}
};
+
+ protected Map fComboBoxes = new HashMap();
+ private ModifyListener fComboBoxListener = new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ Combo combo = (Combo) e.widget;
+ String state = ProposalFilterPreferencesUtil.comboStateAsString(combo);
+ fOverlayStore.setValue((String) fComboBoxes.get(combo), state);
+ }
+ };
+
protected Map fCheckBoxes = new HashMap();
private SelectionListener fCheckBoxListener = new SelectionListener() {
@@ -157,6 +168,24 @@ public abstract class AbstractPreferencePage extends PreferencePage implements I
return textControl;
}
+ protected void addComboBox(Composite composite, String label, String key, int textLimit, int indentation) {
+
+ Label labelControl = new Label(composite, SWT.NONE);
+ labelControl.setText(label);
+ GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+ gd.horizontalIndent = indentation;
+ labelControl.setLayoutData(gd);
+
+ Combo comboControl = new Combo(composite, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); // TODO: When will the combo be disposed?
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ gd.widthHint = convertWidthInCharsToPixels(textLimit + 1);
+ comboControl.setLayoutData(gd);
+ comboControl.setTextLimit(textLimit);
+ fComboBoxes.put(comboControl, key);
+ comboControl.addModifyListener(fComboBoxListener); // TODO: When will the listener be removed?
+
+ }
+
protected void addFiller(Composite composite) {
PixelConverter pixelConverter= new PixelConverter(composite);
Label filler= new Label(composite, SWT.LEFT );
@@ -292,11 +321,22 @@ public abstract class AbstractPreferencePage extends PreferencePage implements I
String key = (String) fTextFields.get(t);
t.setText(fOverlayStore.getString(key));
}
+
+ e = fComboBoxes.keySet().iterator();
+ while (e.hasNext()) {
+ Combo c = (Combo) e.next();
+ String key = (String) fComboBoxes.get(c);
+ String state = fOverlayStore.getString(key);
+ // Interpret the state string as a Combo state description
+ ProposalFilterPreferencesUtil.restoreComboFromString(c, state);
+ }
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
public void init(IWorkbench workbench) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeAssistPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeAssistPreferencePage.java
index e147b045a4c..1a38dd84082 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeAssistPreferencePage.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CodeAssistPreferencePage.java
@@ -58,6 +58,7 @@ public class CodeAssistPreferencePage extends AbstractPreferencePage {
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ContentAssistPreference.ADD_INCLUDE));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ContentAssistPreference.CURRENT_FILE_SEARCH_SCOPE));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ContentAssistPreference.PROJECT_SEARCH_SCOPE));
+ overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ContentAssistPreference.PROPOSALS_FILTER));
OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
overlayKeys.toArray(keys);
@@ -135,7 +136,10 @@ public class CodeAssistPreferencePage extends AbstractPreferencePage {
// label= PreferencesMessages.getString("CEditorPreferencePage.ContentAssistPage.parameterForegroundColor");
// addColorButton(contentAssistComposite, label, ContentAssistPreference.PARAMETERS_FOREGROUND, 0);
- initializeFields();
+ label = PreferencesMessages.getString("CEditorPreferencePage.ContentAssistPage.proposalFilterSelect") ; //$NON-NLS-1$
+ addComboBox(contentAssistComposite, label, ContentAssistPreference.PROPOSALS_FILTER, 20, 0);
+
+ initializeFields();
PlatformUI.getWorkbench().getHelpSystem().setHelp(contentAssistComposite, ICHelpContextIds.C_EDITOR_CONTENT_ASSIST_PREF_PAGE);
@@ -168,6 +172,8 @@ public class CodeAssistPreferencePage extends AbstractPreferencePage {
PreferenceConverter.setDefault(store, ContentAssistPreference.PARAMETERS_FOREGROUND, new RGB(0, 0, 0));
store.setDefault(ContentAssistPreference.ORDER_PROPOSALS, false);
store.setDefault(ContentAssistPreference.ADD_INCLUDE, true);
+ store.setDefault(ContentAssistPreference.PROPOSALS_FILTER, ProposalFilterPreferencesUtil.getProposalFilternamesAsString()); // $NON_NLS 1$
}
+
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
index 40c7598a71b..382cd386e80 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties
@@ -85,6 +85,7 @@ CEditorPreferencePage.ContentAssistPage.autoActivationGroupTitle=Auto activation
CEditorPreferencePage.ContentAssistPage.autoActivationEnableDot=Enable "." as trigger
CEditorPreferencePage.ContentAssistPage.autoActivationEnableArrow=Enable "->" as trigger
CEditorPreferencePage.ContentAssistPage.autoActivationDelay=dela&y (ms)
+CEditorPreferencePage.ContentAssistPage.proposalFilterSelect=Completion Proposal Filter:
CEditorPreferencePage.ContentAssistPage.completionProposalBackgroundColor=&Background for completion proposals:
CEditorPreferencePage.ContentAssistPage.completionProposalForegroundColor=&Foreground for completion proposals:
CEditorPreferencePage.ContentAssistPage.parameterBackgroundColor=Bac&kground for method parameters:
@@ -260,3 +261,4 @@ PathEntryVariableSelectionDialog.ExtensionDialog.description = Choose extension
#Indexer
IndexerPrefs.description=Sets default Indexer Options for new Projects
+ProposalFilterPreferencesUtil.defaultFilterName=
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/ProposalFilterPreferencesUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/ProposalFilterPreferencesUtil.java
new file mode 100644
index 00000000000..1fa50504efd
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/ProposalFilterPreferencesUtil.java
@@ -0,0 +1,232 @@
+package org.eclipse.cdt.internal.ui.preferences;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.internal.ui.text.contentassist.ContentAssistPreference;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.widgets.Combo;
+
+/**
+ * A class which encapsulates several utility functions
+ * related to code completion preference settings.
+ */
+public class ProposalFilterPreferencesUtil {
+
+ /**
+ * Private default constructor prevents instantiation
+ */
+ private ProposalFilterPreferencesUtil() {
+ }
+
+ /**
+ * Get an array of proposal filter names
+ * (i.e. the human-readable text for display
+ * to fill into the Combo)
+ */
+ public static String[] getProposalFilterNames() {
+ ArrayList names = new ArrayList();
+ try {
+ IExtensionPoint point = Platform.getExtensionRegistry()
+ .getExtensionPoint(CUIPlugin.PLUGIN_ID, "ProposalFilter"); //$NON-NLS-1$
+ if (point != null) {
+ IExtension[] extensions = point.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ IExtension extension = extensions[i];
+ IConfigurationElement[] elements = extension
+ .getConfigurationElements();
+ for (int j = 0; j < elements.length; ++j) {
+ IConfigurationElement element = elements[j];
+ if ("ProposalFilter".equals(element.getName())) { //$NON-NLS-1$
+ String filterName = element.getAttribute("name");
+ if (null != filterName) {
+ names.add(filterName);
+ }
+ }
+ }
+ }
+ }
+ } catch (InvalidRegistryObjectException e) {
+ // No action required since we will at least be using the fail-safe default filter
+ CUIPlugin.getDefault().log(e);
+ }
+ String[] filterNames = (String[]) names
+ .toArray(new String[names.size()]);
+ return filterNames;
+ }
+
+ /**
+ * Look up all contributed completion proposal filters
+ * and return their names as a semicolon-separated list
+ * plus a leading entry for the selected index 0,
+ * plus a leading entry.
+ * A Combo may be initialized from this string.
+ * @return The list of filter names
+ */
+ public static String getProposalFilternamesAsString() {
+ StringBuffer filterNames = new StringBuffer("0;");
+ filterNames.append(""); // TODO: NP externalize this!
+ String[] names = getProposalFilterNames();
+ for (int i = 0; i < names.length; i++) {
+ String name = names[i];
+ filterNames.append(";");
+ filterNames.append(name);
+ }
+ return filterNames.toString();
+ }
+
+ /**
+ * Return the configuration element which corresponds
+ * to the human-readable filter name
+ * @param filterName The human-readable filter name
+ * @return The configuration element, or null if there is none
+ */
+ public static IConfigurationElement getElementForName(String filterName) {
+ IConfigurationElement element = null;
+ IExtensionPoint point = Platform.getExtensionRegistry()
+ .getExtensionPoint(CUIPlugin.PLUGIN_ID, "ProposalFilter"); //$NON-NLS-1$
+ if (point != null) {
+ try {
+ IExtension[] extensions = point.getExtensions();
+ if (extensions.length >= 1) {
+ for (int i = 0; i < extensions.length; i++) {
+ IExtension extension = extensions[i];
+
+ IConfigurationElement[] elements = extension
+ .getConfigurationElements();
+
+ for (int j = 0; j < elements.length; ++j) {
+ IConfigurationElement testElement = elements[j];
+ if ("ProposalFilter".equals(testElement.getName())) { //$NON-NLS-1$
+ String testName = testElement
+ .getAttribute("name");
+ if ((null != testName)
+ && (filterName.equals(testName))) {
+ element = testElement;
+ break;
+ }
+ }
+ }
+ // Did we find the corresponding element?
+ if (null != element)
+ break;
+ }
+ }
+ } catch (InvalidRegistryObjectException e) {
+ // In case of failure we'll just return null
+ }
+ }
+
+ return element;
+ }
+
+ /**
+ * The state of a Combo consists of the list of entries
+ * and the index of the selected entry.
+ * This method converts the state of the given Combo
+ * to a string representation for storage in a preference store.
+ * The string contains a semicolon-separated list of entries.
+ * The first entry is the index of the selected entry.
+ * The following entries are the texts of the individual fields.
+ * Since the semicolon is the separator, the entries cannot contain semicolons.
+ * This method will replace semicolons with commas if any are found.
+ * @param combo The Combo whose state shall be converted
+ * @return A string representation of the Combo state
+ */
+ public static String comboStateAsString(Combo combo) {
+ StringBuffer text = new StringBuffer();
+ int selectionIndex = combo.getSelectionIndex();
+ text.append(selectionIndex);
+ String[] entries = combo.getItems();
+ for (int i = 0; i < entries.length; i++) {
+ text.append(";");
+ String entry = entries[i].replaceAll(";", ",");
+ text.append(entry);
+ }
+ return text.toString();
+ }
+
+ /**
+ * The state of a Combo consists of the list of entries
+ * and the index of the selected entry.
+ * This method takes a string representation of the state (e.g. from a preference store)
+ * and restores it into the Combo.
+ * For a description of the text format see method comboStateAsString().
+ * @param combo The combo to be restored.
+ * @param text The text representation of the state.
+ */
+ public static void restoreComboFromString(Combo combo, String text) {
+ try {
+ int endFirstEntry = text.indexOf(";");
+ if (endFirstEntry > 0) { // First entry must contain at least one character
+ String selectedString = text.substring(0, endFirstEntry);
+ int selectedIndex = Integer.parseInt(selectedString);
+ String[] entryList = text.substring(endFirstEntry + 1,
+ text.length()).split(";");
+ combo.setItems(entryList);
+ combo.select(selectedIndex);
+ }
+ } catch (NumberFormatException e) {
+ // If this fails we just return the unmodified Combo
+ }
+ }
+
+ /**
+ * Convenience class wraps the data to initialize a Combo
+ */
+ public static class ComboState {
+ public int selectedIndex;
+
+ public String[] items;
+ }
+
+ /**
+ * Convenience method to extract the state of a Combo
+ * from the state string stored e.g. in a preference store
+ * @param comboPreference The state string
+ * @return A ComboState instance.
+ */
+ public static ComboState getComboState(String comboPreference) {
+ ComboState state = new ComboState();
+ try {
+ int endFirstEntry = comboPreference.indexOf(";");
+ if (endFirstEntry > 0) { // First entry must contain at least one character
+ String selectedString = comboPreference.substring(0,
+ endFirstEntry);
+ state.selectedIndex = Integer.parseInt(selectedString);
+ state.items = comboPreference.substring(endFirstEntry + 1,
+ comboPreference.length()).split(";");
+ }
+ } catch (NumberFormatException e) {
+ // If this fails we return an empty ComboState
+ state.items = new String[0];
+ }
+ return state;
+ }
+
+ /**
+ * Look up the setting for the preferred proposal filter
+ * and return it's configuration element.
+ * @return The configuration element, or null if none is found.
+ */
+ public static IConfigurationElement getPreferredFilterElement() {
+ IConfigurationElement preferredElement = null;
+ try {
+ IPreferenceStore store = CUIPlugin.getDefault()
+ .getPreferenceStore();
+ String filterComboStateString = store
+ .getString(ContentAssistPreference.PROPOSALS_FILTER);
+ ComboState state = getComboState(filterComboStateString);
+ preferredElement = getElementForName(state.items[state.selectedIndex]);
+ } catch (Exception e) {
+ // If anything goes wrong we'll just return null
+ }
+ return preferredElement;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java
index 747115d15f4..c1332b24e4e 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java
@@ -11,7 +11,6 @@
package org.eclipse.cdt.internal.ui.text.contentassist;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.core.dom.CDOM;
@@ -22,17 +21,21 @@ import org.eclipse.cdt.core.dom.IASTServiceProvider.UnsupportedDialectException;
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.cdt.internal.ui.CUIMessages;
+import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
import org.eclipse.cdt.internal.ui.text.CParameterListValidator;
import org.eclipse.cdt.internal.ui.util.ExternalEditorInput;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.ICCompletionProposal;
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
+import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
@@ -128,48 +131,12 @@ public class CCompletionProcessor2 implements IContentAssistProcessor {
}
}
- ICCompletionProposal[] propsArray = null;
+ IProposalFilter filter = getCompletionFilter();
+ ICCompletionProposal[] proposalsInput = (ICCompletionProposal[]) proposals.toArray(new ICCompletionProposal[proposals.size()]) ;
- if (!proposals.isEmpty()) {
- errorMessage = null;
- propsArray = (ICCompletionProposal[])proposals.toArray(new ICCompletionProposal[proposals.size()]);
- CCompletionProposalComparator propsComp = new CCompletionProposalComparator();
- propsComp.setOrderAlphabetically(true);
- Arrays.sort(propsArray, propsComp);
-
- // remove duplicates but leave the ones with return types
-
- int last = 0;
- int removed = 0;
- for (int i = 1; i < propsArray.length; ++i) {
- if (propsComp.compare(propsArray[last], propsArray[i]) == 0) {
- // We want to leave the one that has the return string if any
- boolean lastReturn = propsArray[last].getIdString() != propsArray[last].getDisplayString();
- boolean iReturn = propsArray[i].getIdString() != propsArray[i].getDisplayString();
-
- if (!lastReturn && iReturn)
- // flip i down to last
- propsArray[last] = propsArray[i];
-
- // Remove the duplicate
- propsArray[i] = null;
- ++removed;
- } else
- // update last
- last = i;
- }
- if (removed > 0) {
- // Strip out the null entries
- ICCompletionProposal[] newArray = new ICCompletionProposal[propsArray.length - removed];
- int j = 0;
- for (int i = 0; i < propsArray.length; ++i)
- if (propsArray[i] != null)
- newArray[j++] = propsArray[i];
- propsArray = newArray;
- }
- }
+ ICCompletionProposal[] proposalsFiltered = filter.filterProposals(proposalsInput);
- return propsArray;
+ return proposalsFiltered;
} catch (UnsupportedDialectException e) {
errorMessage = CUIMessages.getString(dialectError);
@@ -179,6 +146,32 @@ public class CCompletionProcessor2 implements IContentAssistProcessor {
return null;
}
+
+ private IProposalFilter getCompletionFilter() {
+ IProposalFilter filter = null;
+ try {
+ IConfigurationElement filterElement = ProposalFilterPreferencesUtil.getPreferredFilterElement();
+ if (null != filterElement) {
+ Object contribObject = filterElement
+ .createExecutableExtension("class"); //$NON-NLS-1$
+ if ((contribObject instanceof IProposalFilter)) {
+ filter = (IProposalFilter) contribObject;
+ }
+ }
+ } catch (InvalidRegistryObjectException e) {
+ // No action required since we will be using the fail-safe default filter
+ CUIPlugin.getDefault().log(e);
+ } catch (CoreException e) {
+ // No action required since we will be using the fail-safe default filter
+ CUIPlugin.getDefault().log(e);
+ }
+
+ if (null == filter) {
+ // fail-safe default implementation
+ filter = new DefaultProposalFilter();
+ }
+ return filter;
+ }
private String scanPrefix(IDocument document, int end) {
try {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ContentAssistPreference.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ContentAssistPreference.java
index c82ec2677eb..9f351ebead4 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ContentAssistPreference.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/ContentAssistPreference.java
@@ -63,7 +63,9 @@ public class ContentAssistPreference {
public final static String CURRENT_FILE_SEARCH_SCOPE= "content_assist_current_file_search_scope"; //$NON-NLS-1$
/** Preference key for completion search scope */
public final static String PROJECT_SEARCH_SCOPE= "content_assist_project_search_scope"; //$NON-NLS-1$
-
+ /** Preference key for completion filtering */
+ public final static String PROPOSALS_FILTER= "content_assist_proposal_filter"; //$NON_NLS 1$
+
private static Color getColor(IPreferenceStore store, String key, IColorManager manager) {
RGB rgb= PreferenceConverter.getColor(store, key);
return manager.getColor(rgb);
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DefaultProposalFilter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DefaultProposalFilter.java
new file mode 100644
index 00000000000..bd6d6efdbb1
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/DefaultProposalFilter.java
@@ -0,0 +1,58 @@
+package org.eclipse.cdt.internal.ui.text.contentassist;
+
+import java.util.Arrays;
+
+import org.eclipse.cdt.ui.text.ICCompletionProposal;
+import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
+
+/**
+ * The default code completion filter: Remove duplicate entries on the basis of
+ * their id string. Use CCompletionProposalComparator for sorting.
+ */
+public class DefaultProposalFilter implements IProposalFilter {
+
+ public ICCompletionProposal[] filterProposals(
+ ICCompletionProposal[] proposals) {
+
+ CCompletionProposalComparator propsComp = new CCompletionProposalComparator();
+ propsComp.setOrderAlphabetically(true);
+ Arrays.sort(proposals, propsComp);
+
+ // remove duplicates but leave the ones with return types
+
+ int last = 0;
+ int removed = 0;
+ for (int i = 1; i < proposals.length; ++i) {
+ if (propsComp.compare(proposals[last], proposals[i]) == 0) {
+ // We want to leave the one that has the return string if any
+ boolean lastReturn = proposals[last].getIdString() != proposals[last]
+ .getDisplayString();
+ boolean iReturn = proposals[i].getIdString() != proposals[i]
+ .getDisplayString();
+
+ if (!lastReturn && iReturn)
+ // flip i down to last
+ proposals[last] = proposals[i];
+
+ // Remove the duplicate
+ proposals[i] = null;
+ ++removed;
+ } else
+ // update last
+ last = i;
+ }
+ if (removed > 0) {
+ // Strip out the null entries
+ ICCompletionProposal[] newArray = new ICCompletionProposal[proposals.length
+ - removed];
+ int j = 0;
+ for (int i = 0; i < proposals.length; ++i)
+ if (proposals[i] != null)
+ newArray[j++] = proposals[i];
+ proposals = newArray;
+ }
+
+ return proposals;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/contentassist/IProposalFilter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/contentassist/IProposalFilter.java
new file mode 100644
index 00000000000..b07a9bcc218
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/contentassist/IProposalFilter.java
@@ -0,0 +1,18 @@
+package org.eclipse.cdt.ui.text.contentassist;
+
+import org.eclipse.cdt.ui.text.ICCompletionProposal;
+
+
+public interface IProposalFilter {
+
+ /**
+ * Filter a list of ICCompletionProposals
+ * - Change the order of entries
+ * - Remove undesired (duplicate) entries
+ * - Supplement existing entries with additional information
+ * @param proposals The List of proposals
+ * @return The filtered list of proposals as array
+ */
+ ICCompletionProposal[] filterProposals(ICCompletionProposal[] proposals) ;
+
+}