Rev 8 | Blame | Last modification | View Log | RSS feed
/** Copyright 2006 Google Inc.** Licensed under the Apache License, Version 2.0 (the "License"); you may not* use this file except in compliance with the License. You may obtain a copy of* the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the* License for the specific language governing permissions and limitations under* the License.*/package org.tela_botanica.client;import java.util.Iterator;import java.util.Vector;import com.google.gwt.i18n.client.Dictionary;import com.google.gwt.json.client.JSONArray;import com.google.gwt.json.client.JSONNumber;import com.google.gwt.json.client.JSONParser;import com.google.gwt.json.client.JSONString;import com.google.gwt.json.client.JSONValue;import com.google.gwt.user.client.HTTPRequest;import com.google.gwt.user.client.ResponseTextHandler;import com.google.gwt.user.client.ui.Composite;import com.google.gwt.user.client.ui.FlexTable;import com.google.gwt.user.client.ui.Grid;import com.google.gwt.user.client.ui.HTML;import com.google.gwt.user.client.ui.HorizontalPanel;import com.google.gwt.user.client.ui.VerticalPanel;import com.google.gwt.user.client.ui.DockPanel;import com.google.gwt.user.client.ui.Button;import com.google.gwt.user.client.ui.CheckBox;import com.google.gwt.user.client.ui.Widget;import com.google.gwt.user.client.ui.ClickListener;import com.google.gwt.user.client.ui.HasHorizontalAlignment;import com.google.gwt.user.client.ui.HasVerticalAlignment;import com.google.gwt.user.client.ui.Label;/** Le retour de getUser appelle getCount qui appelle update pour veiller à une* initialisation correcte**/public class TaxonList extends Composite implementsAutoCompleteAsyncTextBoxListener {// Barre de navigationprivate class NavBar extends Composite implements ClickListener {public final DockPanel bar = new DockPanel();public final Button gotoFirst = new Button("<<", this);public final Button gotoNext = new Button(">", this);public final Button gotoPrev = new Button("<", this);public final Button gotoEnd = new Button(">>", this);public final HTML status = new HTML();public NavBar() {initWidget(bar);bar.setStyleName("navbar");status.setStyleName("status");HorizontalPanel buttons = new HorizontalPanel();buttons.add(status);buttons.setCellHorizontalAlignment(status,HasHorizontalAlignment.ALIGN_RIGHT);buttons.setCellVerticalAlignment(status,HasVerticalAlignment.ALIGN_MIDDLE);buttons.setCellWidth(status, "100%");buttons.add(gotoFirst);buttons.add(gotoPrev);buttons.add(gotoNext);buttons.add(gotoEnd);bar.add(buttons, DockPanel.EAST);bar.setCellHorizontalAlignment(buttons, DockPanel.ALIGN_RIGHT);VerticalPanel actions = new VerticalPanel();HorizontalPanel actionButton = new HorizontalPanel();/*actionButton.add(new Button("Ajout",new ClickListener() {public void onClick(Widget sender) {deleteElement();}}));*/HTML delButton=new HTML("Suppression");delButton.setStyleName("html_button");delButton.addClickListener(new ClickListener() {public void onClick(Widget sender) {deleteElement();}});actionButton.add(delButton);HTML exportButton=new HTML("<a href=\""+serviceBaseUrl+"/InventoryExport/" +user+"\">"+"Tout exporter</a>");actionButton.add(exportButton);exportButton.setStyleName("html_button");actionButton.setSpacing(5);actions.add(actionButton);HorizontalPanel selections = new HorizontalPanel();selections.setSpacing(3);actions.add(selections);selections.add(new HTML("Sélection : "));Label allLabel = new Label("Tous");Label separatorLabel = new Label(",");Label noneLabel = new Label("Aucun");allLabel.setStyleName("selection_label");noneLabel.setStyleName("selection_label");selections.add(allLabel);allLabel.addClickListener(new ClickListener() {public void onClick(Widget sender) {selectAll();}});selections.add(separatorLabel);selections.add(noneLabel);noneLabel.addClickListener(new ClickListener() {public void onClick(Widget sender) {deselectAll();}});bar.add(actions, DockPanel.WEST);bar.setCellHorizontalAlignment(buttons, DockPanel.ALIGN_LEFT);bar.setVerticalAlignment(DockPanel.ALIGN_MIDDLE);}public void onClick(Widget sender) {if (sender == gotoNext) {// Move forward a page.startIndex += VISIBLE_TAXON_COUNT;if (startIndex >= count)startIndex -= VISIBLE_TAXON_COUNT;} else {if (sender == gotoPrev) {// Move back a page.startIndex -= VISIBLE_TAXON_COUNT;if (startIndex < 0)startIndex = 0;} else {if (sender == gotoEnd) {gotoEnd();} else {if (sender == gotoFirst) {startIndex = 0;}}}}update(true);}}private void setStatusText(String text) {navBar.status.setText(text);}private static final int VISIBLE_TAXON_COUNT = 15;private Grid header = new Grid(1, 6);private FlexTable table = new FlexTable();private VerticalPanel panel = new VerticalPanel();private int startIndex = 0;private String serviceBaseUrl = getServiceBaseUrl();private int count = 65000;private String user;private NavBar navBar=null;int sizeChecked=0;int itemDeleted=0;public TaxonList() {getUser(); // Appelle le reste des initialisationsinitWidget(panel);}/*** Action lancee par la selection d'un nom dans l'assistant de saisie. Lance* la recherche d'informations complémentaires (famille, numero* nomenclaturaux etc) et met a jour l'inventaire (addelement())** @return void*/public void onValidate(SourcesAutoCompleteAsyncTextBoxEvents sender,final String str,final String value) {setStatusDisabled();// On met a jour rapidement l'affichage puis on lance la requete ....int row = table.insertRow(table.getRowCount());// Case a cochertable.setWidget(row, 0, new CheckBox());// Nom saisitable.setText(row, 1, str);table.getFlexCellFormatter().setWidth(row, 0, "2%");table.getFlexCellFormatter().setWidth(row, 1, "31%");// Recherche complement d'informationif (value !=null) {HTTPRequest.asyncGet(serviceBaseUrl + "/NameValid/" + value,new ResponseTextHandler() {public void onCompletion(String strcomplete) {JSONValue jsonValue = JSONParser.parse(strcomplete);JSONArray jsonArray;if ((jsonArray = jsonValue.isArray()) != null) {// Nom retenu, Num Nomen nom retenu, Num Taxon,// FamilleaddElement(str, value,((JSONString) jsonArray.get(0)).stringValue(),((JSONString) jsonArray.get(1)).stringValue(),((JSONString) jsonArray.get(2)).stringValue(),((JSONString) jsonArray.get(3)).stringValue());}}});}// Saisie libreelse {addElement(str, " ", " ", " ", " ", " ");}}/*** Ajoute un element à l'inventaire** @param nom_sel :* nom selectionne* @param num_nom_sel :* numero nomenclatural nom selectionne* @param nom_ret :* nom retenu* @param num_nom_ret :* numero nomenclaturel nom retenu* @param num_taxon :* numero taxonomique* @param famille :* famille*/public void addElement(String nom_sel, String num_nom_sel, String nom_ret,String num_nom_ret, String num_taxon, String famille) {// Calcul du nouveau numéro d'ordre/** int order=1; if (table.getRowCount()>0) { order=new* Integer(table.getText(table.getRowCount()-1,6)).intValue()+1; }*/count++;HTTPRequest.asyncPost(serviceBaseUrl + "/Inventory/", "identifiant="+ user + "&nom_sel=" + nom_sel + "&num_nom_sel=" + num_nom_sel+ "&nom_ret=" + nom_ret + "&num_nom_ret=" + num_nom_ret+ "&num_taxon=" + num_taxon + "&famille=" + famille,new ResponseTextHandler() {public void onCompletion(String str) {// (Optimisation) Si on reste sur la meme page : ajout à la finif (((count-2)/VISIBLE_TAXON_COUNT)==(count-1/VISIBLE_TAXON_COUNT)) {update(false);}else {gotoEnd();update(true);}}});}/*** Suppression d'un element lde l'inventaire, a partir de son numero d'ordre**/public void deleteElement() {setStatusDisabled();boolean checked = false;Vector parseChecked = new Vector();// Lifo ...for (int i = table.getRowCount() - 1; i >= 0; i--) {if (((CheckBox) table.getWidget(i, 0)).isChecked()) {checked = true;parseChecked.add(table.getText(i, 6));count--;}}sizeChecked=parseChecked.size();itemDeleted=0;for (Iterator it = parseChecked.iterator(); it.hasNext();) {itemDeleted++;HTTPRequest.asyncPost(serviceBaseUrl + "/Inventory/" + user+ "/" + (String) it.next(), "action=DELETE",new ResponseTextHandler() {public void onCompletion(String str) {// On ne lance la suppression qu'a la finif (itemDeleted==sizeChecked) {gotoEnd();update(true);}}});}if (!checked) {setStatusEnabled();}}/*** Selection de l'ensemble des elements affichés**/public void selectAll() {for (int i = table.getRowCount() - 1; i >= 0; i--) {((CheckBox) table.getWidget(i, 0)).setChecked(true);}}public void deselectAll() {for (int i = table.getRowCount() - 1; i >= 0; i--) {((CheckBox) table.getWidget(i, 0)).setChecked(false);}}/**** Lancement des initialisations dependantes de réponses asynchrones : le* retour d'une demande d'initialisation declanche la demande* d'initialisation suivantes user : resultat recherche nom d'utilisateur* count : resultat nombre d'enregistrements d'inventaires affichage* enregistrements trouvés**/private void initAsync() {navBar = new NavBar();// Information complementaire : un tableau associe au retour de// l'assistant de saisie// Mise en forme du headerheader.setCellSpacing(0);header.setCellPadding(2);header.setWidth("100%");header.setStyleName("taxon-ListHeader");header.setText(0, 0, "");header.setText(0, 1, "Nom saisi");header.setText(0, 2, "Nom retenu");header.setHTML(0, 3, "Code<br>Nomenclatural");header.setHTML(0, 4, "Code<br>Taxonomique");header.setText(0, 5, "Famille");header.getCellFormatter().setWidth(0, 0, "2%");header.getCellFormatter().setWidth(0, 1, "31%");header.getCellFormatter().setWidth(0, 2, "31%");header.getCellFormatter().setWidth(0, 3, "9%");header.getCellFormatter().setWidth(0, 4, "9%");header.getCellFormatter().setWidth(0, 5, "18%");// Mise en forme de la table.table.setCellSpacing(0);table.setBorderWidth(0);table.setCellPadding(2);table.setWidth("100%");// Mise en forme barre navigationnavBar.setWidth("100%");table.setStyleName("taxon-List");panel.add(navBar);panel.add(header);panel.add(table);getCount();// update()}/*** Recherche utilisateur en cours**/private void getUser() {HTTPRequest.asyncGet(serviceBaseUrl + "/User/",new ResponseTextHandler() {public void onCompletion(String str) {JSONValue jsonValue = JSONParser.parse(str);JSONString jsonString;if ((jsonString = jsonValue.isString()) != null) {user = jsonString.stringValue();}initAsync();}});}/*** Recherche nombre d'enregistrement pour l'utilisateur en cours**/private void getCount() {setStatusDisabled();HTTPRequest.asyncGet(serviceBaseUrl + "/InventoryList/" + user + "/",new ResponseTextHandler() {public void onCompletion(String str) {JSONValue jsonValue = JSONParser.parse(str);JSONNumber jsonNumber;if ((jsonNumber = jsonValue.isNumber()) != null) {count = (int) jsonNumber.getValue();gotoEnd(); // Derniere pageupdate(true);}}});}/*** Mise a jour de l'affichage, à partir des données d'inventaire deja* saisies. La valeur de this.startIndex permet de determiner quelles* données seront affichées**/private void update(final boolean deep) {setStatusDisabled();// TODO : optimisation : ne supprimer que les lignes qui ne seront pas// alimentes .// TODO : ne pas recreer la table a chaque fois ... : parcouris le retour, le comparer au present// et inserer ou supprimer s'il le faut.// TODO : ou alors prevoir un update pour les ajouts (forcemment à la fin) et un update pour les suppressions ...// Sauf qu'il y a les chgts de pages ... : oui, la un fait un update normal ...HTTPRequest.asyncGet(serviceBaseUrl + "/InventoryList/" + user + "/"+ startIndex + "/" + VISIBLE_TAXON_COUNT,new ResponseTextHandler() {public void onCompletion(String str) {JSONValue jsonValue = JSONParser.parse(str);JSONArray jsonArray;JSONArray jsonArrayNested;// Lifo ...if (deep) {for (int i = table.getRowCount() - 1; i >= 0; i--) {table.removeRow(i);}}else {table.removeRow(table.getRowCount());}if ((jsonArray = jsonValue.isArray()) != null) {int arraySize = jsonArray.size();for (int i = 0; i < arraySize; ++i) {if (!deep && i != arraySize -1) {continue;}if ((jsonArrayNested = jsonArray.get(i).isArray()) != null) {int row = table.insertRow(table.getRowCount());// Case a cochertable.setWidget(row, 0, new CheckBox());// Nom saisitable.setText(row, 1, ((JSONString) jsonArrayNested.get(0)).stringValue());// Nom retenutable.setText(row, 2, ((JSONString) jsonArrayNested.get(2)).stringValue());// Num nomenclaturaltable.setText(row, 3, ((JSONString) jsonArrayNested.get(1)).stringValue());// Num Taxonomiquetable.setText(row, 4, ((JSONString) jsonArrayNested.get(4)).stringValue());// Familletable.setText(row, 5, ((JSONString) jsonArrayNested.get(5)).stringValue());// Numero d'ordretable.setText(row, 6, ((JSONString) jsonArrayNested.get(6)).stringValue());table.getCellFormatter().setVisible(row, 6, false);table.getFlexCellFormatter().setWidth(row, 0, "2%");table.getFlexCellFormatter().setWidth(row, 1, "31%");table.getFlexCellFormatter().setWidth(row, 2, "31%");table.getFlexCellFormatter().setWidth(row, 3, "9%");table.getFlexCellFormatter().setWidth(row, 4, "9%");table.getFlexCellFormatter().setWidth(row, 5, "18%");}}}setStatusEnabled();}});}/*** Recuperation du prefixe d'appel des services*/private String getServiceBaseUrl() {Dictionary theme = Dictionary.getDictionary("Parameters");return theme.get("serviceBaseUrl");}/*** Affichage message d'attente et désactivation navigation** @param* @return void*/private void setStatusDisabled() {navBar.gotoFirst.setEnabled(false);navBar.gotoPrev.setEnabled(false);navBar.gotoNext.setEnabled(false);navBar.gotoEnd.setEnabled(false);setStatusText("Patientez ...");}/*** Affichage numero de page et gestion de la navigation**/private void setStatusEnabled() {// Il y a forcemment un disabled avant d'arriver iciif (count > 0) {if (startIndex >= VISIBLE_TAXON_COUNT) { // Au dela de la// premiere pagenavBar.gotoPrev.setEnabled(true);navBar.gotoFirst.setEnabled(true);if (startIndex < (count - VISIBLE_TAXON_COUNT)) { // Pas la// derniere// pagenavBar.gotoNext.setEnabled(true);navBar.gotoEnd.setEnabled(true);setStatusText((startIndex + 1) + " - "+ (startIndex + VISIBLE_TAXON_COUNT) + " sur " + count );} else { // Derniere pagesetStatusText((startIndex + 1) + " - " + count + " sur " + count );}} else { // Premiere pageif (count > VISIBLE_TAXON_COUNT) { // Des pages derrieresnavBar.gotoNext.setEnabled(true);navBar.gotoEnd.setEnabled(true);setStatusText((startIndex + 1) + " - "+ (startIndex + VISIBLE_TAXON_COUNT) + " sur " + count);} else {setStatusText((startIndex + 1) + " - " + count + " sur " + count);}}}else { // Pas d'inventaire, pas de navigationsetStatusText("0 - 0 sur 0");}}/** Positionnement index de parcours (this.startIndex) pour affichage de la* dernière page** @param* @return void*/private void gotoEnd() {if ((count == 0) || (count % VISIBLE_TAXON_COUNT) > 0) {startIndex = count - (count % VISIBLE_TAXON_COUNT);} else {startIndex = count - VISIBLE_TAXON_COUNT;}}}