Subversion Repositories eFlore/Applications.cel

Rev

Rev 721 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
195 david 1
package org.tela_botanica.client.vues.image;
3 aperonnet 2
 
61 jpm 3
import java.util.Iterator;
4
 
3 aperonnet 5
import org.tela_botanica.client.image.ImageMediateur;
401 aurelien 6
import org.tela_botanica.client.interfaces.ListePaginable;
3 aperonnet 7
import org.tela_botanica.client.interfaces.Rafraichissable;
61 jpm 8
import org.tela_botanica.client.modeles.ListeObservation;
9
import org.tela_botanica.client.modeles.Observation;
721 aurelien 10
import org.tela_botanica.client.util.Util;
401 aurelien 11
import org.tela_botanica.client.vues.MiniBarrePaginationVue;
3 aperonnet 12
 
61 jpm 13
import com.google.gwt.user.client.Window;
99 jpm 14
import com.gwtext.client.data.Record;
3 aperonnet 15
import com.gwtext.client.data.SimpleStore;
16
import com.gwtext.client.data.Store;
17
import com.gwtext.client.dd.DragSource;
18
import com.gwtext.client.dd.DropTarget;
19
import com.gwtext.client.dd.DropTargetConfig;
20
import com.gwtext.client.widgets.Component;
155 aurelien 21
import com.gwtext.client.widgets.Container;
99 jpm 22
import com.gwtext.client.widgets.Toolbar;
3 aperonnet 23
import com.gwtext.client.widgets.event.ContainerListenerAdapter;
99 jpm 24
import com.gwtext.client.widgets.form.ComboBox;
25
import com.gwtext.client.widgets.form.event.ComboBoxListenerAdapter;
401 aurelien 26
import com.gwtext.client.widgets.grid.CellMetadata;
3 aperonnet 27
import com.gwtext.client.widgets.grid.ColumnConfig;
28
import com.gwtext.client.widgets.grid.ColumnModel;
29
import com.gwtext.client.widgets.grid.GridDragData;
30
import com.gwtext.client.widgets.grid.GridPanel;
401 aurelien 31
import com.gwtext.client.widgets.grid.Renderer;
62 jpm 32
import com.gwtext.client.widgets.grid.event.GridListenerAdapter;
401 aurelien 33
import com.gwtext.client.widgets.grid.event.GridRowListenerAdapter;
34
import com.gwtext.client.widgets.menu.BaseItem;
35
import com.gwtext.client.widgets.menu.Item;
36
import com.gwtext.client.widgets.menu.Menu;
37
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter;
3 aperonnet 38
import com.gwtext.client.core.EventObject;
99 jpm 39
import com.gwtext.client.core.Ext;
40
import com.gwtext.client.core.ExtElement;
3 aperonnet 41
import com.gwtext.client.dd.DragData;
42
 
5 aperonnet 43
/**
63 jpm 44
 * liste d'observation pour l'association d'images aux observations
5 aperonnet 45
 * @author aurelien
46
 *
47
 */
401 aurelien 48
public class MiniListeObservationVue extends GridPanel implements Rafraichissable, ListePaginable {
3 aperonnet 49
 
5 aperonnet 50
	/**
51
	 * Le médiateur associé à la vue
52
	 */
3 aperonnet 53
	private ImageMediateur iMediateur = null ;
54
 
5 aperonnet 55
	/**
56
	 * Booléen d'instanciation
57
	 */
3 aperonnet 58
	private boolean estInstancie = false ;
59
 
5 aperonnet 60
	/**
61
	 * Le modèle de colonnes
62
	 */
63
	private ColumnModel colModel = null ;
64
 
61 jpm 65
	private SimpleStore store = null ;
66
 
408 aurelien 67
	private MiniBarrePaginationVue pgBar = new MiniBarrePaginationVue(this) ;
99 jpm 68
 
69
	private Toolbar bt = new Toolbar() ;
70
 
5 aperonnet 71
	/**
99 jpm 72
	 * Combobox permettant de selectionner le mode
73
	 * modification ou bien création
74
	 */
75
	private ComboBox selecteurMode = new ComboBox();
76
 
77
	Store storeMode = null ;
78
 
79
	private boolean liaison;
80
 
401 aurelien 81
	int pageEnCours = 0;
82
 
408 aurelien 83
	int nbElements = 0;
84
 
85
	int taillePage = 50;
86
 
638 aurelien 87
	private String modeleLieu = "IDLOCCOMMUNE, LIEUDIT, STATION";
88
 
99 jpm 89
	/**
408 aurelien 90
	 * Nombre de pages totales
91
	 */
92
	private int pageMax = 1 ;
93
 
94
	/**
5 aperonnet 95
	 * Constructeur avec arguments
96
	 * @param im le médiateur à associer à la vue
97
	 */
3 aperonnet 98
	public MiniListeObservationVue(ImageMediateur im)
99
	{
100
		iMediateur = im ;
101
 
102
		this.setId("x-view-mini-obs") ;
5 aperonnet 103
 
408 aurelien 104
		// on construit le modèle de colonnes
105
 
973 aurelien 106
		// Le store suivant est ensuite remplacé par le store contenant les données obtenus depuis le serveur (cf rafraichir)
408 aurelien 107
		Renderer colRend = new Renderer() {
108
 
109
			public String render(Object value, CellMetadata cellMetadata,
110
					Record record, int rowIndex, int colNum, Store store) {
111
 
112
				if(value == null || value.equals("null") || value.equals("000null") || value.equals("0000-00-00 00:00:00")) {
113
 
114
					return "" ;
115
				}
116
 
117
				return value.toString() ;
118
			}
119
 
120
		} ;
121
 
122
		Renderer dateRend = new Renderer() {
123
 
124
			public String render(Object value, CellMetadata cellMetadata,
125
					Record record, int rowIndex, int colNum, Store store) {
126
 
127
				if(value == null || value.equals("null") || value.equals("000null") || value.equals("0000-00-00 00:00:00")) {
128
 
129
					return "" ;
130
				}
131
				else
132
				{
133
					String dateEntiere = value.toString() ;
134
					String[] dateEtHeure = dateEntiere.split(" ", 2);
135
					if(verifierFormatDate(dateEtHeure[0])) {
136
						String[] dateFormateeTab = dateEtHeure[0].split("-",3);
137
						return dateFormateeTab[2]+"/"+dateFormateeTab[1]+"/"+dateFormateeTab[0] ;
138
					}
139
				}
140
 
141
				return value.toString() ;
142
			}
143
 
144
		} ;
145
 
5 aperonnet 146
		// on crée un store simple contenant un petit set de données et deux colonnes
973 aurelien 147
		store = new SimpleStore(new String[]{"transmis","plante","date","lieu","ordre_obs","id_obs"}, getObs());
401 aurelien 148
		ColumnConfig[] columns = {
149
		new ColumnConfig("", "transmis", 30, true, new Renderer() {
150
 
151
			public String render(Object value, CellMetadata cellMetadata,
152
					Record record, int rowIndex, int colNum, Store store) {
153
				if(value.equals("1"))
154
				{
155
					return "<img src=\"tela.png\"/></img>" ;
156
				}
157
				else
158
				{
159
					return "" ;
160
				}
161
			}
162
 
638 aurelien 163
		}),
408 aurelien 164
		new ColumnConfig("Taxon", "plante", 145, true, colRend),
165
		new ColumnConfig("Date", "date", 68, true, dateRend),
638 aurelien 166
		new ColumnConfig("Lieu", "lieu", 145, true, colRend),
973 aurelien 167
		new ColumnConfig("Numero", "ordre_obs", 50, true, colRend), } ;
3 aperonnet 168
 
5 aperonnet 169
        ColumnModel columnModel = new ColumnModel(columns);
170
 
171
        colModel = columnModel ;
155 aurelien 172
 
5 aperonnet 173
 
174
        setTitle("Observations");
175
        // on associe le modèle de colonnes
176
        setColumnModel(columnModel);
62 jpm 177
        setAutoScroll(true) ;
178
        setHeight("100%") ;
179
		setAutoWidth(true) ;
5 aperonnet 180
        // on autorise le drag 'n drop pour un certain groupe
3 aperonnet 181
 		this.setEnableDragDrop(true);
182
 		this.setDdGroup("DragGroupName");
5 aperonnet 183
        store.load();
184
		setStore(store) ;
185
 
401 aurelien 186
		setBottomToolbar(pgBar) ;
99 jpm 187
 
188
		Object[][] mode = {{"toutes les observations",false} , {"observations liées", true} };
189
		storeMode = new SimpleStore(new String[] { "nom_mode", "mode" },
190
				mode);
191
		storeMode.load();
192
		selecteurMode.setStore(storeMode);
193
		selecteurMode.setDisplayField("nom_mode") ;
194
		selecteurMode.setLabel("mode ") ;
195
		selecteurMode.setForceSelection(true) ;
196
		selecteurMode.setValue("toutes les observations") ;
197
		selecteurMode.setEditable(false) ;
100 jpm 198
		selecteurMode.setCls("x-selec-consult") ;
99 jpm 199
 
200
		bt = new Toolbar() ;
201
		bt.addField(selecteurMode) ;
202
 
155 aurelien 203
		//this.setAutoExpandColumn("plante");
204
 
99 jpm 205
		setTopToolbar(bt) ;
206
 
207
		selecteurMode.addListener(new ComboBoxListenerAdapter() {
208
 
209
			public void onSelect(ComboBox comboBox, Record record, int index) {
210
 
211
				// et on met la valeur à jour dans la combobox
212
				comboBox.setValue(record.getAsString("nom_mode"));
213
				setModification(record.getAsString("mode")) ;
214
			}
215
 
216
		});
217
 
62 jpm 218
		setAutoScroll(true) ;
5 aperonnet 219
		// on configure le drag 'n drop
220
		configDragAndDrop() ;
61 jpm 221
 
62 jpm 222
		this.addGridListener(new GridListenerAdapter() {
223
 
224
			public void onContextMenu(EventObject e) {
225
 
401 aurelien 226
				// si pas de selection, on selection au moins la ligne sur laquelle on a fait le clic
227
				if(getSelectionModel().getSelections().length <= 0) {
228
					int index = getView().findRowIndex(e);
229
			  		Record rddrop = getStore().getRecordAt(index) ;
230
					getSelectionModel().selectRecords(rddrop);
231
				}
232
 
62 jpm 233
				e.stopEvent() ;
104 jpm 234
				MenuLiaisonVue mlv = new MenuLiaisonVue(iMediateur,liaison) ;
62 jpm 235
				mlv.showAt(e.getXY()) ;
236
 
237
			}
238
 
401 aurelien 239
		}) ;
408 aurelien 240
 
241
		obtenirNombreMiniListeObservations();
3 aperonnet 242
	}
243
 
5 aperonnet 244
	/**
245
	 * Configure le drag 'n drop pour la liste
246
	 */
247
	private void configDragAndDrop()
3 aperonnet 248
	{
249
		// on choisit le texte qui sera affiché lors d'un drag 'n drop
250
		setDragDropText("Faites glisser la selection d'observations sur une image pour les lier") ;
251
 
252
		//On active le drag 'n drop
253
		this.setEnableDragDrop(true);
254
 
255
		// on fabrique la nouvelle configuration
256
		// les éléments sur lesquels on fait du drag 'n drop doivent tous avoir le même ddGroup
257
		this.setDdGroup("DragGroupName");
258
		DropTargetConfig dtc = new DropTargetConfig();
259
		dtc.setdDdGroup("DragGroupName");
260
 
261
		//La drop target permet de gérer l'évenement onDrop sur l'élement courant
262
		@SuppressWarnings("unused")
263
		DropTarget tg = new DropTarget(this, dtc)
264
		{
62 jpm 265
			public boolean notifyDrop(DragSource source, EventObject e, DragData data){
3 aperonnet 266
 
267
				// si on reçoit des données provenant d'une grille
268
				if(data instanceof GridDragData)
269
		    	  {
270
					// on la convertit
271
		    		  	GridDragData gdd = (GridDragData)data ;
272
		    		  	// et on vérifie que les données ne viennent pas de l'élément courant
273
		    		  	if(gdd.getGrid().getId().equals("x-view-mini-obs"))
274
		    		  	{
275
		    		  		return false ;
276
		    		  	}
277
		    		  	else
278
		    		  	{
279
		    		  		// on appelle le médiateur
280
		    		  		return iMediateur.lierImagesDD(source, e, data) ;
281
		    		  	}
282
		    	  }
283
				return false ;
284
			}
285
 
286
			public String notifyOver(DragSource source, EventObject e, DragData data){
287
			    return "x-dd-drop-ok";
288
			}
289
		};
290
 
291
	}
292
 
5 aperonnet 293
	/**
294
	 * Méthode héritée de l'interface rafraichissable
295
	 */
3 aperonnet 296
	public void rafraichir(Object nouvelleDonnees,
297
			boolean repandreRaffraichissement) {
298
 
61 jpm 299
		if(nouvelleDonnees instanceof ListeObservation)
300
		{
63 jpm 301
			if(this.getView() != null)
61 jpm 302
			{
63 jpm 303
				ListeObservation data = (ListeObservation)nouvelleDonnees ;
973 aurelien 304
				String[][] listeObs = new String[data.size()][6] ;
63 jpm 305
				int i = 0 ;
61 jpm 306
 
63 jpm 307
				for (Iterator it = data.keySet().iterator(); it.hasNext();)
308
				{
309
 
310
					Observation obs=(Observation) data.get(it.next());
311
 
638 aurelien 312
					listeObs[i][0] = obs.getTransmis();
313
					listeObs[i][1] = obs.getNomSaisi();
314
					listeObs[i][2] = obs.getDate() ;
315
					listeObs[i][3] = Util.formaterLieu(obs, modeleLieu);
316
					listeObs[i][4] = obs.getNumeroOrdre();
973 aurelien 317
					listeObs[i][5] = obs.getId();
61 jpm 318
 
63 jpm 319
					i++ ;
320
				}
321
 
973 aurelien 322
				store = new SimpleStore(new String[]{"transmis","plante","date","lieu","ordre_obs","id_obs"}, listeObs);
63 jpm 323
				store.load();
324
				this.reconfigure(store, colModel) ;
61 jpm 325
			}
63 jpm 326
			else
327
			{
328
				addListener(new ContainerListenerAdapter() {
329
 
330
					public void onShow(Component c)
331
					{
408 aurelien 332
						obtenirNombreMiniListeObservations() ;
63 jpm 333
					}
334
 
173 aurelien 335
					public void onAfterLayout(Container c)
336
					{
408 aurelien 337
						obtenirNombreMiniListeObservations() ;
173 aurelien 338
					}
339
 
63 jpm 340
				}) ;
341
			}
61 jpm 342
 
343
		}
344
 
408 aurelien 345
		// Si on reçoit un tableau d'entiers
346
		// c'est un tableau d'un seul entier qui est le nombre d'observation correspondant aux critères
347
		if(nouvelleDonnees instanceof int[])
348
		{
349
			int[] pages = (int[])nouvelleDonnees ;
350
 
351
			// on calcule le nombre de pages nécessaires et on les met à jour dans le modèle
352
			pageMax  = calculerNbPages(pages[0]) ;
353
			nbElements = pages[0];
354
 
355
			// et on notifie de le mediateur du changement des valeurs
356
			changerPageMaxEtCourante(pageMax,pageEnCours,taillePage,nbElements) ;
357
 
358
			masquerChargement();
359
			obtenirMiniListeObservations();
360
		}
361
 
362
		redimensionner();
363
 
99 jpm 364
		deMasquerChargement() ;
365
 
3 aperonnet 366
	}
367
 
61 jpm 368
	private void obtenirMiniListeObservations()
369
	{
408 aurelien 370
		iMediateur.obtenirMiniListeObservations(this, taillePage, pageEnCours) ;
61 jpm 371
	}
372
 
408 aurelien 373
	private void obtenirNombreMiniListeObservations()
374
	{
375
		iMediateur.obtenirNombreMiniListeObservations(this) ;
376
	}
377
 
5 aperonnet 378
	/**
379
	 * Renvoie le faux set de données pour le store
380
	 * @return un tableau à deux colonnes int - String
381
	 */
382
	private Object[][] getObs() {
3 aperonnet 383
	         return new Object[][]{
61 jpm 384
 
3 aperonnet 385
	         } ;
386
	 }
61 jpm 387
 
62 jpm 388
	public Store getStore()
389
	{
390
		return store ;
391
	}
61 jpm 392
 
401 aurelien 393
	public MiniBarrePaginationVue getBarrePagination()
99 jpm 394
	{
395
		return pgBar ;
401 aurelien 396
	}
62 jpm 397
 
99 jpm 398
	private void setModification(String mode)
399
	{
400
		if(mode.equals("true")) {
3 aperonnet 401
 
99 jpm 402
			liaison = true ;
403
			selecteurMode.removeClass("x-selec-consult") ;
404
			selecteurMode.setCls("x-selec-liaison") ;
408 aurelien 405
			getBarrePagination().disable();
406
			doLayout();
99 jpm 407
		}
408
		else
409
		{
410
			liaison = false ;
411
			selecteurMode.removeClass("x-selec-liaison") ;
412
			selecteurMode.setCls("x-selec-consult") ;
408 aurelien 413
			getBarrePagination().enable();
414
			doLayout();
99 jpm 415
		}
416
 
417
		store.removeAll() ;
418
		iMediateur.changerModeLiaison(liaison) ;
419
 
420
	}
421
 
422
	public boolean getMode() {
423
		return liaison ;
424
	}
425
 
426
	/**
427
	 * Recherche l'élement actuellement affiché et affiche son message de chargement
428
	 */
429
	public void masquerChargement()
430
	{
431
			ExtElement masked = Ext.get(getId()) ;
432
 
433
			if (masked!=null) {
434
				masked.mask("Chargement") ;
435
			}
436
	}
437
 
438
	/**
439
	 * Recherche l'élement actuellement affiché et affiche son message de chargement
440
	 */
441
	public void deMasquerChargement()
442
	{
443
			ExtElement masked = Ext.get(getId()) ;
444
 
445
			if (masked!=null) {
446
				masked.unmask() ;
447
			}
448
	}
449
 
104 jpm 450
	public String getIdSelectionnees() {
451
 
452
		Record[] sels = getSelectionModel().getSelections() ;
453
 
408 aurelien 454
		String id = "";
455
 
456
		for(int i = 0; i < sels.length; i++) {
457
			id += ","+sels[i].getAsString("id_obs") ;
458
		}
459
 
460
		id = id.replaceFirst(",", "");
461
 
104 jpm 462
		return id ;
463
 
464
	}
99 jpm 465
 
104 jpm 466
	public void supprimerLiaison() {
467
 
468
 
469
		Record[] rdObs = getSelectionModel().getSelections() ;
470
 
471
		for(int i = 0 ; i < rdObs.length ; i++) {
472
 
473
			getStore().remove(rdObs[i]) ;
474
			this.getView().refresh() ;
475
 
476
		}
477
 
478
	}
479
 
155 aurelien 480
	public void redimensionner() {
481
		if(getView() != null) {
408 aurelien 482
 
483
			int taille = 400;
484
 
485
			if(Window.getClientHeight() > 800 ) {
486
				taille = Window.getClientHeight() - 350;
487
			}
488
			setHeight(taille);
489
			getView().setForceFit(true);
490
			doLayout();
155 aurelien 491
		}
492
		else {
408 aurelien 493
 
155 aurelien 494
		}
495
	}
401 aurelien 496
 
497
	/**
498
	 * Montre le menu de liaison aux coordonnées indiquées
499
	 * @param e
500
	 */
501
	public void montrerContextMenuLiaison(EventObject e) {
502
 
503
		final Menu liObs = new Menu();
504
		final Item lierObservation = new Item("Lier aux images selectionnées");
505
		liObs.addItem(lierObservation);
506
 
507
		liObs.addListener(new MenuListenerAdapter() {
508
 
509
			// gestion du clic sur un item
510
			public void onItemClick(BaseItem item, EventObject ev) {
511
 
512
				// si c'est la suppression
513
				if (item.equals(lierObservation)) {
514
					// on notifie le médiateur
515
 
516
				}
517
 
518
				// enfin, on cache le menu
519
				liObs.hide();
520
 
521
			}
522
 
523
		});
524
 
525
		liObs.showAt(e.getXY());
526
	}
527
 
528
	public void changerNumeroPage(int pageCourante) {
529
 
530
		pageEnCours = pageCourante ;
531
		masquerChargement();
532
 
533
		// On lance le chargerment des observations
408 aurelien 534
		iMediateur.obtenirNombreMiniListeObservations(this);
401 aurelien 535
 
408 aurelien 536
	}
537
 
538
	/**
539
	 * Appelle le modèle pour qu'il change la taille de page utilisée
540
	 * @param nouvelleTaillePage la nouvelle taille de page
541
	 */
542
 
543
	public void changerTaillePage(int nouvelleTaillePage)
544
	{
545
 
546
		taillePage = nouvelleTaillePage ;
547
		pageEnCours = calculerPageCourante(nbElements) ;
548
 
549
		masquerChargement();
550
 
551
		// On lance le chargerment des observations
552
		iMediateur.obtenirNombreMiniListeObservations(this);
401 aurelien 553
 
408 aurelien 554
 
555
		// et on met à jour la taille de page dans les barres d'outils
556
		pgBar.selectionnerTaillePage(nouvelleTaillePage);
557
 
558
 
401 aurelien 559
	}
408 aurelien 560
 
561
	/**
562
	 * Met à jour les barre d'outils avec des nouvelles valeurs
563
	 * @param pageMax le nombre de pages
564
	 * @param pageEncours la page en cours
565
	 * @param taillePage la taille de page
566
	 * @param nbElement le nombre d'élements par page
567
	 */
568
	public void changerPageMaxEtCourante(int pageMax, int pageEncours, int taillePage, int nbElement)
569
	{
570
 
571
		int[] pages = {pageMax,pageEncours, taillePage, nbElement} ;
572
		pgBar.rafraichir(pages, false) ;
573
 
574
	}
575
 
576
	/**
577
	 * Calcule le nombre de pages nécessaires pour afficher un nombre d'élements donnés en fonction de la taille de page
578
	 * en cours
579
	 * @param nbElements le nombre d'élements total
580
	 * @return le nombre de pages
581
	 */
582
	public int calculerNbPages(int nbElements)
583
	{
584
		// A cause de la betise de java pour les conversion implicite on fait quelques conversions manuellement
585
		// pour eviter qu'il arrondisse mal la division
586
		// nombre de pages = (nombre d'element / taille de la page) arrondie à l'entier superieur
587
 
588
		double nPage = (1.0*nbElements)/(1.0*taillePage) ;
589
		double nPageRound = Math.ceil(nPage) ;
590
		Double nPageInt = new Double(nPageRound) ;
591
 
592
		// on convertit en entier
593
		return nPageInt.intValue() ;
594
	}
401 aurelien 595
 
408 aurelien 596
 
597
	/**
598
	 * Recalcule la page en cours lors du changement du nombre d'élements
599
	 * @param nbElements le nombre d'élements total
600
	 * @return la nouvelle page encours
601
	 */
602
	public int calculerPageCourante(int nbElements)
603
	{
604
		// on calcule le nombre de page
605
		int nouvelNbPages = calculerNbPages(nbElements) ;
606
		// la nouvelle page en cours
607
		double nPageCourante = (1.0*pageEnCours)/(1.0*pageMax) * (1.0*nouvelNbPages) ;
401 aurelien 608
 
408 aurelien 609
		// on arrondit au supérieur
610
		double nPageRound = Math.ceil(nPageCourante) ;
611
		Double nPageInt = new Double(nPageRound) ;
612
 
613
		// on convertit en entier
614
		return Math.abs(nPageInt.intValue()) ;
401 aurelien 615
	}
408 aurelien 616
 
617
	public boolean verifierFormatDate(String date) {
618
 
619
		String regex = "[1-9][0-9]{3}-[0-9]{2}-[0-9]{2}" ;
620
		if(date.matches(regex) && !date.equals("0000-00-00")) {
621
			return true ;
622
		}
623
		else {
624
			return false;
625
		}
626
	}
3 aperonnet 627
}