Subversion Repositories eFlore/Applications.cel

Compare Revisions

Ignore whitespace Rev 1017 → Rev 1018

/trunk/src/org/tela_botanica/client/vues/image/MenuImageVue.java
50,6 → 50,8
private Item uploadSimple = null ;
private Item gestionMotsCles = null;
private Menu mn = null ;
 
/**
81,6 → 83,7
// on construit le menu
uploaderImage = new MenuItem("Ajouter des images", mn);
supprimerImage = new Item("Supprimer les images selectionnées");
gestionMotsCles = new Item("Gérer les mots clés");
ajouterImageSelection = new Item(
"Ajouter les images sélectionnées au tampon");
viderSelection = new Item("Vider le tampon");
87,6 → 90,7
afficherSelection = new Item("Afficher le tampon");
addItem(uploaderImage);
addItem(supprimerImage);
addItem(gestionMotsCles);
addSeparator() ;
addItem(ajouterImageSelection);
addItem(viderSelection);
127,6 → 131,11
getIMediateur().afficherIdSelectionImages();
}
// si c'est l'affichage de la selection
if (item.equals(gestionMotsCles)) {
getIMediateur().afficherFenetreGestionMotsCles();
}
// enfin, on cache le menu
hide();
 
/trunk/src/org/tela_botanica/client/vues/image/PanneauMetadonneesVue.java
2,11 → 2,9
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.interfaces.Rafraichissable;
import org.tela_botanica.client.vues.ArbreMotsClesVue;
import org.tela_botanica.client.vues.image.ImageMotsClesVue;
import org.tela_botanica.client.vues.image.filtres.RechercheFiltreTaxonVue;
 
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Label;
16,25 → 14,18
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.Panel;
import com.gwtext.client.widgets.TabPanel;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.event.ContainerListener;
import com.gwtext.client.widgets.event.ContainerListenerAdapter;
import com.gwtext.client.widgets.event.PanelListener;
import com.gwtext.client.widgets.event.PanelListenerAdapter;
import com.gwtext.client.widgets.form.DateField;
import com.gwtext.client.widgets.form.Field;
import com.gwtext.client.widgets.form.TextArea;
import com.gwtext.client.widgets.form.TextField;
import com.gwtext.client.widgets.form.event.FieldListener;
import com.gwtext.client.widgets.form.event.FieldListenerAdapter;
import com.gwtext.client.widgets.grid.GridPanel;
import com.gwtext.client.widgets.grid.GridView;
import com.gwtext.client.widgets.grid.PropertyGridPanel;
import com.gwtext.client.widgets.grid.event.GridCellListenerAdapter;
import com.gwtext.client.widgets.layout.FitLayout;
import com.gwtext.client.widgets.layout.RowLayout;
import com.gwtext.client.widgets.layout.RowLayoutData;
import com.gwtext.client.widgets.layout.VerticalLayout;
85,7 → 76,7
/**
* L'onglet des mots clés
*/
private ArbreMotsClesVue panneauMotsCles = null;
private ImageMotsClesVue panneauMotsCles = null;
/**
* l'onglet des observations
150,8 → 141,8
panneauExifGrid = new Panel("Exif");
panneauIptcGrid = new Panel("Iptc");
panneauInfoGrid = new Panel("Infos");
panneauMotsCles = new ArbreMotsClesVue(im);
panneauMotsCles.setHeight("500px");
panneauMotsCles = new ImageMotsClesVue(im);
panneauMotsCles.setHeight("50%");
 
Panel sousPanneauInfosGenerales = new Panel("Infos Générales");
sousPanneauInfosGenerales.setLayout(new VerticalLayout());
492,7 → 483,7
*
* @return the panneauMotsCles
*/
public ArbreMotsClesVue getPanneauMotsCles() {
public ImageMotsClesVue getPanneauMotsCles() {
return panneauMotsCles;
}
 
/trunk/src/org/tela_botanica/client/vues/image/BarreOutilsVue.java
4,23 → 4,17
import org.tela_botanica.client.util.Util;
import org.tela_botanica.client.vues.MenuAideVue;
 
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dev.util.collect.HashMap;
import com.google.gwt.user.client.Window;
import com.gwtext.client.core.EventCallback;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.Ext;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.SplitButton;
import com.gwtext.client.widgets.Toolbar;
import com.gwtext.client.widgets.ToolbarButton;
import com.gwtext.client.widgets.ToolbarItem;
import com.gwtext.client.widgets.ToolbarMenuButton;
import com.gwtext.client.widgets.ToolbarTextItem;
import com.gwtext.client.widgets.event.SplitButtonListener;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.event.SplitButtonListenerAdapter;
import com.gwtext.client.widgets.menu.Menu;
 
/**
* Barre d'outils contenant le menu de gestion des images (accessible aussi par
131,10 → 125,18
}
});
ToolbarButton menuGestionMotsCles = new ToolbarButton("Gérer les mots clés");
menuGestionMotsCles.addListener(new ButtonListenerAdapter() {
@Override
public void onClick(Button button, EventObject e) {
getIMediateur().afficherFenetreGestionMotsCles();
}
});
this.addButton(menuImage);
this.addButton(menuSuppression);
this.addButton(menuGestionMotsCles);
this.addButton(menuTampon);
this.addItem(texteFiltres);
//this.addButton(aide);
}
212,7 → 214,7
if(nomFiltre.equals("id_mots_cles")) {
String[] tabMotsCles = valeurFiltre.split(";");
String[] tabMotsClesTexte = iMediateur.obtenirTexteMotsCles(tabMotsCles);
String[] tabMotsClesTexte = iMediateur.getTexteMotsCles(tabMotsCles);
if(tabMotsClesTexte.length > 1) {
valeurFiltreTransformee = Util.implode(",", tabMotsClesTexte);
/trunk/src/org/tela_botanica/client/vues/image/FenetreGestionMotsCles.java
New file
0,0 → 1,535
package org.tela_botanica.client.vues.image;
 
import org.tela_botanica.client.interfaces.Rafraichissable;
 
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.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.WindowListenerAdapter;
import com.gwtext.client.widgets.form.TextField;
import com.gwtext.client.widgets.layout.HorizontalLayout;
import com.gwtext.client.widgets.layout.VerticalLayout;
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;
 
/**
* Arbre des mots clés, qui est une vue rafraichissable, qui contient des mots
* clés cochables et réorganisables à volonté
*
* @author aurelien
*
*/
public abstract class FenetreGestionMotsCles extends com.gwtext.client.widgets.Window implements Rafraichissable {
 
/**
* 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;
/**
* Bouton d'annulation
*/
private Button annuler = null;
/**
* Une string permettant connaitre les mots clés cochés en cours séparés par
* des virgules
*/
private String motsClesEnCours = "";
private String[] tableauMotsClesEnCours = new String[0];
/**
* 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 d'évènement qui sert à savoir si les mots clés ont bien été reçu
*/
private boolean motsCleInitialises;
 
/**
* Constructeur avec paramètre
*
* @param im
* le médiateur à associer
*/
public FenetreGestionMotsCles() {
// on crée le panel
setTitle("Mots clés");
this.setLayoutData(new VerticalLayout());
 
// 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-imgs");
 
// on crée une racine pour l'arbre
TreeNode root = new TreeNode("Tags");
root.setId("racine");
String[] usObject = { "Mots clés", "racine" };
root.setExpandable(true);
arbreMotsCles.setRootNode(root);
arbreMotsCles.setRootVisible(true);
arbreMotsCles.setBorder(false);
arbreMotsCles.setWidth(500);
root.setUserObject(usObject);
arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() {
 
public void onClick(Node node, EventObject e) {
if(!arbreCharge) {
expand();
}
}
 
public void onExpand(Node node) {
if(!arbreCharge) {
obtenirArbreMotsCles();
arbreCharge = true;
}
}
 
});
 
// on crée l'éditeur pour l'arbre
tfEdit = new TextField();
tfEdit.setAutoWidth(true);
te = new TreeEditor(arbreMotsCles, tfEdit);
valider = new Button("Appliquer");
annuler = new Button("Annuler");
arbreMotsCles.add(te);
Panel panelIntermediaire = new Panel();
panelIntermediaire.setLayoutData(new VerticalLayout());
Panel panelBoutons = new Panel();
panelBoutons.setLayout(new HorizontalLayout(50));
panelBoutons.setWidth("100%");
 
// on met en forme le layout
panelIntermediaire.add(arbreMotsCles);
panelBoutons.add(annuler);
panelBoutons.add(valider);
this.add(panelIntermediaire);
this.add(panelBoutons);
arbreMotsCles.setHeight("348px");
setCloseAction(com.gwtext.client.widgets.Window.HIDE);
// on ajoute les listeners
ajouterListeners();
 
}
 
 
/**
* 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;
}
protected abstract void surAffichageMenuContextuel(TreeNode node, EventObject e, TreeEditor te);
protected abstract void surAjoutMotCle(TreeNode node, Tree arbre);
protected abstract void surSuppressionMotCle(TreeNode node, Tree arbre);
protected abstract void surDeplacementMotCle(TreeNode node, Tree arbre);
protected abstract void surChangementTexte(TreeNode node, Tree arbre);
protected abstract void surClicValider(String chaineMotsCles, Tree arbre);
protected abstract void demanderArbreMotsCles(Rafraichissable r);
 
/**
* Ajoute les listeners nécessaires pour la gestion des évènements
*/
private void ajouterListeners() {
arbreMotsCles.addListener(new TreePanelListenerAdapter() {
public void onExpandNode(TreeNode node) {
cocherMotsCles(tableauMotsClesEnCours);
}
 
// gestion du clic sur un noeud
public void onClick(TreeNode node, EventObject e) {
 
e.stopEvent();
gererClicNoeud(node);
}
 
// gestion du clic droit sur un noeud
public void onContextMenu(TreeNode node, EventObject e) {
 
e.stopEvent();
surAffichageMenuContextuel(node, e, getTe());
 
}
 
// gestion du double clic sur un noeud
public void onDblClick(TreeNode node, EventObject e) {
 
modifNoeud = true;
if (!node.getId().equals("racine")) {
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;
usObject[1] = ((String[]) nd.getUserObject())[1];
nd.setUserObject(usObject);
 
// si c'est un nouveau noeud
if (ajoutNoeud) {
// on considère l'ajout achevé
ajoutNoeud = false;
// et on notifie le médiateur de l'ajout et on lui passe
// l'arbre
surAjoutMotCle(nd, getArbreMotsCles().getTree());
}
// si c'est noeud déjà existant
else {
// on considère la modification achevée
modifNoeud = false;
if(!text.equals(oldText)) {
// et on notifie le médiateur de la modification et on lui
// passe l'arbre
surChangementTexte(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
surDeplacementMotCle(node, getArbreMotsCles().getTree());
}
 
});
 
// 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();
/*getIMediateur().mettreAjourMotsClesId(
usObject[0], usObject[1]);*/
 
if (tn.getUI().isChecked()) {
// et les concatène à la string des mots
// clés en cours
motsClesEnCours += usObject[1] + ",";
}
 
return true;
}
 
});
 
// enfin on notifie le médiateur et on lui passe l'arbre et la
// liste des mots clés ainsi obtenue
surClicValider(motsClesEnCours, arbreMotsCles.getTree());
}
});
annuler.addListener(new ButtonListenerAdapter() {
public void onClick(Button button, EventObject e) {
close();
}
});
}
 
/**
* Envoie une demande au médiateur pour obtenir l'arbre des mots clés
*/
public void obtenirArbreMotsCles() {
demanderArbreMotsCles(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())) {
// 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
surSuppressionMotCle(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.setCls("x-view-treenode-keyword");
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] = "";
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 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()) {
node.getUI().toggleCheck(false);
} else {
node.getUI().toggleCheck(true);
}
}
 
/**
* 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) {
 
getArbreMotsCles().getNodeById(node.getId())
.getUI().toggleCheck(false);
// 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().toggleCheck(true);
getArbreMotsCles().getNodeById(nodeId).ensureVisible();
return true;
}
}
// et on passe au suivant
return 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
*/
public 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és
Node[] 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 oui
arbreCharge = true;
}
}
 
// Si on reçoit un tableau de String (cas ou l'on séléectionne une
// nouvelle image)
if (nouvelleDonnees instanceof String[]) {
 
// 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
tableauMotsClesEnCours = (String[]) nouvelleDonnees;
if(this.isVisible()) {
cocherMotsCles(tableauMotsClesEnCours);
} else {
addListener(new WindowListenerAdapter() {
@Override
public void onShow(Component component) {
cocherMotsCles(tableauMotsClesEnCours);
}
});
}
}
}
 
private String genererIdMotCle(TreeNode nd) {
return "" + (nd.hashCode() + (Math.random() * 10000));
}
/**
* 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.setChecked(false);
child.setUserObject(usObj);
ndPereCopie.appendChild(child);
 
if (!ndNodeFils[i].isLeaf()) {
copierFilsNoeud(ndNodeFils[i], child);
}
 
}
}
}
 
 
public void activerBoutonValider(boolean activer) {
valider.setVisible(activer);
}
}
 
/trunk/src/org/tela_botanica/client/vues/image/ImageMotsClesVue.java
New file
0,0 → 1,95
package org.tela_botanica.client.vues.image;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.interfaces.Rafraichissable;
import com.google.gwt.user.client.ui.HTML;
import com.gwtext.client.widgets.Panel;
 
/**
* 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 ImageMotsClesVue extends Panel implements Rafraichissable {
 
/**
* Une string permettant connaitre les mots clés cochés en cours séparés par
* des virgules
*/
private String motsClesEnCours = "";
private String[] tableauMotsClesEnCours = new String[0];
/**
* 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];
private HTML motsClesAffiches = new HTML();
 
/**
* Constructeur sans paramètre (privé car interdit d'utilisation)
*/
@SuppressWarnings("unused")
private ImageMotsClesVue() {
super();
}
 
/**
* Constructeur avec paramètre
*
* @param im
* le médiateur à associer
*/
public ImageMotsClesVue(ImageMediateur im) {
// on crée le panel
super("Mots clés");
this.setHeight("100%");
this.add(motsClesAffiches);
motsClesAffiches.setHeight("100%");
this.setBorder(false);
this.setBodyBorder(false);
this.setCollapsible(true);
this.setTitleCollapse(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
*/
public void rafraichir(Object nouvelleDonnees,
boolean repandreRafraichissement) {
// Si on reçoit un tableau de String (cas ou l'on séléectionne une
// nouvelle image)
if (nouvelleDonnees instanceof String[]) {
 
// le tableau de String contient les id des mots clés associés à
// l'image
// on affiche les mots clés contenu dans le tableau
tableauMotsClesEnCours = (String[]) nouvelleDonnees;
afficherMotsCles(tableauMotsClesEnCours);
}
}
 
private void afficherMotsCles(String[] tableauMotsClesEnCours) {
motsClesEnCours = "<ul class=\"liste_mots_cles\">";
for (int i = 0; i < tableauMotsClesEnCours.length; i++) {
if(!tableauMotsClesEnCours[i].trim().isEmpty()) {
motsClesEnCours += "<li>"+tableauMotsClesEnCours[i]+"</li>";
}
}
motsClesEnCours += "</ul>";
motsClesAffiches.setHTML(motsClesEnCours);
}
}