New file |
0,0 → 1,751 |
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 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 panel |
super("Projets"); |
|
this.setLayout(new VerticalLayout()); |
oMediateur = om; |
|
setBorder(false); |
setCollapsible(true); |
setTitleCollapse(true); |
setAutoScroll(true); |
|
// on ajoute les listeners |
ajouterListenersPanel(); |
|
} |
|
/** |
* 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 |
@Override |
public void onRender(Component component) { |
livue = oMediateur.getListeObservation(); |
|
// on crée le conteneur de l'arbre |
arbreMotsCles = 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'arbre |
TreeNode 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'arbre |
tfEdit = new TextField(); |
te = new TreeEditor(arbreMotsCles, tfEdit); |
ajouterMotCle = new Button("Ajouter un projet"); |
arbreMotsCles.add(te); |
|
arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() { |
@Override |
public void onClick(Node node, EventObject e) { |
if(!arbreCharge) { |
expand(); |
} |
} |
|
@Override |
public void onExpand(Node node) { |
if(!arbreCharge) { |
obtenirArbreMotsCles(); |
arbreCharge = true; |
} |
} |
}); |
|
// on interdit le drag and drop dans l'arbre |
arbreMotsCles.setRootVisible(true); |
arbreMotsCles.setBorder(false); |
|
// on met en forme le layout |
add(arbreMotsCles); |
add(ajouterMotCle); |
|
// enfin on considère le composant comme instancié |
estInstancie = true; |
|
configDragAndDrop(); |
|
// on ajoute les listeners d'évenements |
ajouterListeners(); |
} |
|
}); |
} |
|
/** |
* 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 |
@Override |
public 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 |
@Override |
public void onContextMenu(TreeNode node, EventObject e) { |
|
e.stopEvent(); |
montrerContextMenuArbre(node, e, getTe()); |
|
} |
|
// gestion du double clic sur un noeud |
@Override |
public 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 |
@Override |
public void onTextChange(TreeNode node, String text, String oldText) { |
|
if(!MotsClesUtilitaire.estUnMotCleAutorise(text)) { |
te.startEdit(node); |
Window.alert("Un mot clé ne peut pas être vide ou contenir les caractères suivants : "+MotsClesUtilitaire.getChaineCaracteresInterdits()); |
return; |
} |
|
// on récupère les informations associées au noeud |
TreeNode nd = node; |
String[] usObject = new String[2]; |
usObject[0] = text; |
usObject[1] = ((String[]) nd.getUserObject())[1]; |
nd.setUserObject(usObject); |
|
// si c'est un nouveau noeud |
if (ajoutNoeud) { |
ajouterMotCleDansArbreMediateur(nd); |
} |
// si c'est noeud déjà existant |
else { |
if (modifNoeud) { |
modifierMotCleDansArbreMediateur(nd); |
} |
} |
//arbreMotsCles.disable(); |
} |
|
// gestion du déplacement d'un noeud |
@Override |
public void onMoveNode(Tree tree, TreeNode node, |
TreeNode oldParent, TreeNode newParent, int index) { |
// on notifie le médiateur et on lui passe l'arbre |
getOMediateur().deplacerMotCleDansArbre(node, |
getArbreMotsCles().getTree()); |
} |
|
@Override |
public 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; |
} |
|
|
@Override |
public void onNodeDrop(TreePanel treePanel, |
TreeNode target, DragData dragData, |
String point, DragDrop source, TreeNode dropNode) { |
|
|
} |
|
}); |
|
// gestion de la validation |
ajouterMotCle.addListener(new ButtonListenerAdapter() { |
|
// lors du clic |
@Override |
public 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'arbre |
getOMediateur().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'arbre |
getOMediateur().modifierMotCleDansArbre(nd, |
getArbreMotsCles().getTree()); |
// et on considère la modification achevée |
modifNoeud = 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 ddGroup |
arbreMotsCles.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étruit |
n.getParentNode().removeChild(n); |
n.destroy(); |
// puis on en notifie le médiateur en lui passant le noeud supprimé |
// et l'arbre |
getOMediateur() |
.supprimerMotCleDansArbre(n, arbreMotsCles.getTree(), this); |
} |
} else { |
// si l'utilisateur tente de supprimer la racine, on l'avertit de |
// son erreur |
Window.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) { |
if(parent == null) { |
parent = arbreMotsCles.getRootNode(); |
} |
|
ajoutNoeud = true; |
|
TreeNode nd = MotsClesUtilitaire.ajouterNoeud(parent, false); |
// on le concatène au parent et on étend ses enfants |
parent.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 racine |
getArbreMotsCles().getRootNode().cascade( |
new NodeTraversalCallback() { |
|
// pour chaque noeud |
@Override |
public boolean execute(Node node) { |
|
// on parcourt le tableau des mots clés |
for (int i = 0; i < motsClesIds.length; i++) { |
// si le mot clé fait partie des id à cocher on |
// le coche |
String 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 suivant |
return 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 arbre |
Node[] rootChild = arbreMotsCles.getRootNode().getChildNodes(); |
for (int i = 0; i < rootChild.length; i++) { |
|
rootChild[i].remove(); |
} |
|
arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() { |
|
@Override |
public 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 |
*/ |
@Override |
public 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és |
Node[] 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 oui |
arbreCharge = true; |
} |
|
|
// s'il y a des mots clés en attente (lors du premier rendering) |
if (motsCleInitialises == false && motsClesEnAttente != null) { |
// on les coche |
cocherMotsCles(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 tableau |
cocherMotsCles(motsClesIds); |
|
} |
// si l'arbre n'est pas encore instancié on met les mots clés en |
// attente |
else { |
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); |
noeudEnAjout.setId(id); |
cheminTemporaireAjout = null; |
} |
} |
} |
|
public void raz() { |
|
arbreCharge = false ; |
arbreMotsCles.collapseAll(); |
arbreMotsCles.clear() ; |
|
// on crée une racine pour l'arbre |
TreeNode 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() { |
|
@Override |
public void onExpand(Node node) { |
if(!arbreCharge) |
{ |
obtenirArbreMotsCles() ; |
arbreCharge = true ; |
} |
} |
|
}) ; |
|
motsClesEnCours = ""; |
} |
|
@Override |
public boolean renvoyerEtatFiltre() { |
// TODO Auto-generated method stub |
return false; |
} |
|
@Override |
public String renvoyerNomFiltre() { |
// TODO Auto-generated method stub |
return null; |
} |
|
@Override |
public 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; |
} |
|
@Override |
public 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() { |
|
@Override |
public void onItemClick(BaseItem item, EventObject e) { |
if (item.equals(suppN)) { |
supprimerNoeud(n); |
} |
if (item.equals(ajoutN)) { |
ajouterNoeud(n); |
} |
} |
}); |
|
mn.showAt(e.getXY()); |
} |
|
@Override |
public void viderFiltre() { |
arbreMotsCles.getSelectionModel().clearSelections(); |
motsClesEnCours = ""; |
} |
} |
Property changes: |
Added: svn:mergeinfo |