Rev 2737 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package org.tela_botanica.client.util.autocompletion;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;import org.tela_botanica.client.cel2;import org.tela_botanica.client.modeles.objets.Utilisateur;import com.google.gwt.core.client.Callback;import com.google.gwt.core.client.JavaScriptObject;import com.google.gwt.event.dom.client.KeyCodes;import com.google.gwt.event.dom.client.KeyDownEvent;import com.google.gwt.event.dom.client.KeyDownHandler;import com.google.gwt.event.dom.client.KeyPressEvent;import com.google.gwt.event.dom.client.KeyPressHandler;import com.google.gwt.event.logical.shared.SelectionEvent;import com.google.gwt.event.logical.shared.SelectionHandler;import com.google.gwt.event.logical.shared.ValueChangeEvent;import com.google.gwt.event.logical.shared.ValueChangeHandler;import com.google.gwt.http.client.Request;import com.google.gwt.http.client.RequestBuilder;import com.google.gwt.http.client.RequestCallback;import com.google.gwt.http.client.RequestException;import com.google.gwt.http.client.Response;import com.google.gwt.http.client.URL;import com.google.gwt.user.client.Event;import com.google.gwt.user.client.Timer;import com.google.gwt.user.client.Window;import com.google.gwt.user.client.ui.ChangeListener;import com.google.gwt.user.client.ui.Label;import com.google.gwt.user.client.ui.MultiWordSuggestOracle;import com.google.gwt.user.client.ui.SuggestBox;import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay;import com.google.gwt.user.client.ui.TextBox;import com.google.gwt.user.client.ui.SuggestBox.SuggestionDisplay;import com.google.gwt.user.client.ui.SuggestOracle;import com.google.gwt.user.client.ui.Widget;import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;import com.gwtext.client.widgets.BoxComponent;import com.gwtext.client.widgets.Component;import com.gwtext.client.widgets.Container;import com.gwtext.client.widgets.Panel;import com.gwtext.client.widgets.event.PanelListener;import com.gwtext.client.widgets.event.PanelListenerAdapter;import com.gwtext.client.widgets.layout.FitLayout;@SuppressWarnings("unchecked")public abstract class AutoCompletionComboBox extends Panel {Label label = null;MultiWordSuggestOracle msu = null;SuggestBox suggestions = null;DefaultSuggestionDisplay sgd = null;Callback<String, String> surCopierColler = null;SuggestOracle.Request requeteOracle;SuggestOracle.Callback callBackOracle;Timer suggestionTimer = null;int tempsAvantRequete = 500;Map<String, String> possibilites = null;String urlRequete = "";public AutoCompletionComboBox(String nomLabel, String urlRequete) {this.setStyleName("champAutoComplete");this.label = new Label(nomLabel+":");this.urlRequete = urlRequete;sgd = new SuggestBox.DefaultSuggestionDisplay();msu = new MultiWordSuggestOracle() {@Overridepublic void requestSuggestions(Request request, Callback callback) {List<MultiWordSuggestion> retenus = new ArrayList<MultiWordSuggestion>();Iterator<String> it = possibilites.keySet().iterator();while (it.hasNext()) {String cle = it.next();String cleAffichee = preTraiterValeurAvantAffichage(possibilites.get(cle));MultiWordSuggestion muWoSug = new MultiWordSuggestion(possibilites.get(cle), cleAffichee);retenus.add(muWoSug);}Response reponse = new Response(retenus);callback.onSuggestionsReady(request, reponse);}};suggestions = new SuggestBox(msu, new TextBox(), sgd) {public void onBrowserEvent(Event event) {switch (event.getTypeInt()) {case Event.ONPASTE: {if(surCopierColler != null) {surCopierColler.onSuccess(suggestions.getValueBox().getValue());}}break;default:// WTF: Curieux bloc qui est nécessaire car si on appelle pas super.onBrowserEvent// aucun évènement ne fonctionne et si on le fait, cela génère des nullPointerException// donc on transige en l'appelant dans un try catchtry {super.onBrowserEvent(event);} catch (Exception e) {// à priori rien à faire}}}};suggestions.setAutoSelectEnabled(false);setLayout(new FitLayout());add(label);add(suggestions);gererEvenements();}public void gererEvenements() {suggestions.addKeyDownHandler(new KeyDownHandler() {@Overridepublic void onKeyDown(KeyDownEvent event) {// Lorsque la liste de suggestions est ouverte, une frappe sur entrée selectionne la valeur// Si elle est fermée, elle déclenche la fonction abstraite de validation (utile pour les champs// du genre station, milieu etc... et la saisie d'obs rapideif(event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {if((sgd == null || !sgd.isSuggestionListShowing())) {onValidationSaisie();event.stopPropagation();return;} else {// Dans les autres cas, un appui sur entrée ne doit pas redéclencher l'autcomplétionreturn;}}if(event.getNativeKeyCode() == KeyCodes.KEY_DOWN) {// Un appui sur flèche bas permet de demander toute la listeif(!sgd.isSuggestionListShowing()) {requeteToutesSuggestions();}}// Tout autre frappe d'un caractère "normal" déclenche le timer d'autocomplétionif(!KeyDownEvent.isArrow(event.getNativeKeyCode())) {gererTimer();}}});requeteOracle = new SuggestOracle.Request();callBackOracle = new SuggestOracle.Callback() {public void onSuggestionsReady(SuggestOracle.Request request, SuggestOracle.Response response) {suggestions.showSuggestionList();}};suggestions.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>(){@Overridepublic void onSelection(SelectionEvent<Suggestion> event) {onSelectionValeur();}});suggestions.addValueChangeHandler(new ValueChangeHandler<String>() {@Overridepublic void onValueChange(ValueChangeEvent<String> event) {onModificationValeur();}});surCopierColler = new Callback<String, String>() {@Overridepublic void onSuccess(String result) {gererTimer();}@Overridepublic void onFailure(String reason) {// rien à faire ça n'échoue jamais}};addListener(new PanelListenerAdapter() {@Overridepublic void onResize(BoxComponent component, int adjWidth, int adjHeight,int rawWidth, int rawHeight) {redimensionner(rawWidth);}});}public void redimensionner(final int largeur) {suggestions.setWidth((largeur - label.getOffsetWidth() - 13)+"px");}public void gererTimer() {if(suggestionTimer == null) {suggestionTimer = new Timer() {public void run() {requeteSuggestions();}};suggestionTimer.schedule(tempsAvantRequete);} else {suggestionTimer.schedule(tempsAvantRequete);}}public void setTempsAvantRequete(int temps) {tempsAvantRequete = temps;}public int getTempsAvantRequete(int temps) {return tempsAvantRequete;}public void requeteToutesSuggestions() {// Cette méthode permet de demander l'autocomplétion même si// la valeur saisie est vide (cas de l'appui sur flèche bas)envoyerRequeteSuggestions("*");}public void requeteSuggestions() {// Suppression des espaces et caractères inutilesString valeur = suggestions.getValue().trim().isEmpty() ? null : suggestions.getValue().trim();// ceci permet au composant qui utilise l'autocomplétion// d'annuler une requete et également d'éviter de faire une requête lors du vidage du champif(valeur == null) {return;}envoyerRequeteSuggestions(valeur);}private void envoyerRequeteSuggestions(final String valeur) {final String urlRequeteFmt = preTraiterUrlRequete(urlRequete, valeur);RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, urlRequeteFmt) ;try {rb.sendRequest(null, new RequestCallback() {public void onError(final Request request, final Throwable exception) {// TODO Auto-generated method stub}public void onResponseReceived(final Request request,final Response response) {surReponseRequete(valeur, response);}}) ;} catch (RequestException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void surReponseRequete(String requete, Response response) {possibilites = parserResultatRequete(response);msu.clear();Iterator<String> it = possibilites.keySet().iterator();while (it.hasNext()) {msu.add(possibilites.get(it.next()));}requeteOracle.setQuery(requete);if(requete.equals("*")) {// TODO : il y a peut être une méthode plus simple// mais ceci permet d'afficher les suggestions en cas d'appui// sur bas lorsque la liste est videmsu.setDefaultSuggestionsFromText(possibilites.values());SuggestOracle.Request rq = new SuggestOracle.Request();rq.setQuery(null);msu.requestDefaultSuggestions(rq, callBackOracle);} else {msu.requestSuggestions(requeteOracle, callBackOracle);}}public String getText() {return suggestions.getText();}public String getRawValue() {return suggestions.getText();}public void setValue(String texte) {suggestions.setText(texte);}public void reset() {suggestions.setValue("");}public void setTabIndex(int index) {suggestions.setTabIndex(index);}public String getLabelText() {return label.getText();}public int getFieldWidth() {return suggestions.getOffsetWidth();}public int getLabelWidth() {return label.getOffsetWidth();}public void agrandirChamp(int largeur) {suggestions.setWidth(largeur+"px");}protected String preTraiterValeurAvantAffichage(String valeur) {return valeur;}protected String preTraiterUrlRequete(String urlRequete, String valeur) {return urlRequete+URL.encodeQueryString(valeur);}protected abstract Map<String, String> parserResultatRequete(Response response);protected abstract void onModificationValeur();protected abstract void onSelectionValeur();protected abstract void onValidationSaisie();}