package net.bettyluke.tracinstant.ui;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.swing.DefaultComboBoxModel;
import net.bettyluke.tracinstant.data.SavedSearch;
import net.bettyluke.tracinstant.prefs.TracInstantProperties;
/**
* ComboBoxModel that does little other than try to enforce type safety
* (SavedSearch instead of Object) a little, and saves/loads the data from App Prefs.
*/
public class SearchComboBoxModel extends DefaultComboBoxModel<SavedSearch> {
private static final int MAX_SAVED_SEARCHES = 50;
private TreeMap<Integer, SavedSearch> hiddenElements = new TreeMap<>();
public SearchComboBoxModel() {
loadSavedSearches();
}
private void loadSavedSearches() {
clearPrefixFilter();
for (int i = 0; i < MAX_SAVED_SEARCHES; ++i) {
String str = TracInstantProperties.get().getValue("SearchHistory_" + i);
if (str == null) {
break;
}
addElement(new SavedSearch(str));
}
setSelectedItem(null);
}
public void saveSavedSearches() {
clearPrefixFilter();
int i = 0;
for (; i < getSize(); ++i) {
TracInstantProperties.get().putString("SearchHistory_" + i,
getElementAt(i).formatAsPreference());
}
for (; i < MAX_SAVED_SEARCHES; ++i) {
TracInstantProperties.get().remove("SearchHistory_" + i);
}
}
@Override
public void setSelectedItem(Object anItem) {
clearPrefixFilter();
super.setSelectedItem(anItem);
}
@Override
public void addElement(SavedSearch ss) {
clearPrefixFilter();
super.addElement(ss);
}
@Override
public void insertElementAt(SavedSearch ss, int index) {
clearPrefixFilter();
super.insertElementAt(ss, index);
}
@Override
public SavedSearch getElementAt(int index) {
return super.getElementAt(index);
}
public void updateSearch(SavedSearch ss) {
clearPrefixFilter();
int count = getSize();
for (int i = 0; i < count; ++i) {
if (getElementAt(i).searchText.equalsIgnoreCase(ss.searchText)) {
removeElementAt(i--);
count--;
}
}
insertElementAt(ss, 0);
setSelectedItem(ss);
}
public SavedSearch findSearch(String text) {
text = text.trim();
int count = getSize();
// First priority: matching the full search text
for (int i = 0; i < count; ++i) {
SavedSearch ss = getElementAt(i);
if (ss.searchText.equalsIgnoreCase(text)) {
return ss;
}
}
// Second priority: matching an alias
for (int i = 0; i < count; ++i) {
SavedSearch ss = getElementAt(i);
if (!ss.alias.isEmpty() && ss.alias.equalsIgnoreCase(text)) {
return ss;
}
}
return null;
}
public void clearPrefixFilter() {
for (Entry<Integer, SavedSearch> entry : hiddenElements.entrySet()) {
super.insertElementAt(entry.getValue(), entry.getKey());
}
hiddenElements.clear();
}
public void setPrefixFilter(String prefix) {
clearPrefixFilter();
if (prefix == null) {
return;
}
prefix = prefix.toUpperCase();
int count = getSize();
for (int i = count - 1; i >= 0; --i) {
String alias = getElementAt(i).alias;
if (alias == null || !alias.toUpperCase().startsWith(prefix)) {
hiddenElements.put(i, getElementAt(i));
removeElementAt(i);
}
}
}
}