Rev 2726 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package org.tela_botanica.client.vues.image;
import java.util.HashMap;
import org.tela_botanica.client.i18n.Msg;
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.interfaces.VueListable;
import org.tela_botanica.client.modeles.objets.Ontologies;
import org.tela_botanica.client.util.Util;
import org.tela_botanica.client.vues.BarrePaginationVue;
import com.google.gwt.user.client.Timer;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.SortDir;
import com.gwtext.client.data.FieldDef;
import com.gwtext.client.data.IntegerFieldDef;
import com.gwtext.client.data.Record;
import com.gwtext.client.data.RecordDef;
import com.gwtext.client.data.Store;
import com.gwtext.client.data.StringFieldDef;
import com.gwtext.client.dd.DragData;
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.event.ContainerListenerAdapter;
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.GridHeaderListenerAdapter;
import com.gwtext.client.widgets.grid.event.GridRowListener;
import com.gwtext.client.widgets.grid.event.RowSelectionListenerAdapter;
/**
* Liste d'image composée de miniatures et d'information sur l'image, implémente
* l'interface rafraichissable et l'interface vueListable
*
* @author aurelien
*/
public class ListeImageVue extends GridPanel implements Rafraichissable,
VueListable, ListePaginable {
/**
* Le médiateur associé à la vue
*/
private ImageMediateur iMediateur = null;
/**
* Config de colonne
*/
private ColumnConfig numImage;
/**
* Config de colonne
*/
private ColumnConfig transmisImage;
/**
* Config de colonne
*/
private ColumnConfig urlImage;
/**
* Config de colonne
*/
private ColumnConfig lieImage;
/**
* Config de colonne
*/
private ColumnConfig datImage;
/**
* Config de colonne
*/
private ColumnConfig appImage;
/**
* Config de colonne
*/
private ColumnConfig noteImage;
/**
* Config de colonne
*/
private ColumnConfig nomImage;
/**
* Config de colonne
*/
private ColumnConfig obsAssociees;
/**
* Modele de colonnes
*/
private ColumnModel modeleColonnes;
/**
* Booleen d'instanciation
*/
private boolean estInstancie = false;
/**
* Store qui contient les données à afficher
*/
private Store st = null;
/**
* Configuration des colonnes du store
*/
private ColumnConfig cl = null;
/**
* Barre de pagination
*/
private BarrePaginationVue bt = null;
/**
* Taille max des images dans la liste
*/
private int tailleOr = 50 ;
/**
* Garder ou non l'aspet original des images
*/
private boolean garderRatio = true;
private SortDir directionTri;
private String champTri;
private boolean triActif;
/**
* Constructeur sans arguments (privé car ne doit pas être utilisé)
*/
private ListeImageVue() {
super();
}
/**
* Constructeur avec argument
*
* @param im
* le médiateur à associer
*/
public ListeImageVue(ImageMediateur im) {
new ListeImageVue();
this.setId("listeImageGrid");
// on associe le médiateur
this.iMediateur = im;
// on place la barre de pagination
bt = new BarrePaginationVue(this);
bt.setLabelElement(Msg.get("images"));
bt.setTaillePageParDefaut(50);
setBottomToolbar(bt);
directionTri = SortDir.ASC;
// on construit le modèle de colonnes
numImage = new ColumnConfig(Msg.get("numero"), "num_image", 30, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String ImgNum = record.getAsString("num_image");
return "<div class=\"centered-list\">" + ImgNum
+ "</div>";
}
});
transmisImage = new ColumnConfig(" ", "transmis", 10, true, new Renderer() {
@Override
public String render(Object value, CellMetadata cellMetadata,
Record record, int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String nomObs = record.getAsString("obs_associees");
if(nomObs == null) {
return "";
}
boolean transmise = estAssocieeTransmise(nomObs)[1];
if(transmise)
{
return "<img src=\"tela.png\"/></img>" ;
}
else
{
return "" ;
}
}
});
datImage = new ColumnConfig(Msg.get("date"), "dat_image", 80, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String ImgDat = record.getAsString("dat_image");
if (ImgDat == null) {
ImgDat = " ";
}
return "<div class=\"centered-list\">" + ImgDat
+ "</div>";
}
});
lieImage = new ColumnConfig(Msg.get("lieu"), "lie_image", 120, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String ImgLie = record.getAsString("lie_image");
if (ImgLie == null) {
ImgLie = " ";
}
return "<div class=\"centered-list\">" + ImgLie
+ "</div>";
}
});
appImage = new ColumnConfig(Msg.get("appareil"), "app_image", 120, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String ImgApp = record.getAsString("app_image");
if (ImgApp == null) {
ImgApp = " ";
}
return "<div class=\"centered-list\">" + ImgApp
+ "</div>";
}
});
// la colonne url possède une méthode de rendu spéciale
urlImage = new ColumnConfig(Msg.get("image"), "url_image_S", 30, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
// on affiche une div contenant l'image pointée par
// l'url
int[] XY = {record.getAsInteger("taille_x") ,record.getAsInteger("taille_y")} ;
int[] XYresize = {tailleOr,tailleOr} ;
if(garderRatio) {
XYresize = calculerDimensions(XY);
}
String ImgUrl = record.getAsString("url_image_S");
String ImgNum = record.getAsString("num_image");
return "<div class=\"img-list centered-list\"> <img src=\""
+ ImgUrl + "\" title='" + ImgNum + "' width=\""+XYresize[0]+" px\" height=\""+XYresize[1]+" px\"> </div>";
}
});
noteImage = new ColumnConfig(Msg.get("note"), "note_image", 80, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String htmlImage = "";
int noteImg = record.getAsInteger("note_image");
if (noteImg >= 0) {
htmlImage += "<div class=\"img-note centered-list\">";
for (int i = 0; i <= noteImg; i++) {
htmlImage += "<img src=\"note-on.gif\">";
}
htmlImage += "</div>";
}
return htmlImage;
}
});
nomImage = new ColumnConfig(Msg.get("nom-original"), "nom_original", 120, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String imgNomOr = record.getAsString("nom_original");
if (imgNomOr == null) {
imgNomOr = " ";
}
return "<div class=\"centered-list\">" + imgNomOr
+ "</div>";
}
});
obsAssociees = new ColumnConfig(Msg.get("nom-associe"), "obs_associees", 80, true,
new Renderer() {
@Override
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
cellMetadata.setCssClass("centered-list");
String nomObs = record.getAsString("obs_associees");
if(nomObs == null) {
return "";
}
String nomFormate = getNomsObservationsFormatees(nomObs);
return "<div class=\"centered-list\">" + nomFormate
+ "</div>";
}
});
// on associe le modèle de colonnes
ColumnConfig[] cm = { numImage, transmisImage, urlImage, obsAssociees, datImage, lieImage, appImage,
noteImage,nomImage} ;
modeleColonnes = new ColumnModel(cm);
this.setColumnModel(modeleColonnes);
this.setAutoScroll(true);
this.setAutoWidth(true);
this.setEnableColumnResize(true);
RecordDef rd = new RecordDef(ImageMediateur.getDefinitionsChampsGrilleImages());
st = new Store(rd);
// on associe le store
this.setStore(st);
this.getView().setAutoFill(true);
// on crée un masque de chargement qui s'affichera lors des mises à jour
this.setLoadMask("chargement");
//Enable drag and drop
this.setEnableDragDrop(true);
//You need to set the same group for both grids
this.setDdGroup("DragGroupName");
// on ajoute les listeners
ajouterListeners();
}
/**
* Ajoute les listeners pour la gestion des évènements
*/
private void ajouterListeners() {
this.addGridHeaderListener(new GridHeaderListenerAdapter() {
@Override
public void onHeaderClick(GridPanel grid, int colIndex, EventObject e) {
triActif = true;
Timer t = new Timer() {
@Override
public void run() {
enregistrerEtatTri();
// Trier ne change pas le nombre de page, on peut donc se passer d'un appel
// au comptage (ce serait mieux si ces deux appels étaient combinés)
iMediateur.obtenirPhotoGalerieSansCalculerPages(ListeImageVue.this);
}
};
// Le changement de tri n'est pas immédiat et si on recharge le liste tout de suite
// on a l'ancien tri et pas le nouveau (200 millisecondes suffisent et ne se voient pas)
// #mondeDeMerde
t.schedule(200);
}
});
this.addListener(new ContainerListenerAdapter() {
@Override
public void onHide(Component component) {
}
// lors du premier rendu on demande les données qui sont déjà
// contenues dans la galerie qui est le premier élément affiché
@Override
public void onRender(Component component) {
if (!isEstInstancie()) {
setEstInstancie(true);
setDragDropText(Msg.get("glissez-deposer-images-obs")) ;
getIMediateur().synchroniserSelection("galerie");
}
}
@Override
public void onShow(Component component) {
}
});
this.addGridRowListener(new GridRowListener() {
// gestion du clic sur une ligne
@Override
public void onRowClick(GridPanel grid, int rowIndex, EventObject e) {
// on notifie le médiateur et on lui passe le numéro de ligne
getIMediateur().clicListeImage(rowIndex);
}
// gestion du clic droit
@Override
public void onRowContextMenu(GridPanel grid, int rowIndex,
EventObject e) {
// on stoppe l'évenement pour empecher le navigateur d'afficher
// son propre menu
e.stopEvent();
// on notifie le médiateur en lui passant l'évenement
getIMediateur().montrerContextMenu(e);
}
// gestion du double clic
@Override
public void onRowDblClick(GridPanel grid, int rowIndex,
EventObject e) {
// on notifie le médiateur en lui passant le numéro de ligne
getIMediateur().doubleClicListeImage(rowIndex);
}
});
this.getSelectionModel().addListener(new RowSelectionListenerAdapter() {
// gestion de la sélection
@Override
public void onSelectionChange(RowSelectionModel sm) {
// si on a rien de sélectionné
if (sm.getCount() <= 0) {
// on notifie le médiateur (qui désactive notamment l'accès
// à certaines infos)
getIMediateur().aucuneSelection();
} else {
// sinon on notifie le médiateur
getIMediateur().selection();
// et on lui demande de synchroniser la selection avec les
// autres vues
getIMediateur().synchroniserSelection("liste");
}
}
});
//Enable drag and drop
this.setEnableDragDrop(true);
//Same name in destination
this.setDdGroup("DragGroupName");
DropTargetConfig dtc = new DropTargetConfig();
dtc.setdDdGroup("DragGroupName");
//Now this is the important part, you need a drop target
@SuppressWarnings("unused")
DropTarget tg = new DropTarget(this, dtc)
{
@Override
public boolean notifyDrop(DragSource source, EventObject e, DragData data){
if(data instanceof GridDragData)
{
GridDragData gdd = (GridDragData)data ;
if(gdd.getGrid().getId().equals("listeImageGrid"))
{
return false ;
}
else
{
return iMediateur.lierObsDD(source, e, data, getId()) ;
}
}
else
{
return false ;
}
}
@Override
public String notifyOver(DragSource source, EventObject e, DragData data){
return "x-dd-drop-ok";
}
};
}
/**
* Méthode héritée de l'interface VueListable Sélectionne les images dans la
* galerie suivant les identifiants donnés en paramètres
*/
@Override
public String[] getIdSelectionnees() {
Record[] selection = this.getSelectionModel().getSelections();
int taille = selection.length;
String id_selection[] = new String[taille];
for (int i = 0; i < selection.length; i++) {
id_selection[i] = selection[i].getAsString("num_image");
}
return id_selection;
}
/**
* Accesseur pour la config de colonnes
*
* @return la config de colonnes
*/
public ColumnConfig getCl() {
return cl;
}
/**
* Accesseur pour le médiateur
*
* @return le médiateur associé
*/
public ImageMediateur getIMediateur() {
return iMediateur;
}
/**
* Accesseur pour le modèle de colonnes
*
* @return le modèle de colonnes
*/
public ColumnModel getModeleColonnes() {
return modeleColonnes;
}
/**
* Accesseur pour le store
*
* @return le store contenant les données
*/
public Store getSt() {
return st;
}
/**
* Accesseur pour le booleen d'instanciation
*
* @return le booleen d'instanciation
*/
public boolean isEstInstancie() {
return estInstancie;
}
/**
* Méthode héritée de l'interface rafraichissable
*
* @param nouvelleDonnees
* les nouvelles données
* @param repandreRafraichissement
* le booleen de notification du rafraichissement
*/
@Override
public void rafraichir(Object nouvelleDonnees,
boolean repandreRafraichissement) {
// si on reçoit un store
if (nouvelleDonnees instanceof Store) {
// on affecte celui-ci comme gestionnaire de données
st = (Store) nouvelleDonnees;
st.sort(champTri, directionTri);
st.load();
// et on reconfigure et rafraichit la vue
this.reconfigure(st, this.getColumnModel());
}
// si on doit répandre l'évenement
if (repandreRafraichissement) {
// on notifie le médiateur avec une copie des données
getIMediateur().synchroniserDonneesZoomListeGalerie(
nouvelleDonnees, this);
}
}
/**
* Sélectionne des enregistrements donné
*
* @param sel
* un tableau d'enregistrement à selectionner
*/
public void selectionnerEnregistrements(Record[] sel) {
if (isEstInstancie()) {
getSelectionModel().clearSelections();
getSelectionModel().selectRecords(sel);
}
}
/**
* Accesseur pour la toolbar de pagination
*
* @return la toolbar de pagination
*/
public BarrePaginationVue getToolBarVue() {
return bt;
}
/**
* Setteur pour le booleen d'instanciation
*
* @param estInstancie
* la nouvelle valeur du booleen
*/
public void setEstInstancie(boolean estInstancie) {
this.estInstancie = estInstancie;
}
public void mettreAjourInfos(String commentaires, String date, String note) {
for (int i = 0; i < getSelectionModel().getCount(); i++) {
getSelectionModel().getSelections()[i].set("note_image", note);
getSelectionModel().getSelections()[i].set("dat_image", date);
}
}
@Override
public void changerNumeroPage(int pageCourante) {
iMediateur.changerNumeroPage(pageCourante) ;
}
@Override
public void changerTaillePage(int nouvelleTaillePage) {
iMediateur.changerTaillePage(nouvelleTaillePage) ;
}
public int[] calculerDimensions(int[] tailleXY) {
float[] tailleXYf = {new Float(tailleXY[0]),new Float(tailleXY[1])} ;
float tailleOr = this.tailleOr ;
float maxTaille = Math.max(tailleXYf[1],tailleXYf[0]) ;
float[] XYresize = new float[2];
if(maxTaille == tailleXY[0]) {
float rapport = tailleXYf[1]/tailleXYf[0] ;
XYresize[0] = tailleOr ;
XYresize[1] = tailleOr*rapport ;
}else {
float rapport = tailleXYf[0]/tailleXYf[1] ;
XYresize[1] = tailleOr ;
XYresize[0] = tailleOr*rapport ;
}
int[] res = {Math.round(XYresize[0]),Math.round(XYresize[1])} ;
return res;
}
private String getNomsObservationsFormatees(String nomObs) {
String htmlInfobulle = "";
String[][] obs = getObservationsAssociees(nomObs);
for(int i = 0; i < obs.length; i++) {
if(obs[i].length == 3 && obs[i][1] != null && !obs[i][1].equals("")) {
htmlInfobulle += ", "+obs[i][1];
}
}
htmlInfobulle = htmlInfobulle.replaceFirst(", ", "");
return htmlInfobulle;
}
private String[][] getObservationsAssociees(String nomObs) {
if(nomObs.trim().equals("")) {
return new String[0][0];
}
String[] obsTab = nomObs.split(";;");
String[][] obsAnalysees = new String[obsTab.length][3];
for(int i = 0; i < obsTab.length; i++) {
obsAnalysees[i] = obsTab[i].split("#");
}
return obsAnalysees;
}
private boolean[] estAssocieeTransmise(String nomObs) {
String[][] obs = getObservationsAssociees(nomObs);
boolean[] associeesTranmises = {false, false};
if(obs.length > 0) {
associeesTranmises[0] = true;
}
for(int i = 0; i < obs.length; i++) {
if(obs[i].length == 3 && obs[i][2] != null && obs[i][2].equals("1")) {
associeesTranmises[1] = true;
}
}
return associeesTranmises;
}
private void enregistrerEtatTri() {
if(triActif) {
this.directionTri = st.getSortState().getDirection();
this.champTri = st.getSortState().getField();
}
}
public String renvoyerTri() {
String tri = "ordre";
if(triActif) {
HashMap<String, String> corr = Ontologies.getCorrespondanceGrilleImageChampsTri();
if(corr.containsKey(champTri)) {
tri = corr.get(champTri);
}
}
return tri;
}
public String renvoyerDirectionTri() {
String triDir = "ASC";
try {
triDir = (triActif) ? directionTri.getDirection() : "ASC";
} catch (Exception e) {
triDir = "ASC";
}
return triDir;
}
}