Subversion Repositories eFlore/Applications.cel

Rev

Rev 1758 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

package org.tela_botanica.client.vues.image;

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.vues.BarrePaginationVue;

import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.HTML;
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.XTemplate;
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.util.Format;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.Container;
import com.gwtext.client.widgets.DataView;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.event.ContainerListenerAdapter;
import com.gwtext.client.widgets.event.DataViewListenerAdapter;
import com.gwtext.client.widgets.event.PanelListenerAdapter;
import com.gwtext.client.widgets.grid.GridDragData;

/**
 * Galerie d'images miniatures Avec barre de pagination
 * 
 * @author aurelien
 */
public class GalerieImageVue extends Panel implements Rafraichissable,
                VueListable, ListePaginable {

        /**
         * instance du médiateur
         */
        private ImageMediateur iMediateur = null;
        /**
         * Dataview, littéralement "vue de données" qui permet de définir la manière
         * d'afficher les données
         */
        private DataView dView = null;
        /**
         * Dataview, littéralement "vue de données" qui permet de définir la manière
         * d'afficher les données
         */
        private Store st = null;
        /**
         * Barre de pagination gérant l'affichage d'un nombre donné d'élements par
         * page et la navigation entre eux
         */
        private BarrePaginationVue pt = null;
        /**
         * Booleen indiquant si la galerie est instanciée ou pas
         */
        private boolean estInstancie = false;
        
        private boolean garderRatio = true;
        
        private int tailleOr = 100 ;
        
        boolean lienUploadInitialise = false ;
        
        HTML videPanel = null ;


        /**
         * Constructeur sans argument, privé car ne doit pas être utilisé
         */
        @SuppressWarnings("unused")
        private GalerieImageVue() {
                super();
        }

        /**
         * Constructeur avec argument
         * 
         * @param im
         *            le médiateur avec lequel la vue va communiquer
         */
        public GalerieImageVue(ImageMediateur im) {
                super("Galerie");
                iMediateur = im;
                
                // on ajoute des listeners au composant tout entier
                this.addListener(new ContainerListenerAdapter() {

                        // pour gagner du temps on n'instancie la vue en elle même que lors
                        // du premier affichage (lazy rendering)
                        @Override
                        public void onShow(Component component) {

                                if (!estInstancie) {
                                        initialiser();
                                }
                                
                        }
                });
                
                AjouterListenersLiens();

                // et on ajoute la tool bar
                pt = new BarrePaginationVue(this);
                pt.setLabelElement("Images");
                pt.setTaillePageParDefaut(50);
                this.setBottomToolbar(pt);

        }

        /**
         * Ajoute tous les listeners nécessaires à l'intercation utilisateur avec la
         * vue de données
         */
        public void ajouterListenersDataView() {

                // ajout de listeners pour la gestion de la selection
                // dans la galerie
                
                dView.addListener(new DataViewListenerAdapter() {

                        // gestion du clic sur une image

                        @Override
                        public void onClick(DataView source, int index, Element node,
                                        EventObject e) {
                                
                                // on en notifie le médiateur
                                getIMediateur().clicGalerieImage(index, node, e);

                        }

                        // gestion du clic droit

                        @Override
                        public void onContextMenu(DataView source, int index, Element node,
                                        EventObject e) {

                                // on stoppe l'évenement
                                e.stopEvent();
                                // et on notifie le médiateur
                                getIMediateur().montrerContextMenu(e);

                        }

                        // gestion du double clic

                        @Override
                        public void onDblClick(DataView source, int index, Element node,
                                        EventObject e) {

                                // on notife le mediateur
                                getIMediateur().clicGalerieImage(index, node, e);

                        }

                        // gestion des actions en fonction de la selection

                        @Override
                        public void onSelectionChange(DataView view, Element[] selections) {

                                // s'il n'y a aucun élement sélectionné
                                if (selections.length <= 0) {
                                        // on en notifie le médiateur
                                        getIMediateur().aucuneSelection();
                                } else {
                                        // sinon on notifie le médiateur
                                        getIMediateur().selection();
                                        // et on lui demande de synchroniser la séléction avec les
                                        // autres vues
                                        getIMediateur().synchroniserSelection("galerie");
                                }
                        }
                });
        }

        /**
         * Accesseur pour la dataview
         * 
         * @return la dataview
         */
        public DataView getDView() {
                return dView;
        }

        /**
         * Renvoie les ids des images sélectionnées
         * 
         * @return un tableau de String contenant les identifiants des images
         *         sélectionnées
         */
        @Override
        public String[] getIdSelectionnees() {
                Record[] selection = getDView().getSelectedRecords();
                int taille = selection.length;
                String id_selection[] = new String[taille];

                for (int i = 0; i < selection.length; i++) {

                        id_selection[i] = selection[i].getAsString("id_image");
                }

                return id_selection;
        }

        /**
         * Accesseur pour le médiateur
         * 
         * @return le médiateur associé à la vue
         */
        public ImageMediateur getIMediateur() {
                return iMediateur;
        }

        /**
         * Accesseur pour le store
         * 
         * @return le store associé à la vue
         */
        public Store getSt() {
                return st;
        }

        /**
         * Accesseur pour la toolbar
         * 
         * @return la toolbar associée à la vue
         */
        public BarrePaginationVue getToolBarVue() {
                return pt;
        }

        /**
         * Fonction d'initialisation du contenu (appelée lors du premier affichage
         * de la liste)
         */
        public void initialiser() {

                // Preparation de la dataview et du template
                // le template va créer une div contenant une image
                // pour chacune des photos
                final XTemplate template = new XTemplate(
                                new String[] {
                                                "<tpl for='.'>",
                                                "<div class='thumb-wrap' id='{num_image}'>",
                                                "<div class='thumb dview-list'>{indication_transmission}{indication_liaison}<img class='miniature_galerie' src='{url_image_M}' width='{taille_x_s} px' height='{taille_y_s} px' title='{infobulle}' /></div>",
                                                "<span class='info_image'>{nom_obs_associees_formatees}</span></div>", "</tpl>",
                                                "<div class='x-clear'></div>" });
                // pour des raisons de performances on compile le template en une
                // fonction
                template.compile();

                // la dataview affichera les images en accord avec le template
                // cree precedemment
                dView = new DataView("div.thumb-wrap") {

                        @Override
                        public void prepareData(Data data) {
                                data.setProperty("shortName", Format.ellipsis(data
                                                .getProperty("nom_original"), 15));
                                
                                int[] XY = {data.getPropertyAsInt("taille_x") ,data.getPropertyAsInt("taille_y")} ;
                                int[] XYresize ;
                                
                                if(garderRatio) {
                                        XYresize = calculerDimensions(XY);
                                }
                                else {
                                        XYresize = new int[2] ;
                                        XYresize[0] = XYresize[1] = tailleOr ;
                                        
                                }
                                
                                data.setProperty("taille_x_s", XYresize[0]);
                                data.setProperty("taille_y_s", XYresize[1]);    
                                
                                String nomObs = data.getProperty("obs_associees");

                                String htmltransmis = "";
                                String htmllie = "";
                                
                                boolean associee = estAssocieeTransmise(nomObs)[0];
                                boolean transmise = estAssocieeTransmise(nomObs)[1];
                                
                                String nomFormate = getNomsObservationsFormatees(nomObs);
                                
                                if(associee) {
                                        htmllie = "<img class='picto_haut_droite' src='chain.png' />";
                                }
                                
                                if(transmise) {
                                        htmltransmis = "<img class='picto_haut_gauche' src='tela.png' />";
                                }

                                data.setProperty("infobulle", nomFormate);
                                data.setProperty("indication_transmission", htmltransmis);
                                data.setProperty("indication_liaison", htmllie);
                                data.setProperty("nom_obs_associees_formatees", nomFormate);
                                                                
                        }
                };
                dView.setTpl(template);

                // parametre d'affichage de la dataview
                this.setAutoScroll(true);
                dView.setAutoHeight(true);
                dView.setMultiSelect(true);
                dView.setOverCls("x-view-over");
                dView.setEmptyText("");

                // creation du store
                FieldDef defNumImage = new IntegerFieldDef("num_image");
                FieldDef defNomImage = new StringFieldDef("nom_original");
                FieldDef defDatImage = new StringFieldDef("dat_image");
                FieldDef defLieImage = new StringFieldDef("lie_image");
                FieldDef defAppImage = new StringFieldDef("app_image");
                FieldDef defUrlImageS = new StringFieldDef("url_image_S");
                FieldDef defUrlImageM = new StringFieldDef("url_image_M");
                FieldDef defUrlImage = new StringFieldDef("url_image");
                FieldDef defTailleX = new IntegerFieldDef("taille_x");
                FieldDef defTailleY = new IntegerFieldDef("taille_y");
                FieldDef defObsAssociees = new StringFieldDef("obs_associees");
                FieldDef[] defTab = { defNumImage, defNomImage, defDatImage, defLieImage,
                                defAppImage, defUrlImageS, defUrlImageM, defUrlImage,defTailleX,defTailleY, defObsAssociees};
                RecordDef rd = new RecordDef(defTab);
                st = new Store(rd);
                dView.setStore(st);

                this.getDView().setLoadingText("chargement");

                this.add(dView);
                dView.hide();
                
                videPanel = new HTML("<div class=\"avertissement\" >Aucune image à afficher. <br/> <a id=\"lienUploadMultiple\" href=\"#\" > Cliquez ici pour ajouter un dossier entier ou plusieurs fichiers </a> (nécessite Java) <br/> " +
                                "                       <a id=\"lienUploadSimple\" href=\"#\" > Cliquez ici pour ajouter un fichier à la fois </a> <br/> " +
                                "                       Pour ajouter des images plus tard, allez dans le menu Fichier -> Ajouter des images </div>");
                this.add(videPanel);
                
                // ajouts de la gestion des evenements pour la dataview
                configDragAndDrop() ;
                ajouterListenersDataView();
                
                estInstancie = true ;
                
        }
        
        public void configDragAndDrop()
        {
                // on fabrique la nouvelle configuration
                // les éléments sur lesquels on fait du drag 'n drop doivent tous avoir le même ddGroup
                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)
                {
                        @Override
                        public boolean notifyDrop(DragSource source, EventObject e, DragData data){             
                                
                                // si les données proviennent d'une grille
                                if(data instanceof GridDragData)
                        {
                                        // on appelle le médiateur
                                        return iMediateur.lierObsDD(source, e, data,getId()) ;   
                        }
                                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 rafraichissable
         */
        @Override
        public void rafraichir(Object nouvelleDonnees,
                        boolean repandreRafraichissement) {

                // si l'objet reçu est un store
                if (nouvelleDonnees instanceof Store) {

                                st = (Store) nouvelleDonnees;
                                
                        if(st.getCount() != 0) {
                                
                                // on le charge
                                st.load();
        
                                if(videPanel != null && videPanel.isVisible()) {
                                        videPanel.setVisible(false) ;
                                }
                                
                                if(dView != null) {
                                        if(!dView.isVisible()) {
                                                dView.setVisible(true);
                                        }
                                                // on l'affecte à la vue
                                                dView.setStore(st);
                                                // et on rafrachit la vue
                                                dView.refresh();
                                }
                        }
                        else 
                        {
                                st.removeAll();
                                st.load();
                                dView.setStore(st);
                                
                                if(dView.isVisible()) {
                                        dView.hide() ;
                                }
                                
                                if(videPanel != null && !videPanel.isVisible()) {
                                        videPanel.setVisible(true);
                                        AjouterListenersLiens();
                                }
                                
                        }
                }

                // si le composant doit répandre le rafraichissement
                if (repandreRafraichissement) {
                        // il en notifie le médiateur en lui donnant une copie des données
                        // et en notifiant qu'il en est l'expéditeur
                        getIMediateur().synchroniserDonneesZoomListeGalerie(
                                        nouvelleDonnees, this);
                }       
        }

        /**
         * Méthode héritée de l'interface VueListable Sélectionne les images dans la
         * galerie suivant les identifiants donnés en paramètres
         * 
         * @param ids
         *            les identifiants des images à sélectionner
         */
        public void selectionnerImages(int[] ids) {

                getDView().select(ids);

        }

        @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 void AjouterListenersLiens() {

                addListener(new PanelListenerAdapter() {
                        
                        @Override
                        public void onAfterLayout(Container c) {
                                ExtElement uploadS = Ext.get("lienUploadSimple");
                                uploadS.removeAllListeners();
                                uploadS.addListener("click", new EventCallback() {
                                        @Override
                                        public void execute(EventObject e) {
                                                getIMediateur().uploaderImages(false);
                                        }
                                        
                                }) ;
                        
                                ExtElement uploadM = Ext.get("lienUploadMultiple");
                                uploadM.removeAllListeners();
                                uploadM.addListener("click", new EventCallback() {
                                        @Override
                                        public void execute(EventObject e) {
                                                getIMediateur().uploaderImages(true);
                                        }
                                });
                        }

                });
        }
        
        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;
        }
}