Rev 965 | Blame | Last modification | View Log | RSS feed
package org.tela_botanica.client.vues.observation.filtres;import org.tela_botanica.client.interfaces.Filtrable;import org.tela_botanica.client.interfaces.Rafraichissable;import org.tela_botanica.client.observation.ObservationMediateur;import com.google.gwt.user.client.Window;import com.gwtext.client.core.EventObject;import com.gwtext.client.data.Node;import com.gwtext.client.data.NodeTraversalCallback;import com.gwtext.client.data.Tree;import com.gwtext.client.dd.DragData;import com.gwtext.client.dd.DragDrop;import com.gwtext.client.dd.DropTargetConfig;import com.gwtext.client.widgets.Button;import com.gwtext.client.widgets.Component;import com.gwtext.client.widgets.Panel;import com.gwtext.client.widgets.event.ButtonListenerAdapter;import com.gwtext.client.widgets.event.PanelListenerAdapter;import com.gwtext.client.widgets.form.TextField;import com.gwtext.client.widgets.layout.VerticalLayout;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.widgets.tree.DropNodeCallback;import com.gwtext.client.widgets.tree.MultiSelectionModel;import com.gwtext.client.widgets.tree.TreeDragData;import com.gwtext.client.widgets.tree.TreeEditor;import com.gwtext.client.widgets.tree.TreeNode;import com.gwtext.client.widgets.tree.TreePanel;import com.gwtext.client.widgets.tree.event.TreeNodeListenerAdapter;import com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter;public class ArbreMotsClesObservationVue extends Panel implements Rafraichissable, Filtrable {/*** Le médiateur associé à la vue*/private ObservationMediateur oMediateur = null;/*** Le treepanel qui affiche l'arbre*/private static TreePanel arbreMotsCles = null;/*** L'éditeur qui permet de modifier les mots clés dans l'arbre*/private TreeEditor te = null;/*** Le textfield associé à l'éditeur*/private TextField tfEdit = null;/*** Bouton de validation*/private Button ajouterMotCle = null;/*** Une string permettant connaitre les mots clés cochés en cours séparés par* des virgules*/private String motsClesEnCours = "";/*** Tableau contenant les mots clés qui n'ont pas encore été jaouté à l'arbre* (sert au lazy rendering quand on reçoit des mots clés avant que le rendu* du conteneur n'ai été effectué)*/private String[] motsClesEnAttente = new String[0];/*** Booléen d'évènement qui sert à savoir si on est en train d'ajouter un* noeud*/private boolean ajoutNoeud = false;/*** Booléen d'évènement qui sert à savoir si on est en train de modifier un* noeud*/private boolean modifNoeud = false;/*** Booléen d'instanciation du conteneur*/private boolean arbreCharge = false;/*** Booléen nécessaire pour l'affichage**/private boolean estInstancie = false;/*** Booléen d'évènement qui sert à savoir si les mots clés ont bien été reçu*/private boolean motsCleInitialises;private Component livue = null;MultiSelectionModel msModel = null;/*** Constructeur sans paramètre (privé car interdit d'utilisation)*/@SuppressWarnings("unused")private ArbreMotsClesObservationVue() {super();}/*** Constructeur avec paramètre** @param im* le médiateur à associer*/public ArbreMotsClesObservationVue(ObservationMediateur om) {// on crée le panelsuper("Projets");this.setLayout(new VerticalLayout());oMediateur = om;setBorder(false);setCollapsible(true);setTitleCollapse(true);setAutoScroll(true);// on ajoute les listenersajouterListenersPanel();}/*** 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@Overridepublic void onRender(Component component) {livue = oMediateur.getListeObservation();// on crée le conteneur de l'arbrearbreMotsCles = new TreePanel();// on permet le drag and drop dans l'arbre//arbreMotsCles.setEnableDD(true);arbreMotsCles.setId("x-view-tree-keyword-obs");msModel = new MultiSelectionModel();arbreMotsCles.setSelectionModel(msModel);// on crée une racine pour l'arbreTreeNode root = new TreeNode("Projets");root.setId("racine_obs");String[] usObject = { "Projets", "racine_obs" };root.setUserObject(usObject);root.setExpandable(true);arbreMotsCles.setRootNode(root);// on crée l'éditeur pour l'arbretfEdit = new TextField();te = new TreeEditor(arbreMotsCles, tfEdit);ajouterMotCle = new Button("Ajouter un projet");arbreMotsCles.add(te);arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() {@Overridepublic void onClick(Node node, EventObject e) {if(!arbreCharge) {expand();}}@Overridepublic void onExpand(Node node) {if(!arbreCharge) {obtenirArbreMotsCles();arbreCharge = true;}}});// on interdit le drag and drop dans l'arbrearbreMotsCles.setRootVisible(true);arbreMotsCles.setBorder(false);// on met en forme le layoutadd(arbreMotsCles);add(ajouterMotCle);// enfin on considère le composant comme instanciéestInstancie = true;configDragAndDrop();// on ajoute les listeners d'évenementsajouterListeners();}});}/*** Acesseur pour le médiateur** @return le médiateur associé à la vue*/private ObservationMediateur getOMediateur() {return oMediateur;}/*** Acesseur pour l'arbre des mots clés** @return le panel contenant l'arbre*/public TreePanel getArbreMotsCles() {return arbreMotsCles;}/*** Accesseur pour l'éditeur** @return l'éditeur associé à l'arbre*/public TreeEditor getTe() {return te;}/*** Acesseur pour le TextField associé à l'éditeur** @return le champ texte associé à l'éditeur*/public TextField getTfEdit() {return tfEdit;}/*** Ajoute les listeners nécessaires pour la gestion des évènements*/private void ajouterListeners() {arbreMotsCles.addListener(new TreePanelListenerAdapter() {// gestion du clic sur un noeud@Overridepublic void onClick(TreeNode node, EventObject e) {e.stopEvent();boolean multi = false;if(e.hasModifier()) {multi = true;}gererClicNoeud(node,multi);}// gestion du clic droit sur un noeud@Overridepublic void onContextMenu(TreeNode node, EventObject e) {e.stopEvent();montrerContextMenuArbre(node, e, getTe());}// gestion du double clic sur un noeud@Overridepublic void onDblClick(TreeNode node, EventObject e) {modifNoeud = true;if (!node.getId().equals("racine_obs")) {te.startEdit(node);}}// gestion de la modification du texte d'un noeud@Overridepublic void onTextChange(TreeNode node, String text, String oldText) {// on récupère les informations associées au noeudTreeNode nd = node;String[] usObject = new String[2];usObject[0] = text;usObject[1] = ((String[]) nd.getUserObject())[1];nd.setUserObject(usObject);// si c'est un nouveau noeudif (ajoutNoeud) {// on notifie le médiateur de l'ajout et on lui passe// l'arbregetOMediateur().ajouterMotCleDansArbre(nd,getArbreMotsCles().getTree());// et considère l'ajout achevéajoutNoeud = false;}// si c'est noeud déjà existantelse {if (modifNoeud) {// on notifie le médiateur de la modification et on lui// passe l'arbregetOMediateur().modifierMotCleDansArbre(nd,getArbreMotsCles().getTree());// et on considère la modification achevéemodifNoeud = false;}}}// gestion du déplacement d'un noeud@Overridepublic void onMoveNode(Tree tree, TreeNode node,TreeNode oldParent, TreeNode newParent, int index) {// on notifie le médiateur et on lui passe l'arbregetOMediateur().deplacerMotCleDansArbre(node,getArbreMotsCles().getTree());}@Overridepublic boolean doBeforeNodeDrop(TreePanel treePanel,TreeNode target, DragData dragData,String point, DragDrop source,TreeNode dropNode,DropNodeCallback dropNodeCallback) {if(dragData instanceof TreeDragData) {return true;}String idMotCle = ((String[])target.getUserObject())[1];if(oMediateur.gererDDObsSurMotCle(target, dragData)) {cocherMotCle(idMotCle);return true;}return false;}@Overridepublic void onNodeDrop(TreePanel treePanel,TreeNode target, DragData dragData,String point, DragDrop source, TreeNode dropNode) {}});// gestion de la validationajouterMotCle.addListener(new ButtonListenerAdapter() {// lors du clic@Overridepublic void onClick(Button button, EventObject e) {TreeNode[] noeuds = ((MultiSelectionModel)arbreMotsCles.getSelectionModel()).getSelectedNodes();TreeNode noeudAjout;if(noeuds.length > 0) {noeudAjout = noeuds[noeuds.length - 1];} else {noeudAjout = arbreMotsCles.getRootNode();}ajouterNoeud(noeudAjout);}});}/*** Configure le drag 'n drop pour la liste*/private void configDragAndDrop(){// on fabrique la nouvelle configuration// les éléments sur lesquels on fait du drag 'n drop doivent tous avoir le même ddGrouparbreMotsCles.setDdGroup("ObsMotsClesGroup");//arbreMotsCles.setEnableDD(true);arbreMotsCles.setEnableDrag(true);arbreMotsCles.setEnableDrop(true);DropTargetConfig dtc = new DropTargetConfig();dtc.setdDdGroup("ObsMotsClesGroup");}/*** Envoie une demande au médiateur pour obtenir l'arbre des mots clés*/public void obtenirArbreMotsCles() {getOMediateur().obtenirArbreMotsCles(this);}/*** Supprime un noeud de l'arbre** @param n* le noeud à supprimer*/public void supprimerNoeud(TreeNode n) {// si ça n'est pas la racine (qu'on ne peut pas supprimer)if (!n.getId().equals(getArbreMotsCles().getRootNode().getId())) {if(Window.confirm("Etes vous sur de vouloir supprimer ce projet ?")) {// on détache le noeud et on le détruitn.getParentNode().removeChild(n);n.destroy();// puis on en notifie le médiateur en lui passant le noeud supprimé// et l'arbregetOMediateur().supprimerMotCleDansArbre(n, arbreMotsCles.getTree());}} else {// si l'utilisateur tente de supprimer la racine, on l'avertit de// son erreurWindow.alert("Impossible de supprimer la racine de l'arbre");}}/*** Ajoute un noeud dans l'arbre au parent donné** @param parent* le futur parent du noeud à ajouter*/public void ajouterNoeud(TreeNode parent) {// on met l'ajout du noeud à vraiajoutNoeud = true;// on crée un nouveau noeud videTreeNode nd = new TreeNode("");nd.setCls("x-view-treenode-keyword");// on associe un objet au noeud qui contient des infosString[] usObject = new String[2];// l'objet contient le nom du noeudusObject[0] = "";usObject[1] = genererIdMotCle(nd);nd.setId(usObject[1]);nd.setUserObject(usObject);// l'identifiant d'un noeud c'est son hashcode// l'objet associé au noeud contient aussi son identifiant// on le concatène au parent et on étend ses enfantsparent.appendChild(nd);parent.expand();// enfin on place le curseur et on fait apparaitre le champ d'édition// pour que l'utilisateur nomme son mot cléte.startEdit(nd);}/*** Fonction de gestion sur le clic sur le noeud** @param node*/public void gererClicNoeud(TreeNode node, boolean multi) {if(!arbreCharge) {obtenirArbreMotsCles();} else {if(multi) {}((MultiSelectionModel)arbreMotsCles.getSelectionModel()).select(node, multi);oMediateur.obtenirNombreObservation();}}/*** Parcourt l'arbre et coche les noeud qui font partie de la liste des mots* clés à cocher** @param motsClesIds* un tableau contenant les identifiants des mots clés à cocher*/public void cocherMotsCles(final String[] motsClesIds) {if (getArbreMotsCles() != null&& getArbreMotsCles().getRootNode() != null) {// à partir de la racinegetArbreMotsCles().getRootNode().cascade(new NodeTraversalCallback() {// pour chaque noeud@Overridepublic boolean execute(Node node) {// on parcourt le tableau des mots clésfor (int i = 0; i < motsClesIds.length; i++) {// si le mot clé fait partie des id à cocher on// le cocheString usObject[] = (String[]) node.getUserObject();String nodeId = usObject[1];if (nodeId.equals(motsClesIds[i])) {getArbreMotsCles().getNodeById(nodeId).getUI().getTextEl().addClassName("x-tree-node-text-kw");return true;}}if((getArbreMotsCles().getNodeById(node.getId()).getUI().getTextEl()) != null) {getArbreMotsCles().getNodeById(node.getId()).getUI().getTextEl().removeClassName("x-tree-node-text-kw");}// et on passe au suivantreturn true;}});}else {motsClesEnAttente = motsClesIds ;}}public void cocherMotCle(String motCleId) {getArbreMotsCles().getNodeById(motCleId).getUI().getTextEl().addClassName("x-tree-node-text-kw");}public void initialiser() {arbreCharge = false ;motsClesEnCours = "";arbreMotsCles.collapseAll();// on vide l'ancien arbreNode[] rootChild = arbreMotsCles.getRootNode().getChildNodes();for (int i = 0; i < rootChild.length; i++) {rootChild[i].remove();}arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() {@Overridepublic void onExpand(Node node) {if(!arbreCharge){obtenirArbreMotsCles() ;arbreCharge = true ;}}}) ;}/*** Méthode héritée de l'interface rafraichissable** @param nouvelleDonnees* les nouvelles données pour l'objet* @param repandreRafraichissement* booleen qui dit si on doit répandre l'évenement*/@Overridepublic void rafraichir(Object nouvelleDonnees,boolean repandreRafraichissement) {if(nouvelleDonnees instanceof Tree) {Tree nouvelArbre = (Tree)nouvelleDonnees ;// on prend sa racine et on l'attache à l'arbre des mots clésNode[] rootChild = getArbreMotsCles().getRootNode().getChildNodes();for (int i = 0; i < rootChild.length; i++) {rootChild[i].remove();}copierFilsNoeud(nouvelArbre.getRootNode(),getArbreMotsCles().getRootNode());// si l'arbre n'était pas encore considéré comme instanciéif (!arbreCharge) {// on signale que ouiarbreCharge = true;}// s'il y a des mots clés en attente (lors du premier rendering)if (motsCleInitialises == false && motsClesEnAttente != null) {// on les cochecocherMotsCles(motsClesEnAttente) ;motsCleInitialises = true;}if(motsClesEnAttente.length > 0) {cocherMotsCles(motsClesEnAttente);}}// Si on reçoit un tableau de String (cas ou l'on séléectionne une// nouvelle obs)if (nouvelleDonnees instanceof String) {String chaineMc = (String)nouvelleDonnees;String[] motsClesIds = chaineMc.split(";");// et que l'arbre est instanciéif (arbreCharge) {// le tableau de String contient les id des mots clés associés à// l'image// on coche les mots clés contenu dans le tableaucocherMotsCles(motsClesIds);}// si l'arbre n'est pas encore instancié on met les mots clés en// attenteelse {motsClesEnAttente = motsClesIds;}}}private String genererIdMotCle(TreeNode nd) {double IdMC = (nd.hashCode() + ((Math.random() * 10000) + 1));return ""+IdMC;}/*** 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[1]);child.setUserObject(usObj);ndPereCopie.appendChild(child);if (!ndNodeFils[i].isLeaf()) {copierFilsNoeud(ndNodeFils[i], child);}}}}public void raz() {arbreCharge = false ;arbreMotsCles.collapseAll();arbreMotsCles.clear() ;// on crée une racine pour l'arbreTreeNode root = new TreeNode("Projets");root.setId("racine_obs");String[] usObject = { "Projets", "racine_obs" };root.setUserObject(usObject);root.setExpandable(true);arbreMotsCles.setRootNode(root);arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() {@Overridepublic void onExpand(Node node) {if(!arbreCharge){obtenirArbreMotsCles() ;arbreCharge = true ;}}}) ;motsClesEnCours = "";}@Overridepublic boolean renvoyerEtatFiltre() {// TODO Auto-generated method stubreturn false;}@Overridepublic String renvoyerNomFiltre() {// TODO Auto-generated method stubreturn null;}@Overridepublic String[] renvoyerValeursAFiltrer() {String val = "";TreeNode[] noeuds = ((MultiSelectionModel)arbreMotsCles.getSelectionModel()).getSelectedNodes();for(int i = 0; i< noeuds.length ; i++) {if(noeuds[i].getDepth() > 0) {val += ";"+noeuds[i].getId();}}val = val.replaceFirst(";", "");String[] valeursFiltres = {"id_mots_cles", val};return valeursFiltres;}@Overridepublic void valider() {// TODO Auto-generated method stub}public void montrerContextMenuArbre(final TreeNode n, EventObject e,TreeEditor te) {Menu mn = new Menu();final com.gwtext.client.widgets.menu.Item ajoutN = new Item("Ajouter un projet");final com.gwtext.client.widgets.menu.Item suppN = new Item("Supprimer projet");mn.addItem(ajoutN);mn.addItem(suppN);mn.addListener(new MenuListenerAdapter() {@Overridepublic void onItemClick(BaseItem item, EventObject e) {if (item.equals(suppN)) {supprimerNoeud(n);}if (item.equals(ajoutN)) {ajouterNoeud(n);}}});mn.showAt(e.getXY());}@Overridepublic void viderFiltre() {arbreMotsCles.getSelectionModel().clearSelections();motsClesEnCours = "";}}