Rev 2277 | Blame | Last modification | View Log | RSS feed
package org.tela_botanica.client.vues.observation.filtres;import org.tela_botanica.client.i18n.Msg;import org.tela_botanica.client.interfaces.Filtrable;import org.tela_botanica.client.interfaces.Rafraichissable;import org.tela_botanica.client.observation.ObservationMediateur;import org.tela_botanica.client.util.MotsClesUtilitaire;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;private String cheminTemporaireAjout = null;public Rafraichissable thisRafraichissable;/*** 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(Msg.get("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(Msg.get("projets"));root.setId("racine_obs");String[] usObject = { Msg.get("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(Msg.get("ajouter-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) {if(!MotsClesUtilitaire.estUnMotCleAutorise(text)) {te.startEdit(node);String[] params = { MotsClesUtilitaire.getChaineCaracteresInterdits() };Window.alert(Msg.get("mot-cle-non-vide", params));return;}if(!MotsClesUtilitaire.estUnePositionAutorisee(node, node.getParentNode(), text)) {te.startEdit(node);Window.alert(Msg.get("mot-cle-existe-deja"));return;}// 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) {ajouterMotCleDansArbreMediateur(nd);}// si c'est noeud déjà existantelse {if (modifNoeud) {modifierMotCleDansArbreMediateur(nd);}}//arbreMotsCles.disable();}@Overridepublic boolean doBeforeMoveNode(Tree tree, TreeNode node,TreeNode oldParent, TreeNode newParent, int index) {boolean ok = true;if(!MotsClesUtilitaire.estUnePositionAutorisee(node, newParent, node.getText())) {ok = false;Window.alert(Msg.get("mot-cle-existe-deja"));}return ok;}@Overridepublic boolean onNodeDragOver(TreePanel treePanel, TreeNode target,DragData dragData, String point, DragDrop source,TreeNode dropNode) {boolean ok = true;if(dragData instanceof TreeDragData) {ok = MotsClesUtilitaire.estUnePositionAutorisee(dropNode, target, dropNode.getText());}return ok;}// 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);}});}private void ajouterMotCleDansArbreMediateur(TreeNode nd) {// on notifie le médiateur de l'ajout et on lui passe// l'arbregetOMediateur().ajouterMotCleDansArbre(nd,getArbreMotsCles().getTree(), this);// et considère l'ajout achevéajoutNoeud = false;}private void modifierMotCleDansArbreMediateur(TreeNode nd) {// 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;}/*** 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(Msg.get("confirmer-suppression-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(), this);}} else {// si l'utilisateur tente de supprimer la racine, on l'avertit de// son erreurWindow.alert(Msg.get("impossible-supprimer-racine"));}}/*** Ajoute un noeud dans l'arbre au parent donné** @param parent* le futur parent du noeud à ajouter*/public void ajouterNoeud(TreeNode parent) {if(parent == null) {parent = arbreMotsCles.getRootNode();}ajoutNoeud = true;TreeNode nd = MotsClesUtilitaire.ajouterNoeud(parent, false);// on le concatène au parent et on étend ses enfantsparent.appendChild(nd);parent.expand();cheminTemporaireAjout = nd.getId();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) {if(getArbreMotsCles().getNodeById(motCleId) != null) {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) {arbreMotsCles.enable();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();}MotsClesUtilitaire.copierFilsNoeud(nouvelArbre.getRootNode(),getArbreMotsCles().getRootNode(), false);// 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;}}// reception d'un nouvel identifiant de mot cléif(nouvelleDonnees instanceof Integer) {if(cheminTemporaireAjout != null) {String id = ((Integer)(nouvelleDonnees)).toString();TreeNode noeudEnAjout = arbreMotsCles.getNodeById(cheminTemporaireAjout);String[] userObj = {noeudEnAjout.getText(), id};noeudEnAjout.setUserObject(userObj);cheminTemporaireAjout = null;}}}public void raz() {arbreCharge = false ;arbreMotsCles.collapseAll();arbreMotsCles.clear() ;// on crée une racine pour l'arbreTreeNode root = new TreeNode(Msg.get("projets"));root.setId("racine_obs");String[] usObject = { Msg.get("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) {String usObject[] = (String[]) noeuds[i].getUserObject();String nodeId = usObject[1];val += ";"+nodeId;}}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(Msg.get("ajouter-projet"));final com.gwtext.client.widgets.menu.Item suppN = new Item(Msg.get("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 = "";}}