Subversion Repositories eFlore/Applications.cel

Rev

Rev 54 | Rev 70 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.tela_botanica.client.vues;

import java.util.Iterator;

import org.tela_botanica.client.interfaces.Filtrable;
import org.tela_botanica.client.interfaces.Rafraichissable;
import org.tela_botanica.client.modeles.EntiteGeographiqueObservation;
import org.tela_botanica.client.modeles.ListeEntiteGeographiqueObservation;
import org.tela_botanica.client.observation.ObservationMediateur;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Label;
import com.gwtext.client.data.Node;
import com.gwtext.client.data.NodeTraversalCallback;
import com.gwtext.client.data.Tree;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.event.PanelListenerAdapter;
import com.gwtext.client.widgets.tree.TreeNode;
import com.gwtext.client.widgets.tree.TreePanel;

/**
 * fenêtre de recherche affichant l'arbre des mots clés en lecture et un bouton
 * cliquable
 * 
 * @author aurelien
 * 
 */
public class ArbreEntiteGeographiqueObservationFiltreVue extends Panel implements Rafraichissable,
                Filtrable {

        /**
         * Le médiateur associé à la vue
         */
        private ObservationMediateur    observationMediateur            = null;

        /**
         * Les localites en cours
         */
        private String entitesGeographiquesEncours = "";

        /**
         * Le treepanel qui affiche l'arbre
         */
        private TreePanel arbreEntitesGeographiques = null;



        /**
         * La structure de donnees qui stocke l'arbre. Utilisee a ce niveau car trop liee a la vue
         */
        
        private Tree donneeEntitesGeographiques = new Tree();;
        
        /**
         * booléen d'initialisation
         */
        private boolean estInstancie = false;

        /**
         * booléen d'etat
         */
        private boolean filtreModifie = false;

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

        /**
         * Constructeur avec paramètres
         * 
         * @param im
         *            le médiateur à associer
         */
        public ArbreEntiteGeographiqueObservationFiltreVue(ObservationMediateur obs) {

                // on crée le panel
                super();
                
                this.observationMediateur = obs;

                // on crée le conteneur de l'arbre
                Label labelRecherche = new Label("Localités :");
                arbreEntitesGeographiques = new TreePanel();

                this.setPaddings(5);

                this.setBorder(false);
                this.setCollapsible(true);
                this.setAutoWidth(true);

                add(labelRecherche);

                // on ajoute les listeners
                ajouterListenersPanel();
                estInstancie = false;
        }

        /**
         * Ajoute les listeners pour le rendu du panel
         */
        private void ajouterListenersPanel() {
                  this.addListener(new PanelListenerAdapter() {

                        // on instancie réellement les composants au moment du rendu pour
                        // accélérer l'affichage
                        // et éviter des bugs
                        public void onRender(Component component) {

                                // on interdit le drag and drop dans l'arbre
                                arbreEntitesGeographiques.setEnableDD(false);
                                arbreEntitesGeographiques.setId("x-view-tree-filter");
                                arbreEntitesGeographiques.setAutoWidth(false);
                                arbreEntitesGeographiques.setAutoScroll(true);
                                arbreEntitesGeographiques.setBorder(false);

                                // on crée une racine pour l'arbre
                                TreeNode root = new TreeNode("Tags");
                                root.setId("racine_filtre");
                                String[] usObject = { "Localités", "racine" };
                                root.setUserObject(usObject);

                                arbreEntitesGeographiques.setRootNode(root);
                                arbreEntitesGeographiques.setRootVisible(true);
                                arbreEntitesGeographiques.setBorder(false);

                                // on met en forme le layout
                                //((Panel) component).add(arbreEntitesGeographiques);
                                add(arbreEntitesGeographiques);

                                // on ajoute les listeners d'évenements
                                ajouterListeners();

                                
                                // enfin on considère le composant comme instancié
                                estInstancie = true;

                                
                        }

                });
        }

        
        
        /**
         * ajoute les listeners pour les boutons et le cochage des mots clés
         */
        private void ajouterListeners() {

        }

        /**
         * Méthode héritée de l'interface rafraichissable
         */
        public void rafraichir(Object nouvelleDonnees,
                        boolean repandreRaffraichissement) {


                if (nouvelleDonnees instanceof ListeEntiteGeographiqueObservation) {
                
                        
                        String entite=null;
                        String parent=null;
                        
                        ListeEntiteGeographiqueObservation data = (ListeEntiteGeographiqueObservation) nouvelleDonnees ;
                
                        
                        if (data.isEmpty()) {
                                // on crée un arbre vide
                                TreeNode root = new TreeNode();
                                root.setId("racine");
                                root.setText("Tags");
                                String[] usObj = { "Tags", "racine" };
                                root.setUserObject(usObj);
                                donneeEntitesGeographiques.setRootNode(root);
                                
                        }
                        
                        // on la parse et on récupère les informations quiç nous interessent
                        for (Iterator<String> it= data.keySet().iterator(); it.hasNext();) {
                                
                                EntiteGeographiqueObservation ent=(EntiteGeographiqueObservation) data.get(it.next());
                                
                                entite=ent.getEntite();
                                parent=ent.getParent();
                                
                        
                                String[] usObj = { entite };

                                        // et on construit l'arbre à partir de la racine (qui est
                                        // toujours le premier élément)
                                        if (entite.equals("racine")) {
                                                TreeNode root = new TreeNode();
                                                root.setId(entite);
                                                root.setText(entite);
                                                root.setUserObject(usObj);
                                                donneeEntitesGeographiques.setRootNode(root);
                                        } else {
                                                // et en ajoutant les noeuds un à un (qui sont renvoyé
                                                // dans l'ordre hierarchique de leur niveau
                                                // ce qui permet de les traiter séquentiellement)
                                                TreeNode node = new TreeNode();
                                                node.setId(entite);
                                                node.setText(entite);
                                                node.setChecked(false);
                                                Node parentNode = donneeEntitesGeographiques.getNodeById(parent);
                                                node.setUserObject(usObj);
                                                parentNode.appendChild(node);
                                        }
                                }

                        }
                        
                        // on vide tous les noeuds
                        arbreEntitesGeographiques.getRootNode().eachChild(new NodeTraversalCallback() {

                                public boolean execute(Node node) {

                                        node.remove();
                                        return true;
                                }

                        });

                        // et on recopie le nouvel arbre
                        copierFilsNoeud(donneeEntitesGeographiques.getRootNode(), arbreEntitesGeographiques
                                        .getRootNode());

                        // si l'arbre n'était pas encore considéré comme instancié
                        if (!estInstancie) {
                                // on signale que oui
                                estInstancie = true;
                        }

                        // l'état du filtre est réinitialisé
                        filtreModifie = false;
                        show() ;
        }
        

        


        /**
         * Accesseur pour le panneau contenant l'arbre
         * 
         * @return le panneau de l'arbre des mots clés
         */
        public TreePanel getArbreMotsCles() {
                return arbreEntitesGeographiques;
        }

        /**
         * Méthode héritée de Filtrable renvoie le nom du filtre
         */
        public String renvoyerNomFiltre() {

                return "Localités";
        }

        /**
         * Renvoie un tableau contenant le nom du champ à filtrer et la valeur
         * 
         * @return un tableau contenant le nom du champ à filtrer et sa valeur
         */
        public String[] renvoyerValeursAFiltrer() {

                valider();

                String[] valeursFiltrees = { "localites", entitesGeographiquesEncours };

                return valeursFiltrees;
        }

        /**
         * Fonction récursive qui prend deux noeuds d'arbre en paramètre et crée un
         * copie du sous arbre du premier noeud, qu'elle concatène au deuxième
         * 
         * @param ndPereOriginal
         *            le père des noeuds de l'arbre original
         * @param ndPereCopie
         *            le père qui va recevoir les copies
         */
        private void copierFilsNoeud(Node ndPereOriginal, TreeNode ndPereCopie) {
                if (ndPereCopie != null && ndPereOriginal != null) {
                        Node[] ndNodeFils = ndPereOriginal.getChildNodes();

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

                                String[] usObj = (String[]) ndNodeFils[i].getUserObject();
                                TreeNode child = new TreeNode(usObj[0]);
                                child.setId(usObj[0] + "_filtre");
                                child.setChecked(false);
                                child.setUserObject(usObj);
                                ndPereCopie.appendChild(child);

                                if (!ndNodeFils[i].isLeaf()) {
                                        copierFilsNoeud(ndNodeFils[i], child);
                                }

                        }
                }
        }

        /**
         * Méthode héritée de Filtrable Renvoie l'état du filtre (modifié ou non)
         */
        public boolean renvoyerEtatFiltre() {

                return filtreModifie;
        }

        public void valider() {
                if (estInstancie) {
                        // on vide les mots clés en cours
                        entitesGeographiquesEncours = "";
                        // pour chaque noeud à partir de la racine
                        getArbreMotsCles().getRootNode().cascade(
                                        new NodeTraversalCallback() {

                                                // on éxécute une fonction
                                                public boolean execute(Node node) {

                                                        // on récupère le mot clé associé au noeud et ses
                                                        // infos
                                                        TreeNode tn = getArbreMotsCles().getNodeById(
                                                                        node.getId());

                                                        String[] usObject = (String[]) tn.getUserObject();
                                                        //observationMediateur.mettreAjourEntitesGeographiques(usObject[0],
                                                                //      usObject[1]);

                                                        if (tn.getUI().isChecked()) {
                                                                // et les concatène à la string des mots clés en
                                                                // cours
                                                                entitesGeographiquesEncours += usObject[1] + ",";
                                                        }

                                                        return true;
                                                }

                                        });

                        // on suppose que le filtre a change
                        filtreModifie = true;
                }
        }

}