Subversion Repositories eFlore/Applications.cel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 aperonnet 1
package org.tela_botanica.client.vues;
2
 
3
import org.tela_botanica.client.image.ImageMediateur;
4
import org.tela_botanica.client.interfaces.Filtrable;
5
import org.tela_botanica.client.interfaces.Rafraichissable;
155 aurelien 6
import org.tela_botanica.client.observation.ObservationMediateur;
2 aperonnet 7
 
8
import com.google.gwt.user.client.ui.Label;
155 aurelien 9
import com.gwtext.client.core.EventObject;
2 aperonnet 10
import com.gwtext.client.data.Node;
11
import com.gwtext.client.data.NodeTraversalCallback;
12
import com.gwtext.client.data.Tree;
155 aurelien 13
import com.gwtext.client.widgets.Button;
2 aperonnet 14
import com.gwtext.client.widgets.Component;
15
import com.gwtext.client.widgets.Panel;
155 aurelien 16
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
2 aperonnet 17
import com.gwtext.client.widgets.event.PanelListenerAdapter;
155 aurelien 18
import com.gwtext.client.widgets.layout.RowLayout;
19
import com.gwtext.client.widgets.layout.RowLayoutData;
2 aperonnet 20
import com.gwtext.client.widgets.tree.TreeNode;
21
import com.gwtext.client.widgets.tree.TreePanel;
155 aurelien 22
import com.gwtext.client.widgets.tree.event.TreeNodeListenerAdapter;
2 aperonnet 23
 
24
/**
5 aperonnet 25
 * fenêtre de recherche affichant l'arbre des mots clés en lecture et un bouton
2 aperonnet 26
 * cliquable
5 aperonnet 27
 *
2 aperonnet 28
 * @author aurelien
5 aperonnet 29
 *
2 aperonnet 30
 */
5 aperonnet 31
public class ArbreMotsClesFiltreVue extends Panel implements Rafraichissable,
32
		Filtrable {
2 aperonnet 33
 
34
	/**
35
	 * Le médiateur associé à la vue
36
	 */
5 aperonnet 37
	private ImageMediateur iMediateur = null;
155 aurelien 38
 
2 aperonnet 39
	/**
155 aurelien 40
	 * Le médiateur associé à la vue
41
	 */
42
	private ObservationMediateur oMediateur = null;
43
 
44
	/**
2 aperonnet 45
	 * Les mots clés en cours
46
	 */
5 aperonnet 47
	private String motsClesEncours = "";
48
 
2 aperonnet 49
	/**
50
	 * Le treepanel qui affiche l'arbre
51
	 */
155 aurelien 52
	private static TreePanel arbreMotsCles = null;
5 aperonnet 53
 
2 aperonnet 54
	/**
55
	 * booléen d'initialisation
56
	 */
5 aperonnet 57
	private boolean estInstancie = false;
155 aurelien 58
 
59
	private boolean arbreInitialise = false;
5 aperonnet 60
 
2 aperonnet 61
	/**
62
	 * booléen d'etat
63
	 */
5 aperonnet 64
	private boolean filtreModifie = false;
155 aurelien 65
 
66
	/**
67
	 * prefixe pour générer des ids adaptées
68
	 */
69
	private String prefixe = "_filtre" ;
70
 
71
	private final String prefixeImg = "_images" ;
72
 
73
	private final String prefixeObs = "_obs" ;
5 aperonnet 74
 
2 aperonnet 75
	/**
76
	 * Constructeur sans argument (privé car ne doit pas être utilisé)
77
	 */
78
	@SuppressWarnings("unused")
5 aperonnet 79
	private ArbreMotsClesFiltreVue() {
80
		super();
2 aperonnet 81
	}
5 aperonnet 82
 
2 aperonnet 83
	/**
84
	 * Constructeur avec paramètres
5 aperonnet 85
	 *
86
	 * @param im
87
	 *            le médiateur à associer
2 aperonnet 88
	 */
5 aperonnet 89
	public ArbreMotsClesFiltreVue(ImageMediateur im) {
90
 
2 aperonnet 91
		// on crée le panel
5 aperonnet 92
		super();
93
		iMediateur = im;
155 aurelien 94
		this.prefixe += prefixeImg;
168 aurelien 95
		Label labelRecherche = new Label("Par mots clés :");
155 aurelien 96
		add(labelRecherche);
97
		initialiserPanel();
98
	}
99
 
100
	/**
101
	 * Constructeur avec paramètres
102
	 *
103
	 * @param im
104
	 *            le médiateur à associer
105
	 */
106
	public ArbreMotsClesFiltreVue(ObservationMediateur om) {
5 aperonnet 107
 
155 aurelien 108
		// on crée le panel
109
		super();
110
		oMediateur = om;
111
		this.prefixe += prefixeObs;
112
		initialiserPanel();
113
 
114
		this.setLayout(new RowLayout());
115
 
116
	}
117
 
118
	public void initialiserPanel() {
2 aperonnet 119
		// on crée le conteneur de l'arbre
5 aperonnet 120
		arbreMotsCles = new TreePanel();
155 aurelien 121
		arbreMotsCles.setId("x-view-tree-filter"+prefixe);
5 aperonnet 122
 
77 jpm 123
		// on crée une racine pour l'arbre
124
		TreeNode root = new TreeNode("Tags");
155 aurelien 125
		root.setId("racine"+prefixe);
126
		String[] usObject = { "Mots clés", "racine" };
77 jpm 127
		root.setUserObject(usObject);
155 aurelien 128
 
129
		root.setExpandable(true);
130
 
77 jpm 131
		arbreMotsCles.setRootNode(root);
132
 
155 aurelien 133
		arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() {
134
 
135
			public void onClick(Node node, EventObject e) {
136
				if(!arbreInitialise) {
137
					expand();
138
				}
139
			}
140
 
141
			public void onExpand(Node node) {
142
				if(!arbreInitialise) {
143
					obtenirArbreMotsCles();
144
					arbreInitialise = true;
145
				}
146
			}
147
 
148
		});
149
 
5 aperonnet 150
		this.setPaddings(5);
151
 
152
		this.setBorder(false);
153
		this.setCollapsible(true);
154
		this.setAutoWidth(true);
155
 
2 aperonnet 156
		// on ajoute les listeners
5 aperonnet 157
		ajouterListenersPanel();
158
		estInstancie = false;
2 aperonnet 159
	}
5 aperonnet 160
 
2 aperonnet 161
	/**
162
	 * Ajoute les listeners pour le rendu du panel
163
	 */
5 aperonnet 164
	private void ajouterListenersPanel() {
2 aperonnet 165
		this.addListener(new PanelListenerAdapter() {
166
 
5 aperonnet 167
			// on instancie réellement les composants au moment du rendu pour
168
			// accélérer l'affichage
2 aperonnet 169
			// et éviter des bugs
170
			public void onRender(Component component) {
5 aperonnet 171
 
2 aperonnet 172
				// on interdit le drag and drop dans l'arbre
5 aperonnet 173
				arbreMotsCles.setEnableDD(false);
174
				arbreMotsCles.setAutoWidth(false);
175
				arbreMotsCles.setAutoScroll(true);
176
				arbreMotsCles.setBorder(false);
177
 
155 aurelien 178
				// on met en forme le layout
179
				((Panel) component).add(arbreMotsCles,new RowLayoutData("80%"));
180
 
181
				if(iMediateur == null) {
182
					Panel p = new Panel();
183
					p.setBorder(false);
184
					Button valider = new Button("Rechercher") ;
185
					valider.addListener(new ButtonListenerAdapter() {
186
 
187
						public void onClick(Button button, EventObject e) {
188
							getOMediateur().obtenirNombreObservation();
189
						}
190
 
191
					});
192
					p.add(valider,new RowLayoutData());
193
					add(p);
58 jpm 194
				}
5 aperonnet 195
 
2 aperonnet 196
				// on ajoute les listeners d'évenements
5 aperonnet 197
				ajouterListeners();
155 aurelien 198
				//obtenirArbreMotsCles();
2 aperonnet 199
			}
155 aurelien 200
 
5 aperonnet 201
		});
2 aperonnet 202
	}
5 aperonnet 203
 
2 aperonnet 204
	/**
205
	 * ajoute les listeners pour les boutons et le cochage des mots clés
5 aperonnet 206
	 */
207
	private void ajouterListeners() {
135 aurelien 208
 
2 aperonnet 209
	}
5 aperonnet 210
 
2 aperonnet 211
	/**
212
	 * Méthode héritée de l'interface rafraichissable
213
	 */
214
	public void rafraichir(Object nouvelleDonnees,
215
			boolean repandreRaffraichissement) {
5 aperonnet 216
 
2 aperonnet 217
		// si on a reçu un arbre
5 aperonnet 218
		if (nouvelleDonnees instanceof Tree) {
219
			Tree nouvelArbre = (Tree) nouvelleDonnees;
155 aurelien 220
 
135 aurelien 221
			// on vide tous les noeuds de l'ancien arbre
222
			Node[] rootChild = arbreMotsCles.getRootNode().getChildNodes();
223
			for (int i = 0; i < rootChild.length; i++) {
224
 
225
				rootChild[i].remove();
226
			}
5 aperonnet 227
 
228
			// et on recopie le nouvel arbre
229
			copierFilsNoeud(nouvelArbre.getRootNode(), arbreMotsCles
230
					.getRootNode());
231
 
232
			// si l'arbre n'était pas encore considéré comme instancié
233
			if (!estInstancie) {
234
				// on signale que oui
235
				estInstancie = true;
236
			}
135 aurelien 237
 
155 aurelien 238
			if(!arbreInitialise) {
239
				arbreInitialise = true;
240
			}
241
 
135 aurelien 242
			arbreMotsCles.setRootNode(arbreMotsCles.getRootNode());
5 aperonnet 243
 
244
			// l'état du filtre est réinitialisé
245
			filtreModifie = false;
155 aurelien 246
			doLayout() ;
2 aperonnet 247
		}
5 aperonnet 248
 
249
		if (nouvelleDonnees instanceof TreeNode) {
250
			TreeNode nd = (TreeNode) nouvelleDonnees;
251
 
2 aperonnet 252
			// si le noeud n'existe pas déjà c'est un ajout
155 aurelien 253
			if (arbreMotsCles.getTree().getNodeById(nd.getId() +prefixe) == null) {
2 aperonnet 254
				// donc on ne fait rien de spécial
255
			}
256
			// si le noeud existe déjà c'est un déplacement
5 aperonnet 257
			else {
2 aperonnet 258
				// alors on supprime d'abord le noeud concerné
155 aurelien 259
				arbreMotsCles.getTree().getNodeById(nd.getId() +prefixe)
5 aperonnet 260
						.remove();
2 aperonnet 261
			}
5 aperonnet 262
 
135 aurelien 263
			// on chercher le père du nouveau noeud
5 aperonnet 264
			Node ndPereOriginal = nd.getParentNode();
135 aurelien 265
 
266
 
155 aurelien 267
			String idPereFiltre = ndPereOriginal.getId() +prefixe;
5 aperonnet 268
 
269
			String[] usObj = (String[]) nd.getUserObject();
270
			TreeNode child = new TreeNode(usObj[0]);
155 aurelien 271
			child.setId(usObj[1] +prefixe);
2 aperonnet 272
			child.setChecked(false);
5 aperonnet 273
			child.setUserObject(usObj);
274
			arbreMotsCles.getNodeById(idPereFiltre).appendChild(child);
275
 
2 aperonnet 276
			// et on ajoute le nouveau noeud à son père
5 aperonnet 277
			copierFilsNoeud(nd, child);
58 jpm 278
			this.doLayout();
2 aperonnet 279
		}
5 aperonnet 280
 
2 aperonnet 281
		// si on reçoit une string
5 aperonnet 282
		if (nouvelleDonnees instanceof String) {
155 aurelien 283
			String idSupp = (String) nouvelleDonnees +prefixe;
2 aperonnet 284
			// c'est une suppression et si le noeud existe bien
5 aperonnet 285
			if (arbreMotsCles.getTree().getNodeById(idSupp) != null) {
2 aperonnet 286
				// on le supprime
5 aperonnet 287
				arbreMotsCles.getTree().getNodeById(idSupp).remove();
2 aperonnet 288
			}
58 jpm 289
 
2 aperonnet 290
		}
5 aperonnet 291
 
2 aperonnet 292
	}
5 aperonnet 293
 
2 aperonnet 294
	/**
295
	 * Accesseur pour le médiateur
5 aperonnet 296
	 *
2 aperonnet 297
	 * @return le médiateur associé
298
	 */
5 aperonnet 299
	public ImageMediateur getIMediateur() {
300
		return iMediateur;
2 aperonnet 301
	}
155 aurelien 302
 
303
	public ObservationMediateur getOMediateur() {
304
		return oMediateur ;
305
	}
5 aperonnet 306
 
2 aperonnet 307
	/**
308
	 * Accesseur pour le panneau contenant l'arbre
5 aperonnet 309
	 *
2 aperonnet 310
	 * @return le panneau de l'arbre des mots clés
311
	 */
5 aperonnet 312
	public TreePanel getArbreMotsCles() {
313
		return arbreMotsCles;
2 aperonnet 314
	}
5 aperonnet 315
 
2 aperonnet 316
	/**
5 aperonnet 317
	 * Méthode héritée de Filtrable renvoie le nom du filtre
2 aperonnet 318
	 */
319
	public String renvoyerNomFiltre() {
5 aperonnet 320
 
321
		return "mots clés";
2 aperonnet 322
	}
5 aperonnet 323
 
2 aperonnet 324
	/**
325
	 * Renvoie un tableau contenant le nom du champ à filtrer et la valeur
5 aperonnet 326
	 *
2 aperonnet 327
	 * @return un tableau contenant le nom du champ à filtrer et sa valeur
328
	 */
329
	public String[] renvoyerValeursAFiltrer() {
5 aperonnet 330
 
331
		valider();
155 aurelien 332
		String[] valeursFiltrees = new String[2] ;
333
		valeursFiltrees[1] = motsClesEncours;
334
 
335
		if(iMediateur != null) {
336
			valeursFiltrees[0] = "ci_meta_mots_cles";
337
		}
338
		else
339
		{
340
			valeursFiltrees[0] = "mots_cles";
341
		}
5 aperonnet 342
 
343
		return valeursFiltrees;
2 aperonnet 344
	}
5 aperonnet 345
 
2 aperonnet 346
	/**
5 aperonnet 347
	 * Fonction récursive qui prend deux noeuds d'arbre en paramètre et crée un
348
	 * copie du sous arbre du premier noeud, qu'elle concatène au deuxième
349
	 *
350
	 * @param ndPereOriginal
351
	 *            le père des noeuds de l'arbre original
352
	 * @param ndPereCopie
353
	 *            le père qui va recevoir les copies
2 aperonnet 354
	 */
5 aperonnet 355
	private void copierFilsNoeud(Node ndPereOriginal, TreeNode ndPereCopie) {
356
		if (ndPereCopie != null && ndPereOriginal != null) {
357
			Node[] ndNodeFils = ndPereOriginal.getChildNodes();
135 aurelien 358
 
2 aperonnet 359
			for (int i = 0; i < ndNodeFils.length; i++) {
5 aperonnet 360
 
361
				String[] usObj = (String[]) ndNodeFils[i].getUserObject();
362
				TreeNode child = new TreeNode(usObj[0]);
155 aurelien 363
				child.setId(usObj[1] +prefixe);
2 aperonnet 364
				child.setChecked(false);
5 aperonnet 365
				child.setUserObject(usObj);
366
				ndPereCopie.appendChild(child);
367
 
368
				if (!ndNodeFils[i].isLeaf()) {
369
					copierFilsNoeud(ndNodeFils[i], child);
2 aperonnet 370
				}
5 aperonnet 371
 
2 aperonnet 372
			}
373
		}
374
	}
375
 
376
	/**
5 aperonnet 377
	 * Méthode héritée de Filtrable Renvoie l'état du filtre (modifié ou non)
2 aperonnet 378
	 */
379
	public boolean renvoyerEtatFiltre() {
5 aperonnet 380
 
381
		return filtreModifie;
2 aperonnet 382
	}
155 aurelien 383
 
384
	public void mettreAJourMotsCles(String valeur, String id) {
385
		if(getIMediateur() != null) {
386
			getIMediateur().mettreAjourMotsClesId(valeur,
387
				id);
388
		}
389
		else
390
		{
391
			getOMediateur().mettreAjourMotsClesId(valeur, id);
392
		}
393
	}
394
 
395
	public void obtenirArbreMotsCles() {
396
		if(getIMediateur() != null) {
397
			getIMediateur().obtenirArbreMotsCles(this);
398
		}
399
		else
400
		{
401
			getOMediateur().obtenirArbreMotsCles(this);
402
		}
403
	}
5 aperonnet 404
 
405
	public void valider() {
406
		if (estInstancie) {
2 aperonnet 407
			// on vide les mots clés en cours
5 aperonnet 408
			motsClesEncours = "";
2 aperonnet 409
			// pour chaque noeud à partir de la racine
5 aperonnet 410
			getArbreMotsCles().getRootNode().cascade(
411
					new NodeTraversalCallback() {
412
 
413
						// on éxécute une fonction
414
						public boolean execute(Node node) {
415
 
416
							// on récupère le mot clé associé au noeud et ses
417
							// infos
418
							TreeNode tn = getArbreMotsCles().getNodeById(
419
									node.getId());
420
 
421
							String[] usObject = (String[]) tn.getUserObject();
155 aurelien 422
							mettreAJourMotsCles(usObject[0], usObject[1]);
5 aperonnet 423
 
424
							if (tn.getUI().isChecked()) {
425
								// et les concatène à la string des mots clés en
426
								// cours
427
								motsClesEncours += usObject[1] + ",";
2 aperonnet 428
							}
5 aperonnet 429
 
430
							return true;
431
						}
432
 
433
					});
434
 
2 aperonnet 435
			// on suppose que le filtre a change
5 aperonnet 436
			filtreModifie = true;
2 aperonnet 437
		}
438
	}
439
 
155 aurelien 440
	public void raz() {
441
 
442
		// on vide tous les noeuds de l'ancien arbre
443
		Node[] rootChild = arbreMotsCles.getRootNode().getChildNodes();
444
		for (int i = 0; i < rootChild.length; i++) {
445
 
446
			rootChild[i].remove();
447
		}
448
 
449
		arbreInitialise = false ;
450
 
451
		// on crée une racine pour l'arbre
452
		TreeNode root = new TreeNode("Tags");
453
		root.setId("racine"+prefixe);
454
		String[] usObject = { "Mots clés", "racine" };
455
		root.setUserObject(usObject);
456
 
457
		root.setExpandable(true);
458
 
459
		arbreMotsCles.setRootNode(root);
460
 
461
		arbreMotsCles.getRootNode().addListener(new TreeNodeListenerAdapter() {
462
 
463
			public void onClick(Node node, EventObject e) {
464
				if(!arbreInitialise) {
465
					expand();
466
				}
467
			}
468
 
469
			public void onExpand(Node node) {
470
				if(!arbreInitialise) {
471
					obtenirArbreMotsCles();
472
					arbreInitialise = true;
473
				}
474
			}
475
		});
476
	}
477
 
2 aperonnet 478
}