Subversion Repositories eFlore/Applications.cel

Rev

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

Rev Author Line No. Line
1940 aurelien 1
package org.tela_botanica.client.util;
2
 
1967 aurelien 3
import java.util.ArrayList;
1940 aurelien 4
import java.util.HashMap;
5
import java.util.Iterator;
1967 aurelien 6
import java.util.List;
1940 aurelien 7
import java.util.Map;
8
 
9
import org.tela_botanica.client.interfaces.Rafraichissable;
10
import org.tela_botanica.client.modeles.dao.ListeReferentielChampsEtendusDAO;
2033 aurelien 11
import org.tela_botanica.client.modeles.objets.ListeChampsEtendus;
12
import org.tela_botanica.client.modeles.objets.ListeGroupesChampsEtendus;
1940 aurelien 13
 
2392 aurelien 14
import com.google.gwt.core.client.Callback;
1940 aurelien 15
import com.google.gwt.user.client.Timer;
16
import com.google.gwt.user.client.Window;
1945 aurelien 17
import com.google.gwt.user.client.ui.HTML;
1940 aurelien 18
import com.google.gwt.user.client.ui.HorizontalPanel;
19
import com.gwtext.client.core.EventCallback;
20
import com.gwtext.client.core.EventObject;
2392 aurelien 21
import com.gwtext.client.core.Ext;
1940 aurelien 22
import com.gwtext.client.core.ListenerConfig;
23
import com.gwtext.client.data.ArrayReader;
24
import com.gwtext.client.data.FieldDef;
25
import com.gwtext.client.data.MemoryProxy;
26
import com.gwtext.client.data.Record;
27
import com.gwtext.client.data.RecordDef;
1967 aurelien 28
import com.gwtext.client.data.SimpleStore;
1940 aurelien 29
import com.gwtext.client.data.Store;
30
import com.gwtext.client.data.StringFieldDef;
31
import com.gwtext.client.widgets.Button;
2033 aurelien 32
import com.gwtext.client.widgets.Panel;
1940 aurelien 33
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
34
import com.gwtext.client.widgets.form.ComboBox;
1945 aurelien 35
import com.gwtext.client.widgets.form.Field;
1940 aurelien 36
import com.gwtext.client.widgets.form.FormPanel;
37
import com.gwtext.client.widgets.form.event.ComboBoxListenerAdapter;
2033 aurelien 38
import com.gwtext.client.widgets.layout.FormLayout;
1940 aurelien 39
 
40
@SuppressWarnings("unchecked")
41
public abstract class FormulaireSaisieChampEtendu extends FormPanel implements Rafraichissable {
42
 
43
	private final int KEY_ALT = 18;
44
	private final int KEY_BACKSPACE = 8;
45
	private final int KEY_CTRL = 17;
46
	private final int KEY_DELETE = 46;
47
	private final int KEY_DOWN = 40;
48
	private final int KEY_END = 35;
49
	private final int KEY_ENTER = 13;
50
	private final int KEY_ESCAPE = 27;
51
	private final int KEY_HOME = 36;
52
	private final int KEY_LEFT = 37;
53
	private final int KEY_PAGEDOWN = 34;
54
	private final int KEY_PAGEUP = 33;
55
	private final int KEY_RIGHT = 39;
56
	private final int KEY_SHIFT = 16;
57
	private final int KEY_TAB = 9;
58
	private final int KEY_UP = 38;
59
 
60
	final ComboBox nChamp;
2392 aurelien 61
	final String resultTplRefPerso = "<div class=\"search-item-ref\">{label_fmt}</div>";
1945 aurelien 62
	Button ajouterChampsEtenduEtFermer;
63
	Button ajouterChampsEtendu;
64
	Button annulerAjouterChampEtendu;
1940 aurelien 65
	String idChamp = null;
66
 
2033 aurelien 67
	Panel conteneurGroupesChampsEtendus;
1967 aurelien 68
	final ComboBox groupesChampsEtendus;
2033 aurelien 69
	HTML indicationSaisieGroupe;
1967 aurelien 70
 
2033 aurelien 71
	private static ListeGroupesChampsEtendus cacheGroupes;
72
 
1940 aurelien 73
	private Timer timer = null;
74
 
2033 aurelien 75
	private static Map<String, String> cacheClesValeur;
2392 aurelien 76
	private HTML descriptionChamp = null;
77
 
1945 aurelien 78
	private Record rdSelectionne = null;
1967 aurelien 79
    private Record groupeSelectionne = null;
1945 aurelien 80
	private String valeurBrute = "";
1940 aurelien 81
 
82
	public FormulaireSaisieChampEtendu() {
83
		super();
84
		setPaddings(3);
85
		setBodyBorder(false);
86
 
2033 aurelien 87
		indicationSaisieGroupe = new HTML("Vous pouvez ajouter plusieurs champs à la fois correspondant à un groupe "+
88
				"par exemple les champs des projet 'sauvages de ma rue' ou 'florilèges', etc... <br />"+
89
				"De nouveaux groupes seront ajoutés régulièrement en fonction des champs les plus utilisés");
1967 aurelien 90
		indicationSaisieGroupe.addStyleName("aideCreerChampEtendu");
91
 
92
		groupesChampsEtendus = new ComboBox();
2033 aurelien 93
		groupesChampsEtendus.setWidth("350px");
1967 aurelien 94
		groupesChampsEtendus.setLabel("Ajouter un groupe de champs");
95
		groupesChampsEtendus.setDisplayField("label") ;
2392 aurelien 96
		groupesChampsEtendus.setValueField("cle");
1967 aurelien 97
		groupesChampsEtendus.setEditable(false);
98
		groupesChampsEtendus.setHideTrigger(false);
99
		groupesChampsEtendus.setForceSelection(true);
100
		groupesChampsEtendus.setCls("champ-separation");
101
		groupesChampsEtendus.setValue("");
102
 
2033 aurelien 103
		conteneurGroupesChampsEtendus = new Panel();
104
		conteneurGroupesChampsEtendus.setBorder(false);
105
		conteneurGroupesChampsEtendus.setPaddings(0);
106
		conteneurGroupesChampsEtendus.setMargins(0);
107
		conteneurGroupesChampsEtendus.setLayout(new FormLayout());
108
		conteneurGroupesChampsEtendus.setWidth("100%");
109
 
110
		add(conteneurGroupesChampsEtendus);
111
 
112
		if(cacheGroupes == null) {
113
			ListeReferentielChampsEtendusDAO lrceDao = new ListeReferentielChampsEtendusDAO(null);
114
			lrceDao.obtenirGroupesChampsEtendus(this);
115
		} else {
116
			this.rafraichir(cacheGroupes, false);
1967 aurelien 117
		}
2033 aurelien 118
 
1945 aurelien 119
		HTML indicationSaisie = new HTML("Saisissez un nom de champ ou choisisez un nom proposé par l'autocomplétion "+
120
				"Si vous choissisez un nom de champ existant vous pourrez profiter d'une autocomplétion "+
2392 aurelien 121
				"sur les valeurs déjà saisies pour ce champ par les autres utilisateurs.<br /> "+
122
				"Les champs de la forme 'label (clé)' sont des champs 'standards' ayant un rôle et une description " +
123
				"bien définie");
1945 aurelien 124
		indicationSaisie.addStyleName("aideCreerChampEtendu");
125
		add(indicationSaisie);
126
 
1940 aurelien 127
		HorizontalPanel hp = new HorizontalPanel();
128
		hp.setBorderWidth(0);
1967 aurelien 129
 
1940 aurelien 130
		nChamp = new ComboBox("Nom du champ", "nom_champ_etendu");
2392 aurelien 131
		nChamp.setWidth("350px");
132
		nChamp.setTpl(resultTplRefPerso);
133
		nChamp.setMode(ComboBox.REMOTE);
134
		nChamp.setItemSelector("div.search-item-ref");
135
		nChamp.setTypeAhead(false);
136
		nChamp.setLoadingText("Recherche...");
137
		nChamp.setHideTrigger(true);
138
		nChamp.setValidateOnBlur(false);
139
		Store store = initStoreChampsEtendusVide();
140
		store.load();
141
	    nChamp.setStore(store);
1940 aurelien 142
		add(nChamp);
143
 
2392 aurelien 144
		descriptionChamp = new HTML();
145
		descriptionChamp.addStyleName("aideWikiChampEtendu");
146
		add(descriptionChamp);
147
 
1967 aurelien 148
		ajouterChampsEtenduEtFermer = new Button("Ajouter et fermer");
149
		ajouterChampsEtenduEtFermer.setTooltip("Ajouter un champ étendu ou un groupe de champs et fermer la fenêtre");
1940 aurelien 150
		ajouterChampsEtendu = new Button("Ajouter");
1967 aurelien 151
		ajouterChampsEtendu.setTooltip("Ajouter un champ étendu ou un groupe de champ");
1940 aurelien 152
		annulerAjouterChampEtendu = new Button("Annuler");
1945 aurelien 153
		annulerAjouterChampEtendu.setTooltip("Fermer la fenêtre sans ajouter de champ");
1940 aurelien 154
 
1945 aurelien 155
		hp.add(ajouterChampsEtenduEtFermer);
1940 aurelien 156
		hp.add(ajouterChampsEtendu);
157
		hp.add(annulerAjouterChampEtendu);
158
		add(hp);
159
 
160
		ajouterListeners();
161
	}
162
 
163
	private void ajouterListeners() {
164
		ListenerConfig listenerConfigAutocompletion=new ListenerConfig();
165
	    listenerConfigAutocompletion.setDelay(200);
166
	    listenerConfigAutocompletion.setStopPropagation(false);
167
	    listenerConfigAutocompletion.setStopEvent(true);
168
 
169
	    nChamp.addKeyPressListener(new EventCallback() {
170
 
171
			@Override
172
			public void execute(EventObject e) {
173
 
174
				switch(e.getKey()) {
175
 
176
					case KEY_ALT:
177
		    	      case KEY_CTRL:
178
		    	      case KEY_END:
179
		    	      case KEY_HOME:
180
		    	      case KEY_LEFT:
181
		    	      case KEY_PAGEDOWN:
182
		    	      case KEY_PAGEUP:
183
		    	      case KEY_RIGHT:
184
		    	      case KEY_SHIFT:
185
		    	      case KEY_TAB:
186
		    	      case KEY_UP:
187
	    	        break;
188
 
1945 aurelien 189
		    	  case KEY_ENTER:
190
  	    	    	  if(rdSelectionne != null) {
2392 aurelien 191
  	    	    		nChamp.setValue(rdSelectionne.getAsString("label"));
192
  	    	    		valeurBrute = rdSelectionne.getAsString("cle");
1945 aurelien 193
  	    	    	  }
194
	              break;
195
 
1940 aurelien 196
		    	    case KEY_DOWN:
197
  	    	    	  if(nChamp.getValueAsString().isEmpty() && !nChamp.isExpanded()) {
1945 aurelien 198
  	    	    		obtenirListeValeurs("*");
1940 aurelien 199
  	    	    	  }
200
  	    	    	break;
201
 
202
		    	    case KEY_ESCAPE:
203
		    	    	surAnnulation();
204
		    	    break;
205
 
206
		    	    default:
207
		    	    	if(timer != null) {
208
		    	    		timer.cancel();
209
		    	    	}
210
		    	    	timer = new Timer() {
211
 
212
							@Override
213
							public void run() {
1945 aurelien 214
			  	    	      	obtenirListeValeurs();
1940 aurelien 215
							}
216
						};
217
						timer.schedule(300);
2392 aurelien 218
						valeurBrute = nChamp.getRawValue();
219
						nChamp.setRawValue(valeurBrute);
1940 aurelien 220
				}
221
			}
222
	    },listenerConfigAutocompletion);
223
 
224
	    nChamp.addListener(new ComboBoxListenerAdapter() {
1945 aurelien 225
            @Override
2392 aurelien 226
			public void onSelect(ComboBox comboBox, Record record, int index) {
1945 aurelien 227
            	rdSelectionne = record;
2392 aurelien 228
            	telechargerEtAfficherDescriptionChamps(rdSelectionne.getAsString("cle"));
229
            	nChamp.setRawValue(rdSelectionne.getAsString("label"));
230
            	valeurBrute = rdSelectionne.getAsString("cle");
1945 aurelien 231
            }
2392 aurelien 232
 
233
			@Override
234
			public void onBlur(Field field) {
235
            	if(rdSelectionne != null && !rdSelectionne.getAsString("cle").equals(valeurBrute)) {
236
            		nChamp.setRawValue(valeurBrute);
237
            	}
238
            	telechargerEtAfficherDescriptionChamps(valeurBrute);
1945 aurelien 239
            }
2392 aurelien 240
         });
1940 aurelien 241
 
1967 aurelien 242
	    groupesChampsEtendus.addListener(new ComboBoxListenerAdapter() {
243
			@Override
244
			public void onSelect(ComboBox comboBox, Record record, int index) {
245
            	groupeSelectionne = record;
246
            }
247
	     });
248
 
1945 aurelien 249
	    ajouterChampsEtenduEtFermer.addListener(new ButtonListenerAdapter() {
250
			@Override
251
			public void onClick(Button button, EventObject e) {
1967 aurelien 252
				if(doitAjouterGroupe()) {
2392 aurelien 253
					surValidationMultiple(renvoyerListeChampsEtendus(groupeSelectionne.getAsString("cle")));
1945 aurelien 254
				} else {
1967 aurelien 255
					if(champEtenduEstValide()) {
256
						surValidation(validerEtRenvoyerChampEtendu());
257
					} else {
258
						Window.alert("Le nom du champ étendu ne peut pas être vide");
259
					}
260
				}
1945 aurelien 261
			}
262
		});
263
 
1940 aurelien 264
	    ajouterChampsEtendu.addListener(new ButtonListenerAdapter() {
265
			@Override
266
			public void onClick(Button button, EventObject e) {
1945 aurelien 267
				if(champEtenduEstValide()) {
268
					surAjout(validerEtRenvoyerChampEtendu());
269
					raz();
270
				} else {
271
					Window.alert("Le nom du champ étendu ne peut pas être vide");
272
				}
1940 aurelien 273
			}
274
		});
275
 
276
	    annulerAjouterChampEtendu.addListener(new ButtonListenerAdapter() {
277
			@Override
278
			public void onClick(Button button, EventObject e) {
279
				surAnnulation();
280
			}
281
		});
282
	}
283
 
1945 aurelien 284
	private void raz() {
285
		timer = null;
286
		idChamp = null;
287
		nChamp.clearValue();
288
		nChamp.focus();
289
	}
290
 
2392 aurelien 291
	private ChampSaisieEtendu validerEtRenvoyerChampEtendu() {
292
		String valeurChamp = nChamp.getRawValue();
293
		// Valeur contient soit la clé, soit le label s'il existe
294
		// valeur brute contient toujours la clé
295
		// TODO: utiliser les champs de google et pas ceux de GWT-EXT qui puent du cul
296
		ChampSaisieEtendu retour = new ChampSaisieEtendu(valeurChamp, valeurBrute);
297
		retour.setId(valeurBrute);
1945 aurelien 298
		return retour;
1940 aurelien 299
	}
300
 
1967 aurelien 301
	private List<ChampSaisieEtendu> renvoyerListeChampsEtendus(String groupe) {
302
		List<ChampSaisieEtendu> champsDuGroupe = new ArrayList<ChampSaisieEtendu>();
2033 aurelien 303
		HashMap<String, String> listeChampsEtendus = cacheGroupes.get(groupe);
1967 aurelien 304
		for (Iterator<String> iterator = listeChampsEtendus.keySet().iterator(); iterator.hasNext();) {
305
			String cle = iterator.next();
306
			String label = listeChampsEtendus.get(cle);
307
			ChampSaisieEtendu champ = new ChampSaisieEtendu(label, cle);
308
			champsDuGroupe.add(champ);
309
		}
310
 
311
		return champsDuGroupe;
312
	}
313
 
314
	private boolean doitAjouterGroupe() {
2392 aurelien 315
		return groupeSelectionne != null && !groupeSelectionne.getAsString("cle").equals("");
1967 aurelien 316
	}
317
 
1945 aurelien 318
	private boolean champEtenduEstValide() {
2392 aurelien 319
		String valeurChamp = nChamp.getRawValue();
1945 aurelien 320
		return (valeurChamp != null && !valeurChamp.isEmpty());
321
	}
322
 
1940 aurelien 323
	private boolean estUnChampSelectionne(String valeur) {
324
		return cacheClesValeur.containsValue(valeur);
325
	}
326
 
1945 aurelien 327
	private void obtenirListeValeurs() {
2392 aurelien 328
		obtenirListeValeurs(nChamp.getRawValue());
1940 aurelien 329
	}
330
 
1945 aurelien 331
	private void obtenirListeValeurs(String valeur) {
1940 aurelien 332
		ListeReferentielChampsEtendusDAO lrce = new ListeReferentielChampsEtendusDAO(null);
333
		lrce.obtenirListeNomsChampsEtendus(this, valeur+"*");
334
	}
335
 
1945 aurelien 336
	public abstract void surAjout(ChampSaisieEtendu champ);
1967 aurelien 337
	public abstract void surAjoutMultiple(List<ChampSaisieEtendu> champs);
1940 aurelien 338
	public abstract void surValidation(ChampSaisieEtendu champ);
1967 aurelien 339
	public abstract void surValidationMultiple(List<ChampSaisieEtendu> champs);
1940 aurelien 340
	public abstract void surAnnulation();
341
 
342
	public void rafraichir(Object nouvelleDonnees, boolean repandreRaffraichissement) {
343
 
2033 aurelien 344
		if(nouvelleDonnees instanceof ListeChampsEtendus) {
345
			int i = 0;
346
 
347
			ListeChampsEtendus clesLabels = (ListeChampsEtendus)nouvelleDonnees;
348
			cacheClesValeur = clesLabels;
2392 aurelien 349
			Object[][] refData = new Object[clesLabels.keySet().size()][3];
2033 aurelien 350
 
351
			for (Iterator<String> it = clesLabels.keySet().iterator(); it.hasNext();)
352
			{
353
				String cle = it.next();
2392 aurelien 354
				String label = clesLabels.get(cle);
355
 
2033 aurelien 356
				refData[i][0]= cle;
357
				refData[i][1]= label;
2392 aurelien 358
				if(cle.equals(label.toLowerCase())) {
359
					refData[i][2]= label;
360
				} else {
361
					refData[i][2]= label+" ("+cle+")";
362
				}
363
 
2033 aurelien 364
				i++;
365
			}
366
 
367
			FieldDef defCle = new StringFieldDef("cle");
368
			FieldDef defLabel = new StringFieldDef("label");
2392 aurelien 369
			FieldDef defLabelFmt = new StringFieldDef("label_fmt");
370
			FieldDef[] defTab = {defCle, defLabel, defLabelFmt};
2033 aurelien 371
 
372
			RecordDef rd = new RecordDef(defTab);
373
 
374
			final MemoryProxy dataProxy = new MemoryProxy(refData);
375
			final ArrayReader reader = new ArrayReader(rd);
376
 
377
			Store store=new Store(dataProxy,reader);
378
 
379
			nChamp.setStore(store);
380
			store.load();
1940 aurelien 381
		}
382
 
2033 aurelien 383
		if(nouvelleDonnees instanceof ListeGroupesChampsEtendus) {
384
			cacheGroupes  = (ListeGroupesChampsEtendus)nouvelleDonnees;
385
			groupesChampsEtendus.setStore(getGroupesChampsEtendusStore(cacheGroupes));
386
			if(cacheGroupes.size() > 0) {
387
				conteneurGroupesChampsEtendus.add(indicationSaisieGroupe);
388
				conteneurGroupesChampsEtendus.add(groupesChampsEtendus);
389
				doLayout();
390
			}
391
		}
1940 aurelien 392
	}
1967 aurelien 393
 
2392 aurelien 394
 
395
    private void telechargerEtAfficherDescriptionChamps(final String cle) {
396
		ListeReferentielChampsEtendusDAO.telechargerDescriptionWikini(cle, new Callback<String, String>() {
397
			@Override
398
			public void onSuccess(String description) {
399
				afficherDescriptionEtLienWikiChampEtendu(cle, description);
400
			}
401
 
402
			@Override
403
			public void onFailure(String reason) {
404
				// rien
405
			}
406
		});
407
	}
408
 
409
    private void afficherDescriptionEtLienWikiChampEtendu(final String cle, String description) {
410
    	if(description.trim().isEmpty()) {
411
			String urlDesc = ListeReferentielChampsEtendusDAO.obtenirUrlEditionDescriptionWiki(cle);
412
			descriptionChamp.setHTML("<span> Aucune description n'existe pour ce champ.<br />" +
413
					"Vous pouvez la remplir sur cette page :" +
414
					"<a id=\"lien_description_wiki_ce_"+cle+"\" href="+urlDesc+" target=\"_blank\">"+cle+"</span></span>");
415
			Ext.get("lien_description_wiki_ce_"+cle).addListener("click", new EventCallback() {
416
				@Override
417
				public void execute(EventObject e) {
418
					ListeReferentielChampsEtendusDAO.creerPageWikini(cle);
419
				}
420
			});
421
		} else {
422
			descriptionChamp.setHTML("<span class=\"descriptionChampEtenduTitre\">Description :</span> "+description);
423
		}
424
    }
425
 
2033 aurelien 426
	private Store getGroupesChampsEtendusStore(ListeGroupesChampsEtendus listeGroupesChampsEtendus) {
427
		int i = 1;
1967 aurelien 428
		Object[][] valeurs = new Object[listeGroupesChampsEtendus.size()+1][2];
429
 
430
		valeurs[0][0] = "...";
431
		valeurs[0][1] = "";
432
		if(listeGroupesChampsEtendus.size() > 0) {
433
			for (Iterator<String> it = listeGroupesChampsEtendus.keySet().iterator(); it.hasNext();)
434
			{
435
				String cle = it.next();
436
				valeurs[i][0]= cle;
437
				valeurs[i][1]= cle;
438
				i++;
439
			}
440
		}
2392 aurelien 441
		SimpleStore store = new SimpleStore(new String[] {"label","cle"},valeurs);
1967 aurelien 442
		store.load();
443
		return store;
444
	}
2392 aurelien 445
 
446
	private Store initStoreChampsEtendusVide() {
447
		Object[][] refData = new Object[0][1];
448
 
449
		FieldDef defLabel = new StringFieldDef("label");
450
		FieldDef defCle = new StringFieldDef("cle");
451
		FieldDef[] defTab = {defLabel, defCle};
452
 
453
		RecordDef rd = new RecordDef(defTab);
454
 
455
		final MemoryProxy dataProxy = new MemoryProxy(refData);
456
		final ArrayReader reader = new ArrayReader(rd);
457
 
458
		Store store = new Store(dataProxy,reader);
459
 
460
		return store;
461
	}
1940 aurelien 462
}