package com.limegroup.gnutella.gui.search;
import java.awt.Toolkit;
import java.util.Arrays;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import com.limegroup.gnutella.gui.ClearableAutoCompleteTextField;
import com.limegroup.gnutella.settings.SearchSettings;
import com.limegroup.gnutella.util.I18NConvert;
/**
* Specialized class that only allows valid search characters to be
* entered into text fields.
*/
public class SearchField extends ClearableAutoCompleteTextField {
/**
* Constant for the array of characters that should not be
* allowed in search strings.
*/
private static final char[] ILLEGAL_CHARS =
SearchSettings.ILLEGAL_CHARS.getValue();
/**
* Constant for the maximum number of bytes to allow in queries.
*/
private static final int MAX_QUERY_LENGTH =
SearchSettings.MAX_QUERY_LENGTH.getValue();
// statically make sure that the array of illegal characters is
// sorted
static {
Arrays.sort(ILLEGAL_CHARS);
}
/**
* Toolkit for sounding beeps when invalid characters are entered.
*/
private static final Toolkit TOOLKIT =
Toolkit.getDefaultToolkit();
/**
* Creates a new search field.
*/
public SearchField() {
super();
}
/**
* Creates a new search field with the specified number of columns.
*
* @param columns the number of columns to display in the field
*/
public SearchField(int columns) {
super(columns);
}
// overridden to filter out invalid search characters
protected Document createDefaultModel() {
return new SearchFieldDocument();
}
/**
* Helper class that filters out all characters that are not
* accepted as search strings. If the character is not accepted,
* the system should beep.
*/
private static class SearchFieldDocument extends PlainDocument {
public void insertString(int offs,
String str,
AttributeSet a)
throws BadLocationException {
if(str == null) {
super.insertString(offs, str, a);
return;
}
if(offs >= MAX_QUERY_LENGTH) {
TOOLKIT.beep();
return;
}
// Normalized String are maybe longer than MAX_QUERY_LENGTH
String norm = I18NConvert.instance().getNorm(str);
if (norm.length() > MAX_QUERY_LENGTH) {
TOOLKIT.beep();
return;
}
char[] source = str.toCharArray();
char[] result = new char[source.length];
int j = 0;
for (int i = 0; i<result.length; i++) {
// if the character is not in the illegal chars, put
// it in the search string
if(Arrays.binarySearch(ILLEGAL_CHARS, source[i]) < 0) {
result[j++] = source[i];
} else {
// beep to let the user know we won't accept it
TOOLKIT.beep();
}
}
super.insertString(offs, new String(result, 0, j), a);
}
}
}