/*
* 02/06/2010
*
* CompletionProviderBase.java - Base completion provider implementation.
*
* This library is distributed under a modified BSD license. See the included
* RSyntaxTextArea.License.txt file for details.
*/
package org.fife.ui.autocomplete;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.ListCellRenderer;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.Segment;
/**
* A base class for all standard completion providers. This class implements
* functionality that should be sharable across all <tt>CompletionProvider</tt>
* implementations.
*
* @author Robert Futrell
* @version 1.0
* @see AbstractCompletionProvider
*/
public abstract class CompletionProviderBase implements CompletionProvider {
/**
* The parent completion provider.
*/
private CompletionProvider parent;
/**
* The renderer to use for completions from this provider. If this is
* <code>null</code>, a default renderer is used.
*/
private ListCellRenderer listCellRenderer;
/**
* Text that marks the beginning of a parameter list, for example, '('.
*/
private char paramListStart;
/**
* Text that marks the end of a parameter list, for example, ')'.
*/
private char paramListEnd;
/**
* Text that separates items in a parameter list, for example, ", ".
*/
private String paramListSeparator;
/**
* Whether auto-activation should occur after letters.
*/
private boolean autoActivateAfterLetters;
/**
* Non-letter chars that should cause auto-activation to occur.
*/
private String autoActivateChars;
/**
* Provides completion choices for a parameterized completion's parameters.
*/
private ParameterChoicesProvider paramChoicesProvider;
/**
* A segment to use for fast char access.
*/
private Segment s = new Segment();
protected static final String EMPTY_STRING = "";
/**
* Comparator used to sort completions by their relevance before sorting
* them lexicographically.
*/
private static final Comparator<Completion> sortByRelevanceComparator =
new SortByRelevanceComparator();
/**
* {@inheritDoc}
*/
public void clearParameterizedCompletionParams() {
paramListEnd = paramListStart = 0;
paramListSeparator = null;
}
/**
* {@inheritDoc}
*/
public List<Completion> getCompletions(JTextComponent comp) {
List<Completion> completions = getCompletionsImpl(comp);
if (parent!=null) {
completions.addAll(parent.getCompletions(comp));
Collections.sort(completions);
}
// NOTE: We can't sort by relevance prior to this; we need to have
// things alphabetical so we can easily narrow down completions to
// those starting with what was already typed.
if (/*sortByRelevance*/true) {
Collections.sort(completions, sortByRelevanceComparator);
}
return completions;
}
/**
* Does the dirty work of creating a list of completions.
*
* @param comp The text component to look in.
* @return The list of possible completions, or an empty list if there
* are none.
*/
protected abstract List<Completion> getCompletionsImpl(JTextComponent comp);
/**
* {@inheritDoc}
*/
public ListCellRenderer getListCellRenderer() {
return listCellRenderer;
}
/**
* {@inheritDoc}
*/
public ParameterChoicesProvider getParameterChoicesProvider() {
return paramChoicesProvider;
}
/**
* {@inheritDoc}
*/
public char getParameterListEnd() {
return paramListEnd;
}
/**
* {@inheritDoc}
*/
public String getParameterListSeparator() {
return paramListSeparator;
}
/**
* {@inheritDoc}
*/
public char getParameterListStart() {
return paramListStart;
}
/**
* {@inheritDoc}
*/
public CompletionProvider getParent() {
return parent;
}
/**
* {@inheritDoc}
*/
public boolean isAutoActivateOkay(JTextComponent tc) {
Document doc = tc.getDocument();
char ch = 0;
try {
doc.getText(tc.getCaretPosition(), 1, s);
ch = s.first();
} catch (BadLocationException ble) { // Never happens
ble.printStackTrace();
}
return (autoActivateAfterLetters && Character.isLetter(ch)) ||
(autoActivateChars!=null && autoActivateChars.indexOf(ch)>-1);
}
/**
* Sets the characters that auto-activation should occur after. A Java
* completion provider, for example, might want to set <code>others</code>
* to "<code>.</code>", to allow auto-activation for members of an object.
*
* @param letters Whether auto-activation should occur after any letter.
* @param others A string of (non-letter) chars that auto-activation should
* occur after. This may be <code>null</code>.
*/
public void setAutoActivationRules(boolean letters, String others) {
autoActivateAfterLetters = letters;
autoActivateChars = others;
}
/**
* Sets the param choices provider. This is used when a user
* code-completes a parameterized completion, such as a function or method.
* For any parameter to the function/method, this object can return
* possible completions.
*
* @param pcp The parameter choices provider, or <code>null</code> for
* none.
* @see #getParameterChoicesProvider()
*/
public void setParameterChoicesProvider(ParameterChoicesProvider pcp) {
paramChoicesProvider = pcp;
}
/**
* {@inheritDoc}
*/
public void setListCellRenderer(ListCellRenderer r) {
listCellRenderer = r;
}
/**
* {@inheritDoc}
*/
public void setParameterizedCompletionParams(char listStart,
String separator, char listEnd) {
if (listStart<0x20 || listStart==0x7F) {
throw new IllegalArgumentException("Invalid listStart");
}
if (listEnd<0x20 || listEnd==0x7F) {
throw new IllegalArgumentException("Invalid listEnd");
}
if (separator==null || separator.length()==0) {
throw new IllegalArgumentException("Invalid separator");
}
paramListStart = listStart;
paramListSeparator = separator;
paramListEnd = listEnd;
}
/**
* {@inheritDoc}
*/
public void setParent(CompletionProvider parent) {
this.parent = parent;
}
}