/trunk/src/org/tela_botanica/client/vues/BarreNotationVue.java |
---|
New file |
0,0 → 1,232 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.google.gwt.user.client.ui.ClickListener; |
import com.google.gwt.user.client.ui.Image; |
import com.google.gwt.user.client.ui.MouseListenerAdapter; |
import com.google.gwt.user.client.ui.Widget; |
import com.gwtext.client.widgets.Panel; |
/** |
* Une barre de notation avec des étoiles, tout ce qu'il ya de plus classique, |
* utilisant Ajax (et pas CSS) |
* @author aurelien |
* |
*/ |
public class BarreNotationVue extends Panel implements Rafraichissable { |
/** |
* Le médiateur associé |
*/ |
@SuppressWarnings("unused") |
private ImageMediateur iMediateur = null ; |
/** |
* La note actuellement affichée |
*/ |
private int noteEnCours = 0 ; |
/** |
* La note maximum |
*/ |
private int noteMax = 0 ; |
/** |
* Booléen indiquant si une note est affectée à la barre en ce moment |
*/ |
private boolean estNote = false ; |
/** |
* Tablmeau d'images contenant les étoiles affichées |
*/ |
private Image[] etoiles = null ; |
/** |
* Constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
@SuppressWarnings("unused") |
private BarreNotationVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec arguments |
* @param im le médiateur à associer à la vue |
* @param noteMax la note maximale |
*/ |
public BarreNotationVue(ImageMediateur im, int noteMax) |
{ |
iMediateur = im ; |
setNoteMax(noteMax) ; |
this.setSize(200, 100) ; |
this.setBodyBorder(false) ; |
this.setBorder(false) ; |
this.setCls("x-view-notation") ; |
ajouterListeners() ; |
} |
public void ajouterListeners() |
{ |
for (int i = 0; i < etoiles.length; i++) { |
etoiles[i].addMouseListener(new MouseListenerAdapter() { |
// si la souris passe sur la barre |
public void onMouseEnter(Widget sender) { |
Image enCours = (Image)sender ; |
// on met en surbrillance toutes les étoiles allant de la première jusqu'à |
// celle sous le curseur |
for(int i = 0 ; etoiles[i] != enCours ; i++) |
{ |
etoiles[i].setUrl("note-hover.gif") ; |
} |
enCours.setUrl("note-hover.gif") ; |
} |
// si la souris sort de la barre |
public void onMouseLeave(Widget sender) { |
// on affiche la véritable note |
afficherNote() ; |
} |
}) ; |
etoiles[i].addClickListener(new ClickListener() { |
// si on clique sur une étoiles |
public void onClick(Widget sender) { |
int i = 0 ; |
// on récupère le numéro de l'étoile sur laquelle on a cliqué |
while(etoiles[i] != (Image)sender) |
{ |
i++ ; |
} |
// et on affecte la note |
noter(i) ; |
} |
}) ; |
} |
} |
/** |
* Fonction héritée de l'interface rafraichissable |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRaffraichissement) { |
// si on recoit un tableau de string |
if(nouvelleDonnees instanceof String[]) |
{ |
// on récupère le premier élément (un entier, qui contient la note) |
String[] note = (String[])nouvelleDonnees ; |
int noteInt = Integer.parseInt(note[0]) ; |
// si l'entier est une note valide |
if(noteInt != -1 && noteInt >= 0) |
{ |
noter(noteInt) ; |
} |
// sinon si l'entier vaut -1 |
else |
{ |
// alors on note avec 0 |
// et on met le booleen de notation a false (qui signifie que l'image n'est pas encore notée) |
estNote = false ; |
noteEnCours = 0 ; |
// et demande l'affichage |
afficherNote() ; |
} |
} |
} |
/** |
* Affecte une note à la barre et rafraichit l'affichage |
* @param note la nouvelle note |
*/ |
public void noter(int note) |
{ |
// on affecte la note |
noteEnCours = note ; |
// on met le boolean de notation à true (l'image est notée) |
estNote = true ; |
// et on demande l'affichage |
afficherNote() ; |
} |
/** |
* Setteur pour la note maximale |
* @param nMax la nouvelle note maximale |
*/ |
public void setNoteMax(int nMax) |
{ |
// on affecte la note |
noteMax = nMax ; |
// on prépare le tableau d'image |
etoiles = new Image[noteMax] ; |
// qu'on remplit par defaut avec des images d'étoiles vides |
for(int i = 0 ; i < noteMax ; i++) |
{ |
etoiles[i] = new Image("etoile_vide.jpg") ; |
etoiles[i].setStylePrimaryName("x-view-notation-bar") ; |
this.add(etoiles[i]) ; |
} |
} |
/** |
* Affiche la note d'une image sous la forme d'étoiles |
*/ |
public void afficherNote() |
{ |
// si l'image est notée |
if(estNote) |
{ |
// on affiche autant d'étoiles que le chiffre de la note |
for(int i = 0 ; i <= noteEnCours ; i++) |
{ |
etoiles[i].setUrl("note-on.gif") ; |
} |
// et si elle est inférieure à la note maximale, on remplit le reste par des étoiles vides |
for (int j = noteEnCours + 1 ; j < noteMax ; j++) |
{ |
etoiles[j].setUrl("note-off.gif") ; |
} |
} |
// sinon |
else |
{ |
// on remplit toute la barre avec des étoiles vides |
for(int i = 0 ; i < noteMax ; i++) |
{ |
etoiles[i].setUrl("note-off.gif") ; |
} |
} |
} |
/** |
* Accesseur pour la note en cours sous forme de string |
* @return |
*/ |
public String getNote() |
{ |
return ""+noteEnCours ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/MenuImageVue.java |
---|
New file |
0,0 → 1,103 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.widgets.menu.BaseItem; |
import com.gwtext.client.widgets.menu.Item; |
import com.gwtext.client.widgets.menu.Menu; |
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter; |
/** |
* 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é) |
*/ |
@SuppressWarnings("unused") |
private MenuImageVue() |
{ |
super(); |
} |
/** |
* Constructeur avec paramètre |
* @param im le médiateur à associer |
*/ |
public MenuImageVue(ImageMediateur im) |
{ |
super() ; |
iMediateur = im ; |
// on construit le menu |
uploaderImage = new Item("Uploader des images") ; |
supprimerImage = new Item("Supprimer les images selectionnées") ; |
addItem(uploaderImage); |
addItem(supprimerImage) ; |
// on ajoute les listeners |
ajouterListeners() ; |
} |
/** |
* Ajoute les listeners pour la gestions des évènements |
*/ |
private void ajouterListeners() |
{ |
this.addListener(new MenuListenerAdapter() { |
// 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() ; |
} |
// si c'est la suppression |
if(item.equals(supprimerImage)) |
{ |
// on notifie le médiateur |
getIMediateur().supprimerImages() ; |
} |
// enfin, on cache le menu |
hide() ; |
} |
}) ; |
} |
/** |
* 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 |
---|
New file |
0,0 → 1,387 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.google.gwt.user.client.DOM; |
import com.google.gwt.user.client.Event; |
import com.google.gwt.user.client.ui.ClickListener; |
import com.google.gwt.user.client.ui.Image; |
import com.google.gwt.user.client.ui.Widget; |
import com.gwtext.client.core.RegionPosition; |
import com.gwtext.client.widgets.Container; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.event.PanelListenerAdapter; |
import com.gwtext.client.widgets.layout.BorderLayout; |
import com.gwtext.client.widgets.layout.BorderLayoutData; |
/** |
* Panneau d'affichage d'une image avec des boutons précdents et suivant |
* @author aurelien |
* |
*/ |
public class ZoomImageVue extends Panel implements Rafraichissable { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = 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é) |
*/ |
@SuppressWarnings("unused") |
private ZoomImageVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec argument |
* @param im le médiateur à associer à la vue |
*/ |
public ZoomImageVue(ImageMediateur im) |
{ |
super("Zoom"); |
setId("x-view-zoom-panel") ; |
// on associe le médiateur |
iMediateur = im ; |
prev.setStylePrimaryName("x-view-zoom-button-p") ; |
suiv.setStylePrimaryName("x-view-zoom-button-s") ; |
// on crée une image qui gère le double clic et la roulette de la souris |
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(); |
} |
// lors d'un déplacement de la roulette |
if (Event.ONMOUSEWHEEL == DOM.eventGetType(event)) { |
// on simule un clic sur le bouton précédent |
if(event.getMouseWheelVelocityY() >= 1) |
{ |
prev.click() ; |
} |
// ou suivant |
if(event.getMouseWheelVelocityY() <= -1) |
{ |
suiv.click() ; |
} |
} |
} |
}; |
this.setHeader(false) ; |
imageConteneur = new Panel() ; |
imageConteneur.setBorder(false); |
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); |
image.sinkEvents(Event.ONMOUSEWHEEL) ; |
// l'image de base est vide |
image.setUrl("vide.jpg"); |
this.setLayout(new BorderLayout()); |
prev.setWidth("60px"); |
suiv.setWidth("60px"); |
this.add(prev,new BorderLayoutData(RegionPosition.WEST)); |
this.add(imageConteneur,new BorderLayoutData(RegionPosition.CENTER)); |
this.add(suiv,new BorderLayoutData(RegionPosition.EAST)); |
imageConteneur.setMaskDisabled(true) ; |
this.setBorder(false); |
conteneurInitialise = true ; |
initialise = true ; |
// 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) { |
// si on reçoit une string |
if(nouvelleDonnees instanceof String[] && initialise && conteneurInitialise) |
{ |
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 |
{ |
// sinon on met une image vide |
getImage().setUrl("vide.jpeg") ; |
} |
} |
/** |
* Desactive visuellement le panneau et les boutons |
*/ |
public void desactiverPanneau() |
{ |
getImage().setUrl("vide.jpeg") ; |
prev.setEnabled(false) ; |
suiv.setEnabled(false); |
} |
/** |
* Active visuellement le panneau et les boutons |
*/ |
public void activerPanneau() |
{ |
prev.setEnabled(true); |
suiv.setEnabled(true); |
} |
/** |
* 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 ; |
}*/ |
// 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 ; |
} |
public Panel getImageConteneur() { |
return imageConteneur ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/BarreRechercheFiltreVue.java |
---|
New file |
0,0 → 1,158 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Filtrable; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.google.gwt.user.client.ui.Label; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.event.KeyListener; |
import com.gwtext.client.widgets.form.TextField; |
/** |
* Fenêtre de recherche pour les mots clés, contenant un champ texte, |
* et un bouton cliquable |
* @author aurelien |
* |
*/ |
public class BarreRechercheFiltreVue extends Panel implements Rafraichissable, Filtrable { |
/** |
* Médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = null ; |
/** |
* Barre de recherche |
* |
*/ |
private TextField champRecherche = null ; |
/** |
* Booleen d'etat du filtre |
*/ |
private boolean filtreModifie = false ; |
/** |
* mot(s) à chercher |
*/ |
private String motsAChercher = "" ; |
/** |
* Constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
@SuppressWarnings("unused") |
private BarreRechercheFiltreVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec médiateur |
* @param im |
*/ |
public BarreRechercheFiltreVue(ImageMediateur im) |
{ |
super() ; |
iMediateur = im ; |
Label labelRecherche = new Label("Commentaires :") ; |
champRecherche = new TextField() ; |
add(labelRecherche) ; |
add(champRecherche) ; |
setPaddings(5) ; |
setBorder(false) ; |
setAutoWidth(true) ; |
setCollapsible(true) ; |
ajouterListeners() ; |
} |
/** |
* ajoute des listeners |
*/ |
private void ajouterListeners() |
{ |
// gestion de la touche entrée |
champRecherche.addKeyListener(EventObject.ENTER, new KeyListener() { |
public void onKey(int key, EventObject e) { |
valider() ; |
getIMediateur().obtenirPhotoGalerie(getIMediateur().getFiltreCommentaires()) ; |
} |
}) ; |
} |
/** |
* Fonction héritée de l'interface rafraichissable |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRaffraichissement) { |
filtreModifie = false ; |
} |
/** |
* renvoie l'état du filtre (modifié ou non) |
* @return l'état du filtre |
*/ |
public boolean renvoyerEtatFiltre() { |
return filtreModifie ; |
} |
/** |
* Renvoie le nom du filtre |
* @return le nom du filtre |
*/ |
public String renvoyerNomFiltre() { |
return "Recherche Commentaires" ; |
} |
/** |
* Renvoie un tableau contenant le nom du champ à filtrer et la valeur |
* @return un tableau contenant le nom du champ à filtrer et sa valeur |
*/ |
public String[] renvoyerValeursAFiltrer() { |
String[] valeurFiltre = {"ci_meta_comment" , motsAChercher } ; |
return valeurFiltre ; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé |
*/ |
public ImageMediateur getIMediateur() |
{ |
return iMediateur ; |
} |
/** |
* Effectue quelque opérations dans la classe et envoie une requête de données |
* au médiateur |
*/ |
public void valider() |
{ |
filtreModifie = true ; |
motsAChercher = champRecherche.getText() ; |
} |
/** |
* Affiche la fenetre |
*/ |
public void afficherFiltre() { |
champRecherche.setValue(motsAChercher) ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/MenuFiltreVue.java |
---|
New file |
0,0 → 1,99 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.widgets.menu.BaseItem; |
import com.gwtext.client.widgets.menu.Item; |
import com.gwtext.client.widgets.menu.Menu; |
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter; |
public class MenuFiltreVue extends Menu { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur ; |
/** |
* Item pour la recherche par mots clés |
*/ |
private Item chercherImage = null ; |
/** |
* Item pour la recherche sur les commentaires |
*/ |
private Item chercherCommentaire = null ; |
/** |
* Constructeur sans argument (privé car ne doit être utilisé) |
*/ |
@SuppressWarnings("unused") |
private MenuFiltreVue() |
{ |
super(); |
} |
/** |
* Constructeur avec paramètre |
* @param im le médiateur à associer |
*/ |
public MenuFiltreVue(ImageMediateur im) |
{ |
super() ; |
iMediateur = im ; |
// on construit le menu |
chercherImage = new Item("Filtrer par les mots clés") ; |
chercherCommentaire = new Item("Filtrer par les commentaires") ; |
addItem(chercherImage) ; |
addItem(chercherCommentaire) ; |
// on ajoute les listeners |
ajouterListeners() ; |
} |
/** |
* Ajoute les listeners pour la gestions des évènements |
*/ |
private void ajouterListeners() |
{ |
this.addListener(new MenuListenerAdapter() { |
// gestion du clic sur un item |
public void onItemClick(BaseItem item, EventObject e) { |
// si c'est la recherche par mots clé |
if(item.equals(chercherImage)) |
{ |
// on notifie le médiateur |
// getIMediateur().afficherFiltreMotsCles() ; |
} |
// si c'est la recherche par commentaires |
if(item.equals(chercherCommentaire)) |
{ |
// on notifie le médiateur |
//getIMediateur().afficherFiltreCommentaires() ; |
} |
// enfin, on cache le menu |
hide() ; |
} |
}) ; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
public ImageMediateur getIMediateur() |
{ |
return iMediateur ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/PanneauMetadonneesVue.java |
---|
New file |
0,0 → 1,363 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.google.gwt.user.client.ui.Label; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.core.NameValuePair; |
import com.gwtext.client.widgets.Button; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.TabPanel; |
import com.gwtext.client.widgets.event.ButtonListenerAdapter; |
import com.gwtext.client.widgets.form.DateField; |
import com.gwtext.client.widgets.form.TextArea; |
import com.gwtext.client.widgets.form.TextField; |
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.VerticalLayout; |
/** |
* 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 ; |
/** |
* Barre de notation |
*/ |
BarreNotationVue noteVue = null ; |
/** |
* Booleen d'instanciation |
*/ |
boolean estInstancie = false ; |
/** |
* Constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
@SuppressWarnings("unused") |
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") ; |
panneauMotsCles = new ArbreMotsClesVue(im) ; |
panneauMotsCles.setHeight("500px") ; |
Panel sousPanneauInfosGenerales = new Panel("Infos Générales") ; |
sousPanneauInfosGenerales.setLayout(new VerticalLayout()); |
sousPanneauInfosGenerales.setBorder(false) ; |
sousPanneauInfosGenerales.setHeight(200); |
sousPanneauInfosGenerales.setAutoWidth(true) ; |
sousPanneauInfosGenerales.setMargins(5) ; |
sousPanneauInfosGenerales.setPaddings(5) ; |
sousPanneauInfosGenerales.setCollapsible(true) ; |
Label labelComm = new Label("Commentaires :") ; |
labelComm.setHeight("20px") ; |
commentaireGeneral = new TextArea() ; |
commentaireGeneral.setWidth("90%") ; |
Label labelDate = new Label("Date :") ; |
Label labelNote = new Label("Note :") ; |
panneauMotsCles.setBorder(false) ; |
labelDate.setHeight("20px") ; |
dateImage = new DateField() ; |
dateImage.setAutoWidth(true) ; |
dateImage.setFormat("d/m/Y") ; |
validerInfo = new Button("OK") ; |
noteVue = new BarreNotationVue(im, 5) ; |
sousPanneauInfosGenerales.add(labelComm) ; |
sousPanneauInfosGenerales.add(commentaireGeneral) ; |
sousPanneauInfosGenerales.add(labelDate) ; |
sousPanneauInfosGenerales.add(dateImage) ; |
sousPanneauInfosGenerales.add(labelNote) ; |
sousPanneauInfosGenerales.add(noteVue) ; |
sousPanneauInfosGenerales.add(validerInfo) ; |
sousPanneauInfosGenerales.setAutoHeight(true); |
panneauMotsCles.setAutoHeight(true) ; |
panneauInfoGrid.setBorder(false); |
panneauInfoGrid.setAutoHeight(true); |
panneauInfoGrid.add(sousPanneauInfosGenerales) ; |
panneauInfoGrid.add(panneauMotsCles) ; |
this.add(panneauInfoGrid) ; |
this.add(panneauExifGrid) ; |
this.add(panneauIptcGrid) ; |
gViewExif = new GridView(); |
gViewExif.setForceFit(true); |
ExifGrid = new PropertyGridPanel() ; |
ExifGrid.setId("meta_exif"); |
ExifGrid.setView(gViewExif); |
ExifGrid.setNameText("Métadonnées Exif"); |
ExifGrid.setAutoWidth(true); |
ExifGrid.setAutoHeight(true); |
ExifGrid.setSorted(false); |
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) { |
button.focus() ; |
// lors du clic sur le bouton valider on met à jour les commentaires et la date |
getIMediateur().mettreAJourInfo(commentaireGeneral.getText(), dateImage.getRawValue(), noteVue.getNote()) ; |
} |
}); |
// 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() ; |
} |
// 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() ; |
} |
}) ; |
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() ; |
} |
// 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() ; |
} |
}) ; |
} |
/** |
* 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] ; |
String[][] gen = (String[][])meta[2] ; |
NameValuePair[] exifSource = new NameValuePair[exif.length] ; |
NameValuePair[] iptcSource = new NameValuePair[iptc.length] ; |
int maxLength ; |
if(exif.length <= iptc.length) |
{ |
maxLength = iptc.length ; |
} |
else |
{ |
maxLength = exif.length ; |
} |
for(int i = 0; i < maxLength ; i++) |
{ |
if(i < exif.length && !exif[i][0].equals("null")) |
{ |
exifSource[i] = new NameValuePair(exif[i][0],exif[i][1]) ; |
} |
if(i < iptc.length && !iptc[i][0].equals("null")) |
{ |
iptcSource[i] = new NameValuePair(iptc[i][0],iptc[i][1]) ; |
} |
} |
// on met à jour les champs avec la bonne valeur |
commentaireGeneral.setValue(gen[0][1]) ; |
dateImage.setRawValue(gen[1][1]) ; |
// et on met à jour les données pour l'affichage |
ExifGrid.setSource(exifSource); |
IptcGrid.setSource(iptcSource); |
} |
} |
/** |
* Accesseur pour le panneau des mots clés |
* @return the panneauMotsCles |
*/ |
public ArbreMotsClesVue getPanneauMotsCles() { |
return panneauMotsCles; |
} |
public BarreNotationVue getNoteVue() { |
return noteVue ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/ArbreMotsClesFiltreVue.java |
---|
New file |
0,0 → 1,338 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Filtrable; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.google.gwt.user.client.ui.Label; |
import com.gwtext.client.data.Node; |
import com.gwtext.client.data.NodeTraversalCallback; |
import com.gwtext.client.data.Tree; |
import com.gwtext.client.widgets.Component; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.event.PanelListenerAdapter; |
import com.gwtext.client.widgets.tree.TreeNode; |
import com.gwtext.client.widgets.tree.TreePanel; |
/** |
* fenêtre de recherche affichant l'arbre des mots clés en lecture et un bouton |
* cliquable |
* @author aurelien |
* |
*/ |
public class ArbreMotsClesFiltreVue extends Panel implements Rafraichissable, Filtrable { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = null ; |
/** |
* Les mots clés en cours |
*/ |
private String motsClesEncours = "" ; |
/** |
* Le treepanel qui affiche l'arbre |
*/ |
private TreePanel arbreMotsCles = null ; |
/** |
* booléen d'initialisation |
*/ |
private boolean estInstancie = false ; |
/** |
* booléen d'etat |
*/ |
private boolean filtreModifie = false ; |
/** |
* Constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
@SuppressWarnings("unused") |
private ArbreMotsClesFiltreVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec paramètres |
* @param im le médiateur à associer |
*/ |
public ArbreMotsClesFiltreVue(ImageMediateur im) |
{ |
// on crée le panel |
super() ; |
//this.setLayout(new VerticalLayout()); |
iMediateur = im ; |
// on crée le conteneur de l'arbre |
Label labelRecherche = new Label("Mots clés :") ; |
arbreMotsCles = new TreePanel() ; |
this.setPaddings(5) ; |
this.setBorder(false) ; |
this.setCollapsible(true) ; |
this.setAutoWidth(true) ; |
add(labelRecherche) ; |
// on ajoute les listeners |
ajouterListenersPanel() ; |
estInstancie = false ; |
} |
/** |
* Ajoute les listeners pour le rendu du panel |
*/ |
private void ajouterListenersPanel() |
{ |
this.addListener(new PanelListenerAdapter() { |
// on instancie réellement les composants au moment du rendu pour accélérer l'affichage |
// et éviter des bugs |
public void onRender(Component component) { |
// on interdit le drag and drop dans l'arbre |
arbreMotsCles.setEnableDD(false) ; |
arbreMotsCles.setId("x-view-tree-filter") ; |
arbreMotsCles.setAutoWidth(false) ; |
arbreMotsCles.setAutoScroll(true) ; |
arbreMotsCles.setBorder(false) ; |
// on crée une racine pour l'arbre |
TreeNode root = new TreeNode("Tags") ; |
root.setId("racine_filtre") ; |
String[] usObject = {"Mots clés" , "racine" } ; |
root.setUserObject(usObject) ; |
arbreMotsCles.setRootNode(root) ; |
arbreMotsCles.setRootVisible(true) ; |
arbreMotsCles.setBorder(false) ; |
// on met en forme le layout |
((Panel)component).add(arbreMotsCles) ; |
// on ajoute les listeners d'évenements |
ajouterListeners() ; |
// et on demande l'arbre des mots clés |
getIMediateur().obtenirArbreMotsCles(getIMediateur().getPanneauFiltres().getMotsClesFiltre()) ; |
// enfin on considère le composant comme instancié |
estInstancie = true ; |
} |
}) ; |
} |
/** |
* ajoute les listeners pour les boutons et le cochage des mots clés |
*/ |
private void ajouterListeners() |
{ |
} |
/** |
* Méthode héritée de l'interface rafraichissable |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRaffraichissement) { |
// si on a reçu un arbre |
if(nouvelleDonnees instanceof Tree) |
{ |
Tree nouvelArbre = (Tree)nouvelleDonnees ; |
// on vide tous les noeuds |
arbreMotsCles.getRootNode().eachChild(new NodeTraversalCallback() { |
public boolean execute(Node node) { |
node.remove() ; |
return true ; |
} |
}) ; |
// et on recopie le nouvel arbre |
copierFilsNoeud(nouvelArbre.getRootNode(), arbreMotsCles.getRootNode()) ; |
// si l'arbre n'était pas encore considéré comme instancié |
if(!estInstancie) |
{ |
// on signale que oui |
estInstancie = true ; |
} |
// l'état du filtre est réinitialisé |
filtreModifie = false ; |
show() ; |
} |
if(nouvelleDonnees instanceof TreeNode) |
{ |
TreeNode nd = (TreeNode)nouvelleDonnees ; |
// si le noeud n'existe pas déjà c'est un ajout |
if(arbreMotsCles.getTree().getNodeById(nd.getId()+"_filtre") == null) |
{ |
// donc on ne fait rien de spécial |
} |
// si le noeud existe déjà c'est un déplacement |
else |
{ |
// alors on supprime d'abord le noeud concerné |
arbreMotsCles.getTree().getNodeById(nd.getId()+"_filtre").remove() ; |
} |
// on cherche le père du nouveau noeud |
Node ndPereOriginal = nd.getParentNode() ; |
String idPereFiltre = ndPereOriginal.getId()+"_filtre" ; |
String[] usObj = (String[])nd.getUserObject() ; |
TreeNode child = new TreeNode(usObj[0]) ; |
child.setId(usObj[1]+"_filtre") ; |
child.setChecked(false); |
child.setUserObject(usObj) ; |
arbreMotsCles.getNodeById(idPereFiltre).appendChild(child) ; |
// et on ajoute le nouveau noeud à son père |
copierFilsNoeud(nd, child) ; |
} |
// si on reçoit une string |
if(nouvelleDonnees instanceof String) |
{ |
String idSupp = (String)nouvelleDonnees+"_filtre" ; |
// c'est une suppression et si le noeud existe bien |
if(arbreMotsCles.getTree().getNodeById(idSupp) != null) |
{ |
// on le supprime |
arbreMotsCles.getTree().getNodeById(idSupp).remove() ; |
} |
} |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé |
*/ |
public ImageMediateur getIMediateur() |
{ |
return iMediateur ; |
} |
/** |
* Accesseur pour le panneau contenant l'arbre |
* @return le panneau de l'arbre des mots clés |
*/ |
public TreePanel getArbreMotsCles() |
{ |
return arbreMotsCles ; |
} |
/** |
* Méthode héritée de Filtrable |
* renvoie le nom du filtre |
*/ |
public String renvoyerNomFiltre() { |
return "mots clés" ; |
} |
/** |
* Renvoie un tableau contenant le nom du champ à filtrer et la valeur |
* @return un tableau contenant le nom du champ à filtrer et sa valeur |
*/ |
public String[] renvoyerValeursAFiltrer() { |
valider() ; |
String[] valeursFiltrees = {"ci_meta_mots_cles",motsClesEncours} ; |
return valeursFiltrees ; |
} |
/** |
* 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]+"_filtre") ; |
child.setChecked(false); |
child.setUserObject(usObj) ; |
ndPereCopie.appendChild(child) ; |
if(! ndNodeFils[i].isLeaf()) |
{ |
copierFilsNoeud(ndNodeFils[i],child) ; |
} |
} |
} |
} |
/** |
* Méthode héritée de Filtrable |
* Renvoie l'état du filtre (modifié ou non) |
*/ |
public boolean renvoyerEtatFiltre() { |
return filtreModifie ; |
} |
public void valider() |
{ |
if(estInstancie) |
{ |
// 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 ; |
} |
}); |
// on suppose que le filtre a change |
filtreModifie = true ; |
} |
} |
} |
/trunk/src/org/tela_botanica/client/vues/BarreOutilsVue.java |
---|
New file |
0,0 → 1,91 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import com.gwtext.client.widgets.Toolbar; |
import com.gwtext.client.widgets.ToolbarMenuButton; |
/** |
* Barre d'outils contenant le menu de gestion des images (accessible aussi par un clic droit dans la galerie) |
* et d'autres menus et boutons utiles |
* @author aurelien |
* |
*/ |
public class BarreOutilsVue extends Toolbar { |
/** |
* Un bouton qui sert à déployer le menu |
*/ |
ToolbarMenuButton images = null ; |
/** |
* Un bouton qui sert à déployer le menu |
*/ |
ToolbarMenuButton utilisateur = null ; |
/** |
* Le médiateur associé à la toolbar |
*/ |
ImageMediateur iMediateur = null ; |
/** |
* Le menu de gestion des images |
*/ |
MenuImageVue imageMenu = null ; |
/** |
* Le menu de gestion des filtres |
*/ |
MenuFiltreVue filtreMenu = null ; |
/** |
* Le menu de gestion utilisateur |
*/ |
MenuIdVue idMenu = null ; |
/** |
* Constructeur sans argument (ne doit pas être utilisé donc privé) |
*/ |
@SuppressWarnings("unused") |
private BarreOutilsVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec paramètres |
* @param im le médiateur à associer à la vue |
*/ |
public BarreOutilsVue(ImageMediateur im) { |
super() ; |
iMediateur = im ; |
imageMenu = new MenuImageVue(im) ; |
filtreMenu = new MenuFiltreVue(im) ; |
idMenu = new MenuIdVue(im) ; |
images = new ToolbarMenuButton("Fichiers",imageMenu) ; |
utilisateur = new ToolbarMenuButton("Utilisateur",idMenu) ; |
this.addButton(images) ; |
this.addButton(utilisateur) ; |
} |
/** |
* @return the images |
*/ |
public ToolbarMenuButton getImages() { |
return images; |
} |
/** |
* @return the iMediateur |
*/ |
public ImageMediateur getIMediateur() { |
return iMediateur; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/GalerieImageVue.java |
---|
New file |
0,0 → 1,309 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import org.tela_botanica.client.interfaces.VueListable; |
import com.google.gwt.user.client.Element; |
import com.google.gwt.user.client.Window; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.core.XTemplate; |
import com.gwtext.client.data.FieldDef; |
import com.gwtext.client.data.IntegerFieldDef; |
import com.gwtext.client.data.Record; |
import com.gwtext.client.data.RecordDef; |
import com.gwtext.client.data.Store; |
import com.gwtext.client.data.StringFieldDef; |
import com.gwtext.client.util.Format; |
import com.gwtext.client.widgets.Component; |
import com.gwtext.client.widgets.DataView; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.event.ContainerListenerAdapter; |
import com.gwtext.client.widgets.event.DataViewListenerAdapter; |
/** |
* Galerie d'images miniatures |
* Avec barre de pagination |
* @author aurelien |
*/ |
public class GalerieImageVue extends Panel implements Rafraichissable, VueListable { |
/** |
* instance du médiateur |
*/ |
private ImageMediateur iMediateur = null; |
/** |
* Dataview, littéralement "vue de données" qui permet de définir la manière d'afficher les données |
*/ |
private DataView dView = null; |
/** |
* Dataview, littéralement "vue de données" qui permet de définir la manière d'afficher les données |
*/ |
private Store st = null; |
/** |
* Barre de pagination gérant l'affichage d'un nombre donné d'élements par page et la navigation entre eux |
*/ |
private pageToolBarVue pt = null ; |
/** |
* Booleen indiquant si la galerie est instanciée ou pas |
*/ |
private boolean estInstancie = false ; |
/** |
* Constructeur sans argument, privé car ne doit pas être utilisé |
*/ |
@SuppressWarnings("unused") |
private GalerieImageVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec argument |
* @param im le médiateur avec lequel la vue va communiquer |
*/ |
public GalerieImageVue(ImageMediateur im) { |
super("Galerie"); |
iMediateur = im; |
// on ajoute des listeners au composant tout entier |
this.addListener(new ContainerListenerAdapter() { |
// pour gagner du temps on n'instancie la vue en elle même que lors du premier affichage (lazy rendering) |
public void onShow(Component component) { |
if (!estInstancie) { |
initialiser(); |
} |
} |
}); |
// et on ajoute la tool bar |
pt = new pageToolBarVue(im) ; |
this.setBottomToolbar(pt) ; |
} |
/** |
* Ajoute tous les listeners nécessaires à l'intercation utilisateur avec la vue de données |
*/ |
public void ajouterListenersDataView() { |
// ajout de listeners pour la gestion de la selection |
// dans la galerie |
dView.addListener(new DataViewListenerAdapter() { |
// gestion du clic sur une image |
public void onClick(DataView source, int index, Element node, |
EventObject e) { |
// on en notifie le médiateur |
getIMediateur().clicGalerieImage(index, node, e); |
} |
// gestion du clic droit |
public void onContextMenu(DataView source, int index, Element node, |
EventObject e) { |
// on stoppe l'évenement |
e.stopEvent(); |
// et on notifie le médiateur |
getIMediateur().montrerContextMenu(e); |
} |
// gestion du double clic |
public void onDblClick(DataView source, int index, Element node, |
EventObject e) { |
// on notife le mediateur |
getIMediateur().clicGalerieImage(index, node, e); |
} |
// gestion des actions en fonction de la selection |
public void onSelectionChange(DataView view, Element[] selections) { |
// s'il n'y a aucun élement sélectionné |
if (selections.length <= 0) { |
// on en notifie le médiateur |
getIMediateur().aucuneSelection(); |
} else { |
// sinon on notifie le médiateur |
getIMediateur().selection(); |
// et on lui demande de synchroniser la séléction avec les autres vues |
getIMediateur().synchroniserSelection("galerie"); |
} |
} |
}); |
} |
/** |
* Accesseur pour la dataview |
* @return la dataview |
*/ |
public DataView getDView() { |
return dView; |
} |
/** |
* Renvoie les ids des images sélectionnées |
* @return un tableau de String contenant les identifiants des images sélectionnées |
*/ |
public String[] getIdSelectionnees() { |
Record[] selection = getDView().getSelectedRecords(); |
int taille = selection.length; |
String id_selection[] = new String[taille]; |
for (int i = 0; i < selection.length; i++) { |
id_selection[i] = selection[i].getAsString("num_image"); |
} |
return id_selection; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
public ImageMediateur getIMediateur() { |
return iMediateur; |
} |
/** |
* Accesseur pour le store |
* @return le store associé à la vue |
*/ |
public Store getSt() { |
return st; |
} |
/** |
* Accesseur pour la toolbar |
* @return la toolbar associée à la vue |
*/ |
public pageToolBarVue getToolBarVue() |
{ |
return pt ; |
} |
/** |
* Fonction d'initialisation du contenu (appelée lors du premier affichage de la liste) |
*/ |
public void initialiser() { |
// Preparation de la dataview et du template |
// le template va créer une div contenant une image |
// pour chacune des photos |
final XTemplate template = new XTemplate( |
new String[] { |
"<tpl for='.'>", |
"<div class='thumb-wrap' id='{num_image}'>", |
"<div class='thumb'><img src='{url_image_M}' title='{num_image}'></div>", |
"<span>{nom}</span></div>", "</tpl>", |
"<div class='x-clear'></div>" }); |
// pour des raisons de performances on compile le template en une fonction |
template.compile(); |
// la dataview affichera les images en accord avec le template |
// cree precedemment |
dView = new DataView("div.thumb-wrap") { |
public void prepareData(Data data) { |
data.setProperty("shortName", Format.ellipsis(data |
.getProperty("num_image"), 15)); |
} |
}; |
dView.setTpl(template); |
// parametre d'affichage de la dataview |
this.setAutoScroll(true); |
dView.setAutoHeight(true); |
dView.setMultiSelect(true); |
dView.setOverCls("x-view-over"); |
dView.setEmptyText("Aucune image à afficher"); |
// creation du store |
FieldDef defNumImage = new IntegerFieldDef("num_image"); |
FieldDef defDatImage = new StringFieldDef("dat_image"); |
FieldDef defLieImage = new StringFieldDef("lie_image"); |
FieldDef defAppImage = new StringFieldDef("app_image"); |
FieldDef defUrlImageS = new StringFieldDef("url_image_S"); |
FieldDef defUrlImageM = new StringFieldDef("url_image_M"); |
FieldDef defUrlImage = new StringFieldDef("url_image"); |
FieldDef[] defTab = { defNumImage, defDatImage, defLieImage, |
defAppImage, defUrlImageS, defUrlImageM, defUrlImage }; |
RecordDef rd = new RecordDef(defTab); |
st = new Store(rd); |
dView.setStore(st); |
this.getDView().setLoadingText("chargement"); |
// ajouts de la gestion des evenements pour la dataview |
ajouterListenersDataView(); |
this.add(dView); |
// enfin on envoie une demande de données au médiateur |
getIMediateur().obtenirPhotoGalerie(this); |
// et on déclare le composant comme instancié |
estInstancie = true ; |
} |
/** |
* Méthode héritée de l'interface rafraichissable |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRafraichissement) { |
// si l'objet reçu est un store |
if (nouvelleDonnees instanceof Store) { |
st = (Store) nouvelleDonnees; |
// on le charge |
st.load(); |
// on l'affecte à la vue |
dView.setStore(st); |
// et on rafrachit la vue |
dView.refresh(); |
} |
// si le composant doit répandre le rafraichissement |
if (repandreRafraichissement) { |
// 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 |
*/ |
public void selectionnerImages(int[] ids) { |
getDView().select(ids); |
} |
} |
/trunk/src/org/tela_botanica/client/vues/pageToolBarVue.java |
---|
New file |
0,0 → 1,410 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.gwtext.client.core.EventCallback; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.core.Template; |
import com.gwtext.client.data.Record; |
import com.gwtext.client.data.SimpleStore; |
import com.gwtext.client.data.Store; |
import com.gwtext.client.widgets.Button; |
import com.gwtext.client.widgets.Toolbar; |
import com.gwtext.client.widgets.ToolbarButton; |
import com.gwtext.client.widgets.ToolbarTextItem; |
import com.gwtext.client.widgets.event.ButtonListenerAdapter; |
import com.gwtext.client.widgets.form.ComboBox; |
import com.gwtext.client.widgets.form.Field; |
import com.gwtext.client.widgets.form.TextField; |
import com.gwtext.client.widgets.form.event.ComboBoxListenerAdapter; |
import com.gwtext.client.widgets.form.event.TextFieldListenerAdapter; |
/** |
* Barre de pagination asynchrone avec filtrage des touches et accès directs et séquentiels à une page |
* @author aurelien |
* |
*/ |
public class pageToolBarVue extends Toolbar implements Rafraichissable { |
/** |
* Instance du médiateur à qui on notifie les évnènements |
*/ |
private ImageMediateur iMediateur = null ; |
/** |
* Bouton précédent |
*/ |
private ToolbarButton prevPage = new ToolbarButton() ; |
/** |
* Bouton suivant |
*/ |
private ToolbarButton suivPage = new ToolbarButton() ; |
/** |
* Numéro de la page courante (attention, commence à zéro pour des raisons pratiques) |
*/ |
private int pageCourante = 0 ; |
/** |
* Nombre de page total |
*/ |
private int pageTotale = 1 ; |
/** |
* Nombre d'élements total |
*/ |
private int nbElement = 0 ; |
/** |
* Nombre d'élément par page |
*/ |
private int taillePage = 0 ; |
/** |
* Texte statique de la toolbar 1 |
*/ |
private ToolbarTextItem page = new ToolbarTextItem("Page ") ; |
/** |
* Affichage de la page courante |
*/ |
private TextField champPage = new TextField(""+(pageCourante+1)) ; |
/** |
* Affichage de "sur pageTotale " |
*/ |
private ToolbarTextItem surTotalPage = new ToolbarTextItem(" sur "+pageTotale) ; |
/** |
* Texte statique de la toolbar 2 |
*/ |
private ToolbarTextItem afficherNbElem = new ToolbarTextItem("Afficher ") ; |
/** |
* Combobox permettant de selectionner le nombre d'élements à afficher par page |
* et donc de changer la variable taillePage |
*/ |
private ComboBox selecteurTaillePage = new ComboBox() ; |
/** |
* Texte statique de la toolbar 3 |
*/ |
private ToolbarTextItem nbElemParPage = new ToolbarTextItem(" images par page ") ; |
/** |
* Affiche l'intervalle des éléments contenus dans la page |
*/ |
private ToolbarTextItem intervalleElements = new ToolbarTextItem("Images "+pageCourante*taillePage+" sur "+nbElement) ; |
/** |
* retourne le mediateur associe à la barre |
*/ |
public ImageMediateur getImediateur() |
{ |
return iMediateur ; |
} |
/*** |
* constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
@SuppressWarnings("unused") |
private pageToolBarVue() |
{ |
super() ; |
} |
/** |
* constructeur avec paramètres |
* @param im le médiateur à associer à la barre |
*/ |
public pageToolBarVue(ImageMediateur im) |
{ |
super() ; |
iMediateur = im ; |
// on dispose un peu de texte et quelques espaces pour séparer les éléments |
addButton(prevPage) ; |
addSpacer() ; |
addItem(page) ; |
addField(champPage) ; |
addItem(surTotalPage) ; |
addSpacer() ; |
addButton(suivPage) ; |
champPage.setWidth(30) ; |
addSpacer() ; |
addItem(afficherNbElem) ; |
prevPage.setIcon("page_prev.png") ; |
suivPage.setIcon("page_suiv.png") ; |
// le store contient les valeur possibles pour les tailles de page |
final Store store = new SimpleStore(new String[]{"nb_page"}, getNbPages()); |
store.load(); |
// le template definit ce que l'on affiche pour chaque element du store dans la combobox |
final Template tp = new Template("<div class=\"x-combo-list-item\">" |
+ "{nb_page}" |
+ "<div class=\"x-clear\"></div></div>"); |
tp.compile(); |
selecteurTaillePage.setTpl(tp) ; |
selecteurTaillePage.setStore(store) ; |
selecteurTaillePage.setWidth(40) ; |
selecteurTaillePage.setEditable(false) ; |
addField(selecteurTaillePage) ; |
selecteurTaillePage.setValue("50") ; |
selecteurTaillePage.setWidth(50) ; |
addItem(nbElemParPage) ; |
// on remplit l'espace pour que l'intervalle d'élement se place à droite de la barre |
addFill() ; |
addItem(intervalleElements) ; |
addSpacer() ; |
// on ajoute les différents listeners |
ajouterListeners() ; |
} |
/** |
* ajoute les différents listeners nécessaires au bon fonctionnement des éléments de la barre de pagination |
*/ |
private void ajouterListeners() |
{ |
// boutons suivants et précédents |
prevPage.addListener(new ButtonListenerAdapter() { |
public void onClick(Button button, EventObject e) { |
// si la page courante n'est pas la première |
if(pageCourante > 0) |
{ |
// on décrémente la page courante de 1 |
pageCourante -- ; |
// on rafraichit l'affichage |
rafraichirNumeroPage() ; |
// et on notifie le médiateur de l'évenement |
getImediateur().changerNumeroPage(pageCourante) ; |
} |
} |
}) ; |
suivPage.addListener(new ButtonListenerAdapter() { |
public void onClick(Button button, EventObject e) { |
// si la page courante n'est pas la dernière |
if(pageCourante < pageTotale -1) |
{ |
// on incrémente la page courante de 1 |
pageCourante ++ ; |
// on rafraichit l'affichage |
rafraichirNumeroPage() ; |
// et on notifie le médiateur de l'évenement |
getImediateur().changerNumeroPage(pageCourante) ; |
} |
} |
}) ; |
champPage.addListener(new TextFieldListenerAdapter() { |
public void onSpecialKey(Field field, EventObject e) { |
// on teste si la touche entrée a été pressée |
if(e.getKey() == EventObject.ENTER) |
{ |
int nouvellePage = pageCourante ; |
// on teste avec parseInt si la valeur entrée est un entier |
try |
{ |
nouvellePage = Integer.parseInt(champPage.getRawValue()) ; |
} |
// si ce n'est pas le cas alors on remet le numéro de page correct |
catch(NumberFormatException nfe) |
{ |
rafraichirNumeroPage() ; |
champPage.focus(true) ; |
return ; |
} |
// si la conversion reussit on verifie s'il est nécessaire de changer de page |
// et si la nouvelle est comprise dans l'intervalle des pages existantes (0..pageTotale) |
if(nouvellePage != pageCourante + 1 && nouvellePage > 0 && nouvellePage <= pageTotale) |
{ |
// le cas échéant, on charge la nouvelle page et on notifie le médiateur |
changerPageCourante(nouvellePage - 1) ; |
getImediateur().changerNumeroPage(pageCourante) ; |
} |
else |
{ |
// sinon on reaffiche l'ancien numero de page sans rien changer |
rafraichirNumeroPage() ; |
champPage.focus(true) ; |
} |
} |
} |
public void onFocus(Field field) { |
champPage.focus(true) ; |
} |
}); |
// pour éviter de se compliquer la vie, on filtre tous les charactères non numériques |
champPage.addKeyPressListener(new EventCallback() { |
public void execute(EventObject e) { |
// si c'est un numerique |
if(Character.isDigit((char)e.getCharCode())) |
{ |
// on laisse passer |
return ; |
} |
// si c'est la touche entrée ou backspace (valider ou effacer) |
if(e.getKey() == EventObject.ENTER || e.getKey() == EventObject.BACKSPACE) |
{ |
// on laisse passer |
return ; |
} |
else |
{ |
// sinon on remet le numero de page correct et on annule l'évenement |
rafraichirNumeroPage() ; |
e.stopEvent() ; |
} |
} |
}) ; |
// listener pour la selection dans la combobox |
selecteurTaillePage.addListener(new ComboBoxListenerAdapter() { |
public void onSelect(ComboBox comboBox, Record record, int index) { |
String nouvelleTaillePageString = comboBox.getStore().getRecordAt(index).getAsString("nb_page") ; |
int nouvelleTaillePage = Integer.parseInt(nouvelleTaillePageString) ; |
// si la taille de page est différente de l'ancienne |
if(nouvelleTaillePage != taillePage) |
{ |
// on la change |
changerTaillePage(nouvelleTaillePage) ; |
} |
// et on met la valeur à jour dans la combobox |
comboBox.setValue(nouvelleTaillePageString) ; |
} |
}) ; |
} |
/** |
* Met à jour les affichage sur les numéros de pages et d'intervalle d'éléments |
* à partir des variables de classes |
*/ |
public void rafraichirNumeroPage() |
{ |
surTotalPage.setText(" sur "+pageTotale) ; |
if(nbElement == 0) |
{ |
champPage.setValue(""+(0)) ; |
// on met simplement à jour l'intervalle qui contient toujours le même nombre d'éléments |
intervalleElements.setText("Images 0 - 0 sur 0") ; |
} |
else |
{ |
champPage.setValue(""+(pageCourante+1)) ; |
// si la page n'est pas la dernière |
if(pageCourante + 1 != pageTotale) |
{ |
// sauf pour la dernière page qui contient souvent moins d'élements que le nombre d'élements par page |
intervalleElements.setText("Images "+pageCourante*taillePage+" - "+(pageCourante+1)*taillePage+" sur "+nbElement) ; |
} |
else |
{ |
// on met simplement à jour l'intervalle qui contient toujours le même nombre d'éléments |
intervalleElements.setText("Images "+pageCourante*taillePage+" - "+nbElement+" sur "+nbElement) ; |
} |
} |
} |
/** |
* Met à jour la page en cours |
* @param nouvellePageCourante la nouvelle page en cours |
*/ |
public void changerPageCourante(int nouvellePageCourante) |
{ |
pageCourante = nouvellePageCourante ; |
} |
/** |
* Methode héritée de l'interface rafraichissable |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRaffraichissement) { |
// si on reçoit un tableau de int |
if(nouvelleDonnees instanceof int[]) |
{ |
int [] page = (int[])nouvelleDonnees ; |
// le premier élement est le nombre de pages totales |
pageTotale = page[0] ; |
// le second la page en cours |
pageCourante = page[1] ; |
// le troisième la taille de la page |
taillePage = page[2] ; |
// et le dernier le nombre total d'éléments |
nbElement = page[3] ; |
// si la page courante dépasse la page totale (cas normalement improbable car géré en amont) |
// on met le numéro de page à la page courante -1 (car la page courante est comptée à partir |
// de zéro) |
if(pageCourante >= pageTotale && pageCourante != 0) |
{ |
pageCourante = pageTotale - 1 ; |
// le cas échéant on en notifie le médiateur |
getImediateur().changerNumeroPage(pageCourante) ; |
} |
} |
// enfin on rafraichit les informations affichées à partir des nouvelles variables de classes mises à jour |
rafraichirNumeroPage() ; |
} |
/** |
* Renvoie les différents intervalles de pages possibles |
* @return un tableau de tableau de string qui contient les différentes taille de pages |
*/ |
public String[][] getNbPages() |
{ |
String[][] pages = {{"200"},{"100"},{"50"},{"20"},{"10"}} ; |
return pages ; |
} |
/** |
* Envoie au médiateur une demande pour modifier la taille de la page |
* (qui va à son tour faire les modifications nécessaires) |
* @param nouvelleTaillePage la nouvelle taille de page (élement appartenant au tableau renvoyé par getNbPages()) |
*/ |
public void changerTaillePage(int nouvelleTaillePage) { |
getImediateur().changerTaillePage(nouvelleTaillePage) ; |
} |
/** |
* Selectionne la valeur correspond à celle passée en paramètre dans la combobox (si elle existe) |
* @param nouvelleTaillePage la nouvelle taille de page |
*/ |
public void selectionnerTaillePage(int nouvelleTaillePage) { |
selecteurTaillePage.setValue(""+nouvelleTaillePage) ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/MenuIdVue.java |
---|
New file |
0,0 → 1,86 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.widgets.menu.BaseItem; |
import com.gwtext.client.widgets.menu.Item; |
import com.gwtext.client.widgets.menu.Menu; |
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter; |
public class MenuIdVue extends Menu { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur ; |
/** |
* Item pour le changement d'utilisateur |
*/ |
private Item changerId = null ; |
/** |
* Constructeur sans argument (privé car ne doit être utilisé) |
*/ |
@SuppressWarnings("unused") |
private MenuIdVue() |
{ |
super(); |
} |
/** |
* Constructeur avec paramètre |
* @param im le médiateur à associer |
*/ |
public MenuIdVue(ImageMediateur im) |
{ |
super() ; |
iMediateur = im ; |
// on construit le menu |
changerId = new Item("Changer d'utilisateur") ; |
addItem(changerId) ; |
// on ajoute les listeners |
ajouterListeners() ; |
} |
/** |
* Ajoute les listeners pour la gestions des évènements |
*/ |
private void ajouterListeners() |
{ |
this.addListener(new MenuListenerAdapter() { |
// gestion du clic sur un item |
public void onItemClick(BaseItem item, EventObject e) { |
// si c'est la recherche par commentaires |
if(item.equals(changerId)) |
{ |
// on notifie le médiateur |
getIMediateur().afficherMenuId() ; |
} |
// enfin, on cache le menu |
hide() ; |
} |
}) ; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
public ImageMediateur getIMediateur() |
{ |
return iMediateur ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/DateFiltreVue.java |
---|
New file |
0,0 → 1,148 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Filtrable; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.google.gwt.user.client.ui.Label; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.form.DateField; |
/** |
* Classe implémentant un filtre qui permet de rechercher une aimge par rapport à la date associée, |
* des critères plus fins viendront compléter cela |
* @author aurelien |
* |
*/ |
public class DateFiltreVue extends Panel implements Rafraichissable, Filtrable { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = null ; |
/** |
* Le widget calendrier |
*/ |
private DateField filtreDate = null ; |
/** |
* Booleen d'état du filtre |
*/ |
private boolean filtreModifie = false ; |
/** |
* Constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
@SuppressWarnings("unused") |
private DateFiltreVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec arguments |
* @param im le médiateur à associer |
*/ |
public DateFiltreVue(ImageMediateur im) |
{ |
super() ; |
setPaddings(5) ; |
setCollapsible(true) ; |
setBorder(false) ; |
iMediateur = im ; |
Label labelRecherche = new Label("Date :") ; |
add(labelRecherche) ; |
// on crée le calendrier et on définit le format de la date "jj/mm/aaaa" |
filtreDate = new DateField() ; |
filtreDate.setAutoWidth(true) ; |
filtreDate.setFormat("d/m/Y") ; |
add(filtreDate); |
ajouterListeners() ; |
} |
/** |
* Ajoute les listeners |
*/ |
public void ajouterListeners() |
{ |
} |
/** |
* Méthode héritée de l'interface rafraichissable |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRaffraichissement) { |
filtreModifie = false ; |
} |
/** |
* Méthode héritée de l'interface filtrable |
*/ |
public void valider() { |
filtreModifie = true ; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
@SuppressWarnings("unused") |
private ImageMediateur getIMediateur() { |
return iMediateur ; |
} |
/** |
* Méthode héritée de l'interface filtrable |
*/ |
public boolean renvoyerEtatFiltre() { |
return filtreModifie ; |
} |
/** |
* Méthode héritée de l'interface filtrable |
*/ |
public String renvoyerNomFiltre() { |
return "Recherche par date" ; |
} |
/** |
* Méthode héritée de l'interface filtrable |
*/ |
public String[] renvoyerValeursAFiltrer() { |
// si la date est valide |
if(filtreDate.isValid()) |
{ |
// on en sépare les composants |
String dt = filtreDate.getRawValue() ; |
String[] dates = dt.split("/") ; |
if(dates.length == 3) |
{ |
// qu'on réassemble dans un autre format (américain) pour la base de donnée "aaaa-mm-jj" |
String dateFormatee = dates[2]+"-"+dates[1]+"-"+dates[0] ; |
String[] valeursFiltres = {"ci_meta_date" , dateFormatee } ; |
return valeursFiltres ; |
} |
} |
// si la date n'estp as valide on renvoie une chaine vide (ce qui correspond à n'importe qu'elle date) |
String dateFormatee = "" ; |
String[] valeursFiltres = {"ci_meta_date" , dateFormatee } ; |
return valeursFiltres ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/ListeImageVue.java |
---|
New file |
0,0 → 1,437 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import org.tela_botanica.client.interfaces.VueListable; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.data.FieldDef; |
import com.gwtext.client.data.IntegerFieldDef; |
import com.gwtext.client.data.Record; |
import com.gwtext.client.data.RecordDef; |
import com.gwtext.client.data.Store; |
import com.gwtext.client.data.StringFieldDef; |
import com.gwtext.client.widgets.Component; |
import com.gwtext.client.widgets.event.ContainerListenerAdapter; |
import com.gwtext.client.widgets.grid.CellMetadata; |
import com.gwtext.client.widgets.grid.ColumnConfig; |
import com.gwtext.client.widgets.grid.ColumnModel; |
import com.gwtext.client.widgets.grid.GridPanel; |
import com.gwtext.client.widgets.grid.Renderer; |
import com.gwtext.client.widgets.grid.RowSelectionModel; |
import com.gwtext.client.widgets.grid.event.GridRowListener; |
import com.gwtext.client.widgets.grid.event.RowSelectionListenerAdapter; |
/** |
* Liste d'image composée de miniatures et d'information sur l'image, implémente |
* l'interface rafraichissable et l'interface vueListable |
* |
* @author aurelien |
*/ |
public class ListeImageVue extends GridPanel implements Rafraichissable, |
VueListable { |
/** |
* 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; |
/** |
* Config de colonne |
*/ |
private ColumnConfig noteImage; |
/** |
* Modele de colonnes |
*/ |
private ColumnModel modeleColonnes; |
/** |
* Booleen d'instanciation |
*/ |
private boolean estInstancie = false; |
/** |
* 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) { |
new ListeImageVue() ; |
this.setId("listeImageGrid"); |
// on associe le médiateur |
this.iMediateur = im; |
// on place la barre de pagination |
bt = new pageToolBarVue(iMediateur); |
setBottomToolbar(bt) ; |
// on construit le modèle de colonnes |
numImage = new ColumnConfig("numéro", "num_image", 30, true, new Renderer() { |
public String render(Object value, CellMetadata cellMetadata, |
Record record, int rowIndex, int colNum, Store store) { |
String ImgNum = record.getAsString("num_image"); |
return "<div class=\"centered-list\">"+ ImgNum +"</div>"; |
} |
}) ; |
datImage = new ColumnConfig("date", "dat_image", 120, true, new Renderer() { |
public String render(Object value, CellMetadata cellMetadata, |
Record record, int rowIndex, int colNum, Store store) { |
String ImgDat = record.getAsString("dat_image"); |
if(ImgDat == null) |
{ |
ImgDat = " " ; |
} |
return "<div class=\"centered-list\">"+ ImgDat +"</div>"; |
} |
}) ; |
lieImage = new ColumnConfig("lieu", "lie_image", 120, true, new Renderer() { |
public String render(Object value, CellMetadata cellMetadata, |
Record record, int rowIndex, int colNum, Store store) { |
String ImgLie = record.getAsString("lie_image"); |
if(ImgLie == null) |
{ |
ImgLie = " " ; |
} |
return "<div class=\"centered-list\">"+ ImgLie +"</div>"; |
} |
}) ; |
appImage = new ColumnConfig("appareil", "app_image", 120, true, new Renderer() { |
public String render(Object value, CellMetadata cellMetadata, |
Record record, int rowIndex, int colNum, Store store) { |
String ImgApp = record.getAsString("app_image"); |
if(ImgApp == null) |
{ |
ImgApp = " " ; |
} |
return "<div class=\"centered-list\">"+ ImgApp +"</div>"; |
} |
}) ; |
// la colonne url possède une méthode de rendu spéciale |
urlImage = new ColumnConfig("Image", "url_image_S", 30, true, |
new Renderer() { |
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 centered-list\"> <img src=\"" + ImgUrl |
+ "\" title='" + ImgNum + "'> </div>"; |
} |
}); |
noteImage = new ColumnConfig("note", "note_image", 80, true, |
new Renderer() |
{ |
public String render(Object value, CellMetadata cellMetadata, |
Record record, int rowIndex, int colNum, Store store) { |
String htmlImage = "" ; |
int noteImg = record.getAsInteger("note_image") ; |
if(noteImg >= 0) |
{ |
htmlImage += "<div class=\"img-note centered-list\">" ; |
for(int i = 0 ; i <= noteImg ; i++) |
{ |
htmlImage += "<img src=\"note-on.gif\">" ; |
} |
htmlImage += "</div>" ; |
} |
return htmlImage ; |
} |
}) ; |
// on associe le modèle de colonnes |
ColumnConfig[] cm = {numImage, urlImage, datImage, lieImage, appImage, noteImage}; |
modeleColonnes = new ColumnModel(cm); |
this.setColumnModel(modeleColonnes); |
this.setAutoScroll(true); |
this.setAutoWidth(true); |
this.setEnableColumnResize(true); |
// creation du store |
FieldDef defNumImage = new IntegerFieldDef("num_image"); |
FieldDef defDatImage = new StringFieldDef("dat_image"); |
FieldDef defLieImage = new StringFieldDef("lie_image"); |
FieldDef defAppImage = new StringFieldDef("app_image"); |
FieldDef defUrlImageS = new StringFieldDef("url_image_S"); |
FieldDef defUrlImageM = new StringFieldDef("url_image_M"); |
FieldDef defUrlImage = new StringFieldDef("url_image"); |
FieldDef defNoteImage = new StringFieldDef("note_image"); |
FieldDef[] defTab = { defNumImage, defDatImage, defLieImage, |
defAppImage, defUrlImageS, defUrlImageM, defUrlImage, defNoteImage }; |
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(); |
} |
/** |
* Ajoute les listeners pour la gestion des évènements |
*/ |
private void ajouterListeners() { |
this.addListener(new ContainerListenerAdapter() { |
public void onHide(Component component) { |
} |
// 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()) { |
setEstInstancie(true); |
getIMediateur().synchroniserSelection("galerie"); |
} |
} |
public void onShow(Component component) { |
} |
}); |
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); |
} |
}); |
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"); |
} |
} |
}); |
} |
/** |
* 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; |
String id_selection[] = new String[taille]; |
for (int i = 0; i < selection.length; i++) { |
id_selection[i] = selection[i].getAsString("num_image"); |
} |
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; |
} |
/** |
* Accesseur pour le store |
* @return le store contenant les données |
*/ |
public Store getSt() { |
return st; |
} |
/** |
* 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()) { |
getSelectionModel().clearSelections(); |
getSelectionModel().selectRecords(sel); |
} |
} |
/** |
* Accesseur pour la toolbar de pagination |
* @return la toolbar de pagination |
*/ |
public pageToolBarVue getToolBarVue() |
{ |
return bt ; |
} |
/** |
* Setteur pour le booleen d'instanciation |
* @param estInstancie la nouvelle valeur du booleen |
*/ |
public void setEstInstancie(boolean estInstancie) { |
this.estInstancie = estInstancie; |
} |
public void mettreAjourInfos(String commentaires, String date, String note) { |
for (int i = 0; i < getSelectionModel().getCount(); i++) { |
getSelectionModel().getSelections()[i].set("note_image", note) ; |
getSelectionModel().getSelections()[i].set("dat_image", date) ; |
} |
} |
} |
/trunk/src/org/tela_botanica/client/vues/PanneauFiltresVues.java |
---|
New file |
0,0 → 1,128 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.widgets.Button; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.event.ButtonListenerAdapter; |
import com.gwtext.client.widgets.layout.VerticalLayout; |
/** |
* Panneau contenant les filtres qu'on peut appliquer aux images |
* @author aurelien |
* |
*/ |
public class PanneauFiltresVues extends Panel { |
/** |
* Le médiateur associé |
*/ |
@SuppressWarnings("unused") |
private ImageMediateur iMediateur = null ; |
/** |
* L'arbre pour la recherche par mots clés |
*/ |
private ArbreMotsClesFiltreVue motsClesFiltres = null ; |
/** |
* La barre de recherche par commentaires |
*/ |
private BarreRechercheFiltreVue commFiltresVues = null ; |
/** |
* Recherche par date |
*/ |
private DateFiltreVue dateFiltreVues = null ; |
/** |
* Bouton de validation |
*/ |
private Button valider = null ; |
/** |
* Construcuteur sans argument (privé car on ne doit pas l'utiliser) |
*/ |
@SuppressWarnings("unused") |
private PanneauFiltresVues() |
{ |
super() ; |
} |
/** |
* Constructeur avec arguments |
* @param im le médiateur à associer |
*/ |
public PanneauFiltresVues(ImageMediateur im) |
{ |
super("Rechercher des images") ; |
iMediateur = im ; |
this.setCollapsible(true) ; |
setLayout(new VerticalLayout()) ; |
commFiltresVues = new BarreRechercheFiltreVue(im) ; |
add(commFiltresVues) ; |
dateFiltreVues = new DateFiltreVue(im) ; |
add(dateFiltreVues) ; |
motsClesFiltres = new ArbreMotsClesFiltreVue(im) ; |
add(motsClesFiltres) ; |
Panel panelValidation = new Panel() ; |
valider = new Button("Rechercher") ; |
panelValidation.add(valider) ; |
panelValidation.setBorder(false) ; |
add(panelValidation) ; |
valider.addListener(new ButtonListenerAdapter() { |
public void onClick(Button button, EventObject e) { |
iMediateur.obtenirPhotoGalerie(iMediateur.getGalerieImage()) ; |
} |
}) ; |
} |
/** |
* Accesseur pour le filtre des mots clés |
* @return le filtre des mots clés |
*/ |
public ArbreMotsClesFiltreVue getMotsClesFiltre() |
{ |
return motsClesFiltres ; |
} |
/** |
* Accesseur pour le filtre par commentaire |
* @return le filtre des commentaires |
*/ |
public BarreRechercheFiltreVue getBarreRecherche() |
{ |
return commFiltresVues ; |
} |
/** |
* Renvoie un booléen indiquant si un des filtres a été modifié |
* @return true sur un des filtres est modifié, false sinon |
*/ |
public boolean renvoyerEtatFiltre() { |
return (motsClesFiltres.renvoyerEtatFiltre() || commFiltresVues.renvoyerEtatFiltre() || dateFiltreVues.renvoyerEtatFiltre() ) ; |
} |
/** |
* Renvoie un tableau à 2 niveaux contenant des paires "nom_de_filtre", "valeur" |
* @return un tableau contenant les noms et les valeurs à filtrer |
*/ |
public String[][] renvoyerValeursAFiltrer() |
{ |
String[][] filtres = { motsClesFiltres.renvoyerValeursAFiltrer(), commFiltresVues.renvoyerValeursAFiltrer() , dateFiltreVues.renvoyerValeursAFiltrer() } ; |
return filtres ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/ArbreMotsClesVue.java |
---|
New file |
0,0 → 1,466 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
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.Panel; |
import com.gwtext.client.widgets.event.ButtonListenerAdapter; |
import com.gwtext.client.widgets.form.TextField; |
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.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) |
*/ |
@SuppressWarnings("unused") |
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 VerticalLayout()); |
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) ; |
arbreMotsCles.setId("x-view-tree-keyword") ; |
// on crée une racine pour l'arbre |
TreeNode root = new TreeNode("Tags") ; |
root.setId("racine") ; |
String[] usObject = {"Mots clés" , "racine" } ; |
root.setUserObject(usObject) ; |
arbreMotsCles.setRootNode(root) ; |
arbreMotsCles.setRootVisible(false) ; |
arbreMotsCles.setBorder(false) ; |
arbreMotsCles.setWidth(500) ; |
// on crée l'éditeur pour l'arbre |
tfEdit = new TextField() ; |
tfEdit.setAutoWidth(true) ; |
te = new TreeEditor(arbreMotsCles,tfEdit) ; |
valider = new Button("Appliquer") ; |
arbreMotsCles.add(te) ; |
// on met en forme le layout |
this.add(arbreMotsCles) ; |
this.add(valider) ; |
this.setBorder(false) ; |
this.setCollapsible(true) ; |
this.setTitleCollapse(true) ; |
// on ajoute les listeners |
ajouterListeners() ; |
} |
/** |
* Acesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
private ImageMediateur GetIMediateur() { |
return iMediateur ; |
} |
/** |
* Acesseur pour l'arbre des mots clés |
* @return le panel contenant l'arbre |
*/ |
public TreePanel getArbreMotsCles() { |
return arbreMotsCles; |
} |
/** |
* Accesseur pour l'éditeur |
* @return l'éditeur associé à l'arbre |
*/ |
public TreeEditor getTe() { |
return te; |
} |
/** |
* Acesseur pour le TextField associé à l'éditeur |
* @return le champ texte associé à l'éditeur |
*/ |
public TextField getTfEdit() { |
return tfEdit; |
} |
/** |
* Ajoute les listeners nécessaires pour la gestion des évènements |
*/ |
private void ajouterListeners() |
{ |
arbreMotsCles.addListener(new TreePanelListenerAdapter() { |
// gestion du clic sur un noeud |
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() ; |
GetIMediateur().montrerContextMenuArbre(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 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 |
{ |
if(modifNoeud) |
{ |
// 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 ; |
} |
} |
} |
// 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 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 |
GetIMediateur().mettreAjourMotsCles(motsClesEnCours,arbreMotsCles.getTree()) ; |
} |
}) ; |
} |
/** |
* Envoie une demande au médiateur pour obtenir l'arbre des mots clés |
*/ |
public void obtenirArbreMotsCles() { |
GetIMediateur().obtenirArbreMotsCles(this) ; |
} |
/** |
* Supprime un noeud de l'arbre |
* @param n le noeud à supprimer |
*/ |
public void supprimerNoeud(TreeNode n) |
{ |
// si ça n'est pas la racine (qu'on ne peut pas supprimer) |
if(!n.getId().equals(getArbreMotsCles().getRootNode().getId())) |
{ |
// 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.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) { |
// 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) ; |
return true ; |
} |
getArbreMotsCles().getNodeById(node.getId()).getUI().toggleCheck(false) ; |
} |
// 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) { |
// si on a reçu un arbre |
if(nouvelleDonnees instanceof Tree) |
{ |
Tree nouvelArbre = (Tree)nouvelleDonnees ; |
if(nouvelArbre.getRootNode().getChildNodes().length <= 0) |
{ |
// on crée une racine pour l'arbre |
TreeNode root = new TreeNode("Tags") ; |
root.setId("racine") ; |
String[] usObject = {"Mots clés" , "racine" } ; |
root.setUserObject(usObject) ; |
} |
// 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() ; |
} |
getArbreMotsCles().getRootNode().appendChild(nouvelArbre.getRootNode()) ; |
// 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 |
//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) ; |
} |
// si l'arbre n'est pas encore instancié on met les mots clés en attente |
else |
{ |
motsClesEnAttente = (String[])nouvelleDonnees ; |
} |
} |
} |
private String genererIdMotCle(TreeNode nd) |
{ |
return ""+(nd.hashCode()+(Math.random()*10000)) ; |
} |
} |