Subversion Repositories eFlore/Applications.cel

Rev

Rev 683 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
199 david 1
package org.tela_botanica.client.vues.observation.filtres;
54 david 2
 
90 jpm 3
import java.util.Comparator;
68 david 4
import java.util.Iterator;
5
 
54 david 6
import org.tela_botanica.client.interfaces.Filtrable;
7
import org.tela_botanica.client.interfaces.Rafraichissable;
68 david 8
import org.tela_botanica.client.modeles.EntiteGeographiqueObservation;
9
import org.tela_botanica.client.modeles.ListeEntiteGeographiqueObservation;
89 jpm 10
import org.tela_botanica.client.modeles.Observation;
54 david 11
import org.tela_botanica.client.observation.ObservationMediateur;
12
 
72 david 13
import com.google.gwt.core.client.GWT;
263 aurelien 14
import com.google.gwt.user.client.Window;
54 david 15
import com.gwtext.client.data.Node;
16
import com.gwtext.client.data.NodeTraversalCallback;
17
import com.gwtext.client.data.Tree;
18
import com.gwtext.client.widgets.Component;
19
import com.gwtext.client.widgets.Panel;
20
import com.gwtext.client.widgets.event.PanelListenerAdapter;
21
import com.gwtext.client.widgets.tree.TreeNode;
22
import com.gwtext.client.widgets.tree.TreePanel;
87 jpm 23
import com.gwtext.client.widgets.tree.event.TreeNodeListenerAdapter;
85 jpm 24
import com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter;
25
import com.gwtext.client.core.EventObject;
54 david 26
 
27
/**
199 david 28
 * Arbre Filtrant sur les entites geographiques
29
 *
54 david 30
 *
199 david 31
 * @author aurelien + david
54 david 32
 *
33
 */
199 david 34
 
35
 
68 david 36
public class ArbreEntiteGeographiqueObservationFiltreVue extends Panel implements Rafraichissable,
54 david 37
		Filtrable {
38
 
39
	/**
40
	 * Le médiateur associé à la vue
41
	 */
42
	private ObservationMediateur	observationMediateur		= null;
43
 
44
	/**
45
	 * Les localites en cours
46
	 */
68 david 47
	private String entitesGeographiquesEncours = "";
54 david 48
 
49
	/**
50
	 * Le treepanel qui affiche l'arbre
51
	 */
68 david 52
	private TreePanel arbreEntitesGeographiques = null;
54 david 53
 
68 david 54
 
54 david 55
	/**
56
	 * booléen d'initialisation
57
	 */
58
	private boolean estInstancie = false;
59
 
60
	/**
61
	 * booléen d'etat
62
	 */
63
	private boolean filtreModifie = false;
85 jpm 64
	private boolean arbreCharge = false ;
65
 
86 jpm 66
	private String nomFiltre = "" ;
67
 
54 david 68
	/**
69
	 * Constructeur sans argument (privé car ne doit pas être utilisé)
70
	 */
71
	@SuppressWarnings("unused")
68 david 72
	private ArbreEntiteGeographiqueObservationFiltreVue() {
54 david 73
		super();
74
	}
75
 
76
	/**
77
	 * Constructeur avec paramètres
78
	 *
79
	 * @param im
80
	 *            le médiateur à associer
81
	 */
68 david 82
	public ArbreEntiteGeographiqueObservationFiltreVue(ObservationMediateur obs) {
54 david 83
 
84
		// on crée le panel
168 aurelien 85
		super("Localités");
54 david 86
 
87
		this.observationMediateur = obs;
88
 
68 david 89
		arbreEntitesGeographiques = new TreePanel();
54 david 90
 
91
		this.setPaddings(5);
92
 
93
		this.setCollapsible(true);
202 david 94
 
95
		this.setAutoScroll(true);
128 aurelien 96
 
54 david 97
 
98
		// on ajoute les listeners
99
		ajouterListenersPanel();
100
		estInstancie = false;
101
	}
102
 
103
	/**
104
	 * Ajoute les listeners pour le rendu du panel
105
	 */
106
	private void ajouterListenersPanel() {
68 david 107
		  this.addListener(new PanelListenerAdapter() {
54 david 108
 
109
			// on instancie réellement les composants au moment du rendu pour
110
			// accélérer l'affichage
111
			// et éviter des bugs
112
			public void onRender(Component component) {
113
 
114
				// on interdit le drag and drop dans l'arbre
68 david 115
				arbreEntitesGeographiques.setEnableDD(false);
73 david 116
				arbreEntitesGeographiques.setId("x-view-tree-filter-entity");
54 david 117
 
118
				// on crée une racine pour l'arbre
72 david 119
				TreeNode root = new TreeNode("Localités");
70 david 120
				root.setId("racine_entite");
72 david 121
				String[] usObject = { "Localités" };
54 david 122
				root.setUserObject(usObject);
123
 
68 david 124
				arbreEntitesGeographiques.setRootNode(root);
125
				arbreEntitesGeographiques.setRootVisible(true);
126
				arbreEntitesGeographiques.setBorder(false);
85 jpm 127
				root.setExpandable(true) ;
54 david 128
 
68 david 129
				add(arbreEntitesGeographiques);
54 david 130
 
131
				// on ajoute les listeners d'évenements
132
				ajouterListeners();
133
 
134
 
135
				// enfin on considère le composant comme instancié
136
				estInstancie = true;
137
 
68 david 138
 
54 david 139
			}
140
 
141
		});
142
	}
143
 
68 david 144
 
145
 
54 david 146
	/**
70 david 147
	 * ajoute les listeners pour les boutons et le cochage des entites
54 david 148
	 */
149
	private void ajouterListeners() {
85 jpm 150
 
151
		arbreEntitesGeographiques.addListener(new TreePanelListenerAdapter() {
152
 
153
			public void onClick(TreeNode node, EventObject e) {
683 aurelien 154
				gererClicNoeud(node);
85 jpm 155
			}
156
 
157
		}) ;
87 jpm 158
 
159
		arbreEntitesGeographiques.getRootNode().addListener(new TreeNodeListenerAdapter() {
160
 
161
			public void onExpand(Node node) {
162
				if(!arbreCharge)
163
				{
164
					observationMediateur.obtenirListeEntiteGeographique() ;
165
					arbreCharge = true ;
166
				}
167
			}
168
 
169
		}) ;
54 david 170
	}
140 aurelien 171
 
683 aurelien 172
	private void gererClicNoeud(TreeNode node) {
173
 
174
		mettreAJourValeurEnCours(node);
175
		observationMediateur.obtenirNombreObservation() ;
176
	}
177
 
178
	private void mettreAJourValeurEnCours(TreeNode node) {
179
 
180
		nomFiltre = "" ;
181
		entitesGeographiquesEncours = "" ;
182
		String nomPere = "" ;
183
		String nomGrandPere = "" ;
184
		String nomArriereGrandPere = "";
185
 
186
		switch(node.getDepth())
187
		{
188
			case 0:
189
				if(!arbreCharge)
190
				{
191
					arbreEntitesGeographiques.getRootNode().expand();
192
				}
193
				else
194
				{
195
					observationMediateur.obtenirNombreObservation() ;
196
				}
197
				return ;
198
			case 4: nomFiltre += "station,lieudit,location,id_location";
199
			nomPere = ((String[])node.getParentNode().getUserObject())[0] ;
200
			nomGrandPere = ((String[])node.getParentNode().getParentNode().getUserObject())[0] ;
201
			nomArriereGrandPere = ((String[])node.getParentNode().getParentNode().getParentNode().getUserObject())[0] ;
202
			entitesGeographiquesEncours += node.getText()+","+nomPere+","+nomGrandPere+","+nomArriereGrandPere ;
203
			break;
204
			case 3: nomFiltre += "lieudit,location,id_location";
205
				nomPere = ((String[])node.getParentNode().getUserObject())[0] ;
206
				nomGrandPere = ((String[])node.getParentNode().getParentNode().getUserObject())[0] ;
207
				entitesGeographiquesEncours += node.getText()+","+nomPere+","+nomGrandPere ;
208
				break;
209
			case 2: nomFiltre += "location,id_location";
210
				nomPere = ((String[])node.getParentNode().getUserObject())[0] ;
211
				entitesGeographiquesEncours += node.getText()+","+nomPere ;
212
				break;
213
			case 1: nomFiltre += "id_location";
214
				entitesGeographiquesEncours += node.getText() ;
215
				break;
216
			default:
217
				break;
218
		}
219
 
220
		filtreModifie = true ;
221
	}
222
 
140 aurelien 223
	public void initialiser() {
224
 
225
		arbreCharge = false ;
263 aurelien 226
		entitesGeographiquesEncours = "";
140 aurelien 227
		arbreEntitesGeographiques.collapseAll();
228
		// on vide l'ancien arbre
229
		Node[] rootChild = arbreEntitesGeographiques.getRootNode().getChildNodes();
230
		for (int i = 0; i < rootChild.length; i++) {
231
 
232
			rootChild[i].remove();
233
		}
234
 
235
		arbreEntitesGeographiques.getRootNode().addListener(new TreeNodeListenerAdapter() {
236
 
237
			public void onExpand(Node node) {
238
				if(!arbreCharge)
239
				{
240
					observationMediateur.obtenirListeEntiteGeographique() ;
241
					arbreCharge = true ;
242
				}
243
			}
244
 
245
		}) ;
246
	}
54 david 247
 
248
	/**
249
	 * Méthode héritée de l'interface rafraichissable
250
	 */
251
	public void rafraichir(Object nouvelleDonnees,
252
			boolean repandreRaffraichissement) {
253
 
128 aurelien 254
 
68 david 255
		if (nouvelleDonnees instanceof ListeEntiteGeographiqueObservation) {
256
 
257
			ListeEntiteGeographiqueObservation data = (ListeEntiteGeographiqueObservation) nouvelleDonnees ;
258
 
259
				// on crée un arbre vide
166 aurelien 260
				Tree nouvelArbre = new Tree() ;
68 david 261
				TreeNode root = new TreeNode();
72 david 262
				root.setId("racine_entite");
263
				root.setText("Localités");
89 jpm 264
				String[] usObjRoot = { "Localités"};
265
				root.setUserObject(usObjRoot);
166 aurelien 266
				nouvelArbre.setRootNode(root);
68 david 267
 
89 jpm 268
				// on vide tous les noeuds
269
				arbreEntitesGeographiques.getRootNode().eachChild(new NodeTraversalCallback() {
270
 
271
					public boolean execute(Node node) {
272
						node.remove();
273
						return true;
274
					}
275
				});
263 aurelien 276
 
277
			// on la parse et on récupère les informations qui nous interessent
278
			for (Iterator<String> it= data.keySet().iterator(); it.hasNext();) {
199 david 279
 
263 aurelien 280
					EntiteGeographiqueObservation ent=(EntiteGeographiqueObservation) data.get(it.next());
281
					creerHierarchieNoeud(nouvelArbre ,root, ent);
282
					doLayout();
283
				}
284
 
166 aurelien 285
				copierFilsNoeud(root, arbreEntitesGeographiques.getRootNode());
263 aurelien 286
				arbreEntitesGeographiques.getRootNode().sort(comparerNoeuds()) ;
54 david 287
 
89 jpm 288
				// si l'arbre n'était pas encore considéré comme instancié
199 david 289
 
89 jpm 290
				if (!estInstancie) {
291
					// on signale que oui
292
					estInstancie = true;
54 david 293
				}
89 jpm 294
 
295
				// l'état du filtre est réinitialisé
296
				filtreModifie = false;
109 aurelien 297
 
89 jpm 298
				//show() ;
166 aurelien 299
				arbreEntitesGeographiques.doLayout();
54 david 300
 
301
			}
89 jpm 302
 
303
		if(nouvelleDonnees instanceof Observation)
128 aurelien 304
		{
199 david 305
			// Cas d'ajout unitaire d'une observation
306
 
128 aurelien 307
			// si l'arbre n'est pas encore chargé, on ne tient pas compte de l'ajout
308
			// l'arbre complet sera de toute façon renvoyé plus tard lors du premier chargement
309
			// de l'arbre
310
			if(!arbreCharge) {
311
				return;
312
			}
313
 
89 jpm 314
			Observation obs = (Observation)nouvelleDonnees ;
263 aurelien 315
			EntiteGeographiqueObservation ent = new EntiteGeographiqueObservation(obs.getIdentifiantLocalite(),obs.getLocalite(),obs.getLieudit(),obs.getStation());
89 jpm 316
 
263 aurelien 317
			creerHierarchieNoeud(arbreEntitesGeographiques.getTree(), arbreEntitesGeographiques.getRootNode(), ent);
89 jpm 318
 
263 aurelien 319
			doLayout();
320
			arbreEntitesGeographiques.doLayout() ;
89 jpm 321
		}
68 david 322
	}
54 david 323
 
324
 
325
	/**
326
	 * Accesseur pour le panneau contenant l'arbre
327
	 *
328
	 * @return le panneau de l'arbre des mots clés
329
	 */
330
	public TreePanel getArbreMotsCles() {
68 david 331
		return arbreEntitesGeographiques;
54 david 332
	}
333
 
334
	/**
335
	 * Méthode héritée de Filtrable renvoie le nom du filtre
336
	 */
337
	public String renvoyerNomFiltre() {
338
 
339
		return "Localités";
340
	}
341
 
342
	/**
343
	 * Renvoie un tableau contenant le nom du champ à filtrer et la valeur
344
	 *
345
	 * @return un tableau contenant le nom du champ à filtrer et sa valeur
346
	 */
347
	public String[] renvoyerValeursAFiltrer() {
348
 
349
		valider();
85 jpm 350
 
86 jpm 351
		String valeursFiltrees[] = {nomFiltre, entitesGeographiquesEncours } ;
54 david 352
 
353
		return valeursFiltrees;
354
	}
355
 
356
	/**
357
	 * Fonction récursive qui prend deux noeuds d'arbre en paramètre et crée un
358
	 * copie du sous arbre du premier noeud, qu'elle concatène au deuxième
359
	 *
360
	 * @param ndPereOriginal
361
	 *            le père des noeuds de l'arbre original
362
	 * @param ndPereCopie
363
	 *            le père qui va recevoir les copies
364
	 */
365
	private void copierFilsNoeud(Node ndPereOriginal, TreeNode ndPereCopie) {
366
		if (ndPereCopie != null && ndPereOriginal != null) {
367
			Node[] ndNodeFils = ndPereOriginal.getChildNodes();
368
 
369
			for (int i = 0; i < ndNodeFils.length; i++) {
370
 
371
				String[] usObj = (String[]) ndNodeFils[i].getUserObject();
372
				TreeNode child = new TreeNode(usObj[0]);
373
				child.setUserObject(usObj);
166 aurelien 374
				child.setId(""+usObj[1]);
54 david 375
				ndPereCopie.appendChild(child);
376
 
377
				if (!ndNodeFils[i].isLeaf()) {
378
					copierFilsNoeud(ndNodeFils[i], child);
379
				}
380
 
381
			}
382
		}
383
	}
384
 
385
	/**
386
	 * Méthode héritée de Filtrable Renvoie l'état du filtre (modifié ou non)
387
	 */
388
	public boolean renvoyerEtatFiltre() {
389
 
390
		return filtreModifie;
391
	}
392
 
393
	public void valider() {
86 jpm 394
 
54 david 395
		if (estInstancie) {
86 jpm 396
 
54 david 397
		}
398
	}
90 jpm 399
 
400
	public Comparator<TreeNode> comparerNoeuds()
401
	{
402
		return new Comparator<TreeNode>() {
54 david 403
 
90 jpm 404
			public int compare(TreeNode o1, TreeNode o2) {
405
 
109 aurelien 406
				if(o1.getText().equals("Inconnue")) {
407
					return -1 ;
408
				}
409
 
410
				if(o2.getText().equals("Inconnue")) {
411
					return 1 ;
412
				}
413
 
414
				if(o1.getDepth() == 1 && o2.getDepth() == 1)
91 jpm 415
				{
109 aurelien 416
					String l1 = o1.getText() ;
417
					String l2 = o2.getText() ;
418
					if(l1.length() == 1) {
419
						l1 = "0"+l1;
420
					}
91 jpm 421
 
109 aurelien 422
					if(l2.length() == 1) {
423
						l2 = "0"+l2;
424
					}
425
 
128 aurelien 426
					Integer n1 = 0;
427
					Integer n2 = 0;
109 aurelien 428
 
128 aurelien 429
					try{
430
						n1 = Integer.parseInt(l1) ;
431
						n2 = Integer.parseInt(l2) ;
432
					} catch(NumberFormatException ne)  {
433
						n1 = 0;
434
						n2 = 0;
435
					}
436
 
91 jpm 437
					return n1.compareTo(n2) ;
438
				}
439
				else
263 aurelien 440
				{
441
					String n1 = o1.getId() ;
442
					String n2 = o2.getId() ;
443
 
90 jpm 444
 
263 aurelien 445
					return  n1.compareToIgnoreCase(n2);
91 jpm 446
				}
90 jpm 447
			}
448
		} ;
449
	}
104 jpm 450
 
451
	public void raz() {
263 aurelien 452
 
104 jpm 453
		arbreCharge = false ;
140 aurelien 454
		arbreEntitesGeographiques.collapseAll();
104 jpm 455
		arbreEntitesGeographiques.clear() ;
456
 
457
		// on crée une racine pour l'arbre
458
		TreeNode root = new TreeNode("Localités");
459
		root.setId("racine_entite");
460
		String[] usObject = { "Localités" };
461
		root.setUserObject(usObject);
462
 
463
		arbreEntitesGeographiques.setRootNode(root);
464
 
465
		arbreEntitesGeographiques.getRootNode().addListener(new TreeNodeListenerAdapter() {
466
 
467
			public void onExpand(Node node) {
468
				if(!arbreCharge)
469
				{
470
					observationMediateur.obtenirDatesObservation() ;
471
					arbreCharge = true ;
472
				}
473
			}
474
 
475
		}) ;
476
 
263 aurelien 477
		entitesGeographiquesEncours  = "";
104 jpm 478
 
263 aurelien 479
	}
480
 
481
	private TreeNode creerNoeud(String id, String texte) {
104 jpm 482
 
263 aurelien 483
		TreeNode nouveauNoeud = new TreeNode();
484
		nouveauNoeud.setId(""+(id));
485
		nouveauNoeud.setText(texte);
486
		String[] usObj = {texte,id+""};
487
		nouveauNoeud.setUserObject(usObj);
488
 
489
		return nouveauNoeud;
104 jpm 490
	}
91 jpm 491
 
263 aurelien 492
	/**
493
	 *
494
	 * @param arbre l'arbre dans lequel on recherche s'il faut créer les noeuds
495
	 * @param root le noeud racine auquel on concatène la hierarchie crée
496
	 * @param ent l'entité géographique qui doit être décomposée en arborescence
497
	 * @return
498
	 */
499
	private void creerHierarchieNoeud(Tree arbre, TreeNode root, EntiteGeographiqueObservation ent) {
500
 
501
		String idLocation=null;
502
		String location=null;
503
		String lieuDit=null;
504
		String station=null;
505
 
506
 
507
		idLocation=ent.getIdLocalite();
508
		idLocation = idLocation.replaceAll("\"", "");
509
		idLocation = idLocation.replace('\\',' ');
510
		idLocation = idLocation.trim();
511
		location=ent.getCommune();
512
		lieuDit=ent.getLieuDit();
513
		station=ent.getStation();
514
 
515
		if(idLocation.contains("000null") || idLocation.equals(null) || (idLocation.trim()).equals("")) {
516
			idLocation="Inconnue" ;
517
		}
518
 
519
		if(location.contains("000null") || location.equals(null) || (location.trim().equals(""))) {
520
			location="Inconnue" ;
521
		}
522
 
523
		if(lieuDit.contains("000null") || lieuDit.equals(null) || (lieuDit.trim().equals(""))) {
524
			lieuDit="Inconnue" ;
525
		}
526
 
527
		if(station.contains("000null") || station.equals(null) || (station.trim().equals(""))) {
528
			station="Inconnue" ;
529
		}
530
 
531
		Node noeudMemeId = arbre.getNodeById(""+idLocation);
532
		if(noeudMemeId == null) {
533
			// on crée le noeud de l'identifiant location
534
			noeudMemeId = creerNoeud(""+idLocation,idLocation);
535
			root.appendChild(noeudMemeId) ;
536
		}
537
 
538
		// on teste si la localité existe
539
		Node noeudMemeLoc = arbre.getNodeById(""+(idLocation+location));
540
		if(noeudMemeLoc == null)
541
		{
542
			//  on crée le noeud de la location
543
			noeudMemeLoc = creerNoeud(""+idLocation+location, location);
544
			noeudMemeId.appendChild(noeudMemeLoc) ;
545
		}
546
 
547
		// on teste si le lieu dit existe
548
		Node noeudMemeLieu = arbre.getNodeById(""+(idLocation+location+lieuDit));
549
		if(noeudMemeLieu == null)
550
		{
551
			// on crée le noeud du lieu dit
552
			noeudMemeLieu = creerNoeud(idLocation+location+lieuDit, lieuDit);
553
			noeudMemeLoc.appendChild(noeudMemeLieu) ;
554
		}
555
 
556
		// on teste si la station existe
557
		Node noeudMemeStation = arbre.getNodeById(""+(idLocation+location+lieuDit+station));
558
		if(noeudMemeStation == null) {
559
			// on crée le noeud de la station
560
			noeudMemeStation = creerNoeud(idLocation+location+lieuDit+station,station);
561
			noeudMemeLieu.appendChild(noeudMemeStation);
562
		}
563
 
564
		root.sort(comparerNoeuds()) ;
565
	}
683 aurelien 566
 
567
	@Override
568
	public void viderFiltre() {
569
		arbreEntitesGeographiques.getSelectionModel().clearSelections();
570
		entitesGeographiquesEncours ="";
571
	}
572
 
573
	public void viderFiltre(String nom) {
574
 
575
		final int profondeur = calculerProfondeurPourNomFiltre(nom);
576
 
577
		// on vide tous les noeuds
578
		arbreEntitesGeographiques.getRootNode().cascade(new NodeTraversalCallback() {
579
 
580
			public boolean execute(Node node) {
581
 
582
				boolean continuer = true;
583
 
584
				TreeNode noeudArbreEncours = (TreeNode)node;
585
 
586
				if(arbreEntitesGeographiques.getSelectionModel().isSelected(noeudArbreEncours)) {
587
 
588
					int profondeurDepart = noeudArbreEncours.getDepth();
589
 
590
					for(int profondeurNoeudArbreEncours = profondeurDepart; profondeurNoeudArbreEncours >= profondeur; profondeurNoeudArbreEncours--) {
591
						noeudArbreEncours = (TreeNode)noeudArbreEncours.getParentNode();
592
					}
593
 
594
					arbreEntitesGeographiques.getSelectionModel().select(noeudArbreEncours);
595
					mettreAJourValeurEnCours(noeudArbreEncours);
596
 
597
					continuer = false;
598
				}
599
 
600
				return continuer;
601
			}
602
 
603
		});
604
	}
263 aurelien 605
 
683 aurelien 606
	private int calculerProfondeurPourNomFiltre(String nom) {
607
 
608
		int profondeur = 0;
609
 
610
		if(nom.equals("id_location")) {
611
			profondeur = 1;
612
		}
613
 
614
		if(nom.equals("location")) {
615
			profondeur = 2;
616
		}
617
 
618
		if(nom.equals("lieudit")) {
619
			profondeur = 3;
620
		}
621
 
622
		if(nom.equals("station")) {
623
			profondeur = 4;
624
		}
625
 
626
		return profondeur;
627
	}
628
 
54 david 629
}