Rev 2568 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package org.tela_botanica.client.vues.image;import java.util.Iterator;import org.tela_botanica.client.image.ImageMediateur;import org.tela_botanica.client.interfaces.ListePaginable;import org.tela_botanica.client.interfaces.Rafraichissable;import org.tela_botanica.client.modeles.objets.ListeObservation;import org.tela_botanica.client.modeles.objets.Observation;import org.tela_botanica.client.util.Util;import org.tela_botanica.client.vues.MiniBarrePaginationVue;import com.google.gwt.user.client.Window;import com.gwtext.client.data.Record;import com.gwtext.client.data.SimpleStore;import com.gwtext.client.data.Store;import com.gwtext.client.dd.DragSource;import com.gwtext.client.dd.DropTarget;import com.gwtext.client.dd.DropTargetConfig;import com.gwtext.client.widgets.Component;import com.gwtext.client.widgets.Container;import com.gwtext.client.widgets.Toolbar;import com.gwtext.client.widgets.event.ContainerListenerAdapter;import com.gwtext.client.widgets.form.ComboBox;import com.gwtext.client.widgets.form.event.ComboBoxListenerAdapter;import com.gwtext.client.widgets.grid.CellMetadata;import com.gwtext.client.widgets.grid.ColumnConfig;import com.gwtext.client.widgets.grid.ColumnModel;import com.gwtext.client.widgets.grid.GridDragData;import com.gwtext.client.widgets.grid.GridPanel;import com.gwtext.client.widgets.grid.Renderer;import com.gwtext.client.widgets.grid.RowSelectionModel;import com.gwtext.client.widgets.grid.event.GridListenerAdapter;import com.gwtext.client.widgets.grid.event.RowSelectionListenerAdapter;import com.gwtext.client.widgets.menu.BaseItem;import com.gwtext.client.widgets.menu.Item;import com.gwtext.client.widgets.menu.Menu;import com.gwtext.client.widgets.menu.event.MenuListenerAdapter;import com.gwtext.client.core.EventObject;import com.gwtext.client.core.Ext;import com.gwtext.client.core.ExtElement;import com.gwtext.client.dd.DragData;/*** liste d'observation pour l'association d'images aux observations* @author aurelien**/public class MiniListeObservationVue extends GridPanel implements Rafraichissable, ListePaginable {/*** Le médiateur associé à la vue*/private ImageMediateur iMediateur = null ;/*** Booléen d'instanciation*/private boolean estInstancie = false ;/*** Le modèle de colonnes*/private ColumnModel colModel = null ;private SimpleStore store = null ;private MiniBarrePaginationVue pgBar = new MiniBarrePaginationVue(this) ;private Toolbar bt = new Toolbar() ;/*** Combobox permettant de selectionner le mode* modification ou bien création*/private ComboBox selecteurMode = new ComboBox();Store storeMode = null ;private boolean liaison;int pageEnCours = 0;int nbElements = 0;int taillePage = 50;private String modeleLieu = "IDLOCLOCALITE, LIEUDIT, STATION";/*** Nombre de pages totales*/private int pageMax = 1 ;/*** Constructeur avec arguments* @param im le médiateur à associer à la vue*/public MiniListeObservationVue(ImageMediateur im){iMediateur = im ;this.setId("x-view-mini-obs") ;// on construit le modèle de colonnes// Le store suivant est ensuite remplacé par le store contenant les données obtenus depuis le serveur (cf rafraichir)Renderer colRend = new Renderer() {@Overridepublic String render(Object value, CellMetadata cellMetadata,Record record, int rowIndex, int colNum, Store store) {if(value == null || value.equals("null") || value.equals("000null") || value.equals("0000-00-00 00:00:00")) {return "" ;}return value.toString() ;}} ;Renderer dateRend = new Renderer() {@Overridepublic String render(Object value, CellMetadata cellMetadata,Record record, int rowIndex, int colNum, Store store) {if(value == null || value.equals("null") || value.equals("000null") || value.equals("0000-00-00 00:00:00")) {return "" ;}else{String dateEntiere = value.toString() ;String[] dateEtHeure = dateEntiere.split(" ", 2);if(verifierFormatDate(dateEtHeure[0])) {String[] dateFormateeTab = dateEtHeure[0].split("-",3);return dateFormateeTab[2]+"/"+dateFormateeTab[1]+"/"+dateFormateeTab[0] ;}}return value.toString() ;}} ;// on crée un store simple contenant un petit set de données et deux colonnesstore = new SimpleStore(new String[]{"transmis","plante","date","lieu","ordre_obs","id_obs"}, getObs());ColumnConfig[] columns = {new ColumnConfig("", "transmis", 30, true, new Renderer() {@Overridepublic String render(Object value, CellMetadata cellMetadata,Record record, int rowIndex, int colNum, Store store) {if(value.equals("1")){return "<img src=\"tela.png\"/></img>" ;}else{return "" ;}}}),new ColumnConfig("Taxon", "plante", 145, true, colRend),new ColumnConfig("Date", "date", 68, true, dateRend),new ColumnConfig("Lieu", "lieu", 145, true, colRend),new ColumnConfig("Numero", "ordre_obs", 50, true, colRend), } ;ColumnModel columnModel = new ColumnModel(columns);colModel = columnModel ;setTitle("Observations");// on associe le modèle de colonnessetColumnModel(columnModel);setAutoScroll(true) ;setHeight("100%") ;setAutoWidth(true) ;// on autorise le drag 'n drop pour un certain groupethis.setEnableDragDrop(true);this.setDdGroup("DragGroupName");store.load();setStore(store) ;setBottomToolbar(pgBar) ;Object[][] mode = {{"toutes les observations",false} , {"observation liée", true} };storeMode = new SimpleStore(new String[] { "nom_mode", "mode" },mode);storeMode.load();selecteurMode.setStore(storeMode);selecteurMode.setDisplayField("nom_mode") ;selecteurMode.setLabel("mode ") ;selecteurMode.setForceSelection(true) ;selecteurMode.setValue("toutes les observations") ;selecteurMode.setEditable(false) ;selecteurMode.setCls("x-selec-consult") ;bt = new Toolbar() ;bt.addField(selecteurMode) ;//this.setAutoExpandColumn("plante");setTopToolbar(bt) ;selecteurMode.addListener(new ComboBoxListenerAdapter() {@Overridepublic void onSelect(ComboBox comboBox, Record record, int index) {// et on met la valeur à jour dans la comboboxcomboBox.setValue(record.getAsString("nom_mode"));setModification(record.getAsString("mode")) ;}});setAutoScroll(true) ;// on configure le drag 'n dropconfigDragAndDrop() ;this.addGridListener(new GridListenerAdapter() {@Overridepublic void onContextMenu(EventObject e) {// si pas de selection, on selection au moins la ligne sur laquelle on a fait le clicif(getSelectionModel().getSelections().length <= 0) {int index = getView().findRowIndex(e);Record rddrop = getStore().getRecordAt(index) ;getSelectionModel().selectRecords(rddrop);}e.stopEvent() ;MenuLiaisonVue mlv = new MenuLiaisonVue(iMediateur,liaison) ;mlv.showAt(e.getXY()) ;}}) ;// TODO: voir s'il existe un autre moyen de désactiver la multiselection// ça semble bien compliqué de faire comme çagetSelectionModel().addListener(new RowSelectionListenerAdapter() {@Overridepublic boolean doBeforeRowSelect(RowSelectionModel sm, int rowIndex,boolean keepExisting, Record record) {sm.clearSelections();return true;}});obtenirNombreMiniListeObservations();}/*** Configure le drag 'n drop pour la liste*/private void configDragAndDrop(){// on choisit le texte qui sera affiché lors d'un drag 'n dropsetDragDropText("Faites glisser l'observation sur une image ou une selection d'images pour les lier") ;//On active le drag 'n dropthis.setEnableDragDrop(true);// on fabrique la nouvelle configuration// les éléments sur lesquels on fait du drag 'n drop doivent tous avoir le même ddGroupthis.setDdGroup("DragGroupName");DropTargetConfig dtc = new DropTargetConfig();dtc.setdDdGroup("DragGroupName");//La drop target permet de gérer l'évenement onDrop sur l'élement courant@SuppressWarnings("unused")DropTarget tg = new DropTarget(this, dtc){@Overridepublic boolean notifyDrop(DragSource source, EventObject e, DragData data){// si on reçoit des données provenant d'une grilleif(data instanceof GridDragData){// on la convertitGridDragData gdd = (GridDragData)data ;// et on vérifie que les données ne viennent pas de l'élément courantif(gdd.getGrid().getId().equals("x-view-mini-obs")){return false ;}else{// on appelle le médiateurreturn iMediateur.lierImagesDD(source, e, data) ;}}return false ;}@Overridepublic String notifyOver(DragSource source, EventObject e, DragData data){return "x-dd-drop-ok";}};}/*** Méthode héritée de l'interface rafraichissable*/@Overridepublic void rafraichir(Object nouvelleDonnees,boolean repandreRaffraichissement) {if(nouvelleDonnees instanceof ListeObservation){if(this.getView() != null){ListeObservation data = (ListeObservation)nouvelleDonnees ;String[][] listeObs = new String[data.size()][6] ;int i = 0 ;for (Iterator it = data.keySet().iterator(); it.hasNext();){Observation obs=data.get(it.next());listeObs[i][0] = obs.getTransmis();listeObs[i][1] = obs.getNomSaisi();listeObs[i][2] = obs.getDate() ;listeObs[i][3] = Util.formaterLieu(obs, modeleLieu);listeObs[i][4] = obs.getNumeroOrdre();listeObs[i][5] = obs.getId();i++ ;}store = new SimpleStore(new String[]{"transmis","plante","date","lieu","ordre_obs","id_obs"}, listeObs);store.load();this.reconfigure(store, colModel) ;}else{addListener(new ContainerListenerAdapter() {@Overridepublic void onShow(Component c){obtenirNombreMiniListeObservations() ;}@Overridepublic void onAfterLayout(Container c){obtenirNombreMiniListeObservations() ;}}) ;}}// Si on reçoit un tableau d'entiers// c'est un tableau d'un seul entier qui est le nombre d'observation correspondant aux critèresif(nouvelleDonnees instanceof int[]){int[] pages = (int[])nouvelleDonnees ;// on calcule le nombre de pages nécessaires et on les met à jour dans le modèlepageMax = calculerNbPages(pages[0]) ;nbElements = pages[0];// et on notifie de le mediateur du changement des valeurschangerPageMaxEtCourante(pageMax,pageEnCours,taillePage,nbElements) ;masquerChargement();obtenirMiniListeObservations();}redimensionner();deMasquerChargement() ;}private void obtenirMiniListeObservations(){iMediateur.obtenirMiniListeObservations(this, taillePage, pageEnCours) ;}private void obtenirNombreMiniListeObservations(){iMediateur.obtenirNombreMiniListeObservations(this) ;}/*** Renvoie le faux set de données pour le store* @return un tableau à deux colonnes int - String*/private Object[][] getObs() {return new Object[][]{} ;}@Overridepublic Store getStore(){return store ;}public MiniBarrePaginationVue getBarrePagination(){return pgBar ;}private void setModification(String mode){if(mode.equals("true")) {liaison = true ;selecteurMode.removeClass("x-selec-consult") ;selecteurMode.setCls("x-selec-liaison") ;getBarrePagination().disable();doLayout();}else{liaison = false ;selecteurMode.removeClass("x-selec-liaison") ;selecteurMode.setCls("x-selec-consult") ;getBarrePagination().enable();doLayout();}store.removeAll() ;iMediateur.changerModeLiaison(liaison) ;}public boolean getMode() {return liaison ;}/*** Recherche l'élement actuellement affiché et affiche son message de chargement*/public void masquerChargement(){ExtElement masked = Ext.get(getId()) ;if (masked!=null) {masked.mask("Chargement") ;}}/*** Recherche l'élement actuellement affiché et affiche son message de chargement*/public void deMasquerChargement(){ExtElement masked = Ext.get(getId()) ;if (masked!=null) {masked.unmask() ;}}public String getIdSelectionnees() {Record[] sels = getSelectionModel().getSelections() ;String id = "";for(int i = 0; i < sels.length; i++) {id += ","+sels[i].getAsString("id_obs") ;}id = id.replaceFirst(",", "");return id ;}public void supprimerLiaison() {Record[] rdObs = getSelectionModel().getSelections() ;for(int i = 0 ; i < rdObs.length ; i++) {getStore().remove(rdObs[i]) ;this.getView().refresh() ;}}public void redimensionner() {if(getView() != null) {int taille = 400;if(Window.getClientHeight() > 800 ) {taille = Window.getClientHeight() - 350;}setHeight(taille);getView().setForceFit(true);doLayout();}else {}}/*** Montre le menu de liaison aux coordonnées indiquées* @param e*/public void montrerContextMenuLiaison(EventObject e) {final Menu liObs = new Menu();final Item lierObservation = new Item("Lier aux images selectionnées");liObs.addItem(lierObservation);liObs.addListener(new MenuListenerAdapter() {// gestion du clic sur un item@Overridepublic void onItemClick(BaseItem item, EventObject ev) {// si c'est la suppressionif (item.equals(lierObservation)) {// on notifie le médiateur}// enfin, on cache le menuliObs.hide();}});liObs.showAt(e.getXY());}@Overridepublic void changerNumeroPage(int pageCourante) {pageEnCours = pageCourante ;masquerChargement();// On lance le chargerment des observationsiMediateur.obtenirNombreMiniListeObservations(this);}/*** Appelle le modèle pour qu'il change la taille de page utilisée* @param nouvelleTaillePage la nouvelle taille de page*/@Overridepublic void changerTaillePage(int nouvelleTaillePage){taillePage = nouvelleTaillePage ;pageEnCours = calculerPageCourante(nbElements) ;masquerChargement();// On lance le chargerment des observationsiMediateur.obtenirNombreMiniListeObservations(this);// et on met à jour la taille de page dans les barres d'outilspgBar.selectionnerTaillePage(nouvelleTaillePage);}/*** Met à jour les barre d'outils avec des nouvelles valeurs* @param pageMax le nombre de pages* @param pageEncours la page en cours* @param taillePage la taille de page* @param nbElement le nombre d'élements par page*/public void changerPageMaxEtCourante(int pageMax, int pageEncours, int taillePage, int nbElement){int[] pages = {pageMax,pageEncours, taillePage, nbElement} ;pgBar.rafraichir(pages, false) ;}/*** Calcule le nombre de pages nécessaires pour afficher un nombre d'élements donnés en fonction de la taille de page* en cours* @param nbElements le nombre d'élements total* @return le nombre de pages*/public int calculerNbPages(int nbElements){// A cause de la betise de java pour les conversion implicite on fait quelques conversions manuellement// pour eviter qu'il arrondisse mal la division// nombre de pages = (nombre d'element / taille de la page) arrondie à l'entier superieurdouble nPage = (1.0*nbElements)/(1.0*taillePage) ;double nPageRound = Math.ceil(nPage) ;Double nPageInt = new Double(nPageRound) ;// on convertit en entierreturn nPageInt.intValue() ;}/*** Recalcule la page en cours lors du changement du nombre d'élements* @param nbElements le nombre d'élements total* @return la nouvelle page encours*/public int calculerPageCourante(int nbElements){// on calcule le nombre de pageint nouvelNbPages = calculerNbPages(nbElements) ;// la nouvelle page en coursdouble nPageCourante = (1.0*pageEnCours)/(1.0*pageMax) * (1.0*nouvelNbPages) ;// on arrondit au supérieurdouble nPageRound = Math.ceil(nPageCourante) ;Double nPageInt = new Double(nPageRound) ;// on convertit en entierreturn Math.abs(nPageInt.intValue()) ;}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;}}}