Subversion Repositories eFlore/Applications.cel

Rev

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