Subversion Repositories eFlore/Archives.cel-v2

Compare Revisions

Ignore whitespace Rev 35 → Rev 36

/trunk/src/org/tela_botanica/client/vues/pageToolBarVue.java
104,7 → 104,6
*/
private ToolbarTextItem intervalleElements = new ToolbarTextItem("Images "+pageCourante*taillePage+" sur "+nbElement) ;
 
 
/**
* retourne le mediateur associe à la barre
*/
112,8 → 111,7
{
return iMediateur ;
}
/***
* constructeur sans argument (privé car ne doit pas être utilisé)
*/
374,7 → 372,7
/**
* Renvoie les différents intervalles de pages possibles
* @return
* @return un tableau de tableau de string qui contient les différentes taille de pages
*/
public String[][] getNbPages()
{
/trunk/src/org/tela_botanica/client/vues/ListeImageVue.java
50,7 → 50,8
import com.gwtextux.client.data.BufferedStore;
 
/**
* Liste d'image composée de miniatures et d'information sur l'image
* Liste d'image composée de miniatures et d'information sur l'image, implémente
* l'interface rafraichissable et l'interface vueListable
*
* @author aurelien
*/
57,40 → 58,85
public class ListeImageVue extends GridPanel implements Rafraichissable,
VueListable {
 
// instance du médiateur
/**
* Le médiateur associé à la vue
*/
private ImageMediateur iMediateur = null;
 
/**
* Config de colonne
*/
private ColumnConfig numImage;
/**
* Config de colonne
*/
private ColumnConfig urlImage;
/**
* Config de colonne
*/
private ColumnConfig lieImage;
/**
* Config de colonne
*/
private ColumnConfig datImage;
/**
* Config de colonne
*/
private ColumnConfig appImage;
/**
* Modele de colonnes
*/
private ColumnModel modeleColonnes;
 
/**
* Booleen d'instanciation
*/
private boolean estInstancie = false;
 
// données locales
// store qui gère les données de la liste d'images
/**
* Store qui contient les données à afficher
*/
private Store st = null;
/**
* Configuration des colonnes du store
*/
private ColumnConfig cl = null;
/**
* Barre de pagination
*/
private pageToolBarVue bt = null ;
 
/**
* Constructeur sans arguments (privé car ne doit pas être utilisé)
*/
private ListeImageVue()
{
super() ;
}
/**
* Constructeur avec argument
* @param im le médiateur à associer
*/
public ListeImageVue(ImageMediateur im) {
 
super();
new ListeImageVue() ;
 
this.setId("listeImageGrid");
 
// on associe le médiateur
this.iMediateur = im;
// on place la barre de pagination
bt = new pageToolBarVue(im);
this.setBottomToolbar(bt) ;
 
// on construit le modèle de colonnes
numImage = new ColumnConfig("numéro", "num_image", 30, true);
datImage = new ColumnConfig("date", "dat_image", 120, true);
lieImage = new ColumnConfig("lieu", "lie_image", 120, true);
appImage = new ColumnConfig("appareil", "app_image", 200, true);
// la colonne url possède une méthode de rendu spéciale
urlImage = new ColumnConfig("Image", "url_image_S", 30, true,
new Renderer() {
 
97,7 → 143,7
public String render(Object value,
CellMetadata cellMetadata, Record record,
int rowIndex, int colNum, Store store) {
 
// on affiche une div contenant l'image pointée par l'url
String ImgUrl = record.getAsString("url_image_S");
String ImgNum = record.getAsString("num_image");
return "<div class=\"img-list\"> <img src=\"" + ImgUrl
105,7 → 151,8
}
 
});
 
// on associe le modèle de colonnes
ColumnConfig[] cm = {numImage, urlImage, datImage, lieImage, appImage};
modeleColonnes = new ColumnModel(cm);
this.setColumnModel(modeleColonnes);
125,16 → 172,22
defAppImage, defUrlImageS, defUrlImageM, defUrlImage };
RecordDef rd = new RecordDef(defTab);
st = new Store(rd);
// on associe le store
this.setStore(st);
this.getView().setAutoFill(true);
 
// on crée un masque de chargement qui s'affichera lors des mises à jour
this.setLoadMask("chargement");
 
// on ajoute les listeners
ajouterListeners();
 
}
 
public void ajouterListeners() {
/**
* Ajoute les listeners pour la gestion des évènements
*/
private void ajouterListeners() {
this.addListener(new ContainerListenerAdapter() {
 
public void onHide(Component component) {
141,6 → 194,7
 
}
 
// lors du premier rendu on demande les données qui sont déjà contenues dans la galerie qui est le premier élément affiché
public void onRender(Component component) {
 
if (!isEstInstancie()) {
156,22 → 210,27
});
 
this.addGridRowListener(new GridRowListener() {
 
// gestion du clic sur une ligne
public void onRowClick(GridPanel grid, int rowIndex, EventObject e) {
 
// on notifie le médiateur et on lui passe le nuémro de ligne
getIMediateur().clicListeImage(rowIndex);
}
 
// gestion du clic droit
public void onRowContextMenu(GridPanel grid, int rowIndex,
EventObject e) {
 
// on stoppe l'évenement pour empecher le navigateur d'afficher son propre menu
e.stopEvent() ;
// on notifie le médiateur en lui passant l'évenement
getIMediateur().montrerContextMenu(e);
}
 
// gestion du double clic
public void onRowDblClick(GridPanel grid, int rowIndex,
EventObject e) {
 
// on notifie le médiateur en lui passant le numéro de ligne
getIMediateur().doubleClicListeImage(rowIndex);
}
});
178,12 → 237,17
 
this.getSelectionModel().addListener(new RowSelectionListenerAdapter() {
 
// gestion de la sélection
public void onSelectionChange(RowSelectionModel sm) {
 
// si on a rien de sélectionné
if (sm.getCount() <= 0) {
// on notifie le médiateur (qui désactive notamment l'accès à certaines infos)
getIMediateur().aucuneSelection();
} else {
// sinon on notifie le médiateur
getIMediateur().selection();
// et on lui demande de synchroniser la selection avec les autres vues
getIMediateur().synchroniserSelection("liste");
}
}
190,10 → 254,10
});
}
 
public ColumnConfig getCl() {
return cl;
}
 
/**
* Méthode héritée de l'interface VueListable
* Sélectionne les images dans la galerie suivant les identifiants donnés en paramètres
*/
public String[] getIdSelectionnees() {
Record[] selection = this.getSelectionModel().getSelections();
int taille = selection.length;
207,50 → 271,77
return id_selection;
}
 
/**
* Accesseur pour la config de colonnes
* @return la config de colonnes
*/
public ColumnConfig getCl() {
return cl;
}
/**
* Accesseur pour le médiateur
* @return le médiateur associé
*/
public ImageMediateur getIMediateur() {
return iMediateur;
}
 
/**
* Accesseur pour le modèle de colonnes
* @return le modèle de colonnes
*/
public ColumnModel getModeleColonnes() {
return modeleColonnes;
}
 
public ColumnConfig getNumImage() {
return numImage;
}
 
/**
* Accesseur pour le store
* @return le store contenant les données
*/
public Store getSt() {
return st;
}
 
public ColumnConfig getUrlImage() {
return urlImage;
}
 
/**
* @return the estInstancie
* Accesseur pour le booleen d'instanciation
* @return le booleen d'instanciation
*/
public boolean isEstInstancie() {
return estInstancie;
}
 
/**
* Méthode héritée de l'interface rafraichissable
* @param nouvelleDonnees les nouvelles données
* @param repandreRafraichissement le booleen de notification du rafraichissement
*/
public void rafraichir(Object nouvelleDonnees,
boolean repandreRafraichissement) {
 
// si on reçoit un store
if (nouvelleDonnees instanceof Store) {
 
// on affecte celui-ci comme gestionnaire de données
st = (Store) nouvelleDonnees;
st.load();
// et on reconfigure et rafraichit la vue
this.reconfigure(st, this.getColumnModel());
}
 
// si on doit répandre l'évenement
if (repandreRafraichissement) {
// on notifie le médiateur avec une copie des données
getIMediateur().synchroniserDonneesZoomListeGalerie(
nouvelleDonnees, this);
}
}
 
/**
* Sélectionne des enregistrements donné
* @param sel un tableau d'enregistrement à selectionner
*/
public void selectionnerEnregistrements(Record[] sel) {
 
if (isEstInstancie()) {
259,6 → 350,10
}
}
/**
* Accesseur pour la toolbar de pagination
* @return la toolbar de pagination
*/
public pageToolBarVue getToolBarVue()
{
return bt ;
265,19 → 360,11
}
 
/**
* @param estInstancie
* the estInstancie to set
* Setteur pour le booleen d'instanciation
* @param estInstancie la nouvelle valeur du booleen
*/
public void setEstInstancie(boolean estInstancie) {
this.estInstancie = estInstancie;
}
 
/**
* @param mediateur
* the iMediateur to set
*/
public void setIMediateur(ImageMediateur mediateur) {
iMediateur = mediateur;
}
 
}
/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 ;
/trunk/src/org/tela_botanica/client/vues/MenuImageVue.java
1,23 → 1,45
package org.tela_botanica.client.vues;
 
import org.tela_botanica.client.image.ImageMediateur;
 
import com.google.gwt.user.client.ui.MenuItem;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.widgets.Toolbar;
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.MenuListener;
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter;
 
/**
* Menu de gestion des images
* @author aurelien
*
*/
public class MenuImageVue extends Menu {
/**
* Le médiateur associé à la vue
*/
private ImageMediateur iMediateur ;
/**
* Item pour l'upload
*/
private Item uploaderImage = null ;
/**
* Item pour la suppression
*/
private Item supprimerImage = null ;
/**
* Constructeur sans argument (privé car ne doit être utilisé)
*/
private MenuImageVue()
{
super();
}
/**
* Constructeur avec paramètre
* @param im le médiateur à associer
*/
public MenuImageVue(ImageMediateur im)
{
super() ;
24,82 → 46,54
iMediateur = im ;
// on construit le menu
uploaderImage = new Item("Uploader des images") ;
supprimerImage = new Item("Supprimer les images selectionnées") ;
addItem(uploaderImage);
addItem(supprimerImage) ;
ajouterListeners() ;
// on ajoute les listeners
ajouterListeners() ;
}
public void ajouterListeners()
/**
* Ajoute les listeners pour la gestions des évènements
*/
private void ajouterListeners()
{
this.addListener(new MenuListener() {
this.addListener(new MenuListenerAdapter() {
 
 
public void doBeforeHide(Menu menu) {
// TODO Auto-generated method stub
}
 
 
public void doBeforeShow(Menu menu) {
}
 
public void onClick(Menu menu, String menuItemId, EventObject e) {
// TODO Auto-generated method stub
}
 
public void onHide(Menu menu) {
// TODO Auto-generated method stub
}
 
// gestion du clic sur un item
public void onItemClick(BaseItem item, EventObject e) {
// si c'est l'upload
if(item.equals(uploaderImage))
{
// on notifie le médiateur
getIMediateur().uploaderImages() ;
// et on cache le menu
hide() ;
}
// si c'est la suppression
if(item.equals(supprimerImage))
{
// on notifie le médiateur
getIMediateur().supprimerImages() ;
// et on chache le menu
hide() ;
}
}
 
public void onMouseOut(Menu menu, BaseItem menuItem, EventObject e) {
// TODO Auto-generated method stub
}
 
public void onMouseOver(Menu menu, BaseItem menuItem, EventObject e) {
// TODO Auto-generated method stub
}
 
public void onShow(Menu menu) {
 
}
 
}) ;
}
/**
* Accesseur pour le médiateur
* @return le médiateur associé à la vue
*/
public ImageMediateur getIMediateur()
{
return iMediateur ;
/trunk/src/org/tela_botanica/client/vues/ZoomImageVue.java
5,41 → 5,121
import org.tela_botanica.client.interfaces.Rafraichissable;
 
 
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.LoadListener;
import com.google.gwt.user.client.ui.MouseWheelListener;
import com.google.gwt.user.client.ui.MouseWheelVelocity;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.core.RegionPosition;
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.event.ContainerListenerAdapter;
import com.gwtext.client.widgets.event.PanelListener;
import com.gwtext.client.widgets.event.PanelListenerAdapter;
import com.gwtext.client.widgets.layout.BorderLayout;
import com.gwtext.client.widgets.layout.BorderLayoutData;
import com.gwtext.client.widgets.layout.FitLayout;
import com.gwtext.client.widgets.layout.VerticalLayout;
 
/**
* Panneau d'affichage d'une image avec des boutons précdents et suivant
* TODO: assurer le redimensionnement automatique de l'image et la centrer
* @author aurelien
*
*/
public class ZoomImageVue extends Panel implements Rafraichissable {
/**
* Le médiateur associé à la vue
*/
private ImageMediateur iMediateur = null ;
private Image image = null ;
/**
* Panneau conteneur pour l'image
*/
private Panel imageConteneur = null ;
/**
* l'image à afficher
*/
private Image image = new Image("vide.jpg") ;
/**
* Bouton précédent
*/
private final com.google.gwt.user.client.ui.Button prev = new com.google.gwt.user.client.ui.Button("<");
/**
* Bouton suivant
*/
private final com.google.gwt.user.client.ui.Button suiv = new com.google.gwt.user.client.ui.Button(">");
/**
* Taille originale Y de l'image
*/
private int imageHeight = 0 ;
/**
* Taille originale X de l'image
*/
private int imageWidth = 0 ;
/**
* Booleen d'initalisation général
*/
private boolean initialise = false ;
/**
* Booleen d'initalisation du conteneur d'image
*/
private boolean conteneurInitialise = false ;
/**
* Constructeur sans argument (privé car ne doit être utilisé)
*/
private ZoomImageVue()
{
super() ;
}
/**
* Constructeur avec argument
* @param im le médiateur à associer à la vue
*/
public ZoomImageVue(ImageMediateur im)
{
super("Zoom");
// on associe le médiateur
iMediateur = im ;
iMediateur = im ;
// on crée un image qui gère le double clic
image = new Image() {
public void onBrowserEvent(Event event) {
// lors du double clic
if (Event.ONDBLCLICK == DOM.eventGetType(event)) {
 
// on notifie le médiateur
getIMediateur().doubleClicZoomImage();
}
}
}
};
 
imageConteneur = new Panel() ;
imageConteneur.add(image) ;
imageConteneur.setId("x-view-zoom-img") ;
// il n'existe pas de méthode pour ajouter un listener pour le double clic sur une image
// alors on lui dit manuellement de capter l'évènement double clic
image.sinkEvents(Event.ONDBLCLICK);
// l'image de base est vide
image.setUrl("vide.jpg");
this.setLayout(new BorderLayout());
48,32 → 128,58
suiv.setWidth("60px");
this.add(prev,new BorderLayoutData(RegionPosition.WEST));
this.add(image,new BorderLayoutData(RegionPosition.CENTER));
this.add(imageConteneur,new BorderLayoutData(RegionPosition.CENTER));
this.add(suiv,new BorderLayoutData(RegionPosition.EAST));
ajouterListenersBoutons();
// on ajoute les listeners
ajouterListeners();
}
 
/**
* Méthode héritée de l'interface rafraichissable
* @param nouvelleDonnees les nouvelles données
* @param repandreRafraichissement le booleen qui dit si on doit répnadre l'évènement
*/
public void rafraichir(Object nouvelleDonnees, boolean repandreRafraichissement) {
if(nouvelleDonnees instanceof String)
// si on reçoit une string
if(nouvelleDonnees instanceof String[])
{
getImage().setUrl((String)nouvelleDonnees);
String[] infos = (String[])nouvelleDonnees ;
// c'est l'url de l'image qu'on associe à la vue
getImage().setUrl(infos[0]);
if(infos[1] != null && infos[2] != null)
{
int x = Integer.parseInt(infos[1]) ;
int y = Integer.parseInt(infos[2]) ;
setTailleImage(x,y) ;
verifierEtRetaillerImage() ;
}
}
else
{
getImage().setUrl("/images/vide.jpeg") ;
// sinon on met une image vide
getImage().setUrl("vide.jpeg") ;
}
}
/**
* Desactive visuellement le panneau et les boutons
*/
public void desactiverPanneau()
{
getImage().setUrl("/images/vide.jpeg") ;
getImage().setUrl("vide.jpeg") ;
prev.setEnabled(false) ;
suiv.setEnabled(false);
}
/**
* Active visuellement le panneau et les boutons
*/
public void activerPanneau()
{
prev.setEnabled(true);
80,47 → 186,173
suiv.setEnabled(true);
}
public void ajouterListenersBoutons()
/**
* Ajoute les listeners pour la gestions d'évènement
*/
public void ajouterListeners()
{
// gestion du clic sur le bouton précedent
prev.addClickListener(new ClickListener() {
 
// en cas de clic
public void onClick(Widget sender) {
// on notifie le médiateur
getIMediateur().clicBoutonZoomImage("prev");
}
});
// gestion du clic sur le bouton suivant
suiv.addClickListener(new ClickListener() {
 
// en cas de clic
public void onClick(Widget sender) {
// on notifie le médiateur
getIMediateur().clicBoutonZoomImage("suiv");
}
});
// gestion du redimensionnement
this.addListener(new PanelListenerAdapter() {
// lors d'un redimensionnement de l'application
public void onBodyResize(Panel panel,java.lang.String width,java.lang.String height)
{
// on vérifie et on retaille l'image
verifierEtRetaillerImage() ;
}
}) ;
// gestion du redimensionnement lors de l'affichage du conteneur
imageConteneur.addListener(new PanelListenerAdapter() {
// avant de finir d'afficher
public void onAfterLayout(Container self)
{
// on redimensionne
verifierEtRetaillerImage() ;
}
}) ;
}
/**
* Verifie si l'image est plus grande que le conteneur et la retaille le cas echeant
*/
public void verifierEtRetaillerImage()
{
// si l'image est nulle
if(image == null)
{
// on ne fait rien
return ;
}
// on prend la taille originale de l'image
int originalX = getTailleImage()[0] ;
int originalY = getTailleImage()[1] ;
// on la transforme en float (la division entre entier donne de curieux résultats)
float fOriginalX = (new Float(originalX)).floatValue() ;
float fOriginalY = (new Float(originalY)).floatValue() ;
// et on fait le rapport longueur sur hauteur (pour connaitre le ratio)
float rapportTaille = fOriginalX/fOriginalY ;
// la nouvelle taille est pour le moment égale à l'ancienne
int nouvelleTailleX = originalX ;
int nouvelleTailleY = originalY ;
// on prend la taille du conteneur
int tailleConteneurX = imageConteneur.getWidth() ;
int tailleConteneurY = imageConteneur.getHeight() ;
// si celle-ci est égale à 0 (conteneur mal initialisé)
if(imageConteneur.getHeight() == 0 && tailleConteneurX == 0)
{
// on essaie de la calculer en fonction de la taille du parent et des frères
tailleConteneurY = this.getHeight() ;
tailleConteneurX = this.getWidth() - prev.getOffsetWidth() * 2 ;
nouvelleTailleX = originalX ;
nouvelleTailleY = originalY ;
}
// si l'image ne rentre pas telle quelle (longueur ou hauteur trop grande)
if(originalY > tailleConteneurY || originalX > tailleConteneurX)
{
// si la longueur de l'image est la plus grande des deux
if(originalX > originalY)
{
// on prend la longueur comme taille de référence, qu'on met à la longueur du conteneur
nouvelleTailleX = tailleConteneurX ;
// et on recalcule la hauteur, par rapport à la nouvelle longueur, en gardant le format de 'limage
nouvelleTailleY = (int)Math.floor(nouvelleTailleX*1/rapportTaille) ;
}
else
{
// si la hauteur est la plus grande, on fait le même genre d'opération en prenant la hauteur comme référence
nouvelleTailleY = tailleConteneurY ;
nouvelleTailleX = (int)Math.floor(nouvelleTailleY*rapportTaille) ;
}
}
// on modifie enfin la taille de l'image pour qu'elle soit affichée
getImage().setSize(""+nouvelleTailleX+"px", ""+nouvelleTailleY+"px") ;
}
 
 
/**
* Accesseur pour le médiateur
* @return le médiateur associé à la vue
*/
public ImageMediateur getIMediateur() {
return iMediateur;
}
 
 
/**
* Accesseur au conteneur de l'image
* @return le conteneur de l'image
*/
public Image getImage() {
return image;
}
 
 
/**
* Accesseur pour le bouton précédent
* @return le bouton précédent
*/
public com.google.gwt.user.client.ui.Button getPrev() {
return prev;
}
 
 
/**
* Accesseur pour le bouton suivant
* @return le bouton suivant
*/
public com.google.gwt.user.client.ui.Button getSuiv() {
return suiv;
}
/**
* Setter pour la taille de l'image
* @param X la largeur en pixels
* @param Y la hauteur en pixels
*/
public void setTailleImage(int x, int y)
{
imageHeight = y ;
imageWidth = x ;
}
/**
* renvoie la taille originale de l'image
* @return un tableau de deux entiers contenant la largeur puis la hauteur
*/
public int[] getTailleImage()
{
int[] taille = {imageHeight,imageWidth} ;
return taille ;
}
 
}
/trunk/src/org/tela_botanica/client/vues/PanneauMetadonneesVue.java
28,6 → 28,7
import com.gwtext.client.widgets.grid.GridView;
import com.gwtext.client.widgets.grid.PropertyGridPanel;
import com.gwtext.client.widgets.grid.event.GridCellListener;
import com.gwtext.client.widgets.grid.event.GridCellListenerAdapter;
import com.gwtext.client.widgets.layout.RowLayout;
import com.gwtext.client.widgets.layout.RowLayoutData;
import com.gwtext.client.widgets.layout.VerticalLayout;
36,33 → 37,89
import com.gwtext.client.widgets.tree.TreeNode;
import com.gwtext.client.widgets.tree.TreePanel;
 
/**
* Panneau contenant les infos, les métadonnées et l'arbre des mots clés, il implémente l'interface rafraichissable
* @author aurelien
*
*/
public class PanneauMetadonneesVue extends TabPanel implements Rafraichissable {
 
/**
* Le médiateur associé à la vue
*/
private ImageMediateur imediateur = null ;
/**
* Le panneau des Exifs
*/
private PropertyGridPanel ExifGrid = null ;
/**
* Le panneau des Iptc
*/
private PropertyGridPanel IptcGrid = null ;
/**
* La grille pour le panneau des Exifs
*/
private GridView gViewExif = null ;
/**
* La grille pour le panneau de Iptc
*/
private GridView gViewIptc = null ;
/**
* L'onglet des Exifs
*/
private Panel panneauExifGrid = null;
/**
* L'onglet des Iptc
*/
private Panel panneauIptcGrid = null ;
/**
* L'onglet des infos
*/
private Panel panneauInfoGrid = null ;
/**
* L'onglet des mots clés
*/
private ArbreMotsClesVue panneauMotsCles = null ;
/**
* Le champ commentaire
*/
private TextField commentaireGeneral = null ;
/**
* Le champ date
*/
private DateField dateImage = null ;
/**
* Le bouton de validation
*/
Button validerInfo = null ;
/**
* Booleen d'instanciation
*/
boolean estInstancie = false ;
/**
* Constructeur sans argument (privé car ne doit pas être utilisé)
*/
private PanneauMetadonneesVue()
{
super() ;
}
/**
* Constructeur avec argument
* @param im
*/
public PanneauMetadonneesVue(ImageMediateur im)
{
super() ;
// on associe le médiateur
imediateur = im ;
// on crée et dispose les panneaux et les champs
panneauExifGrid = new Panel("Exif") ;
panneauIptcGrid = new Panel("Iptc") ;
panneauInfoGrid = new Panel("info") ;
70,6 → 127,8
panneauInfoGrid.setLayout(new VerticalLayout());
panneauInfoGrid.setHeight(500);
panneauInfoGrid.setMargins(5) ;
panneauInfoGrid.setPaddings(5) ;
Label labelComm = new Label("Commentaires :") ;
labelComm.setHeight("20px") ;
commentaireGeneral = new TextArea() ;
83,14 → 142,6
dateImage.setFormat("d/m/y") ;
validerInfo = new Button("OK") ;
validerInfo.addListener(new ButtonListenerAdapter() {
 
public void onClick(Button button, EventObject e) {
getIMediateur().mettreAJourInfo(commentaireGeneral.getText(), dateImage.getRawValue()) ;
}
});
panneauInfoGrid.add(labelComm) ;
panneauInfoGrid.add(commentaireGeneral) ;
115,25 → 166,64
ExifGrid.setAutoWidth(true);
ExifGrid.setAutoHeight(true);
ExifGrid.setSorted(false);
ExifGrid.addGridCellListener(new GridCellListener() {
gViewIptc = new GridView();
gViewIptc.setForceFit(true);
IptcGrid = new PropertyGridPanel() ;
IptcGrid.setId("meta_iptc");
IptcGrid.setView(gViewIptc);
IptcGrid.setNameText("Métadonnées IPTC");
IptcGrid.setAutoWidth(true);
IptcGrid.setAutoHeight(true);
IptcGrid.setSorted(false);
panneauExifGrid.add(ExifGrid);
panneauIptcGrid.add(IptcGrid);
// on ajoute les listeners
ajouterListeners() ;
// on effectue le rendu
this.doLayout(true) ;
}
private void ajouterListeners()
{
// on ajoute un écouteur
validerInfo.addListener(new ButtonListenerAdapter() {
 
// gestion du clic
public void onClick(Button button, EventObject e) {
// lors du clic sur le bouton valider on met à jour les commentaires et la date
getIMediateur().mettreAJourInfo(commentaireGeneral.getText(), dateImage.getRawValue()) ;
}
});
// gestion des clics dans la grille
ExifGrid.addGridCellListener(new GridCellListenerAdapter() {
 
// lors d'un clic d'une cellule
public void onCellClick(GridPanel grid, int rowIndex, int colIndex,
EventObject e) {
// on empeche l'édition
e.stopEvent() ;
ExifGrid.stopEditing() ;
}
 
public void onCellContextMenu(GridPanel grid, int rowIndex,
int cellIndex, EventObject e) {
// TODO Auto-generated method stub
}
 
// lors du double clic sur une cellule
public void onCellDblClick(GridPanel grid, int rowIndex,
int colIndex, EventObject e) {
// on empêche l'édition
e.stopEvent() ;
ExifGrid.stopEditing() ;
141,36 → 231,21
}) ;
gViewIptc = new GridView();
gViewIptc.setForceFit(true);
IptcGrid = new PropertyGridPanel() ;
IptcGrid.setId("meta_iptc");
IptcGrid.setView(gViewIptc);
IptcGrid.setNameText("Métadonnées IPTC");
IptcGrid.setAutoWidth(true);
IptcGrid.setAutoHeight(true);
IptcGrid.setSorted(false);
IptcGrid.addGridCellListener(new GridCellListener() {
IptcGrid.addGridCellListener(new GridCellListenerAdapter() {
 
// lors d'un clic d'une cellule
public void onCellClick(GridPanel grid, int rowIndex, int colIndex,
EventObject e) {
// on empeche l'édition
e.stopEvent() ;
ExifGrid.stopEditing() ;
}
 
public void onCellContextMenu(GridPanel grid, int rowIndex,
int cellIndex, EventObject e) {
// TODO Auto-generated method stub
}
 
// lors d'un double clic d'une cellule
public void onCellDblClick(GridPanel grid, int rowIndex,
int colIndex, EventObject e) {
// on empeche l'édition
e.stopEvent() ;
ExifGrid.stopEditing() ;
177,34 → 252,44
}
}) ;
panneauExifGrid.add(ExifGrid);
panneauIptcGrid.add(IptcGrid);
this.doLayout(true) ;
}
/**
* Desactive visuellement ce panneau
*/
public void desactiverPanneau()
{
this.setDisabled(true) ;
}
/**
* Active visuellement ce panneau
*/
public void activerPanneau()
{
this.setDisabled(false) ;
}
/**
* Accesseur pour le médiateur
* @return le médiateur associé à la vue
*/
public ImageMediateur getIMediateur()
{
return imediateur ;
}
/**
* Méthode héritée de l'interface rafraichissable
* @param nouvelleDonnees les nouvelles données
* @param repandreRafraichissement le booleen de notification de mise à jour
*/
public void rafraichir(Object nouvelleDonnees, boolean repandreRafraichissement) {
// si on reçoit un tableau d'objets
if(nouvelleDonnees instanceof Object[])
{
// extrait infos, exifs et iptc
Object meta[] = (Object[])nouvelleDonnees ;
String[][] exif = (String[][])meta[0] ;
String[][] iptc = (String[][])meta[1] ;
241,6 → 326,7
dateImage.setValue(gen[1][1]) ;
// et on met à jour les données pour l'affichage
ExifGrid.setSource(exifSource);
IptcGrid.setSource(iptcSource);
 
248,6 → 334,7
}
 
/**
* Accesseur pour le panneau des mots clés
* @return the panneauMotsCles
*/
public ArbreMotsClesVue getPanneauMotsCles() {
/trunk/src/org/tela_botanica/client/vues/BarreOutilsVue.java
21,8 → 21,17
*/
public class BarreOutilsVue extends Toolbar {
/**
* Un bouton qui sert à déployer le menu
*/
ToolbarMenuButton images = null ;
/**
* Le médiateur associé à la toolbar
*/
ImageMediateur iMediateur = null ;
/**
* Le menu de gestion des images
*/
MenuImageVue imageMenu = null ;
 
/**
/trunk/src/org/tela_botanica/client/vues/GalerieImageVue.java
177,7 → 177,7
 
/**
* Accesseur pour le médiateur
* @return le mdéiateur associé à la vue
* @return le médiateur associé à la vue
*/
public ImageMediateur getIMediateur() {
return iMediateur;
185,7 → 185,7
 
/**
* Accesseur pour le store
* @return le store associée à la vue
* @return le store associé à la vue
*/
public Store getSt() {
return st;
205,7 → 205,6
*/
public void initialiser() {
// Preparation de la dataview et du template
// le template va créer une div contenant une image
// pour chacune des photos
284,20 → 283,23
}
 
// si le com)posant doit répandre le rafraichissement
// si le composant doit répandre le rafraichissement
if (repandreRafraichissement) {
// il en notifie le médiateur en lui donnant une copie des données
// il en notifie le médiateur en lui donnant une copie des données et en notifiant qu'il en est l'expéditeur
getIMediateur().synchroniserDonneesZoomListeGalerie(
nouvelleDonnees, this);
}
// si c'est la première mise à jour que l'on reçoit
if(!estInstancie)
{
// alors le composant est considéré comme instancié
estInstancie = true ;
}
}
 
/**
* Méthode héritée de l'interface VueListable
* Sélectionne les images dans la galerie suivant les identifiants donnés en paramètres
* @param ids les identifiants des images à sélectionner
*/
/trunk/src/org/tela_botanica/client/modeles/ImageUploaderAsynchroneDAO.java
1,6 → 1,7
package org.tela_botanica.client.modeles;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.iMediateur;
 
import com.google.gwt.core.client.JavaScriptObject;
25,19 → 26,30
*/
public class ImageUploaderAsynchroneDAO {
private static ImageMediateur iMediateur ;
/**
* Modele associé au DAO
*/
private static ImageModele iModele ;
public void setIMediateur(ImageMediateur im)
/**
* Setteur pour le modele
* @param im le modèle à associer au DAO
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Crée un panel d'upload simple aux fonctions réduites mais utilisant uniquement javascript
* (pour les utilisateurs qui n'ont pas java)
*/
private static void appelerUploadSimple()
{
UploadDialog up = new UploadDialog("Upload simple de fichiers") ;
up.setUrl("jrest/InventoryImage");
UrlParam id = new UrlParam("identifiant",iMediateur.getIdentifiant()) ;
UrlParam id = new UrlParam("identifiant",iModele.getIdentifiant()) ;
UrlParam[] params = {id} ;
up.setBaseParams(params);
46,7 → 58,7
 
public void onClose(Panel panel) {
iMediateur.rafraichirToutesVues() ;
iModele.requeteTerminee() ;
}
});
55,6 → 67,10
}
/**
* Crée une fenêtre contenant une applet java pour uploader plusieurs fichiers à la fois avec quelques
* fonctions avancées (nécessite le plugin java pour le navigateur)
*/
private static void appelerUploadMultiple()
{
final Window nPan = new Window("Upload multiple");
88,7 → 104,7
final String htmlForm =
"<form method=\"post\" name=\"postid\">"
+"<input type=\"hidden\" name=\"identifiant\" value=\""+iMediateur.getIdentifiant()+"\">"
+"<input type=\"hidden\" name=\"identifiant\" value=\""+iModele.getIdentifiant()+"\">"
+"</form>" ;
 
nPan.setHtml(appelApplet+htmlForm);
98,7 → 114,7
 
public void onClose(Panel panel) {
iMediateur.rafraichirToutesVues() ;
iModele.requeteTerminee() ;
}
108,6 → 124,10
nPan.show();
}
/**
* Fonction javascript native qui détecte la présence du plugin java pour le navigateur
* et appelle la méthode d'upload adaptée (appelerUploadSimple ou appelerUploadMultiple)
*/
public static native void choisirMethodeUpload() /*-{
var agt=navigator.userAgent.toLowerCase();
/trunk/src/org/tela_botanica/client/modeles/ImageCarnet.java
10,18 → 10,26
*
* Classe representant une image du carnet,
* elle ne contient pas d'image à proprement parler mais
* plutôt les informations associées ainsi que l'url distante
* plutôt les informations associées ainsi que l'url distante.
* C'est une table de hachage qui contient des paires propriété/valeur
*
*/
public class ImageCarnet extends HashMap {
 
/**
* Constructeur avec un objet JSON
* @param image
*/
public ImageCarnet(JSONObject image)
{
// l'objet JSON est une table de hachage
Set im = image.keySet() ;
// on la parcourt pour chaque clé
for (Iterator iterator = im.iterator(); iterator.hasNext();) {
// si elle est associée à une valeur, on l'ajoute
String key = (String) iterator.next();
if(image.get(key).isString() != null)
{
30,6 → 38,7
}
else
{
// sinon on ajoute la clé avec une valeur vide
String valeur = " " ;
this.put(key, valeur) ;
}
38,6 → 47,9
 
}
/**
* Surcharge de toString qui affiche toutes les propriétés de l'image
*/
public String toString()
{
String valeur = " ";
56,6 → 68,13
return valeur ;
}
/**
* Pour éviter que l'on traite des valeurs nulles à l'affichage
* on passe par cette fonction qui retire les charactères nuls qui font planter
* l'affichage, il ne faut pas utiliser get directement
* @param cle
* @return la valeur associée à la clé
*/
public String renvoyerValeurCorrecte(String cle)
{
if(this.containsKey((cle)))
63,7 → 82,7
String valeur = (String)this.get(cle) ;
if(valeur.equals("null") || valeur == null)
{
return "null" ;
return " " ;
}
else
{
75,65 → 94,114
}
else
{
return "null" ;
return " " ;
}
}
 
/**
* Acesseur pour l'id de l'image
* @return l'id de l'image
*/
public String getId() {
return renvoyerValeurCorrecte("ci_id_image") ;
}
/**
* Acesseur pour le numero d'ordre de l'image
* @return l'ordre de l'image
*/
public String getOrdre() {
return renvoyerValeurCorrecte("ci_ordre") ;
}
/**
* Base de l'url serveur pour les images
* @return url racine pour les images
*/
public String getBaseUrl()
{
return "http://162.38.234.9/Documents/images_serveur/" ;
}
 
/**
* Renvoie le chemin et nom du fichier grand format
* @return le chemin du fichier grand format
*/
public String getUrl() {
return getBaseUrl()+(String)this.get("ci_id_image")+".jpg" ;
}
/**
* Renvoie le chemin et nom du fichier petit format
* @return le chemin du fichier petit format
*/
public String getSUrl() {
return getBaseUrl()+(String)this.get("ci_id_image")+"_S.jpg" ;
}
/**
* Renvoie le chemin et nom du fichier moyen format
* @return le chemin du fichier moyen format
*/
public String getMUrl() {
return getBaseUrl()+(String)this.get("ci_id_image")+"_M.jpg" ;
}
 
 
/**
* Renvoie la taille de l'image
* @return un tableau de deux string contenant la hauteur puis la largeur
*/
public String[] getTailleImage()
{
String[] XY = { renvoyerValeurCorrecte("ci_meta_height") , renvoyerValeurCorrecte("ci_meta_width") } ;
return XY ;
}
/**
* Renvoie la date exif associée à l'image
* @return la date associée à l'image
*/
public String getDate() {
return renvoyerValeurCorrecte("ci_meta_date_time") ;
}
 
 
/**
* Renvoie la ville associée à l'image
* @return la ville iptc
*/
public Object getIptcCity() {
return renvoyerValeurCorrecte("ci_meta_iptc_city") ;
}
 
 
/**
* Renvoie le fabricant de l'appareil
* @return le fabricant
*/
public String getMake() {
return renvoyerValeurCorrecte("ci_meta_make") ;
}
 
 
/**
* Renvoie le modele de l'appareil
* @return le modele
*/
public String getModel() {
return renvoyerValeurCorrecte("ci_meta_model") ;
}
/**
* Renvoie un tableau nom / valeur de toutes les metadonnées Iptc
* @return les métadonnées iptc
*/
public String[][] getMetadonnesIptc() {
String[][] metaIptc = new String[12][2] ;
167,7 → 235,11
return metaIptc ;
}
public Object[][] getMetadonnesExif() {
/**
* Renvoie un tableau nom / valeur de toutes les metadonnées Exif
* @return les métadonnées Exif
*/
public String[][] getMetadonnesExif() {
String[][] metaExif = new String[31][2] ;
int elem = 0 ;
201,7 → 273,11
}
public Object[][] getInfoGenerales() {
/**
* Renvoie un tableau nom / valeur contenant les infos générales
* @return les infos générales
*/
public String[][] getInfoGenerales() {
String[][] metaGen = new String[2][2] ;
214,11 → 290,20
return metaGen ;
}
/**
* Renvoie une string contenant les mots clés séparés par des ','
* @return les mots clés
*/
public String getMotsCles() {
return renvoyerValeurCorrecte("ci_meta_mots_cles") ;
}
/**
* Met à jour le commenentaire et la date
* @param commentaires le nouveau commentaire
* @param date la nouvelle date
*/
public void miseAJourInfoGenerales(String commentaires, String date)
{
put("ci_meta_comment",commentaires) ;
225,7 → 310,11
put("ci_meta_date",date) ;
}
 
/**
* Met à jour les mots clés
* @param motsClesEnCours la liste de mots clés séparés par des ','
*/
public void mettreAjourMotsCles(String motsClesEnCours) {
put("ci_meta_mots_cles",motsClesEnCours) ;
/trunk/src/org/tela_botanica/client/modeles/ImageAsynchroneDAO.java
8,20 → 8,23
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.Window;
 
/**
* DAO d'accès à une image, n'est utilisé que pour l'écriture et pas pour la lecture des images
* qui se fait par paquet
* @author aurelien
*
*/
public class ImageAsynchroneDAO {
 
ImageMediateur iMediateur = null ;
public void setIMediateur(ImageMediateur im)
{
iMediateur = im ;
}
/**
* Met à jour la base de données avec toutes les données d'une image
* @param ic l'image à mettre à jour
*/
public void SynchroniserBaseDeDonnees(final ImageCarnet ic)
{
String postData = "" ;
// on construit le post avec toutes les valeur de l'image
for(Iterator imgIt = ic.keySet().iterator();imgIt.hasNext();)
{
31,10 → 34,11
 
}
 
 
// et on envoie une requête asynchrone
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
//TODO: ajouter une vérification de la mise à jour
}
41,17 → 45,24
}) ;
}
/**
* Met à jour la base de données avec les mots clés associés à l'image
* @param ic l'image à mettre à jour
*/
public void SynchroniserMotsClesImageBaseDeDonnees(final ImageCarnet ic)
{
String postData = "" ;
// on récupère les mots clés de l'image et on fabrique le post
String motsCles = ic.getMotsCles() ;
String id = ic.getId() ;
postData += "&ci_id_image="+id+"&ci_meta_mots_cles="+motsCles ;
 
// on envoie une requête asynchrone
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
//TODO: ajouter une vérification de la mise à jour
}
58,15 → 69,21
}) ;
}
/**
* Supprime une image de la base de données
* @param ic l'image à supprimer
*/
public void supprimerBaseDeDonnees(final ImageCarnet ic)
{
// le post contient l'action delete pour JREST (qui ne gère pas DELETE comme une requête à part entière)
String postData = "" ;
postData += "&action=DELETE" ;
// on envoie un post avec l'id de l'image à supprimer
HTTPRequest.asyncPost("jrest/inventoryImage/0/"+ic.getId(), postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
Window.alert(responseText) ;
//TODO: ajouter une vérification de la mise à jour
}
}) ;
/trunk/src/org/tela_botanica/client/modeles/ListeImageCarnet.java
4,23 → 4,38
import java.util.Vector;
 
/**
* vecteur composé d'ImageCarnet, renvoyé par les objets de type DAO
* pour les images
* table de hachage composée d'ImageCarnet, renvoyé par les objets de type DAO
* pour les images.
* La clé est l'identifiant de l'image dans la base de données, et la valeur un objet
* de type ImageCarnet.
* GWT ne supporte pas encore les type paramètres mais quand il le fera il faudra créer la HashMap
* avec <String,ImageCarnet>
* @author aurelien
*
*/
public class ListeImageCarnet extends HashMap {
/**
* Constructeur sans paramètres
*/
public ListeImageCarnet()
{
super();
}
/**
* Constructeur avec paramètre
* @param taille la taille de la table de hachage
*/
public ListeImageCarnet(int taille)
{
super(taille);
}
/**
* Constructeur avec paramètre
* @param ic un tableau d'ImageCarnet
*/
public ListeImageCarnet(ImageCarnet[] ic)
{
super() ;
/trunk/src/org/tela_botanica/client/modeles/ListeImageAsynchroneDAO.java
3,6 → 3,7
import java.util.Iterator;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.Rafraichissable;
 
import com.google.gwt.json.client.JSONArray;
28,18 → 29,31
*/
public class ListeImageAsynchroneDAO {
ImageMediateur iMediateur = null ;
/**
* Le modèle associé au DAO
*/
ImageModele iModele = null ;
public void setIMediateur(ImageMediateur im)
/**
* Setteur pour le modèle
* @param im le modèle à associer
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Envoie une requete au serveur jrest pour obtenir une liste d'images correspondant à des critères demandés
* @param r le rafraichissable qui a demandé les données
* @param criteres un tableau contenant les critères de selections
*/
public void ObtenirListeImages(final Rafraichissable r, String[][] criteres)
{
String requete = "" ;
// on construit les paramètres du get
if(criteres != null)
{
for (int i = 0; i < criteres.length; i++) {
52,12 → 66,16
}
}
// on envoie le get asynchrone
HTTPRequest.asyncGet("jrest/InventoryImageList/0/"+requete, new ResponseTextHandler() {
// si tout se passe bien on reçoit une réponse JSON
public void onCompletion(String responseText) {
final ListeImageCarnet photoData ;
 
final JSONValue responseValue = JSONParser.parse(responseText);
// si c'est un tableau
if (responseValue.isArray() != null) {
final JSONArray reponse = responseValue.isArray();
65,7 → 83,7
final int taillemax = reponse.size();
photoData = new ListeImageCarnet(taillemax);
// on le parcourt
for (int j = 0; j < taillemax ; j++) {
JSONObject image = (JSONObject)reponse.get(j) ;
72,6 → 90,7
ImageCarnet im = new ImageCarnet(image) ;
// et on en extrait les données pour construire la liste d'image
photoData.put(im.getOrdre(),im) ;
}
78,25 → 97,35
}
else
{
// si c'est un objet alors il n'y a qu'une réponse
if(responseValue.isObject() != null)
{
photoData = new ListeImageCarnet(1);
ImageCarnet im = new ImageCarnet(responseValue.isObject()) ;
// on crée une liste de 1 élement auquel on ajoute ce qui a été reçu
photoData.put(im.getOrdre(),im) ;
}
else
{
// sinon on crée une liste vide
photoData = new ListeImageCarnet(0) ;
}
}
// dans tous les cas on transmet la liste crée au rafraichissable en lui demandant de répandre les données car il est
// le premier à les recevoir
r.rafraichir(photoData,true);
}
});
}
/**
* Met à jour les valeurs d'une liste d'image donnée dans la base de données
* @param li la liste d'image à synchroniser avec la base
*/
public void SynchroniserBaseDeDonnees(ListeImageCarnet li)
{
// on parcourt toute la liste d'image
for(Iterator listIt = li.keySet().iterator() ; listIt.hasNext() ;)
{
String postData = "" ;
103,8 → 132,10
ImageCarnet enCours = (ImageCarnet)li.get(listIt.next()) ;
// pour chaque image on extrait les informations
for(Iterator imgIt = enCours.keySet().iterator();imgIt.hasNext();)
{
// qu'on place dans le poste
String key = (String)imgIt.next() ;
String valeur = enCours.renvoyerValeurCorrecte(key) ;
valeur.replaceAll("'", "\'") ;
112,9 → 143,11
}
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
// on fait un post asynchrone et on les envoie à jrest
HTTPRequest.asyncPost("jrest/inventoryImage/0/", postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
//TODO: vérifier mieux le succès del a requête
}
122,23 → 155,31
}
}
/**
* Supprime des image sur le serveur par rapport à leur identifant
* @param ids un tableau d'identifiants d'images à supprimer
*/
public void supprimerBaseDeDonnees(String[] ids)
{
String postData = "" ;
// on fait un delete dans le post (jrest ne gère pas delete comme une action à part entière)
postData += "&action=DELETE" ;
String uid = "" ;
// on concatène les ids
for (int i = 0; i < ids.length; i++) {
uid += ids[i]+"," ;
}
HTTPRequest.asyncPost("jrest/inventoryImageList/"+iMediateur.getIdentifiant()+"/"+uid, postData, new ResponseTextHandler() {
// et on envoie ça au serveur
HTTPRequest.asyncPost("jrest/inventoryImageList/"+iModele.getIdentifiant()+"/"+uid, postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
iMediateur.rafraichirToutesVues() ;
// quand la requête est éxecutée on le signale au modèle poru qu'il mette à jour les données
// et en notifie le médiateur
iModele.requeteTerminee() ;
}
}) ;
/trunk/src/org/tela_botanica/client/modeles/NombreImageAsynchroneDAO.java
1,6 → 1,7
package org.tela_botanica.client.modeles;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.Rafraichissable;
 
import com.google.gwt.json.client.JSONArray;
11,16 → 12,35
import com.google.gwt.user.client.HTTPRequest;
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
 
/**
* DAO qui renvoie le nombre d'image associées à différents critères donnés (utile pour la pagination)
* @author aurelien
*
*/
public class NombreImageAsynchroneDAO {
 
private ImageMediateur iMediateur = null ;
/**
* Le modèle associé au DAO
*/
private ImageModele iModele = null ;
public void setImediateur(ImageMediateur im)
/**
* Setteur pour le modèle
* @param im le modèlme à associer
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Envoie une requete au serveur jrest pour obtenir le nombre d'images correspondant
* à des critères données en paramètres
* @param r le rafraichissable qui demande la mise à jour
* @param criteres un tableau nom/valeur des critères pour les images
*/
public void obtenirNombreImages(final Rafraichissable r, String[][] criteres)
{
String requete = "" ;
27,6 → 47,7
if(criteres != null)
{
// on construit les paramètres du get avec les critères (&critere1=valeur1&critere2=valeur2 etc...)
for (int i = 0; i < criteres.length; i++) {
if(!criteres[i][0].equals("ci_ordre"))
44,17 → 65,21
}
}
HTTPRequest.asyncGet("jrest/InventoryImageCount/0/"+requete, new ResponseTextHandler() {
// on fait un get asynchrone
HTTPRequest.asyncGet("jrest/InventoryImageCount/"+iModele.getIdentifiant()+"/"+requete, new ResponseTextHandler() {
public void onCompletion(String responseText) {
final JSONValue responseValue = JSONParser.parse(responseText);
// si la requete se passe bien on reçoit un tableau JSON
if(responseValue.isArray() != null)
{
// qui contient une valeur : le nombre d'images correspondant au critères
JSONValue res = responseValue.isArray().get(0) ;
JSONString reponseNombre = res.isString() ;
int maxImages = (int)Integer.parseInt(reponseNombre.stringValue()) ;
int[] nbImages = {maxImages} ;
// on le met dans un tableau d'entiers qu'on tranmset au demandeur de la mise à jour
r.rafraichir(nbImages, true) ;
}
/trunk/src/org/tela_botanica/client/modeles/MotsClesAsynchroneDAO.java
1,42 → 1,54
package org.tela_botanica.client.modeles;
 
import java.util.HashMap;
import java.util.Iterator;
 
import org.tela_botanica.client.image.ImageMediateur;
import org.tela_botanica.client.image.ImageModele;
import org.tela_botanica.client.interfaces.Rafraichissable;
 
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.HTTPRequest;
import com.google.gwt.user.client.ResponseTextHandler;
import com.google.gwt.user.client.Window;
import com.gwtext.client.data.Node;
import com.gwtext.client.data.Tree;
import com.gwtext.client.widgets.tree.TreeNode;
 
/**
* DAO d'accès à l'arbre de mots clés
* @author aurelien
*
*/
public class MotsClesAsynchroneDAO {
private ImageMediateur iMediateur = null ;
/**
* Le modele associé au DAO
*/
private ImageModele iModele = null ;
public void setIMediateur(ImageMediateur im)
/**
* Setteur pour le modèle
* @param im le modèle à associer
*/
public void setIModele(ImageModele im)
{
iMediateur = im ;
iModele = im ;
}
/**
* Envoie une requete au serveur jrest pour obtenir l'arbre des mots clés
* @param r le rafraichissable qui demande les données
*/
public void obtenirListeMotsCles(final Rafraichissable r)
{
HTTPRequest.asyncGet("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant(), new ResponseTextHandler() {
// on demande tous les mots clés associés à l'utilisateur
HTTPRequest.asyncGet("jrest/InventoryKeyWordList/"+iModele.getIdentifiant(), new ResponseTextHandler() {
 
public void onCompletion(String responseText) {
final JSONValue responseValue = JSONParser.parse(responseText);
// si la requête est un succès on reçoit un tableau
if (responseValue.isArray() != null) {
final JSONArray reponse = responseValue.isArray();
 
// et on met à jour le demandeur des données
r.rafraichir(reponse, true) ;
}
}
43,7 → 55,10
});
}
/**
* Envoie requete au serveur jrest pour ajouter un mot clé
* @param motcle le mots clés à ajouter avec son parent et son identifiant
*/
public void ajouterBaseDeDonnees(String motcle)
{
if(!motcle.equals(""))
50,11 → 65,12
{
String postData = motcle ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/","&identifiant="+iMediateur.getIdentifiant()+postData, new ResponseTextHandler() {
// on fait un post asynchrone
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/","&identifiant="+iModele.getIdentifiant()+postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
// si on reçoit une erreur d'ajout, on affiche un message d'erreur
if(responseText.equals("ERROR"))
{
Window.alert("Attention, la base de données des mots clés n'est plus synchronisée avec l'application," +
66,6 → 82,10
}
}
/**
* Envoie requete au serveur jrest pour supprimer un mot clé
* @param motcle le mots clés à supprimer
*/
public void supprimerBaseDeDonnees(String motcle)
{
if(!motcle.equals(""))
73,7 → 93,7
String postData = "" ;
postData += "&action=DELETE" ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant()+"/"+motcle,postData, new ResponseTextHandler() {
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iModele.getIdentifiant()+"/"+motcle,postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
88,6 → 108,10
}
}
 
/**
* Envoie requete au serveur jrest pour modifier un mot clé
* @param motcle le mots clés à modifier avec son parent et son identifiant
*/
public void modifierBaseDeDonnees(String motcle) {
if(!motcle.equals(""))
96,7 → 120,7
String postData = "" ;
postData += "&action=modification"+motcle ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant() ,postData, new ResponseTextHandler() {
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iModele.getIdentifiant() ,postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {
108,6 → 132,10
}
/**
* Envoie requete au serveur jrest pour modifier un mot clé
* @param motcle le mots clés à ajouter avec son ancien parent, son nouveau et son identifiant
*/
public void deplacerBaseDeDonnees(String motcle) {
if(!motcle.equals(""))
116,7 → 144,7
String postData = "" ;
postData += "&action=deplacement"+motcle ;
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iMediateur.getIdentifiant() ,postData, new ResponseTextHandler() {
HTTPRequest.asyncPost("jrest/InventoryKeyWordList/"+iModele.getIdentifiant() ,postData, new ResponseTextHandler() {
public void onCompletion(String responseText) {