Rev 2734 | Blame | Last modification | View Log | RSS feed
package org.tela_botanica.client.vues.observation;// TODO Detecter redim et supprimer ajusterimport java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import org.tela_botanica.client.CarnetEnLigneMediateur;import org.tela_botanica.client.i18n.Msg;import org.tela_botanica.client.interfaces.Rafraichissable;import org.tela_botanica.client.modeles.dao.ImageInformationRepartitionAsynchroneDAO;import org.tela_botanica.client.modeles.dao.ListeReferentielChampsEtendusDAO;import org.tela_botanica.client.modeles.dao.ListeReferentielLocaliteAsynchroneDAO;import org.tela_botanica.client.modeles.dao.ListeReferentielNomAsynchroneDAO;import org.tela_botanica.client.modeles.dao.ListeReferentielPersoAsynchroneDAO;import org.tela_botanica.client.modeles.objets.ChampEtendu;import org.tela_botanica.client.modeles.objets.Configuration;import org.tela_botanica.client.modeles.objets.EntiteGeographiqueObservation;import org.tela_botanica.client.modeles.objets.ListeObservation;import org.tela_botanica.client.modeles.objets.Observation;import org.tela_botanica.client.modeles.objets.Ontologies;import org.tela_botanica.client.modeles.objets.ReferentielLocalite;import org.tela_botanica.client.modeles.objets.ReferentielNom;import org.tela_botanica.client.modeles.objets.ListeReferentielPerso.TypesReferentiels;import org.tela_botanica.client.observation.ObservationMediateur;import org.tela_botanica.client.util.ChampSaisieEtendu;import org.tela_botanica.client.util.FormulaireSaisieChampEtendu;import org.tela_botanica.client.util.Util;import org.tela_botanica.client.util.autocompletion.AutoCompletionComboBox;import com.google.gwt.core.client.Callback;import com.google.gwt.event.dom.client.ClickEvent;import com.google.gwt.event.dom.client.ClickHandler;import com.google.gwt.http.client.Response;import com.google.gwt.user.client.Timer;import com.google.gwt.user.client.Window;import com.google.gwt.user.client.ui.HTML;import com.google.gwt.user.client.ui.PopupPanel;import com.gwtext.client.core.EventCallback;import com.gwtext.client.core.EventObject;import com.gwtext.client.core.Ext;import com.gwtext.client.core.ExtElement;import com.gwtext.client.core.ListenerConfig;import com.gwtext.client.core.Position;import com.gwtext.client.widgets.BoxComponent;import com.gwtext.client.widgets.Button;import com.gwtext.client.widgets.Container;import com.gwtext.client.widgets.DatePicker;import com.gwtext.client.widgets.Panel;import com.gwtext.client.widgets.ToolTip;import com.gwtext.client.widgets.event.ButtonListenerAdapter;import com.gwtext.client.widgets.event.ContainerListenerAdapter;import com.gwtext.client.widgets.event.DatePickerListenerAdapter;import com.gwtext.client.widgets.event.PanelListenerAdapter;import com.gwtext.client.widgets.form.ComboBox;import com.gwtext.client.widgets.form.DateField;import com.gwtext.client.widgets.form.Field;import com.gwtext.client.widgets.form.FormPanel;import com.gwtext.client.widgets.form.Label;import com.gwtext.client.widgets.form.MultiFieldPanel;import com.gwtext.client.widgets.form.TextArea;import com.gwtext.client.widgets.form.TextField;import com.gwtext.client.widgets.form.event.ComboBoxListenerAdapter;import com.gwtext.client.widgets.form.event.TextFieldListenerAdapter;import com.gwtext.client.widgets.layout.AnchorLayoutData;import com.gwtext.client.widgets.layout.ColumnLayout;import com.gwtext.client.widgets.layout.ColumnLayoutData;import com.gwtext.client.widgets.layout.FormLayout;import com.gwtext.client.widgets.layout.RowLayout;import com.gwtext.client.data.Record;/*** Panneau contenant les infos, les métadonnées et l'arbre des mots clés, il implémente l'interface rafraichissable* @author aurelien**/public class FormulaireSaisieObservationVue extends Panel implements Rafraichissable {/*** Le médiateur associé à la vue*/private ObservationMediateur observationMediateur = null;FormPanel panneauFormulaire = null;private DateField date = null;private AutoCompletionComboBox lieudit = null;private AutoCompletionComboBox station = null;private AutoCompletionComboBox milieu = null;private TextField comment = null;private AutoCompletionComboBox localite = null;private String codeLocalite = null;private String pays = null;private AutoCompletionComboBox espece = null;private Map<String, ReferentielNom> referentielNom = null;private Map<String, ReferentielLocalite> referentielLocalite = null;private String numeroNom = null;private String numeroOrdre = null;private String referentielTaxo = null;private String referentielGeo = null;private Map<String, String> avertissementPresence = new HashMap<String, String>();private boolean enRequeteChrologie = false;// Pour remise a zero partielle lors d'une validationprivate enum Champs {DATE, LIEUDIT, STATION, MILIEU, COMMENT, LOCALITE, ESPECE, TOUT, LATITUDE, LONGITUDE, ALTITUDE, ABONDANCE, CERTITUDE, REFERENTIELTAXO, PHENOLOGIE;@Overridepublic String toString() {switch(this) {case DATE:return "date";case LOCALITE:return "localite";case LIEUDIT:return "lieu dit";case STATION:return "station";case MILIEU:return "milieu";case COMMENT:return "notes";case ESPECE:return "espèce";case LATITUDE:return "latitude";case LONGITUDE:return "longitude";case ALTITUDE:return "altitude";case ABONDANCE:return "abondance";case CERTITUDE:return "identification";case REFERENTIELTAXO:return "referentiel";case PHENOLOGIE:return "phenologie";case TOUT:return "date, localite, lieu dit, station, milieu, espèce, notes, latitude, longitude, altitude, abondance, identification, referentiel, phenologie";}return TOUT.toString();}};private String formatDate = null ;private Button boutonOK = new Button(Msg.get("creer"));private Button boutonModifier = new Button(Msg.get("modifier"));private Button boutonSupprimer = new Button(Msg.get("supprimer"));private Button boutonReinitialiser = new Button(Msg.get("reinitialiser"));private boolean selectionlocalite=false;private boolean selectionEspece=false;private boolean selectionAbondance = false;private boolean selectionCertitude = false;private boolean selectionPhenologie = false;private final String VALEURS_MULTIPLES = "("+Msg.get("valeurs-multiples")+")";private final String modeleMessageModif = "localite:lieu-dit:station:milieu:latitude:longitude:altitude:date:espece:notes:abondance:identification:referentiel:phenologie";private boolean localiteModifiee = false;private boolean lieuDitModifie = false;private boolean stationModifiee = false;private boolean milieuModifie = false;private boolean dateModifiee = false;private boolean especeModifiee = false;private boolean commModifie = false;private boolean abondanceModifiee = false;private boolean certitudeModifiee = false;private boolean referentielTaxoModifie = false;private boolean phenologieModifiee = false;;private final int KEY_ALT = 18;private final int KEY_BACKSPACE = 8;private final int KEY_CTRL = 17;private final int KEY_DELETE = 46;private final int KEY_DOWN = 40;private final int KEY_END = 35;private final int KEY_ENTER = 13;private final int KEY_ESCAPE = 27;private final int KEY_HOME = 36;private final int KEY_LEFT = 37;private final int KEY_PAGEDOWN = 34;private final int KEY_PAGEUP = 33;private final int KEY_RIGHT = 39;private final int KEY_SHIFT = 16;private final int KEY_TAB = 9;private final int KEY_UP = 38;/*** Booleen d'instanciation*/boolean estInstancie = false ;private Panel panneauIntermediaire;private Panel panneauPremierColonne;private Panel panneauSecondeColonne;private TextField longitude;private TextField latitude;private TextField altitude;private MultiFieldPanel htmllocalitePanel = null;private MultiFieldPanel coordPanel;private TextField coordonnees;private Label lienSelectionlocalite = null;private HTML afficherFormulaireLatLon;private HTML basculerverscarto;private boolean longlatAjoutee;private boolean latModifiee;private boolean longModifiee;private boolean altModifiee;protected boolean recherchelocaliteEnCours = false;private Timer tCoord;private ComboBox selecteurAbondance = null;private ComboBox selecteurCertitude = null;private ComboBox selecteurReferentielTaxo = null;private ComboBox selecteurStadePheno = null;private boolean selectionMultiple = false;private HTML lienAfficherChampsEtendus = null;private HTML lienAjouterChampsEtendus = null;Panel conteneurChampEtenduGauche = null;Panel conteneurChampEtenduDroite = null;private boolean afficherChampsEtendus = false;private boolean afficherLienAjoutChampsEtendus = false;private boolean premierAffichage = true;private PopupPanel popUpAjoutChampEtendu = new PopupPanel();private Map<String, ChampSaisieEtendu> listeChampsEtendus;/*** Constructeur sans argument (privé car ne doit pas être utilisé)*/@SuppressWarnings("unused")private FormulaireSaisieObservationVue(){super() ;}/*** Constructeur avec argument* @param im*/public FormulaireSaisieObservationVue(ObservationMediateur obs){super(Msg.get("saisie"));// on associe le médiateurobservationMediateur = obs ;referentielTaxo = obs.getRefTaxSelectionne().getCode();panneauFormulaire = new FormPanel(Position.RIGHT);panneauFormulaire.setBorder(false);// Panneau intermediaire qui contient deux colonnes de formulairepanneauIntermediaire = new Panel();if (Window.getClientWidth()> Window.getClientHeight()) {panneauIntermediaire.setLayout(new ColumnLayout());}else {panneauIntermediaire.setLayout(new RowLayout());}panneauIntermediaire.setBorder(false);//création du panneau formulaire de gauche auquels on ajoute les champspanneauPremierColonne = new Panel();panneauPremierColonne.setLayout(new FormLayout());panneauPremierColonne.setBorder(false);//création du panneau formulaire de droitepanneauSecondeColonne = new Panel();panneauSecondeColonne.setLayout(new FormLayout());panneauSecondeColonne.setBorder(false);this.setPaddings(5) ;// Accesskey pour debugginglocalite = new AutoCompletionComboBox(Msg.get("localite"), ListeReferentielLocaliteAsynchroneDAO.getUrlReferentielLocalites()) {@Overrideprotected Map<String, String> parserResultatRequete(Response response) {referentielLocalite = Util.parserRetourReferentielLocaliteIndexeParNom(response);return Util.convertirListeReferentielLocaliteVersMap(referentielLocalite);}@Overridepublic void onSelectionValeur() {localiteModifiee = true;surSelectionLocalite();verifierPresenceTaxonSaisi();}@Overrideprotected void onModificationValeur() {localiteModifiee = true;verifierPresenceTaxonSaisi();}@Overridepublic void onValidationSaisie() {validerSaisie(Champs.LOCALITE);}};//création du lien "Accès carto" dans le formulaire;basculerverscarto = new HTML(" <a id=\"lien_carto\" title=\""+Msg.get("aide-lien-localiser")+"\" href=\"#\" tabindex=\"2\">"+Msg.get("localiser-zone")+"</a>");basculerverscarto.addStyleName("lien_actif");//création info bulle sur le lien "accès carto"ToolTip tip2 = new ToolTip();tip2.setHtml(Msg.get("aide-lien-localiser"));tip2.applyTo(basculerverscarto.getElement());//Sur une meme ligne, ajout de plusieurs champshtmllocalitePanel = new MultiFieldPanel();int largeurlocalite = Window.getClientWidth()/4;htmllocalitePanel.addToRow(localite, largeurlocalite);htmllocalitePanel.addToRow(basculerverscarto, 160);htmllocalitePanel.setBorder(false);htmllocalitePanel.setId("x-localite-panel");panneauPremierColonne.add(htmllocalitePanel);station = new AutoCompletionComboBox(Msg.get("station"), ListeReferentielPersoAsynchroneDAO.getUrlReferentielPerso(TypesReferentiels.REFERENTIEL_STATION)) {@Overrideprotected Map<String, String> parserResultatRequete(Response response) {return Util.parserRetourReferentielPerso(response);}@Overridepublic void onSelectionValeur() {stationModifiee = true;}@Overrideprotected void onModificationValeur() {stationModifiee = true;}@Overridepublic void onValidationSaisie() {validerSaisie(Champs.STATION);}@Overrideprotected String preTraiterUrlRequete(String urlRequete, String valeur) {return ListeReferentielPersoAsynchroneDAO.formaterUrlRequeteAutoCompletionPerso(urlRequete, valeur);}};panneauPremierColonne.add(station, new AnchorLayoutData("95%"));latitude = new TextField(Msg.get("lat"), "lat");latitude.setGrowMax(70);latitude.setAllowBlank(true);longitude = new TextField(Msg.get("lon"), "lon");longitude.setGrowMax(70);longitude.setAllowBlank(true);altitude = new TextField(Msg.get("alt"), "alt");altitude.setGrowMax(70);altitude.setAllowBlank(true);lienSelectionlocalite = new Label("");lienSelectionlocalite.setId("conteneur_selection_localite");lienSelectionlocalite.setStyleName("conteneur_selection_localite");lienSelectionlocalite.addStyleName("lien_actif");// Panneau de type plusieurs champs de formulaire sur une meme ligne, où seront renseignés Lat/LoncoordPanel = new MultiFieldPanel();coordPanel.setPaddings(0, 0, 0, 10);coordPanel.setVisible(false);final double largeur ;largeur = 120;coordPanel.addToRow(latitude, new ColumnLayoutData(largeur));coordPanel.addToRow(longitude, new ColumnLayoutData(largeur));coordPanel.addToRow(lienSelectionlocalite, new ColumnLayoutData(largeur));lienSelectionlocalite.addClass("lien_decale");coordPanel.setBorder(false);coordPanel.addToRow(altitude, new ColumnLayoutData(largeur));//création du champs coordonnéesreferentielGeo = Configuration.getReferentielGeo();coordonnees = new TextField(Msg.get("coordonnees"), "", 0);coordonnees.setMaxLength(0);coordonnees.setReadOnly(true);coordonnees.setCls("fieldname");//création du lien "saisie X/Y" dans le formulaireafficherFormulaireLatLon = new HTML("<span style=\"padding-left:30px;\" class=\"conteneur_lien_afficher_lat_lon\">" +"<a title=\""+Msg.get("indication-formulaire-lat-lon")+"\" class=\"lien_actif\" id=\"lien_coord\" href=\"#\" tabindex=\"6\">"+Msg.get("saisie-lat-lon")+" ("+referentielGeo+")</a>" +"<span><span style=\"padding-left:20px\" class=\"conteneur_lien_localiser_lat_lon\">"+"<a title=\""+Msg.get("indication-formulaire-localiser")+"\" class=\"lien_actif\" id=\"lien_carto_coord\" href=\"#\" tabindex=\"7\">"+Msg.get("localiser-la-carte")+"</a>"+"</span>");//ajout d'un listener sur le lien "saisie X/Y"coordPanel.addListener(new PanelListenerAdapter() {@Overridepublic void onAfterLayout(Container c) {surPremierAffichageCoordPanel(largeur);}});//Sur une meme ligne, ajout de plusieurs champsfinal MultiFieldPanel htmlPanel = new MultiFieldPanel();htmlPanel.addToRow(coordonnees, 100);htmlPanel.addToRow(afficherFormulaireLatLon, new ColumnLayoutData(0.9));htmlPanel.setBorder(false);htmlPanel.setId("x-coord-panel");panneauPremierColonne.add(htmlPanel);panneauPremierColonne.add(coordPanel);date = new DateField(Msg.get("date"), "date", 250);date.setAllowBlank(true);formatDate = "d/m/Y";date.setFormat(formatDate);date.setTitle(Msg.get("indication-format-date"));date.setMaxValue(new Date());//date.setTabIndex(5);panneauPremierColonne.add(date, new AnchorLayoutData("55%"));final String champsListeTpl = "<div class=\"x-combo-list-item search-item-tpl\" title=\"{label}\">{label}</div>";// Selection d'un référentiel par défaut (le premier spécifié dans la config)referentielTaxo = Configuration.getReferentielsDispos().get(0).getCode();selecteurReferentielTaxo = new ComboBox();selecteurReferentielTaxo.setCls("champ-separation");selecteurReferentielTaxo.setLabel(Msg.get("referentiel"));selecteurReferentielTaxo.setStore(Ontologies.getValeursReferentiel());selecteurReferentielTaxo.setValue(referentielTaxo);selecteurReferentielTaxo.setDisplayField("label") ;selecteurReferentielTaxo.setValueField("valeur");selecteurReferentielTaxo.setEditable(false);selecteurReferentielTaxo.setHideTrigger(false);selecteurReferentielTaxo.setForceSelection(true);selecteurReferentielTaxo.setTpl(champsListeTpl);espece = new AutoCompletionComboBox(Msg.get("espece"), ListeReferentielNomAsynchroneDAO.getBaseUrlReferentielNom()) {@Overrideprotected Map<String, String> parserResultatRequete(Response response) {// TODO: bien penser à l'unicité des clés, ici on suppose que// genre espèce auteur suffit mais quelquefois on peut avoir des doublonsreferentielNom = Util.parserRetourReferentielNomIndexeParNom(response);return Util.convertirListeReferentielNomVersMap(referentielNom);}@Overridepublic void onSelectionValeur() {especeModifiee = true;surSelectionEspece();verifierPresenceTaxonSaisi();}@Overrideprotected void onModificationValeur() {especeModifiee = true;// Pour éviter qu'un mauvais nn ne soit gardé lors d'une modification// vers un nom ne faisant pas partie du référentielnumeroNom = null;if(referentielNom.containsKey(espece.getText())) {numeroNom = referentielNom.get(espece.getText()).getNumeroNom();}verifierPresenceTaxonSaisi();}@Overridepublic void onValidationSaisie() {validerSaisie(Champs.ESPECE);}@Overrideprotected String preTraiterUrlRequete(String urlRequete, String valeur) {return ListeReferentielNomAsynchroneDAO.formaterUrlAutoCompletionReferentielNom(urlRequete, referentielTaxo, valeur);}@Overrideprotected String preTraiterValeurAvantAffichage(String valeur) {ReferentielNom nomValeur = referentielNom.get(valeur);String valeurAffichee = nomValeur.getNom();// Pour afficher les noms retenus en grasif (nomValeur.estRetenu()) {valeurAffichee = "<span class=\"nomRetenu\">"+nomValeur.getNom().trim()+"</span>";}return valeurAffichee;}};Panel panelSeparationPp = new Panel();panelSeparationPp.setHeight(15);panelSeparationPp.setBorder(false);panneauPremierColonne.add(panelSeparationPp);panneauPremierColonne.add(selecteurReferentielTaxo, new AnchorLayoutData("85%"));panneauPremierColonne.add(espece, new AnchorLayoutData("95%"));selecteurAbondance = new ComboBox();selecteurAbondance.setCls("champ-separation");selecteurAbondance.setLabel(Msg.get("abondance"));selecteurAbondance.setStore(Ontologies.getValeursAbondance());selecteurAbondance.setDisplayField("label") ;selecteurAbondance.setValueField("valeur");selecteurAbondance.setEditable(true);selecteurAbondance.setHideTrigger(false);selecteurAbondance.setForceSelection(false);selecteurAbondance.setTpl(champsListeTpl);panneauPremierColonne.add(selecteurAbondance, new AnchorLayoutData("95%"));lieudit = new AutoCompletionComboBox(Msg.get("lieu-dit"), ListeReferentielPersoAsynchroneDAO.getUrlReferentielPerso(TypesReferentiels.REFERENTIEL_LIEU_DIT)) {@Overrideprotected Map<String, String> parserResultatRequete(Response response) {return Util.parserRetourReferentielPerso(response);}@Overridepublic void onSelectionValeur() {lieuDitModifie = true;}@Overrideprotected void onModificationValeur() {lieuDitModifie = true;}@Overridepublic void onValidationSaisie() {validerSaisie(Champs.LIEUDIT);}@Overrideprotected String preTraiterUrlRequete(String urlRequete, String valeur) {return ListeReferentielPersoAsynchroneDAO.formaterUrlRequeteAutoCompletionPerso(urlRequete, valeur);}};panneauSecondeColonne.add(lieudit, new AnchorLayoutData("95%"));milieu = new AutoCompletionComboBox(Msg.get("milieu"), ListeReferentielPersoAsynchroneDAO.getUrlReferentielPerso(TypesReferentiels.REFERENTIEL_MILIEU)) {@Overrideprotected Map<String, String> parserResultatRequete(Response response) {return Util.parserRetourReferentielPerso(response);}@Overridepublic void onSelectionValeur() {milieuModifie = true;}@Overrideprotected void onModificationValeur() {milieuModifie = true;}@Overridepublic void onValidationSaisie() {validerSaisie(Champs.MILIEU);}@Overrideprotected String preTraiterUrlRequete(String urlRequete, String valeur) {return ListeReferentielPersoAsynchroneDAO.formaterUrlRequeteAutoCompletionPerso(urlRequete, valeur);}};panneauSecondeColonne.add(milieu, new AnchorLayoutData("95%"));comment = new TextArea(Msg.get("notes"), "comment");comment.setAllowBlank(true);comment.setHeight(50);panneauSecondeColonne.add(comment, new AnchorLayoutData("95%") );Panel panelSeparationPs = new Panel();panelSeparationPs.setHeight(39);panelSeparationPs.setBorder(false);panneauSecondeColonne.add(panelSeparationPs);selecteurCertitude = new ComboBox();selecteurCertitude.setLabel(Msg.get("identification"));selecteurCertitude.setStore(Ontologies.getValeursCertitude());selecteurCertitude.setDisplayField("label") ;selecteurCertitude.setValueField("valeur");selecteurCertitude.setEditable(true);selecteurCertitude.setHideTrigger(false);selecteurCertitude.setForceSelection(false);selecteurCertitude.setTpl(champsListeTpl);panneauSecondeColonne.add(selecteurCertitude, new AnchorLayoutData("95%"));selecteurStadePheno = new ComboBox();selecteurStadePheno.setLabel(Msg.get("phenologie"));selecteurStadePheno.setStore(Ontologies.getValeursPhenologie());selecteurStadePheno.setDisplayField("label") ;selecteurStadePheno.setValueField("valeur");selecteurStadePheno.setEditable(true);selecteurStadePheno.setHideTrigger(false);selecteurStadePheno.setForceSelection(false);selecteurStadePheno.setTpl(champsListeTpl);panneauSecondeColonne.add(selecteurStadePheno, new AnchorLayoutData("95%"));if (Window.getClientWidth() > Window.getClientHeight() || Window.getClientWidth() < 800) {panneauIntermediaire.add(panneauPremierColonne, new ColumnLayoutData(.5));panneauIntermediaire.add(panneauSecondeColonne, new ColumnLayoutData(.5));}else {panneauIntermediaire.add(panneauPremierColonne);panneauIntermediaire.add(panneauSecondeColonne);}panneauFormulaire.add(panneauIntermediaire);if (Ext.isIE()) {panneauPremierColonne.setButtonAlign(Position.RIGHT);panneauPremierColonne.addButton(boutonOK);panneauPremierColonne.addButton(boutonModifier);panneauPremierColonne.addButton(boutonSupprimer);panneauSecondeColonne.setButtonAlign(Position.LEFT);panneauPremierColonne.addButton(boutonReinitialiser);}else {panneauFormulaire.addButton(boutonOK);panneauFormulaire.addButton(boutonModifier);panneauFormulaire.addButton(boutonSupprimer);panneauFormulaire.addButton(boutonReinitialiser);}this.add(panneauFormulaire) ;this.setAutoScroll(true);panneauFormulaire.addListener(new PanelListenerAdapter() {@Overridepublic void onResize(BoxComponent component, int adjWidth, int adjHeight, int rawWidth, int rawHeight) {panneauIntermediaire.setWidth(rawWidth);panneauIntermediaire.setHeight(rawHeight);panneauPremierColonne.doLayout();panneauSecondeColonne.doLayout();htmllocalitePanel.doLayout();htmlPanel.doLayout();redimensionnerChampsEtendus();doLayout();}});lienAfficherChampsEtendus = new HTML(Msg.get("afficher-champs-etendus"));lienAfficherChampsEtendus.setStyleName("img-curseur-depl");lienAfficherChampsEtendus.setStyleName("lienAfficherChampsEtendus");lienAfficherChampsEtendus.setVisible(false);lienAfficherChampsEtendus.addClickHandler(new ClickHandler() {@Overridepublic void onClick(ClickEvent event) {if(afficherChampsEtendus) {afficherChampsEtendus = false;if(conteneurChampEtenduGauche != null && conteneurChampEtenduDroite != null) {conteneurChampEtenduGauche.hide();conteneurChampEtenduDroite.hide();}lienAfficherChampsEtendus.setText(Msg.get("afficher-champs-etendus"));} else {afficherChampsEtendus = true;if(conteneurChampEtenduGauche != null && conteneurChampEtenduDroite != null) {conteneurChampEtenduGauche.show();conteneurChampEtenduDroite.show();redimensionnerChampsEtendus();}lienAfficherChampsEtendus.setText(Msg.get("cacher-champs-etendus"));}}});if(Configuration.saisieChampsEtendusActivee()) {// Chargement du cache des correspondances cles/labels du catalogueListeReferentielChampsEtendusDAO lrceDao = new ListeReferentielChampsEtendusDAO(null);lrceDao.obtenirGroupesChampsEtendus(this);lrceDao.obtenirCatalogueChampsEtendus(this);lienAjouterChampsEtendus = new HTML(Msg.get("ajouter-champ-etendu"));lienAjouterChampsEtendus.addStyleName("lienAjouterChampEtendu");lienAjouterChampsEtendus.setVisible(true);panneauPremierColonne.add(lienAjouterChampsEtendus);gererLienAjoutChampsEtendus();}panneauPremierColonne.add(lienAfficherChampsEtendus);panneauPremierColonne.addListener(new PanelListenerAdapter() {@Overridepublic void onAfterLayout(Container c) {if(premierAffichage) {lienAfficherChampsEtendus.setVisible(false);premierAffichage = false;}}});ajouterListeners() ;ajouterToolTipsBoutons();saisieTabindex();}protected void surSelectionEspece() {ReferentielNom nom = referentielNom.get(espece.getText());numeroNom = nom.getNumeroNom();selectionEspece = true;observationMediateur.obtenirImageInformationExternes(referentielTaxo, numeroNom);}protected void surSelectionLocalite() {ReferentielLocalite infosLoc = referentielLocalite.get(localite.getText());codeLocalite = infosLoc.getCodeLocalite();selectionlocalite=true;}private void gererLienAjoutChampsEtendus() {popUpAjoutChampEtendu.setStylePrimaryName("popup_champ_etendu");lienAjouterChampsEtendus.addClickHandler(new ClickHandler() {@Overridepublic void onClick(ClickEvent event) {FormulaireSaisieChampEtendu formChamp = new FormulaireSaisieChampEtendu() {@Overridepublic void surValidation(ChampSaisieEtendu champ) {ajouterChampEtenduAuFormulaire(champ, true);popUpAjoutChampEtendu.clear();popUpAjoutChampEtendu.hide();}@Overridepublic void surAjout(ChampSaisieEtendu champ) {ajouterChampEtenduAuFormulaire(champ, false);}@Overridepublic void surAnnulation() {popUpAjoutChampEtendu.clear();popUpAjoutChampEtendu.hide();}@Overridepublic void surAjoutMultiple(List<ChampSaisieEtendu> champs) {for (Iterator<ChampSaisieEtendu> iterator = champs.iterator(); iterator.hasNext();) {ChampSaisieEtendu champSaisieEtendu = (ChampSaisieEtendu) iterator.next();ajouterChampEtenduAuFormulaire(champSaisieEtendu, false);}}@Overridepublic void surValidationMultiple(List<ChampSaisieEtendu> champs) {for (Iterator<ChampSaisieEtendu> iterator = champs.iterator(); iterator.hasNext();) {ChampSaisieEtendu champSaisieEtendu = (ChampSaisieEtendu) iterator.next();ajouterChampEtenduAuFormulaire(champSaisieEtendu, false);}popUpAjoutChampEtendu.clear();popUpAjoutChampEtendu.hide();}};popUpAjoutChampEtendu.add(formChamp);popUpAjoutChampEtendu.center();popUpAjoutChampEtendu.setModal(true);popUpAjoutChampEtendu.show();formChamp.redimensionner(popUpAjoutChampEtendu.getOffsetWidth() - 13);}});}private void ajouterChampEtenduAuFormulaire(ChampSaisieEtendu nChamp, boolean fermerPopup) {ChampEtendu chet = new ChampEtendu(nChamp.getCle(), nChamp.getLabel(), "");Map<String, ChampEtendu> champsEt = getValeursChampsEtendus();if(!champsEt.containsKey(chet.getCle())) {champsEt.put(chet.getCle(), chet);afficherChampsEtendus = true;if(fermerPopup) {afficherChampsEtendus(champsEt, chet);popUpAjoutChampEtendu.clear();popUpAjoutChampEtendu.hide();} else {afficherChampsEtendus(champsEt, null);}} else {String[] stParams = {chet.getLabel()};Window.alert(Msg.get("indication-champ-etendu-existe-deja", stParams));}}private void ajouterToolTipsBoutons() {boutonOK.setTitle(Msg.get("indication-bouton-creer-obs"));boutonModifier.setTitle(Msg.get("indication-bouton-modifier-obs"));boutonSupprimer.setTitle(Msg.get("indication-bouton-supprimer-obs"));boutonReinitialiser.setTitle(Msg.get("indication-bouton-reinitialiser-obs"));}private void surPremierAffichageCoordPanel(final double largeur) {ExtElement lienCoord = Ext.get("lien_coord");lienCoord.removeAllListeners();lienCoord.addListener("click", new EventCallback() {@Overridepublic void execute(EventObject e) {coordPanel.setVisible(!coordPanel.isVisible());if(Ext.isIE()) {latitude.focus();}CarnetEnLigneMediateur.fireResize();}}) ;ExtElement lienCartoCoord = Ext.get("lien_carto_coord");lienCartoCoord.removeAllListeners();lienCartoCoord.addListener("click", new EventCallback() {@Overridepublic void execute(EventObject e) {obtenirInformationCoord();}}) ;ExtElement lienCarto = Ext.get("lien_carto");lienCarto.removeAllListeners();lienCarto.addListener("click", new EventCallback() {@Overridepublic void execute(EventObject e) {if(localite.getText() != null && !localite.getText().equals("")) {obtenirInformationLocalite();longlatAjoutee = true;} else {Window.alert(Msg.get("indication-localite-vide-invalide"));}}});if(!Ext.isIE() && Window.getClientWidth() < 1200) {int largeurN = (int)largeur;latitude.setWidth(largeurN+"px");longitude.setWidth(largeurN+"px");lienSelectionlocalite.setWidth(largeurN+"px");}}private void ajouterListeners(){// Listener completion communnefinal Rafraichissable r = this;ListenerConfig listenerConfiglocalite=new ListenerConfig();listenerConfiglocalite.setDelay(200);listenerConfiglocalite.setStopPropagation(false);listenerConfiglocalite.setStopEvent(false);date.addListener(new DatePickerListenerAdapter() {@Overridepublic void onSelect(DatePicker dataPicker, Date date) {dateModifiee = true;}});ListenerConfig listenerConfigAutocompletion=new ListenerConfig();listenerConfigAutocompletion.setDelay(200);listenerConfigAutocompletion.setStopPropagation(false);listenerConfigAutocompletion.setStopEvent(false);ListenerConfig listenerConfigEspece=new ListenerConfig();listenerConfigEspece.setDelay(10);listenerConfigEspece.setStopPropagation(false);listenerConfigEspece.setStopEvent(false);tCoord = new Timer() {@Overridepublic void run() {double[] coord = coordonneesValides();if(!recherchelocaliteEnCours && coord != null && (longModifiee || latModifiee)) {recherchelocaliteEnCours = true;Ext.get(lienSelectionlocalite.getElement()).mask(Msg.get("recherche"));observationMediateur.obtenirInformationCoord(r,coord[0], coord[1]);}}};ajouterListenerChampEvenementsClavier(date);ajouterListenerChampEvenementsClavier(selecteurReferentielTaxo);ajouterListenerChampEvenementsClavier(comment);ajouterListenerChampEvenementsClavier(latitude);ajouterListenerChampEvenementsClavier(longitude);ajouterListenerChampEvenementsClavier(altitude);ajouterListenerChampEvenementsClavier(selecteurAbondance);ajouterListenerChampEvenementsClavier(selecteurCertitude);ajouterListenerChampEvenementsClavier(selecteurStadePheno);ajouterListenerChampsCombobox();boutonOK.addListener(new ButtonListenerAdapter() {@Overridepublic void onClick(Button button, EventObject e) {ajouterObservation();}});boutonModifier.addListener(new ButtonListenerAdapter() {@Overridepublic void onClick(Button button, EventObject e) {if(selectionMultiple) {modifierObservationEnMasse();} else {modifierObservation() ;}}});boutonSupprimer.addListener(new ButtonListenerAdapter() {@Overridepublic void onClick(Button button, EventObject e) {if(!selectionMultiple) {supprimerObservation();} else {observationMediateur.supprimerObservations();}}});boutonReinitialiser.addListener(new ButtonListenerAdapter() {@Overridepublic void onClick(Button button, EventObject e) {setSelectionMultiple(false);raz();}});this.addListener(new ContainerListenerAdapter() {@Overridepublic void onAfterLayout(Container self) {localite.focus();}});}private void ajouterListenerChampsCombobox() {selecteurReferentielTaxo.addListener(new ComboBoxListenerAdapter() {@Overridepublic void onSelect(ComboBox comboBox, Record record, int index) {referentielTaxo = record.getAsString("valeur");observationMediateur.setRefTaxSelectionne(index);referentielTaxoModifie = true;}});selecteurAbondance.addListener(new ComboBoxListenerAdapter() {@Overridepublic void onSelect(ComboBox comboBox, Record record, int index) {selectionAbondance=true;abondanceModifiee = true;}});selecteurCertitude.addListener(new ComboBoxListenerAdapter() {@Overridepublic void onSelect(ComboBox comboBox, Record record, int index) {selectionCertitude=true;certitudeModifiee = true;}});selecteurStadePheno.addListener(new ComboBoxListenerAdapter() {@Overridepublic void onSelect(ComboBox comboBox, Record record, int index) {selectionPhenologie=true;phenologieModifiee = true;}});}private void ajouterListenerChampEvenementsClavier(final TextField champ) {champ.addKeyPressListener(new EventCallback() {@Overridepublic void execute(EventObject e) {surEvenementClavier(e, champ);}});}private void ajouterListenerChampEvenementsClavier(final TextField champ, final ListenerConfig config) {champ.addKeyPressListener(new EventCallback() {@Overridepublic void execute(EventObject e) {surEvenementClavier(e, champ);}}, config);}private void surEvenementClavier(EventObject e, TextField champ) {switch(e.getKey()) {case KEY_ALT:case KEY_CTRL:case KEY_DOWN:case KEY_END:case KEY_ESCAPE:case KEY_HOME:case KEY_LEFT:case KEY_PAGEDOWN:case KEY_PAGEUP:case KEY_RIGHT:case KEY_SHIFT:case KEY_TAB:case KEY_UP:break;case KEY_ENTER:surEvenementClavierToucheEntree(champ);break;default:gererEvenementClavierDefaut(champ);break;}}private void surEvenementClavierToucheEntree(TextField champ) {//TODO: faire un switch ou une enumif(champ.equals(selecteurStadePheno)) {if(!selectionPhenologie) {validerSaisie(Champs.PHENOLOGIE);} else {selectionPhenologie = false;}}if(champ.equals(selecteurCertitude)) {if(!selectionCertitude) {validerSaisie(Champs.CERTITUDE);} else {selectionCertitude = false;}}if(champ.equals(selecteurAbondance)) {if(!selectionAbondance) {validerSaisie(Champs.ABONDANCE);} else {selectionAbondance = false;}}if(champ.equals(longitude)) {validerSaisie(Champs.LONGITUDE);}if(champ.equals(latitude)) {validerSaisie(Champs.LATITUDE);}if(champ.equals(altitude)) {validerSaisie(Champs.ALTITUDE);}if(champ.equals(espece)) {if(selectionEspece) {especeModifiee = true;selectionEspece=false;}else {validerSaisie(Champs.ESPECE);}}if(champ.equals(selecteurReferentielTaxo)) {validerSaisie(Champs.REFERENTIELTAXO);}if(champ.equals(date)) {validerSaisie(Champs.DATE);}if(champ.equals(localite)) {if(champ.equals(localite)) {if (selectionlocalite) {localiteModifiee= true;selectionlocalite=false;}else {validerSaisie(Champs.LOCALITE);}}}}private void gererEvenementClavierDefaut(TextField champ) {//TODO: faire un switch ou une enumif(champ.equals(selecteurStadePheno)) {selecteurStadePheno.setRawValue(selecteurStadePheno.getRawValue());selecteurStadePheno.setValue(selecteurStadePheno.getRawValue());phenologieModifiee = true;selectionPhenologie = false;}if(champ.equals(selecteurCertitude)) {selecteurCertitude.setRawValue(selecteurCertitude.getRawValue());selecteurCertitude.setValue(selecteurCertitude.getRawValue());certitudeModifiee = true;selectionCertitude = false;}if(champ.equals(selecteurAbondance)) {selecteurAbondance.setRawValue(selecteurAbondance.getRawValue());selecteurAbondance.setValue(selecteurAbondance.getRawValue());abondanceModifiee = true;selectionAbondance = false;}if(champ.equals(longitude)) {longModifiee = true;tCoord.cancel();tCoord.schedule(250);}if(champ.equals(latitude)) {latModifiee = true;tCoord.cancel();tCoord.schedule(250);}if(champ.equals(altitude)) {altModifiee = true;}if(champ.equals(comment)) {commModifie = true;}if(champ.equals(espece)) {numeroNom="";especeModifiee = true;}if(champ.equals(selecteurReferentielTaxo)) {referentielTaxoModifie = true;}if(champ.equals(date)) {dateModifiee = true;}if(champ.equals(localite)) {codeLocalite="";localite.collapse();localiteModifiee= true;}}/*** Validation de la saisie*/private void validerSaisie(Champs champs) {if(!selectionMultiple) {ajouterObservation();raz(champs);} else {modifierObservationEnMasse();}}/*** Desactive visuellement ce panneau*/public void desactiverPanneau(){this.setDisabled(true) ;}/*** Active visuellement ce panneau*/public void activerPanneau(){this.setDisabled(false) ;}@Overridepublic void rafraichir(Object nouvelleDonnees, boolean repandreRaffraichissement) {// On recoit une observation dont on veut afficher le detailif(nouvelleDonnees instanceof Observation){Observation obs = (Observation)nouvelleDonnees ;setSelectionMultiple(false);afficherDetailsObservation(obs) ;}if(nouvelleDonnees instanceof ListeObservation) {ListeObservation listeObs = (ListeObservation)nouvelleDonnees;setSelectionMultiple(true);calculerAfficherDifferences(listeObs);}if(nouvelleDonnees instanceof String){String str = (String)nouvelleDonnees ;observationMediateur.obtenirNombreObservation() ;}if(nouvelleDonnees instanceof String[]) {String[] anumNom = (String[])nouvelleDonnees ;numeroNom = anumNom[1];espece.setValue(anumNom[0]);}if(nouvelleDonnees instanceof EntiteGeographiqueObservation){EntiteGeographiqueObservation infosComm = (EntiteGeographiqueObservation)nouvelleDonnees ;if(recherchelocaliteEnCours) {afficherIndicationlocalite(infosComm);} else {rafraichirlocaliteEtCoord(infosComm);}}}private void afficherIndicationlocalite(final EntiteGeographiqueObservation infosCom) {String nlocalite = "";if(infosCom != null && infosCom.getZoneGeo() != null && !infosCom.getZoneGeo().trim().isEmpty()) {nlocalite += infosCom.getZoneGeo();if(infosCom.getIdZoneGeo() != null && !infosCom.getIdZoneGeo().trim().isEmpty()) {if(Util.estUnDepartement(infosCom.getIdZoneGeo())) {nlocalite += " ("+Util.convertirChaineZoneGeoVersDepartement(infosCom.getIdZoneGeo())+")";} else if(infosCom.getPays() != null && !infosCom.getPays().trim().isEmpty()) {nlocalite += " ("+infosCom.getPays()+")";}} else if(infosCom.getPays() != null && !infosCom.getPays().trim().isEmpty()) {nlocalite += " ("+infosCom.getPays()+")";}lienSelectionlocalite.setHtml("<a id=\"lien_selection_localite\" tabindex=\"9\">"+nlocalite+"</a>");lienSelectionlocalite.setStyleName("img-curseur-depl");Ext.get("lien_selection_localite").addListener("click",new EventCallback() {@Overridepublic void execute(EventObject e) {rafraichirlocalite(infosCom);}});Ext.get("lien_selection_localite").addListener("keypress",new EventCallback() {@Overridepublic void execute(EventObject e) {if(e.getCharCode() == KEY_ENTER) {rafraichirlocalite(infosCom);}}});Ext.get("lien_selection_localite").addListener("focus",new EventCallback() {@Overridepublic void execute(EventObject e) {Ext.get("lien_selection_localite").toggleClass("lien_sel");}});Ext.get("lien_selection_localite").addListener("blur",new EventCallback() {@Overridepublic void execute(EventObject e) {Ext.get("lien_selection_localite").toggleClass("lien_sel");}});} else {if(recherchelocaliteEnCours) {lienSelectionlocalite.setHtml("<span id=\"aucune_selection_localite\"> "+Msg.get("erreur-localisation")+" </span>");} else {lienSelectionlocalite.setHtml("<span id=\"aucune_selection_localite\"> </span>");}}Ext.get(lienSelectionlocalite.getElement()).unmask();recherchelocaliteEnCours = false;}private void rafraichirlocalite(EntiteGeographiqueObservation infosCom) {String nlocalite = "";if(infosCom.getZoneGeo() != null && !infosCom.getZoneGeo().equals("")) {nlocalite += infosCom.getZoneGeo();}if(infosCom.getIdZoneGeo() != null && Util.estUnDepartement(infosCom.getIdZoneGeo())) {String codeGeoFormate = Util.convertirChaineZoneGeoVersDepartement(infosCom.getIdZoneGeo());nlocalite += " ("+codeGeoFormate+")";codeLocalite = Util.convertirChaineZoneGeoVersDepartement(infosCom.getIdZoneGeo());} else if(infosCom.getPays() != null && !infosCom.getPays().trim().isEmpty()) {nlocalite += " ("+infosCom.getPays()+")";}if (!nlocalite.isEmpty()) {// Vide ou null, on remplace !if(localite.getText() == null || localite.getText().trim().isEmpty()) {localite.setValue(nlocalite);} else {// Afin de pas effacer un pays précédemment saisi, si on a déjà saisi une localité// avec le même nom mais avec un pays, on ne remplace rienif(localite.getText() != null && !localite.getText().contains(nlocalite)) {localite.setValue(nlocalite);}}localiteModifiee = true;}}// Se déclenche au retour de la "localisation sur la carte"private void rafraichirlocaliteEtCoord(EntiteGeographiqueObservation infosCom) {rafraichirlocalite(infosCom);if(infosCom.getLat() != null && !infosCom.getLat().equals("")) {latitude.setValue(Util.tronquerNombrePourAffichage("" + infosCom.getLat(), 5));}if(infosCom.getLon() != null && !infosCom.getLon().equals("")) {longitude.setValue(Util.tronquerNombrePourAffichage("" + infosCom.getLon(), 5));}latModifiee = true;longModifiee = true;coordPanel.setVisible(true);}public void ajouterObservation() {if(date.getRawValue() != null && !date.getRawValue().equals("") && !Util.verifierDateFormatCel(date.getRawValue())) {Window.alert(Msg.get("indication-date-invalide"));date.setInvalidText(Msg.get("date-invalide"));return;}affecterCodeLocaliteOuPays();String dateObs = Util.remplacerSeparateursDateFormatCel(date.getRawValue());Observation obs=new Observation(espece.getText(),numeroNom,localite.getText(),codeLocalite,lieudit.getText(),station.getText(),milieu.getText(), comment.getText(),dateObs);String[] coords = getValeurCoordonnees();obs.setPays(pays);obs.setLatitude(coords[0]);obs.setLongitude(coords[1]);obs.setAltitude(altitude.getText());obs.setAbondance(getAbondance());obs.setCertitude(getCertitude());obs.setPhenologie(getPhenologie());obs.setReferentielTaxo(Ontologies.getInfosReferentielNomParCode(referentielTaxo).getCodeVersionComplet());obs.setChampsEtendus(getValeursChampsEtendus());observationMediateur.ajouterObservation(obs);}private void modifierObservation() {if(!Window.confirm(Msg.get("question-modifier-observation")+" ?")) {return;}if(date.getRawValue() != null && !date.getRawValue().equals("") && !Util.verifierDateFormatCel(date.getRawValue())) {Window.alert(Msg.get("indication-date-invalide"));date.setInvalidText(Msg.get("date-invalide"));return;}affecterCodeLocaliteOuPays();String dateObs = Util.remplacerSeparateursDateFormatCel(date.getRawValue());Observation obs=new Observation(espece.getText(),numeroNom,localite.getText(),codeLocalite,lieudit.getText(),station.getText(),milieu.getText(), comment.getText(),dateObs);obs.setNumeroOrdre(numeroOrdre);String[] coords = getValeurCoordonnees();obs.setPays(pays);obs.setLatitude(coords[0]);obs.setLongitude(coords[1]);obs.setAltitude(altitude.getText());obs.setAbondance(getAbondance());obs.setCertitude(getCertitude());obs.setPhenologie(getPhenologie());obs.setReferentielTaxo(getReferentielTaxo());obs.setChampsEtendus(getValeursChampsEtendus());observationMediateur.modifierObservation(obs);}private void affecterCodeLocaliteOuPays() {codeLocalite = "";pays = "";// Soit un numéro de département, soit un code de pays à deux lettresString[] codeCom = localite.getText().split(" ");if(codeCom.length > 1 && ressembleAUnCodePaysOuDepartement(codeCom[codeCom.length - 1])) {String codeLoc = codeCom[codeCom.length - 1].replace('(', ' ');codeLoc = codeLoc.replace(')', ' ').trim().replace('\\',' ').trim();if(Util.estUnDepartement(codeLoc)) {codeLocalite = codeLoc ;} else {pays = codeLoc.toUpperCase();}}}private boolean ressembleAUnCodePaysOuDepartement(String s) {String sP = s.replace("(", "").replace(")", "").trim();boolean contientDesParentheses = s.contains("(") && s.contains(")");boolean estUnCodePays = !Util.estUnNombre(sP) && (sP.length() == 2);boolean estUnCodeDepartement = Util.estUnNombre(sP) && (sP.length() >= 1 && sP.length() <= 5);return contientDesParentheses && (estUnCodePays || estUnCodeDepartement);}private void modifierObservationEnMasse() {//TODO: factoriserString paysM = null;String localiteM = null;String codeLocaliteM = null;String numNomSelM = null;String lieuDitM = null;String stationM = null;String milieuM = null;String dateM = null;String especeM = null;String commM = null;String latM = null;String longM = null;String altM = null;String abondanceM = null;String certitudeM = null;String referentielTaxoM = null;String phenologieM = null;String champs = modeleMessageModif;if(localiteModifiee && ! localite.getRawValue().equals(VALEURS_MULTIPLES)) {localiteM = localite.getText();// Soit un numéro de département, soit un code de pays à deux lettresString[] codeCom = localite.getText().split(" ");if(codeCom.length > 1) {String codeLoc = codeCom[1].replace('(', ' ');codeLoc = codeLoc.replace(')', ' ').trim().replace('\\',' ').trim();if(Util.estUnDepartement(codeLoc)) {codeLocaliteM = codeLoc ;} else {paysM = codeLoc;}}}else {champs = champs.replaceAll("localite", "");}if(lieuDitModifie && ! lieudit.getRawValue().equals(VALEURS_MULTIPLES)) {lieuDitM = lieudit.getText();} else {champs = champs.replaceAll(":lieu-dit", "");}if(stationModifiee && ! station.getRawValue().equals(VALEURS_MULTIPLES)) {stationM = station.getText();} else {champs = champs.replaceAll(":station", "");}if(milieuModifie && ! milieu.getRawValue().equals(VALEURS_MULTIPLES)) {milieuM = milieu.getText();} else {champs = champs.replaceAll(":milieu", "");}if(dateModifiee && ! date.getRawValue().equals(VALEURS_MULTIPLES)) {dateM = date.getRawValue();dateM = Util.remplacerSeparateursDateFormatCel(dateM);} else {champs = champs.replaceAll(":date", "");}if(especeModifiee && ! espece.getRawValue().equals(VALEURS_MULTIPLES)) {especeM = espece.getText();numNomSelM = numeroNom;} else {champs = champs.replaceAll(":espece", "");}if(commModifie && ! comment.getRawValue().equals(VALEURS_MULTIPLES)) {commM = comment.getText();} else {champs = champs.replaceAll(":notes", "");}if(latModifiee && ! latitude.getRawValue().equals(VALEURS_MULTIPLES)) {latM = latitude.getText();} else {champs = champs.replaceAll(":latitude", "");}if(altModifiee && ! altitude.getRawValue().equals(VALEURS_MULTIPLES)) {altM = altitude.getText();} else {champs = champs.replaceAll(":altitude", "");}if(longModifiee && ! longitude.getRawValue().equals(VALEURS_MULTIPLES)) {longM = longitude.getText();} else {champs = champs.replaceAll(":longitude", "");}if(abondanceModifiee && !selecteurAbondance.getRawValue().equals(VALEURS_MULTIPLES)) {abondanceM = getAbondance();} else {champs = champs.replaceAll(":abondance", "");}if(certitudeModifiee && !selecteurCertitude.getRawValue().equals(VALEURS_MULTIPLES)) {certitudeM = getCertitude();} else {champs = champs.replaceAll(":identification", "");}if(referentielTaxoModifie && !selecteurReferentielTaxo.getRawValue().equals(VALEURS_MULTIPLES)) {referentielTaxoM = getReferentielTaxo();} else {champs = champs.replaceAll(":referentiel", "");}if(phenologieModifiee && !selecteurStadePheno.getRawValue().equals(VALEURS_MULTIPLES)) {phenologieM = getPhenologie();} else {champs = champs.replaceAll(":phenologie", "");}// TODO : trouver un meilleur système que ça pour gérer le message// affichéString[] champsSt = champs.split(":");String champsTraduits = "";for (int i = 0; i < champsSt.length; i++) {// TODO: vérifier pourquoi des fois la chaîne est vide// ou faire mieux, trouver un meilleur système comme écrit au dessus !if(!champsSt[i].trim().isEmpty()) {champsTraduits += Msg.get(champsSt[i]);champsTraduits += (i != champsSt.length - 1) ? ", " : "";}}String[] stParams = {champsTraduits};String message = Msg.get("question-modifier-champs-observation", stParams)+" ?" ;if(champs.trim().equals("")) {Window.alert(Msg.get("indication-aucun-champ-modifie"));} else {Observation obs = new Observation(especeM,numNomSelM,localiteM,codeLocaliteM,lieuDitM,stationM,milieuM, commM,dateM);obs.setPays(paysM);obs.setNumeroOrdre(numeroOrdre);obs.setLatitude(latM);obs.setLongitude(longM);obs.setAltitude(altM);obs.setAbondance(abondanceM);obs.setCertitude(certitudeM);// Afin de transmettre un ensemble cohérent on force aussi// l'envoi du référentiel en cas de maj de l'espèceif(especeModifiee) {referentielTaxoM = getReferentielTaxo();}obs.setReferentielTaxo(referentielTaxoM);obs.setPhenologie(phenologieM);if(Window.confirm(message)) {observationMediateur.modifierObservationEnMasse(obs);reinitialiserValeurModifiees();}}}private void supprimerObservation() {observationMediateur.supprimerObservation(this, numeroOrdre);}public void afficherDetailsObservation(Observation obs){raz() ;String idLoc ;if(obs.getIdentifiantLocalite() != VALEURS_MULTIPLES) {idLoc = obs.getIdentifiantLocalite().replaceAll(" ","/");idLoc = idLoc.replaceAll("%","");idLoc = idLoc.replaceAll("\"","");idLoc = idLoc.replace('\\',' ');idLoc = idLoc.trim();if(idLoc.length() == 5) {idLoc = idLoc.substring(0,2);}} else {idLoc = obs.getIdentifiantLocalite();if(idLoc.length() == 5) {idLoc = idLoc.substring(0,2);}}if(obs.getIdentifiantLocalite().isEmpty() && !obs.getPays().isEmpty()) {idLoc = obs.getPays();}if(!obs.getDate().equals("null") && !obs.getDate().equals("000null") && !obs.getDate().equals(VALEURS_MULTIPLES)) {String[] dateEtHeure = obs.getDate().split(" ", 2);if(verifierFormatDate(dateEtHeure[0])) {date.setValue(dateEtHeure[0]) ;}else{date.setRawValue("");}} else {date.setRawValue(VALEURS_MULTIPLES);date.clearInvalid();}if(!obs.getLieudit().equals("null") && !obs.getLieudit().equals("000null")) {lieudit.setValue(obs.getLieudit()) ;}if(!obs.getStation().equals("null") && !obs.getStation().equals("000null")) {station.setValue(obs.getStation()) ;}if(!obs.getMilieu().equals("null") && !obs.getMilieu().equals("000null")) {milieu.setValue(obs.getMilieu()) ;}if(!obs.getCommentaire().equals("null") && !obs.getCommentaire().equals("000null")) {comment.setRawValue(Util.remplacerSautsDeligneMalEncodes(obs.getCommentaire()));}if(!obs.getLocalite().equals("null") && !obs.getLocalite().equals("000null")) {if(!idLoc.equals("000null") && !idLoc.equals("")) {if(!idLoc.equals(VALEURS_MULTIPLES)) {localite.setValue(obs.getLocalite()+" ("+idLoc+")") ;} else {localite.setValue(VALEURS_MULTIPLES);}}else{localite.setValue(obs.getLocalite());}}if(!obs.getIdentifiantLocalite().equals("null") && !obs.getIdentifiantLocalite().equals("000null")) {codeLocalite = idLoc;}if(!obs.getNomSaisi().equals("null") && !obs.getNomSaisi().equals("000null")) {espece.setValue(obs.getNomSaisi()) ;}if(!obs.getNumeroNomenclaturalSaisi().equals("null") && !obs.getNumeroNomenclaturalSaisi().equals("000null")) {numeroNom = obs.getNumeroNomenclaturalSaisi() ;}if(!obs.getNumeroOrdre().equals("null") && !obs.getNumeroOrdre().equals("000null")) {numeroOrdre = obs.getNumeroOrdre() ;}if(doitAfficherLatLon(obs)) {latitude.setValue(Util.formaterNombre(obs.getLatitude())) ;longitude.setValue(Util.formaterNombre(obs.getLongitude())) ;}if(!obs.getAltitude().isEmpty() && !obs.getAltitude().equals("null") && !obs.getAltitude().equals("000null")) {altitude.setValue(Util.formaterNombre(obs.getAltitude())) ;}selecteurAbondance.getStore().load();selecteurAbondance.setValue(obs.getAbondance());selecteurCertitude.getStore().load();selecteurCertitude.setValue(obs.getCertitude());selecteurStadePheno.getStore().load();selecteurStadePheno.setValue(obs.getPhenologie());selecteurReferentielTaxo.getStore().load();if(obs.getReferentielTaxo() != VALEURS_MULTIPLES) {referentielTaxo = obs.getCodeCourtReferentielTaxo();if(referentielTaxo == null || referentielTaxo.isEmpty()) {referentielTaxo = Configuration.getReferentielsDispos().get(0).getCode();}selecteurReferentielTaxo.setValue(referentielTaxo);} else {referentielTaxo = "";selecteurReferentielTaxo.setRawValue(VALEURS_MULTIPLES);}afficherChampsEtendus(obs.getChampsEtendus(), null);}private boolean doitAfficherLatLon(Observation obs) {return !obs.getLatitude().isEmpty() &&!obs.getLatitude().equals("null") &&!obs.getLatitude().equals("000null") &&!Util.estZero(obs.getLatitude()) &&!obs.getLongitude().isEmpty() &&!obs.getLongitude().equals("null") &&!obs.getLongitude().equals("000null") &&!Util.estZero(obs.getLongitude());}private void viderChampsEtendus() {if(listeChampsEtendus != null) {for (Iterator<String> it = listeChampsEtendus.keySet().iterator(); it.hasNext();) {ChampSaisieEtendu champEtendu = listeChampsEtendus.get(it.next());champEtendu.destroy();}if(conteneurChampEtenduGauche != null && conteneurChampEtenduDroite != null) {conteneurChampEtenduGauche.clear();conteneurChampEtenduDroite.clear();panneauPremierColonne.remove(conteneurChampEtenduGauche);panneauSecondeColonne.remove(conteneurChampEtenduDroite);}listeChampsEtendus = null;}}private void afficherChampsEtendus(Map<String, ChampEtendu> champsEtendus, ChampEtendu champsAFocus) {champsEtendus = Util.trierListeChampsEtendus(champsEtendus);viderChampsEtendus();FormLayout flmd = new FormLayout();flmd.setLabelWidth(150);FormLayout flmg = new FormLayout();flmg.setLabelWidth(150);conteneurChampEtenduGauche = new Panel();conteneurChampEtenduGauche.setLayout(flmg);conteneurChampEtenduDroite = new Panel();conteneurChampEtenduDroite.setLayout(flmd);conteneurChampEtenduGauche.setAutoWidth(true);conteneurChampEtenduGauche.setStyle("conteneurChampsEtendus");conteneurChampEtenduGauche.setBodyBorder(false);conteneurChampEtenduDroite.setAutoWidth(true);conteneurChampEtenduDroite.setStyle("conteneurChampsEtendus");conteneurChampEtenduDroite.setBodyBorder(false);// pour corriger le décalage sur le panneau induit par le lien d'affichageconteneurChampEtenduDroite.setPaddings(42, 0, 0, 0);if(champsEtendus != null && champsEtendus.size() > 0) {lienAfficherChampsEtendus.setVisible(true);listeChampsEtendus = new HashMap<String, ChampSaisieEtendu>(champsEtendus.size());HashMap<String, String> correspondancesClesLabel = ListeReferentielChampsEtendusDAO.cacheClesLabels;boolean gauche = true;for (Iterator<String> iterator = champsEtendus.keySet().iterator(); iterator.hasNext();) {String id = iterator.next();ChampEtendu champ = champsEtendus.get(id);String valeur = champ.getValeur();String label = id;// Si le champ possède un clé déjà définie par le catalogue, elle lui sera affectée// sinon on la formate en la "déchamotant" et en ajoutant des espacesif(correspondancesClesLabel.containsKey(id)) {label = correspondancesClesLabel.get(id);} else {label = Util.formaterCleChampsEtenduPourAffichage(label);}ChampSaisieEtendu champTexteEtendu = new ChampSaisieEtendu(label, id, ListeReferentielChampsEtendusDAO.getUrlRequeteValeursChampEtendu(id));if(champ.equals(champsAFocus)) {champTexteEtendu.focus();}champTexteEtendu.setId(id);champTexteEtendu.setValue(valeur);if(gauche) {conteneurChampEtenduGauche.add(champTexteEtendu);} else {conteneurChampEtenduDroite.add(champTexteEtendu);}listeChampsEtendus.put(id, champTexteEtendu);gauche = !gauche;}panneauPremierColonne.add(conteneurChampEtenduGauche);panneauSecondeColonne.add(conteneurChampEtenduDroite);if(!afficherChampsEtendus) {conteneurChampEtenduGauche.setVisible(false);conteneurChampEtenduDroite.setVisible(false);} else {redimensionnerChampsEtendus();}} else {lienAfficherChampsEtendus.setVisible(false);}doLayout();}private void redimensionnerChampsEtendus() {int largeur = conteneurChampEtenduGauche.getWidth();if(largeur <= 0) {Timer t = new Timer() {@Overridepublic void run() {redimensionnerChampsEtendus();}};t.schedule(150);} else {for (Iterator<String> iterator = listeChampsEtendus.keySet().iterator(); iterator.hasNext();) {ChampSaisieEtendu ch = listeChampsEtendus.get(iterator.next());ch.redimensionner(largeur - 15);if(ch.getFieldWidth() < ch.getLabelWidth()) {ch.addClass("panneauModePetiteLargeur");ch.agrandirChamp(largeur - 82);} else {//ch.removeClass("panneauModePetiteLargeur");}}}}private Map<String, ChampEtendu> getValeursChampsEtendus() {Map<String, ChampEtendu> valeursChampsEtendus = new HashMap<String, ChampEtendu>();if(listeChampsEtendus != null) {for (Iterator<String> it = listeChampsEtendus.keySet().iterator(); it.hasNext();) {String cle = it.next();ChampSaisieEtendu champTexteEtendu = listeChampsEtendus.get(cle);String label = champTexteEtendu.getLabel();String valeur = champTexteEtendu.getRawValue();ChampEtendu champEtendu = new ChampEtendu(cle, label, valeur);valeursChampsEtendus.put(cle, champEtendu);}}return valeursChampsEtendus;}public void raz(){raz(Champs.TOUT);}public void raz(Champs champs){switch (champs) {case DATE:date.reset() ;break;case LIEUDIT:lieudit.reset() ;break;case STATION:station.reset() ;break;case MILIEU:milieu.reset() ;break;case COMMENT:comment.reset() ;break;case LOCALITE:localite.reset() ;codeLocalite ="";pays="";latitude.reset();longitude.reset();break;case ESPECE:espece.reset();numeroNom = "" ;numeroOrdre = "";break;case LATITUDE:latitude.reset();afficherIndicationlocalite(null);break;case LONGITUDE:longitude.reset();afficherIndicationlocalite(null);break;case ALTITUDE:altitude.reset();break;case ABONDANCE:selecteurAbondance.setValue("");break;case CERTITUDE:selecteurCertitude.setValue("");break;case REFERENTIELTAXO:selecteurReferentielTaxo.setValue("");break;case PHENOLOGIE:selecteurStadePheno.setValue("");break;case TOUT:localite.reset();date.reset() ;lieudit.reset() ;station.reset() ;milieu.reset() ;comment.reset() ;milieu.reset() ;latitude.reset();longitude.reset();altitude.reset();pays="";codeLocalite ="";espece.reset();selecteurAbondance.clearValue();selecteurCertitude.clearValue();selecteurReferentielTaxo.clearValue();selecteurStadePheno.clearValue();referentielTaxo = "";numeroNom = "" ;numeroOrdre = "";afficherIndicationlocalite(null);break;}}public boolean verifierFormatDate(String date) {String regex = "[1-9][0-9]{3}-[0-9]{2}-[0-9]{2}" ;if(date.matches(regex) && !date.equals("0000-00-00")) {return true ;}else {return false;}}public void setSelectionMultiple(boolean selectionMultiple) {this.selectionMultiple = selectionMultiple;if(!selectionMultiple) {boutonReinitialiser.enable();boutonOK.enable();} else {boutonReinitialiser.disable();boutonOK.disable();}}public boolean getSelectionMultiple() {return selectionMultiple;}private void calculerAfficherDifferences(ListeObservation listeObs) {String codeLocalite = null;String pays = null;String localite = null;String lieuDit = null;String station = null;String milieu = null;String espece = null;String date = null;String notes = null;String lat = null;String lon = null;String alt = null;String abondance = null;String certitude = null;String referentielTaxo = null;String phenologie = null;String ordreObs = "";for(Iterator<String> it = listeObs.keySet().iterator();it.hasNext();) {Observation obsEnCours = listeObs.get(it.next());pays = comparerDifferencesChamps(pays, obsEnCours.getPays());codeLocalite = comparerDifferencesChamps(codeLocalite, obsEnCours.getIdentifiantLocalite());localite = comparerDifferencesChamps(localite, obsEnCours.getLocalite());lieuDit = comparerDifferencesChamps(lieuDit, obsEnCours.getLieudit());station = comparerDifferencesChamps(station, obsEnCours.getStation());milieu = comparerDifferencesChamps(milieu, obsEnCours.getMilieu());espece = comparerDifferencesChamps(espece, obsEnCours.getNomSaisi());date = comparerDifferencesChamps(date, obsEnCours.getDate());notes = comparerDifferencesChamps(notes, obsEnCours.getCommentaire());lat = comparerDifferencesChamps(lat, obsEnCours.getLatitude());lon = comparerDifferencesChamps(lon, obsEnCours.getLongitude());alt = comparerDifferencesChamps(alt, obsEnCours.getAltitude());abondance = comparerDifferencesChamps(abondance, obsEnCours.getAbondance());certitude = comparerDifferencesChamps(certitude, obsEnCours.getCertitude());referentielTaxo = comparerDifferencesChamps(referentielTaxo, obsEnCours.getReferentielTaxo());phenologie = comparerDifferencesChamps(phenologie, obsEnCours.getPhenologie());ordreObs += obsEnCours.getNumeroOrdre()+",";}Observation obs=new Observation(espece,numeroNom,localite,codeLocalite,lieuDit,station,milieu, notes,date);obs.setPays(pays);obs.setNumeroOrdre(ordreObs);obs.setLatitude(lat);obs.setLongitude(lon);obs.setAltitude(alt);obs.setAbondance(abondance);obs.setCertitude(certitude);obs.setReferentielTaxo(referentielTaxo);obs.setPhenologie(phenologie);afficherDetailsObservation(obs);}private String comparerDifferencesChamps(String valeurActuelle, String nouvelleValeur) {String retour = "";if(valeurActuelle == null) {retour = nouvelleValeur;} else {if(valeurActuelle.equals(nouvelleValeur)) {retour = valeurActuelle;} else {retour = VALEURS_MULTIPLES;}}return retour;}private void reinitialiserValeurModifiees() {localiteModifiee = false;lieuDitModifie = false;stationModifiee = false;milieuModifie = false;dateModifiee = false;especeModifiee = false;commModifie = false;latModifiee = false;longModifiee = false;altModifiee = false;abondanceModifiee = false;certitudeModifiee = false;referentielTaxoModifie = false;phenologieModifiee = false;}public void saisieTabindex(){localite.setTabIndex(1);lieudit.setTabIndex(3);station.setTabIndex(4);milieu.setTabIndex(5);coordonnees.setTabIndex(-1);coordonnees.addListener(new TextFieldListenerAdapter() {@Overridepublic void onFocus(Field field) {if(coordPanel.isVisible()) {latitude.focus();} else {Ext.get("lien_carto").focus();}}});latitude.setTabIndex(8);longitude.setTabIndex(9);altitude.setTabIndex(10);comment.setTabIndex(11);date.setTabIndex(12);espece.setTabIndex(13);selecteurCertitude.setTabIndex(14);selecteurAbondance.setTabIndex(15);selecteurStadePheno.setTabIndex(16);boutonOK.setTabIndex(17);boutonReinitialiser.setTabIndex(18);}private void obtenirInformationCoord() {if(coordonneesValides() != null) {observationMediateur.obtenirInformationCoord(coordonneesValides()[0],coordonneesValides()[1]);} else {// Centrage de la carte sur une zone correspondant plus ou moins au référentiel.// En dur car la config est tellement mal foutue que j'ai envie de me pendre.String referentiel = this.getReferentielTaxo();String referentielRacine = referentiel.substring(0, referentiel.indexOf(':'));Double lat = null, lon = null;int zoom = 6;switch(referentielRacine) {case "bdtre" :lat = -21.10;lon = 55.30;zoom = 7;break;case "isfan" :lat = 29.28358;lon = 10.21884;zoom = 5;break;case "apd" :lat = 8.75624;lon = 1.80176;zoom = 5;break;case "bdtxa" :lat = 14.6;lon = -61.08334;zoom = 7;break;case "lbf" :lat = 33.53;lon = 35.30;zoom = 7;break;case "bdtfx" :default:lat = 47.0504;lon = 2.2347;zoom = 6;}if (lat != null && lon != null) {// centrage sur la zoneEntiteGeographiqueObservation infos = new EntiteGeographiqueObservation();infos.setLon("" + lon);infos.setLat("" + lat);infos.setZoom(zoom);observationMediateur.rafraichirFenetreCartoSurPoint(infos);} else {// affichage par défaut au cas où on n'aurait pas trouvé de coordonnées pour centrerobservationMediateur.afficherFenetreCarto();}}}private void obtenirInformationLocalite() {String idLoc = obtenirIdLocalite();observationMediateur.obtenirInformationLocalite(getlocaliteSansIdLoc(), idLoc);}private String obtenirIdLocalite() {String idLoc = "";// Soit un numéro de département, soit un code de pays à deux lettresString[] codeCom = localite.getText().split(" ");if(codeCom.length > 1 && ressembleAUnCodePaysOuDepartement(codeCom[codeCom.length - 1])) {String codeLoc = codeCom[codeCom.length - 1].replace('(', ' ');codeLoc = codeLoc.replace(')', ' ').trim().replace('\\',' ').trim();if(Util.estUnNombre(codeLoc)) {idLoc = codeLoc ;} else {idLoc = codeLoc.toUpperCase();}}return idLoc;}public double[] coordonneesValides() {try {double lat = Double.parseDouble(latitude.getValueAsString().replaceAll(",", "."));double lon = Double.parseDouble(longitude.getValueAsString().replaceAll(",", "."));double[] coord = {lat, lon};return coord;} catch (NumberFormatException ne) {return null;}}private String[] getValeurCoordonnees() {double[] coDouble = coordonneesValides();if(coDouble != null) {String[] coord = {coDouble[0]+"",coDouble[1]+""};return coord;} else {String[] coord = {"","" };return coord;}}public String getlocalite() {String valeurlocalite = "";if(localite.getText() != null) {valeurlocalite = localite.getText();}return valeurlocalite;}public String getlocaliteSansIdLoc() {return Util.supprimerChaineIdLocalite(getlocalite());}private String getValeurChampListeLibre(ComboBox champ) {String valeurChamp = champ.getValue();String valeurChampBrute = champ.getRawValue();// Test idiot qui permet de savoir si l'on utilise la valeur saisie directement ou bien la valeur// selectionnee car lors du setValue sur le keypress, gwtext ne prends pas en compte le dernier// caractèreif(valeurChampBrute.trim().length() == 0) {valeurChamp = "";} else {if(valeurChamp != null && valeurChamp.length() > 0) {if(valeurChamp.equals(valeurChampBrute.substring(0, valeurChampBrute.length() -1))) {valeurChamp = champ.getRawValue();}}}return valeurChamp;}public String getAbondance() {return getValeurChampListeLibre(selecteurAbondance);}public String getCertitude() {return getValeurChampListeLibre(selecteurCertitude);}public String getPhenologie() {return getValeurChampListeLibre(selecteurStadePheno);}public String getReferentielTaxo() {String codeCourt = getValeurChampListeLibre(selecteurReferentielTaxo);return Ontologies.getInfosReferentielNomParCode(codeCourt).getCodeVersionComplet();}public boolean localiteInitialisee() {return localiteModifiee;}public void redimensionnerFormulaire() {afficherFormulaireLatLon.setWidth(panneauIntermediaire.getWidth()+"px");panneauPremierColonne.doLayout();panneauSecondeColonne.doLayout();panneauIntermediaire.doLayout();doLayout();}private void verifierPresenceTaxonSaisi() {affecterCodeLocaliteOuPays();if(!enRequeteChrologie && !codeLocalite.isEmpty() && numeroNom != null && !numeroNom.isEmpty()) {enRequeteChrologie = true;// Pour le moment, si on a un code localité, c'est qu'on est en Francefinal String paysStr = pays.isEmpty() ? "FR" : pays;final String cleCache = numeroNom.trim()+paysStr.trim()+codeLocalite.trim();// Pour éviter de vérifier et d'afficher plus d'une fois l'avertissement de présenceif(!avertissementPresence.containsKey(numeroNom.trim()+paysStr.trim()+codeLocalite.trim())) {// Pour l'instant c'est toujours France mais il serait bon un jour d'avoir une chorologie multi pays.// donc ça ne coute rien de le gérer déjà ici dans l'interfaceImageInformationRepartitionAsynchroneDAO.taxonEstPresentDansZoneGeo(referentielTaxo, numeroNom, paysStr, codeLocalite, new Callback<String, String>() {@Overridepublic void onSuccess(String result) {// En cas d'absence d'infos sur la zone le service retourne "" (chaîne vide)// En cas de non signalement dans la zone, il retourne 0,// En cas de présence, il retourne 1if(result.equals("0")) {// L'absence explicite est le seul cas qui nous interesseString[] stParams = {espece.getText(), codeLocalite, Configuration.getChorologieAvertissementCourriel()};String message = Msg.get("indication-premiere-presence", stParams);Window.alert(message);}avertissementPresence.put(cleCache, result);enRequeteChrologie = false;}@Overridepublic void onFailure(String reason) {enRequeteChrologie = false;}});} else {enRequeteChrologie = false;}}}}