/** * This file is part of pwt. * * pwt is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * pwt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with pwt. If not, * see <http://www.gnu.org/licenses/>. */ package fr.putnami.pwt.core.widget.client; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.regexp.shared.RegExp; import com.google.gwt.text.shared.Parser; import com.google.gwt.text.shared.Renderer; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.TextBox; import java.util.Collection; import fr.putnami.pwt.core.widget.client.assist.AbstractContentAssistHandler; import fr.putnami.pwt.core.widget.client.assist.ContentAssistAspect; import fr.putnami.pwt.core.widget.client.assist.ContentAssistHandler; import fr.putnami.pwt.core.widget.client.assist.OracleWrapper; import fr.putnami.pwt.core.widget.client.assist.SimpleOracle; import fr.putnami.pwt.core.widget.client.base.AbstractInputBox; import fr.putnami.pwt.core.widget.client.helper.CompositeFocusHelper; import fr.putnami.pwt.core.widget.client.helper.StringParser; import fr.putnami.pwt.core.widget.client.helper.ToStringRenderer; import fr.putnami.pwt.core.widget.shared.assist.Oracle; public class InputSuggest<T> extends AbstractInputBox<TextBox, T> { private final OracleWrapper<T> oracle; private ContentAssistHandler<T> assistHandler; private ContentAssistAspect<T> assistAspect; private CompositeFocusHelper compositeFocus; private T currentValue; private Oracle.Highlighter<T> highlighter = new Oracle.Highlighter<T>() { @Override public String highlight(T value, String query) { RegExp pattern = RegExp.compile("(" + query + ")", "ig"); return pattern.replace(getRenderer().render(value), "<strong>$1</strong>"); } }; public InputSuggest() { super(new TextBox()); this.oracle = new OracleWrapper<T>(); this.setParser((Parser<T>) StringParser.get()); this.setRenderer(ToStringRenderer.<T> get()); this.init(); } protected InputSuggest(InputSuggest<T> source) { super(new TextBox(), source); this.oracle = source.oracle; this.highlighter = source.highlighter; this.init(); } @Override public IsWidget cloneWidget() { return new InputSuggest<T>(this); } private void init() { this.assistHandler = new TextBoxContentAssistHandler(this.oracle); this.assistAspect = new ContentAssistAspect<T>(this.assistHandler); this.assistAspect.setInput(this.getInput()); this.assistAspect.setHighlighter(highlighter); this.compositeFocus = CompositeFocusHelper.createFocusHelper(this, this.getInput()); this.compositeFocus.addFocusPartner(this.assistAspect.getSuggestionWidget().getElement()); } public Oracle.Highlighter<T> getHighlighter() { return highlighter; } public void setHighlighter(Oracle.Highlighter<T> highlighter) { this.highlighter = highlighter; this.assistAspect.setHighlighter(highlighter); } public void setSuggestions(Collection<T> suggestions) { SimpleOracle<T> wordSuggestOracle = new SimpleOracle<T>(); wordSuggestOracle.addAll(suggestions); wordSuggestOracle.setRenderer(getRenderer()); oracle.setDelagate(wordSuggestOracle); } @Override public HandlerRegistration addValueChangeHandler(ValueChangeHandler<T> handler) { return addHandler(handler, ValueChangeEvent.getType()); } @Override public void setRenderer(Renderer<T> renderer) { super.setRenderer(renderer); if (oracle.getDelegate() instanceof SimpleOracle) { SimpleOracle<T> simpleOracle = (SimpleOracle<T>) oracle.getDelegate(); simpleOracle.setRenderer(renderer); } } public void setOracle(Oracle<T> oracle) { this.oracle.setDelagate(oracle); } public void setSuggestionsLimit(int limit) { this.assistHandler.setLimit(limit); } @Override public void setValue(T value) { super.setValue(value); currentValue = value; } @Override public T flush() { this.clearErrors(); this.validate(currentValue); if (!this.hasErrors()) { this.setValue(currentValue); } return this.getValue(); } @Override public HandlerRegistration addBlurHandler(BlurHandler handler) { return this.compositeFocus.addBlurHandler(handler); } @Override public HandlerRegistration addFocusHandler(FocusHandler handler) { return this.compositeFocus.addFocusHandler(handler); } class TextBoxContentAssistHandler extends AbstractContentAssistHandler<T> { TextBoxContentAssistHandler(Oracle<T> oracle) { super(oracle); } @Override public String getQueryText(IsWidget textInput) { TextBox input = (TextBox) textInput; return input.getText(); } @Override public void handleSuggestionSelected(IsWidget textInput, Oracle.Suggestion<T> suggestion) { TextBox input = (TextBox) textInput; T value = suggestion.getValue(); String replacementString = getRenderer().render(value); input.setText(replacementString); input.setCursorPos(replacementString.length()); T oldValue = InputSuggest.this.currentValue; InputSuggest.this.currentValue = value; ValueChangeEvent.fireIfNotEqual(InputSuggest.this, oldValue, value); } } }