Subversion Repositories eFlore/Archives.cel-v2

Compare Revisions

Ignore whitespace Rev 35 → Rev 36

/trunk/src/org/tela_botanica/client/vues/ArbreMotsClesVue.java
1,72 → 1,104
package org.tela_botanica.client.vues;
 
import java.util.HashMap;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.interfaces.Rafraichissable;
import org.tela_botanica.client.modeles.MotsClesAsynchroneDAO;
 
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Window;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.ExtElement;
import com.gwtext.client.data.Node;
import com.gwtext.client.data.NodeTraversalCallback;
import com.gwtext.client.data.Tree;
import com.gwtext.client.dd.DD;
import com.gwtext.client.dd.DragData;
import com.gwtext.client.dd.DragDrop;
import com.gwtext.client.widgets.BoxComponent;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.Container;
import com.gwtext.client.widgets.Editor;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.event.ButtonListener;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.event.ComponentListener;
import com.gwtext.client.widgets.event.ComponentListenerAdapter;
import com.gwtext.client.widgets.event.ContainerListener;
import com.gwtext.client.widgets.event.ContainerListenerAdapter;
import com.gwtext.client.widgets.event.EditorListener;
import com.gwtext.client.widgets.event.EditorListenerAdapter;
import com.gwtext.client.widgets.event.PanelListenerAdapter;
import com.gwtext.client.widgets.form.Field;
import com.gwtext.client.widgets.form.TextField;
import com.gwtext.client.widgets.layout.RowLayout;
import com.gwtext.client.widgets.layout.RowLayoutData;
import com.gwtext.client.widgets.menu.Menu;
import com.gwtext.client.widgets.tree.DropNodeCallback;
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.TreePanelListener;
import com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter;
 
/**
* Arbre des mots clés, qui est une vue rafraichissable,
* qui contient des mots clés cochables et réorganisables à volonté
* @author aurelien
*
*/
public class ArbreMotsClesVue extends Panel implements Rafraichissable {
 
/**
* Le médiateur associé à la vue
*/
private ImageMediateur iMediateur = null ;
/**
* Le treepanel qui affiche l'arbre
*/
private 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 valider = 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 ;
/**
* 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 estInstancie = false ;
/**
* Booléen d'évènement qui sert à savoir si les mots clés ont bien été reçu
*/
private boolean motsCleInitialises ;
/**
* Constructeur sans paramètre (privé car interdit d'utilisation)
*/
private ArbreMotsClesVue()
{
super() ;
}
/**
* Constructeur avec paramètre
* @param im le médiateur à associer
*/
public ArbreMotsClesVue(ImageMediateur im)
{
// on crée le panel
super("Mots clés") ;
this.setLayout(new RowLayout());
iMediateur = im ;
// on crée le conteneur de l'arbre
arbreMotsCles = new TreePanel() ;
// on permet le drag and drop dans l'arbre
arbreMotsCles.setEnableDD(true) ;
// on crée une racine pour l'arbre
TreeNode root = new TreeNode("Tags") ;
root.setId("racine") ;
String[] usObject = {"Mots clés" , "racine" } ;
76,17 → 108,25
arbreMotsCles.setRootVisible(false) ;
arbreMotsCles.getRootNode().setIcon("tela.png") ;
// on crée l'éditeur pour l'arbre
tfEdit = new TextField() ;
te = new TreeEditor(arbreMotsCles,tfEdit) ;
valider = new Button("Appliquer") ;
arbreMotsCles.add(te) ;
// on met en forme le layout
this.add(arbreMotsCles,new RowLayoutData("90%")) ;
this.add(valider,new RowLayoutData("10%")) ;
// on ajoute les listeners
ajouterListeners() ;
}
/**
* Acesseur pour le médiateur
* @return le médiateur associé à la vue
*/
private ImageMediateur GetIMediateur() {
return iMediateur ;
94,7 → 134,8
}
/**
* @return the arbreMotsCles
* Acesseur pour l'arbre des mots clés
* @return le panel contenant l'arbre
*/
public TreePanel getArbreMotsCles() {
return arbreMotsCles;
101,7 → 142,8
}
 
/**
* @return the te
* Accesseur pour l'éditeur
* @return l'éditeur associé à l'arbre
*/
public TreeEditor getTe() {
return te;
108,16 → 150,21
}
 
/**
* @return the tfEdit
* Acesseur pour le TextField associé à l'éditeur
* @return le champ texte associé à l'éditeur
*/
public TextField getTfEdit() {
return tfEdit;
}
public void ajouterListeners()
/**
* Ajoute les listeners nécessaires pour la gestion des évènements
*/
private void ajouterListeners()
{
arbreMotsCles.addListener(new TreePanelListenerAdapter() {
// gestion du clic sur un noeud
public void onClick(TreeNode node, EventObject e) {
e.stopEvent() ;
124,7 → 171,7
gererClicNoeud(node);
}
 
// gestion du clic droit sur un noeud
public void onContextMenu(TreeNode node, EventObject e) {
e.stopEvent() ;
132,6 → 179,7
}
// gestion du double clic sur un noeud
public void onDblClick(TreeNode node, EventObject e) {
modifNoeud = true ;
138,9 → 186,10
te.startEdit(node);
}
// gestion de la modification du texte d'un noeud
public void onTextChange(TreeNode node, String text, String oldText) {
 
// on récupère les informations associées au noeud
TreeNode nd = node ;
String[] usObject = new String[2] ;
usObject[0] = text ;
147,29 → 196,39
usObject[1] = ((String[])nd.getUserObject())[1] ;
nd.setUserObject(usObject) ;
// si c'est un nouveau noeud
if(ajoutNoeud)
{
// on notifie le médiateur de l'ajout et on lui passe l'arbre
GetIMediateur().ajouterMotCleDansArbre(nd,getArbreMotsCles().getTree()) ;
// et considière l'ajout achevé
ajoutNoeud = false ;
}
// si c'est noeud déjà existant
else
{
// on notifie le médiateur de la modification et on lui passe l'arbre
GetIMediateur().modifierMotCleDansArbre(nd,getArbreMotsCles().getTree()) ;
// et on considère la modification achevée
modifNoeud = false ;
GetIMediateur().modifierMotCleDansArbre(nd,getArbreMotsCles().getTree()) ;
}
}
// gestion du déplacement d'un noeud
public void onMoveNode(Tree tree, TreeNode node, TreeNode oldParent, TreeNode newParent,int index)
{
// on notifie le médiateur et on lui passe l'arbre
GetIMediateur().deplacerMotCleDansArbre(node, getArbreMotsCles().getTree()) ;
}
 
 
// gestion du changement de valeur dans la checkbox
public void onCheckChange(TreeNode node, boolean checked) {
// si on a coché un noeud
if(checked)
{
// on remonte pour cocher tous les parents du noeud
node.bubble(new NodeTraversalCallback() {
public boolean execute(Node node)
185,15 → 244,21
}) ;
// gestion de la validation
valider.addListener(new ButtonListenerAdapter() {
 
// lors du clic
public void onClick(Button button, EventObject e) {
// on vide les mots clés en cours
motsClesEnCours = "" ;
// 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() ;
201,6 → 266,7
if(tn.getUI().isChecked())
{
// et les concatène à la string des mots clés en cours
motsClesEnCours += usObject[1]+"," ;
}
209,6 → 275,7
});
// enfin on notifie le médiateur et on lui passe l'arbre et la liste des mots clés ainsi obtenue
GetIMediateur().mettreAjourMotsCles(motsClesEnCours,arbreMotsCles.getTree()) ;
}
}) ;
215,6 → 282,9
}
/**
* Envoie une demande au médiateur pour obtenir l'arbre des mots clés
*/
public void obtenirArbreMotsCles() {
GetIMediateur().obtenirArbreMotsCles(this) ;
221,39 → 291,61
}
 
 
/**
* 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()))
{
// 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
GetIMediateur().supprimerMotCleDansArbre(n, arbreMotsCles.getTree()) ;
}
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)
{
// on met l'ajout du noeud à vrai
ajoutNoeud = true ;
// on crée un nouveau noeud vide
TreeNode nd = new TreeNode("");
nd.setIcon("tela.png") ;
nd.setChecked(true);
// on associe un objet au noeud qui contient des infos
String[] usObject = new String[2] ;
// l'objet contient le nom du noeud
usObject[0] = "" ;
// l'identifiant d'un noeud c'est son hashcode
usObject[1] = Integer.toString(nd.hashCode()) ;
// l'objet associé au noeud contient aussi son identifiant
nd.setId(usObject[1]) ;
nd.setUserObject(usObject) ;
// on le concatène au parent et on étend ses enfants
parent.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);
}
/**
* Coche le noeud s'il est décoché, le décoche sinon
* @param node
*/
public void gererClicNoeud(TreeNode node)
{
if(node.getUI().isChecked())
266,16 → 358,24
}
}
/**
* 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
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] ;
287,6 → 387,7
return true ;
}
}
// et on passe au suivant
return true;
}
294,32 → 395,53
}
}
/**
* 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
*/
public void rafraichir(Object nouvelleDonnees,
boolean repandreRafraichissement) {
// si on a reçu un arbre
if(nouvelleDonnees instanceof Tree)
{
Tree nouvelArbre = (Tree)nouvelleDonnees ;
// on prend sa racine et on l'attache à l'arbre des mots clés
getArbreMotsCles().getRootNode().appendChild(nouvelArbre.getRootNode()) ;
getArbreMotsCles().expandAll() ;
estInstancie = true ;
// si l'arbre n'était pas encore considéré comme instancié
if(!estInstancie)
{
// on signale que oui
estInstancie = true ;
}
// s'il y a des mots clés en attente (lors du premier rendering)
if(motsCleInitialises == false && motsClesEnAttente != null)
{
// on les coche
// TODO: corriger le bug qui fait que ça ne marche pas la premiere fois !!!!
cocherMotsCles(motsClesEnAttente) ;
motsCleInitialises = true ;
}
}
// Si on reçoit un tableau de String (cas ou l'on séléectionne une nouvelle image)
if(nouvelleDonnees instanceof String[])
{
// et que l'arbre est instancié
if(estInstancie && nouvelleDonnees != null)
{
// 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
String[] motsClesIds = (String[])nouvelleDonnees ;
cocherMotsCles(motsClesIds) ;
cocherMotsCles(motsClesIds) ;
}
// si l'arbre n'est pas encore instancié on met les mots clés en attente
else
{
motsClesEnAttente = (String[])nouvelleDonnees ;