New file |
0,0 → 1,698 |
/* |
* 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 implements |
AutoCompleteAsyncTextBoxListener { |
|
// Barre de navigation |
|
private 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 initialisations |
|
initWidget(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 cocher |
table.setWidget(row, 0, new CheckBox()); |
// Nom saisi |
table.setText(row, 1, str); |
|
table.getFlexCellFormatter().setWidth(row, 0, "2%"); |
table.getFlexCellFormatter() |
.setWidth(row, 1, "31%"); |
|
// Recherche complement d'information |
|
if (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, |
// Famille |
addElement(str, value, |
((JSONString) jsonArray.get(0)) |
.stringValue(), |
((JSONString) jsonArray.get(1)) |
.stringValue(), |
((JSONString) jsonArray.get(2)) |
.stringValue(), |
((JSONString) jsonArray.get(3)) |
.stringValue()); |
} |
} |
|
}); |
} |
// Saisie libre |
else { |
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 fin |
if (((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 fin |
if (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 header |
|
header.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 navigation |
|
navBar.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 page |
update(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 cocher |
table.setWidget(row, 0, new CheckBox()); |
// Nom saisi |
table.setText(row, 1, ((JSONString) jsonArrayNested |
.get(0)).stringValue()); |
// Nom retenu |
table.setText(row, 2, ((JSONString) jsonArrayNested |
.get(2)).stringValue()); |
// Num nomenclatural |
table.setText(row, 3, ((JSONString) jsonArrayNested |
.get(1)).stringValue()); |
// Num Taxonomique |
table.setText(row, 4, ((JSONString) jsonArrayNested |
.get(4)).stringValue()); |
// Famille |
table.setText(row, 5, ((JSONString) jsonArrayNested |
.get(5)).stringValue()); |
// Numero d'ordre |
table.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 ici |
|
if (count > 0) { |
|
if (startIndex >= VISIBLE_TAXON_COUNT) { // Au dela de la |
// premiere page |
navBar.gotoPrev.setEnabled(true); |
navBar.gotoFirst.setEnabled(true); |
if (startIndex < (count - VISIBLE_TAXON_COUNT)) { // Pas la |
// derniere |
// page |
navBar.gotoNext.setEnabled(true); |
navBar.gotoEnd.setEnabled(true); |
setStatusText((startIndex + 1) + " - " |
+ (startIndex + VISIBLE_TAXON_COUNT) + " sur " + count ); |
} else { // Derniere page |
setStatusText((startIndex + 1) + " - " + count + " sur " + count ); |
} |
} else { // Premiere page |
if (count > VISIBLE_TAXON_COUNT) { // Des pages derrieres |
navBar.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 navigation |
setStatusText("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; |
} |
|
} |
|
|
} |